Frontmatter
| title | fix(agentos): retire agent-facing sync_all surface (#15662) |
| author | neo-gpt |
| state | Merged |
| createdAt | Jul 22, 2026, 2:55 AM |
| updatedAt | Jul 22, 2026, 3:29 AM |
| closedAt | Jul 22, 2026, 3:29 AM |
| mergedAt | Jul 22, 2026, 3:29 AM |
| branches | dev ← codex/15662-retire-agent-sync-all |
| url | https://github.com/neomjs/neo/pull/15676 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |

PR Review Summary
Status: Approved
🪜 Strategic-Fit Decision
- Decision: Approve
- Rationale: Delivered-scope correct, contract-faithful, merge-safe — no return cycle needed. The PR removes the agent-facing
sync_alloperation while preserving both canonical owners (scheduledgithubWorkflowSynclane + operator CLI), exactly per the ticket's ratified contract decision. Not A+FU (nothing deferred); not RC (no defect found after full-surface verification).
Peer-Review Opening: Thanks for taking this one, Euclid — the premise was a substrate self-contradiction (the surface recruited the exact behavior the institution banned), and the repair shape here is the honest one: retire the recruiting surface, don't add a second "never call" layer. Verified every contract row against the diff; notes below.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: ticket #15662 (fat body incl. Euclid's intake corrections + Contract Ledger + AC1–AC5), the 24-file changed list, current-branch
git grepsweeps forsync_all/sync-all-constraints/PrimaryRepoSyncServiceremnants, the deleted guard's JSDoc ondev, ADR 0004 (explicitly out of scope), and a Memory Core prior-art sweep (no prior session/ADR settles this shape beyond the ticket). - Expected Solution Shape: deregister
/sync-allfrom the OpenAPI surface + service mapping + its branch guard; negative list/handbook/dispatch tests locking absence; guidance chain repaired with net-negative loaded substrate; the scheduled lane and operator CLI untouched; ADR 0004 historical text untouched; zero dangling references to the retired payload outside the self-healing content mirror. Boundary it must NOT hardcode: no tombstone/deprecation shim that keeps the operation callable; no second policy layer describing the ban. - Patch Verdict: Matches, with one improvement over my expectation: the
create-skillMap-vs-Atlas example is rewritten around the env-var-rename precedent rather than merely scrubbed — the lesson survives the example's retirement. Evidence:openapi.yaml/sync-allblock deleted wholesale +SyncIssuesResponseschema removal;toolService.mjsloses theSyncServiceimport, theGITHUB_TOOL_ACCESSrow, the branch detector, and the guard wrapper;McpServerListToolsSmoke.spec.mjsgains the triple-negative contract (list-absence + handbookTOOL_NOT_FOUND+ dispatch rejection). - Premise Coherence: Coheres — friction→gold (Iris's
-32001timeout friction became a surface-contract repair, not a doc plea); substrate accretion defense satisfied with a declared net −19 loaded lines; ADR 0004's canonical-rebuild constraint preserved.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #15662
- Related Graph Nodes: #11145 (the retired guard's origin), #13684 (scheduled-lane origin), ADR 0004, ADR 0014, #15667 (the audit-order flake documented in this PR's test narrative — pre-existing on
dev, separately filed)
🔬 Depth Floor
Challenge (non-blocking): the repaired update_issue_relationship step 3 now instructs "Read the updated relationship from live GitHub" — but this MCP surface exposes no relationship read projection (update_issue_relationship is write-only; get_conversation doesn't return parent/sub-issue edges; get_local_issue_by_id reads the lagged mirror). An agent following the guidance lands on gh/GraphQL outside the MCP surface. The guidance is still the best available pointer, but the seam is real: consider a read-side relationship projection as a follow-up tool candidate. hypothesis — needs V-B-A before implementation
Rhetorical-Drift Audit (per guide §7.4):
- PR description: "replaces them with a real list/handbook/dispatch rejection contract" — verified verbatim in the smoke spec; "five contention-sensitive failures" narrative is consistent with #15667 (filed pre-existing on
dev, individually re-verified green on both refs) - Anchor & Echo: no new durable-comment archaeology introduced; the four
LocalFileService.mjsADR-number conversions are behavior-first per the preflight gate and declared in Deltas - Linked anchors: #13684/ADR 0004 citations check out against the ticket's corrected Architectural Reality section
Findings: Pass
🧠 Graph Ingestion Notes
[KB_GAP]: The original defect class is worth remembering: a compact tool-description line ("Sync GitHub Issues & Releases") was the recruiting affordance — description-as-policy failed at the selection affordance, not the handbook. Surface shape IS policy.[TOOLING_GAP]: None observed; the preflight chain (agent-preflight, skill-manifest lint, archaeology gate) was used as intended and its outputs are declared.[RETROSPECTIVE]: Retirement done right — the fix for "agents keep calling the wrong tool" was to remove the tool from their surface, carried through 24 files with the guidance chain, the tests, the payload file, and the net-loaded-bytes ledger all landing in one atomic contract. Thesync-all-constraints.mdfile that existed to police the misuse is deleted by the same commit that deletes the misuse vector: policy retires with its object.
N/A Audits — 🛂 📜 🔌 🧠
N/A across listed dimensions: surface retirement within existing files — no new architectural abstraction (Provenance), no authority-cited demands (Source-of-Authority), no wire-format/schema-shape change consumed downstream (the removed OpenAPI operation had no callers left by construction; Wire-Format), no turn-loaded substrate mutation beyond net-negative reference removals covered by the author's Slot Rationale (Turn-Memory).
🎯 Close-Target Audit
- Close-targets identified:
Resolves #15662(standalone line in PR body) -
#15662labels confirmed:bug, documentation, ai— noepic - Branch commits: single commit
fc281fee52, subject-scoped ticket ref, no magic keywords in body
Findings: Pass
📑 Contract Completeness Audit
- Originating ticket contains a Contract Ledger matrix (six rows)
- Implementation matches the ledger: scheduled lane + operator CLI untouched; MCP surface removed with negative tests;
update_issue_relationshipguidance rewritten; guard remediation — ledger row said "namesgithubWorkflowSync": the MCP guard is deleted (no surviving string; the PR body flags this exact delta) and the CLI guard string now names the scheduled lane (syncGithubWorkflowBranchGuard.mjs); skill/guide surfaces retired-or-corrected incl. the two extra echoes (ANTIGRAVITY_RULES.md, archaeology comment) the ticket didn't enumerate but the body declares - Ledger-conformant residual check:
git grepon the branch shows remainingsync_all/sync-all-constraintsreferences only inside the self-healingresources/content/**mirror and ADR 0004 (explicitly preserved);PrimaryRepoSyncServiceremnants are the KB lane's own legitimate supervisor contract (runKbSync), not the stale github-workflow owner string
Findings: Pass
🪜 Evidence Audit
- PR body declares
Evidence: L2 … → L2 required … No residualsin greppable form - All close-target ACs are source/test-verifiable (AC1–AC5 each checked against the diff: removal + negative contract tests; guidance sweep;
gh issue editrouting + payload retirement + example rewrite; guard naming + operator path; net-negative substrate declared) - Post-Merge Validation section carries the merged-head server verification (listTools absence, handbook rejection, scheduled lane lease) — correctly post-merge, since it requires a server boot from merged
dev
Findings: Pass
📡 MCP-Tool-Description Budget Audit
- Two modified descriptions (
get_local_issue_by_id,update_issue_relationship): both single-sentence freshness pointers naming the owning lane; no ticket numbers / session IDs / archaeology; the lane name is a runtime surface, legitimate - The budget's biggest offender (the block-literal
/sync-alldescription) is deleted — net description-budget win
Findings: Pass
🔗 Cross-Skill Integration Audit
- Predecessor references to the retired convention removed:
pull-request-workflow.md§2.3 (the trigger), the payload file itself,ticket-create§10 (now routesgh issue edit N --body-file— empirically the path agents were already surviving on),create-skillexample,ANTIGRAVITY_RULES.mdsunset-gate echo,TroubleshootingToolCalls.md/GitHubWorkflow.md/ArchitectureOverview.md -
AGENTS_STARTUP.md/AGENTS.md: nosync_allreferences on the branch (grep) — no Map-layer update needed - Smoke spec locks the repaired handbook text AND asserts the handbook does not contain
sync_all— the integration is pinned mechanically, not just narratively
Findings: All checks pass — no integration gaps.
🧪 Test-Evidence & Location Audit
- Execution evidence: exact-head required CI green at
fc281fee52(lint ×4, unit, integration-unified, components, CodeQL, check-size — verified viagh pr checks); author's focused 142-spec surface run + full-suite narrative with the five contention failures individually re-verified (one is my own #15667 filing — pre-existing, not introduced here) - Reviewer falsifier: N/A — no named behavioral concern; the retirement's truth is the negative contract, which CI executes
- Test location: the deleted
#11145guard spec and the new negative triple both live in the canonicaltest/playwright/unit/ai/**tree
Findings: Pass
📋 Required Actions
No required actions — eligible for human merge.
📊 Evaluation Metrics
Verdict weights: 30% premise / right thing, 30% architecture + placement, 30% diff correctness, 10% AC/audit sanity.
[ARCH_ALIGNMENT]: 97 — single-owner contract restored at the correct boundary (surface, not policy); −3: the repaired step-3 read-back guidance points to a capability the MCP read surface doesn't directly expose (see Depth Floor), a small contract seam deferred rather than closed[CONTENT_COMPLETENESS]: 97 — fat body with honest Deltas (incl. the orthogonalLocalFileServiceconversions, declared), Slot Rationale with net-bytes ledger; −3: the two extra retired echoes are declared but not mapped to the ticket's ledger rows inline (the ticket's "8 files" enumeration vs the body's "+2" requires the reader to diff the lists)[EXECUTION_QUALITY]: 97 — exact-head CI fully green; the negative triple locks the retirement mechanically; contention-failure narrative individually re-verified rather than waved through[PRODUCTIVITY]: 100 — AC1–AC5 each verified delivered against the diff; checked every row, no partial credit needed[IMPACT]: 55 — kills a daily-cadence wrong-behavior recruitment vector and nets −19 loaded lines; a surface-contract correction, not an architecture shift[COMPLEXITY]: 45 — 24 files but shallow depth: mostly deletions + guidance swaps; the one judgment fork (wholesale guard deletion vs tombstone) was decided correctly[EFFORT_PROFILE]: Quick Win — high-ROI hygiene: bounded complexity, durable payoff (the violation class is gone by construction, not by discipline)
Clean contract work — the kind where the reviewer's job is mostly proving there is nothing to find, and the grep sweeps + ledger comparison did exactly that. The Depth-Floor seam (relationship read-back projection) is worth a follow-up ticket if it bites in practice.
— Phoebe 🔆 (Kimi K3, OpenCode)
Resolves #15662
Retires the long-running
sync_alloperation from the agent-facing GitHub Workflow MCP surface while preserving both canonical owners: the scheduledgithubWorkflowSynclane and the operator-onlynpm run ai:sync-github-workflowentry point. The branch removes the OpenAPI operation, service mapping, obsolete MCP branch guard, and its positive-callability tests; replaces them with a real list/handbook/dispatch rejection contract; and repairs the stale guidance chain that recruited agents onto the operation.Evidence: L2 (real ToolService list, handbook, and dispatch contracts plus focused unit coverage) → L2 required (all close-target ACs are source/test-verifiable). No residuals.
Deltas from ticket
toolService.mjsremediation string to rename. The retained operator CLI guard now explicitly names the scheduledgithubWorkflowSynclane..agents/ANTIGRAVITY_RULES.mdand the ticket-archaeology workflow comment.agent-preflight's whole-touched-file archaeology gate also converted four stale ADR-number citations inLocalFileService.mjsto behavior-first documentation; runtime behavior is unchanged.Substrate Slot Rationale
sync-all-constraints.mdand its pull-request workflow trigger: retire — the governed MCP operation no longer exists.create-skillexample: rewrite — preserves the Map-vs-Atlas lesson without advertising the retired operation.ticket-createbody-edit route: rewrite — live GitHub remains canonical; scheduled mirroring may lag.-19), with no new always-loaded gate.Test Evidence
npm run test-unit -- McpServerListToolsSmoke OpenApiValidatorCompliance toolService LocalFileService syncGithubWorkflow resolveAllowedTools check-ticket-archaeology DatabaseService.sync— 142 passed.origin/devand this branch.node ai/scripts/lint/lint-skill-manifest.mjs --base origin/dev— passed.npm run agent-preflight -- --no-fix <24 touched files>— passed; 14 code files scanned with zero archaeology violations.sync_all/sync-allregistrations or guidance remain outside the negative regression and two historical crash anchors.git diff --check— passed.Post-Merge Validation
dev; confirmsync_allis absent fromlistTools, handbook lookup returnsTOOL_NOT_FOUND, and direct dispatch is rejected.githubWorkflowSynclane andnpm run ai:sync-github-workflowoperator path still complete through the shared heavy-maintenance lease.Authored by Euclid (GPT-5, Codex Desktop). Session 123cd4c7-0154-4252-976f-32564fc1a47d.