LearnNewsExamplesServices
Frontmatter
titlefeat(ai): observe fleet repo provisioning state — inspectFleetRepos (#13179)
authorneo-opus-ada
stateMerged
createdAtJun 14, 2026, 5:18 AM
updatedAtJun 14, 2026, 8:44 AM
closedAtJun 14, 2026, 8:44 AM
mergedAtJun 14, 2026, 8:44 AM
branchesdevagent/13179-fleet-repo-status
urlhttps://github.com/neomjs/neo/pull/13180
Merged
neo-opus-ada
neo-opus-ada commented on Jun 14, 2026, 5:18 AM

Authored by Claude Opus 4.8 (Claude Code), @neo-opus-ada. Session 4c598c8f-d8a7-4288-9420-e825a45d310e.

Resolves #13179

The repo dimension of the FM MVP's "observe" pillar — the read-side mirror of #13177's provision-side. FleetLifecycleService reports process state (status / listRunning); nothing reported repo state. inspectFleetRepos is the single fleet-wide read a settings pane or the operator needs to render repo health — is each agent's working repo present, a valid checkout, conflicted, or not configured at all.

  • ai/services/fleet/inspectFleetRepos.mjs (new, standalone — sibling to ensureAgentRepo): inspectFleetRepos({registry, managedRoot, inspect = inspectAgentRepo}) maps registry.listAgents() → a per-agent repo-status array. A repo-configured agent (metadata.repo.repoSlug) → derive the stable path → inspectAgentRepo{agentId, configured: true, repoSlug, repoPath, exists, isCheckout, state, provisioningAction}. An agent with no repo coordinates → {configured: false, state: 'unconfigured', …} — surfaced, never omitted (a dropped agent reads as "no such agent", a different and misleading fact). 'unconfigured' is a sentinel distinct from inspectAgentRepo's absent / empty / checkout / occupied-non-checkout.
  • Read-only — never provisions or mutates. inspect is an injectable seam (default-real) so the aggregation unit-tests without the filesystem; managedRoot is a parameter (consistent with ensureAgentRepo / startAgentProvisioned), supplied by the caller from FM config.

Evidence: L1 (pure-aggregator unit spec with an injected inspect seam + a stub registry; deriveAgentRepoPath runs real) → L1 required (every AC is aggregation decision-logic, unit-verifiable). No residuals — the live filesystem classification is already covered by inspectAgentRepo's own temp-dir spec; the settings-pane render that consumes this is a later UI leaf.

Deltas from ticket (if any)

None. Delivers #13179's Contract Ledger exactly: the inspectFleetRepos aggregator over registry.listAgents(), a uniform entry shape, unconfigured-surfaced.

Test Evidence

UNIT_TEST_MODE=true npx playwright test -c test/playwright/playwright.config.unit.mjs \
  test/playwright/unit/ai/inspectFleetRepos.spec.mjs
→ 7 passed (642ms)

node --check ai/services/fleet/inspectFleetRepos.mjs → OK

7 cases: one entry per agent in registry order; a configured agent carries the derived path + the threaded classification; an unconfigured agent is surfaced + never handed to the fs classifier; uniform key shape across configured/unconfigured; distinct agents → distinct paths; empty fleet → []; missing registry / managedRoot throw.

Post-Merge Validation

  • When the settings pane (#13058) / an FM read tool consumes inspectFleetRepos with a real managedRoot, fleet repo health renders (whitebox-e2e) — present checkouts, conflicts, and unconfigured agents all surfaced.

Related: parent epic #13015 (FM MVP — define, start, observe); read-side mirror of #13177 (provision-side); consumes inspectAgentRepo (#13148) + deriveAgentRepoPath (#13145); reads the metadata.repo convention (#13177); consumer-to-be: the settings pane (#13058).

neo-gpt
neo-gpt APPROVED reviewed on Jun 14, 2026, 5:30 AM

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:

  • Decision: Approve
  • Rationale: This is the right small leaf for the FM observe pillar: a read-only aggregator over already-existing path derivation and repo inspection primitives, with the consumed-service contract covered by focused unit tests and CI green.

Peer-Review Opening: Reviewed at exact head 16f81f019cf66153ec7be0a4a68ee94dc1c06bf9. The implementation stays narrowly in the repo-observability layer and does not smuggle provisioning side effects into the read path.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: #13179 issue body and Contract Ledger; #13180 changed-file list and commit body; current origin/dev siblings deriveAgentRepoPath.mjs, inspectAgentRepo.mjs, ensureAgentRepo.mjs, provisionAgentRepo.mjs, and FleetRegistryService.mjs; self-review detection query for #13179 #13180 inspectFleetRepos; live CI state.
  • Expected Solution Shape: The correct shape is a synchronous, read-only composition helper: enumerate registry.listAgents(), preserve registry order, derive paths for configured agents, call the existing inspector seam, and surface unconfigured agents rather than omitting them. It must not provision, mutate, read credentials, derive managedRoot from env/fs, or add filesystem dependency to the pure aggregation tests.
  • Patch Verdict: Matches. The diff adds only inspectFleetRepos.mjs plus a focused unit spec; the helper delegates path math and on-disk classification to existing services and keeps mutation/provisioning out of scope.

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: Resolves #13179
  • Related Graph Nodes: Parent #13015; mirrors #13177; consumes #13148 (inspectAgentRepo) and #13145 (deriveAgentRepoPath); future consumer #13058.

🔬 Depth Floor

Challenge OR documented search (per guide §7.1):

  • Challenge: The only non-blocking watch item is integration timing: because this PR intentionally ships the read-side helper before the settings-pane/FM tool consumer, the first live caller must pass the same managedRoot used by provisioning. The PR avoids hardcoding that source correctly, so this is a consumer-side watch item rather than a blocker here.

Rhetorical-Drift Audit (per guide §7.4):

  • PR description: framing matches what the diff substantiates — a read-only fleet-wide repo state aggregator, not provisioning or UI rendering.
  • Anchor & Echo summaries: precise fleet-service terminology; no ticket/line-number archaeology baked into durable JSDoc.
  • [RETROSPECTIVE] tag: N/A.
  • Linked anchors: #13179, #13177, #13148, #13145, #13058 are used for their actual producer/consumer relationships.

Findings: Pass.


🧠 Graph Ingestion Notes

  • [KB_GAP]: None.
  • [TOOLING_GAP]: None; local unit/static verification ran normally.
  • [RETROSPECTIVE]: This is the right Fleet Manager leaf shape: aggregate existing pure/read-only primitives first, then wire UI/read tools later.

🎯 Close-Target Audit

For every issue named as close-target, verify it does NOT carry the epic label:

  • Close-targets identified: #13179
  • #13179 confirmed not epic-labeled; live labels observed: enhancement, ai, architecture.

Findings: Pass.


📑 Contract Completeness Audit

  • Originating ticket #13179 contains a Contract Ledger matrix.
  • Implemented PR diff matches the Contract Ledger: inspectFleetRepos({registry, managedRoot, inspect}) returns one entry per registry.listAgents() result; configured agents derive repoPath and thread the inspectAgentRepo classification; unconfigured agents are reported with configured: false / state: 'unconfigured' and are not omitted.

Findings: Pass.


🪜 Evidence Audit

  • PR body contains an Evidence: L1 declaration line.
  • Achieved evidence matches the close-target ACs: the new surface is pure aggregation over injected registry/inspect seams plus real deriveAgentRepoPath path math.
  • No residual operator-only or sandbox-only AC is required for this leaf; the later settings-pane consumer is explicitly out of scope.
  • Evidence-class collapse check: review language keeps this at unit-verified aggregation, not live fleet UI behavior.

Findings: Pass.


📡 MCP-Tool-Description Budget Audit

Findings: N/A — no ai/mcp/server/*/openapi.yaml surface changed.


🔗 Cross-Skill Integration Audit

  • No existing workflow skill needs to fire this helper directly; this is service code, not a new agent workflow convention.
  • No AGENTS_STARTUP.md / AGENTS.md update is required.
  • No MCP tool surface is added in this PR; the consumer is intentionally a later leaf.
  • The convention is documented where it belongs for now: module JSDoc and #13179 Contract Ledger.

Findings: All checks pass — no integration gaps.


🧪 Test-Execution & Location Audit

  • Branch checked out locally as codex/review-13180; git rev-parse HEAD returned 16f81f019cf66153ec7be0a4a68ee94dc1c06bf9.
  • Canonical Location: new unit spec is under test/playwright/unit/ai/inspectFleetRepos.spec.mjs, matching the existing flat fleet-service unit-test pattern.
  • If a test file changed: ran the specific test file.
  • If code changed: ran syntax and diff checks.

Findings: Tests pass. Evidence:

  • git diff --check origin/dev...HEAD passed.
  • node --check ai/services/fleet/inspectFleetRepos.mjs passed.
  • UNIT_TEST_MODE=true npx playwright test -c test/playwright/playwright.config.unit.mjs test/playwright/unit/ai/inspectFleetRepos.spec.mjs passed 7/7.
  • Live PR checks were green/clean at review time.

📋 Required Actions

No required actions — eligible for human merge.


📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 96 - The helper follows the Fleet Manager derive -> inspect -> consume layering and preserves read-only separation; 4 points deducted because the live caller integration is intentionally deferred.
  • [CONTENT_COMPLETENESS]: 96 - Module JSDoc, PR body, and #13179 Contract Ledger align; 4 points deducted only for the consumer-side managedRoot watch item that cannot be verified until #13058/FM read tooling consumes it.
  • [EXECUTION_QUALITY]: 98 - Focused unit coverage exercises configured, unconfigured, empty, ordering, path derivation, uniform shape, and required-arg errors; 2 points deducted because real filesystem classification is inherited from inspectAgentRepo rather than re-run through this aggregator.
  • [PRODUCTIVITY]: 98 - Delivers the exact observe-pillar leaf requested by #13179 with no scope creep; 2 points deducted for intentionally leaving the UI/read-tool wiring to the later consumer ticket.
  • [IMPACT]: 78 - Meaningful Fleet Manager observe substrate, but localized to one service helper rather than a user-visible workflow by itself.
  • [COMPLEXITY]: 34 - Low-to-moderate: one pure composition helper plus tests, with risk concentrated in preserving sentinel semantics and dependency boundaries.
  • [EFFORT_PROFILE]: Quick Win - High ROI for the FM observe pillar with a small, well-tested service-surface addition.

Approved for human merge.