Skip to content

feat(#478): suggest MCP reindex after a workspace clone is pulled/updated#483

Merged
atlas-apex merged 1 commit into
me2resh:devfrom
atlas-apex:feature/GH-478-reindex-after-pull
Jun 2, 2026
Merged

feat(#478): suggest MCP reindex after a workspace clone is pulled/updated#483
atlas-apex merged 1 commit into
me2resh:devfrom
atlas-apex:feature/GH-478-reindex-after-pull

Conversation

@atlas-apex

Copy link
Copy Markdown
Collaborator

Summary

  • New advisory hook suggest-mcp-reindex-after-pull.sh — closes the post-update index-staleness gap (companion to [Task] MCP-first rule doesn't reach sub-agents — they grep instead of search_code #475's post-clone hook). When a workspace/<name>/ managed-project clone's code drifts because the agent pulled new commits, nothing reindexes that project, so search_code returns stale / not_indexed excerpts and the agent silently falls back to grep. The hook fires on a git HEAD-move inside a workspace clone and reminds the agent to reindex that project, removing the "I forgot the index went stale" failure mode.
  • Trigger granularity is the coarse HEAD-move, not per-file Edit/Write — it matches git pull | merge | checkout | reset at a command boundary. Per-edit reindex prompts were explicitly rejected as far too noisy (one banner per save) and the staleness a single edited file flags is negligible; a pull can rewrite the whole tree in one step, which is exactly when the index goes meaningfully stale. A bare git fetch is not matched (it doesn't move HEAD); a git fetch && git merge compound is caught via the merge token. Rationale recorded in AgDR-0058.
  • Debounce on "Already up to date." — when the tool output shows the pull changed nothing, the banner stays silent; when the output isn't available (or the change came via merge/checkout/reset with no such marker) it fires anyway. Tradeoff: over-firing a cheap advisory beats under-firing, because a real un-reindexed drift produces silent stale results — the precise failure [Task] Reindex workspace clones after git pull — MCP index goes stale (companion to #475) #478 exists to prevent.
  • Project detection is cwd-first with path-arg fallbacks — a git pull is normally run from inside the clone (cwd = workspace/<name>), so the hook reads .cwd / .tool_input.cwd from the PostToolUse payload first, then falls back to an explicit -C <path>, a cd <path> && prefix, or any bare workspace/<name> token. cwd-based detection depends on the harness populating cwd in the payload; the fallbacks cover the rest. The suggestion is scoped to the changed project only — never a portfolio-wide reindex. Skips failed commands (exit_code != 0) and non-workspace pulls.
  • Advisory, non-blocking, exit 0 always — same shape as the clone sibling and check-upstream-drift.sh; graceful when the MCP server is unavailable. Wired as a PostToolUse Bash hook with if: "Bash(git *)"; the hook's internal command-boundary match keeps it a fast no-op on git push/commit/add/clone and on non-workspace pulls. Hook count 37 → 38 updated across CLAUDE.md and site/* (site-counts test green).

Testing

  1. bash .claude/hooks/tests/test_suggest_mcp_reindex_after_pull.shPASS: 19, FAIL: 0 — covers cwd-based / -C / cd-prefix / merge / checkout / reset fire, and silent on non-workspace pull / failed command / "Already up to date." / bare git fetch / non-git command / Edit / Write.
  2. bash .claude/hooks/tests/test_suggest_mcp_reindex_after_clone.shPASS: 11, FAIL: 0 (no regression in the sibling hook).
  3. bash .claude/hooks/tests/test_site_counts.shgreen (hooks: 38 across all scanned site/* files).
  4. shellcheck -S warning .claude/hooks/suggest-mcp-reindex-after-pull.sh → clean.
  5. markdownlint-cli2 on docs/agdr/AgDR-0058-*.md and CLAUDE.md → only MD060 (ignored per repo convention).

Closes #478


Glossary

Term Definition
PostToolUse hook A Claude Code hook that runs after a tool call completes. This hook reads the Bash command + its tool_response.exit_code and emits an advisory banner to stderr.
Advisory (non-blocking) hook A hook that always exits 0 and only prints a banner — it cannot stop the agent, only nudge it. Same shape as check-upstream-drift.sh and the clone-reindex sibling.
HEAD-move A git operation that changes which commit HEAD points at — pull, merge, checkout <branch>, reset --hard. The moment a workspace clone's tree can change wholesale, hence the moment its search index can go stale.
MCP reindex mcp__apexyard-search__reindex(scope="project", project="<name>") — rebuilds the apexyard-search index for one project so search_code / search_docs return fresh results instead of stale or not_indexed ones.
workspace/<name>/ The (gitignored) directory under the ops fork where live working copies of managed-project repos are cloned. <name> is the registered project name.
Debounce Suppressing the banner when the pull changed nothing ("Already up to date.") so an up-to-date clone doesn't nag.
AgDR Agent Decision Record — captures the options considered and the rationale for a technical decision. AgDR-0058 records the trigger-granularity and debounce tradeoffs here.

…ated

Companion to #475 (post-clone reindex hook). Closes the post-UPDATE
index-staleness gap: when a workspace/<name>/ clone's code drifts because
the agent pulled new commits, nothing reindexes that project, so
search_code returns stale/not_indexed results and the agent silently falls
back to grep.

- New advisory hook suggest-mcp-reindex-after-pull.sh fires on a git
  HEAD-move (pull / merge / checkout / reset) inside a workspace clone and
  emits a stderr banner naming the project-scoped reindex call. Exit 0
  always — non-blocking, mirrors the clone sibling + check-upstream-drift.
- Trigger granularity is the coarse HEAD-move, NOT per-file Edit/Write
  (per-edit prompts would be far too noisy; a single edited file barely
  moves the index). AgDR-0058 records this + the debounce tradeoff.
- Debounce: silent on "Already up to date." when the output is visible;
  fires otherwise (over-firing a cheap advisory beats under-firing).
- Project detection: cwd-first (.cwd / .tool_input.cwd — the common case,
  pull run from inside the clone), with -C / cd-prefix / bare-path
  fallbacks. Skips failed commands and non-workspace pulls.
- Scoped to the changed project only — never a portfolio-wide reindex.
- Wired as a PostToolUse Bash hook (Bash(git *)); test covers cwd / path /
  merge / checkout / reset fire + silent on non-workspace / failed /
  up-to-date / non-git / Edit/Write. Hook count 37 -> 38 across CLAUDE.md
  and site/* (site-counts test green).

Closes #478

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@atlas-apex atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: PR #483

Commit: a7b061219737fa26b5dd55e0e075998641839b8f

Summary

Adds a PostToolUse advisory hook (suggest-mcp-reindex-after-pull.sh, #478) that nudges the agent to reindex a single managed project after a git HEAD-move (pull/merge/checkout/reset) inside its workspace/<name>/ clone. Companion to #475's post-clone hook. Ships the hook, a 19-case test, settings wiring, AgDR-0058, and consistent hook-count bumps (CLAUDE.md 25->26 curated narrative; site/* 37->38 gated).

Checklist Results

  • Architecture & Design: Pass
  • Code Quality: Pass
  • Testing: Pass
  • Security: Pass -- no secrets, no injection surface; reads JSON payload via jq, emits stderr only
  • Performance: Pass -- fast no-op on the dominant git push/commit/non-workspace path
  • PR Description & Glossary: Pass -- narrative summary + 7-term glossary + AgDR marker
  • Summary Bullet Narrative: Pass -- every bullet states what + why
  • Technical Decisions (AgDR):Pass -- AgDR-0058 present, all 5 template sections, marker linked
  • Adopter Handbooks: N/A -- no language handbook triggers (shell + md + html diff)

Verification performed (on PR HEAD a7b0612)

  • test_suggest_mcp_reindex_after_pull.sh -> PASS: 19, FAIL: 0
  • test_suggest_mcp_reindex_after_clone.sh (sibling, no-regression) -> PASS: 11, FAIL: 0
  • test_site_counts.sh -> green (find-derived hooks=38, asserted across all site/*)
  • shellcheck -S warning on hook AND test -> clean (no warnings/errors)
  • jq empty .claude/settings.json -> valid JSON
  • Exit-0-always confirmed: every exit in the hook is exit 0 (6 early no-ops + final); no set -e, so a grep miss cannot abort with non-zero. Executable bit 100755.
  • Trigger correctness (adversarial):
    • git fetch && git checkout main -> fires (caught at && boundary by checkout token)
    • echo git pull -> silent (no command-boundary match on pull after echo)
    • git push / git commit -> silent
    • bare git fetch, "Already up to date.", exit_code!=0, Edit/Write -> silent
    • project parse scoped to the changed project (workspace/), cwd-first with -C / cd / bare-token fallbacks
  • Settings wiring mirrors the clone hook: same pin-dir-then-walk-up ops-root resolver, [ -d .claude/hooks ] || exit 0 guard, exec into the hook. if: "Bash(git *)" is correctly broader than the clone hook's git clone * since pull/merge/checkout/reset are all git *; the internal regex narrows to HEAD-moves.

Count convention note (not a defect)

CLAUDE.md's curated narrative says "26 shell scripts" while site/* say "38". Confirmed this is the documented dual-count convention, not a drift bug: the gating test_site_counts.sh derives actual_hooks=38 via find .claude/hooks -maxdepth 1 -name '*.sh' ! -name '_lib*' and scans ONLY site/* files -- CLAUDE.md is intentionally outside its scan set. Both numbers were bumped consistently on their own scales (25->26, 37->38). Gating check is green.

Issues Found

None blocking.

Suggestions

  • nit: git checkout -- <file> (a working-tree file restore that does NOT move HEAD) over-fires the banner, since the regex matches checkout\b regardless of branch-vs-path argument. Benign -- the working tree genuinely changed and a project-scoped reindex is still reasonable -- and consistent with AgDR-0058's explicit "over-firing a cheap advisory beats under-firing" tradeoff. No change required; flagging for awareness only.

Verdict

APPROVED


Reviewed by Rex (Code Reviewer Agent)
Reviewed commit: a7b0612

@atlas-apex atlas-apex merged commit c83681e into me2resh:dev Jun 2, 2026
5 checks passed
me2resh added a commit that referenced this pull request Jun 5, 2026
…ated (#483)

Companion to #475 (post-clone reindex hook). Closes the post-UPDATE
index-staleness gap: when a workspace/<name>/ clone's code drifts because
the agent pulled new commits, nothing reindexes that project, so
search_code returns stale/not_indexed results and the agent silently falls
back to grep.

- New advisory hook suggest-mcp-reindex-after-pull.sh fires on a git
  HEAD-move (pull / merge / checkout / reset) inside a workspace clone and
  emits a stderr banner naming the project-scoped reindex call. Exit 0
  always — non-blocking, mirrors the clone sibling + check-upstream-drift.
- Trigger granularity is the coarse HEAD-move, NOT per-file Edit/Write
  (per-edit prompts would be far too noisy; a single edited file barely
  moves the index). AgDR-0058 records this + the debounce tradeoff.
- Debounce: silent on "Already up to date." when the output is visible;
  fires otherwise (over-firing a cheap advisory beats under-firing).
- Project detection: cwd-first (.cwd / .tool_input.cwd — the common case,
  pull run from inside the clone), with -C / cd-prefix / bare-path
  fallbacks. Skips failed commands and non-workspace pulls.
- Scoped to the changed project only — never a portfolio-wide reindex.
- Wired as a PostToolUse Bash hook (Bash(git *)); test covers cwd / path /
  merge / checkout / reset fire + silent on non-workspace / failed /
  up-to-date / non-git / Edit/Write. Hook count 37 -> 38 across CLAUDE.md
  and site/* (site-counts test green).

Closes #478

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants