feat(harness): discover unlinked agents (SAP-2956) - #732
Conversation
Review — PR #732
|
Follow-up review — PR #732 (round 2)Delta since Finding 1 — fixed. The "If the new agent is its own git repository" paragraph now states the Not fixed
New
Verdict: Approve — the round-1 blocker is resolved; the remaining items (stale doc refs, stale |
20e3dd2 to
5deea09
Compare
|
/claude-review |
Follow-up review — PR #732 (round 3)Delta since round 2: one commit, New
Not fixed from earlier rounds
Nothing from rounds 1–2 looks wrong on re-check. Verdict: Approve after adding the Breaking callout + migration note to the |
|
/claude-review |
Follow-up review — PR #732 (round 4)Delta since round 3 ( Round-3 finding — fixed. The changeset now carries a Breaking: callout for NewNone. Not fixed from earlier rounds (all follow-up-safe, none affect published copy or behavior)
Nothing from rounds 1–3 looks wrong on re-check. Verdict: Approve — the round-3 blocker is resolved and the remaining items are |
222ffb4 to
d377464
Compare
|
/claude-review |
Follow-up review — PR #732 (round 5)Delta since round 4 ( New
Not fixed from earlier rounds (all follow-up-safe, none affect published copy or behavior)
Nothing from rounds 1–4 looks wrong on re-check. New Verdict: Approve after re-running and updating the Validation block; the remaining items are |
|
/claude-review |
Follow-up review — PR #732 (round 6)No delta. The PR head is still Correction to round 5Round 5's only new finding said the Validation block "was measured against a tree two commits Still open from earlier rounds (all follow-up-safe; none affect published copy or behavior)
Verdict: Approve — unchanged head, round-1/2 leftovers are all follow-up-safe. |
Narrow the V0 relationship provider to its actual direct-call semantics and make invocation edges explicit before package-level data-flow evidence is introduced. Refs: SAP-2956
Call out the released system-graph wire value change and give consumers an explicit migration step. Refs: SAP-2956
Keep identity settlement independent from workspace discovery completeness, preserve background invocation refresh semantics, and format the restacked integration. Refs: SAP-2956
d377464 to
f008f5b
Compare
|
/claude-review |
| let canonicalCandidateRoot: string; | ||
| let canonicalWorkspaceRoot: string; | ||
| try { | ||
| canonicalCandidateRoot = await fs.realpath(absoluteRoot); |
| let canonicalWorkspaceRoot: string; | ||
| try { | ||
| canonicalCandidateRoot = await fs.realpath(absoluteRoot); | ||
| canonicalWorkspaceRoot = await fs.realpath(absoluteWorkspaceRoot); |
| const raw = await fs.readFile(path.join(dir, "package.json"), "utf8"); | ||
| const pkg = JSON.parse(raw) as { name?: string }; | ||
| if (pkg.name) return pkg.name; | ||
| const initialDirectory = await fs.lstat(dir); |
| if (!initialDirectory.isDirectory() || initialDirectory.isSymbolicLink()) { | ||
| return fallback; | ||
| } | ||
| const canonicalDirectoryPath = await fs.realpath(dir); |
| return fallback; | ||
| } | ||
| const canonicalDirectoryPath = await fs.realpath(dir); | ||
| const initial = await fs.lstat(packagePath); |
| let raw: string; | ||
| try { | ||
| const opened = await handle.stat(); | ||
| const beforeReadDirectory = await fs.lstat(dir); |
| try { | ||
| const opened = await handle.stat(); | ||
| const beforeReadDirectory = await fs.lstat(dir); | ||
| const beforeReadCanonicalDirectory = await fs.realpath(dir); |
| const opened = await handle.stat(); | ||
| const beforeReadDirectory = await fs.lstat(dir); | ||
| const beforeReadCanonicalDirectory = await fs.realpath(dir); | ||
| const beforeReadPath = await fs.lstat(packagePath); |
| offset += bytesRead; | ||
| } | ||
| const finalHandle = await handle.stat(); | ||
| const finalPath = await fs.lstat(packagePath); |
| ): Promise<CanonicalDirectoryEvidence> { | ||
| const absolute = path.resolve(input); | ||
| try { | ||
| const key = await fs.realpath(absolute); |
Follow-up review — PR #732 (round 6)No content delta. Head moved Public-copy check re-run on the current prose: clean. NewNone. Still open from earlier rounds (all follow-up-safe; none affect published copy or behavior)
Nothing from rounds 1–5 looks wrong on re-check. The round-5 Validation-block item now reads Verdict: Approve — restack only; the three leftovers are follow-up-safe. |
|
/claude-review |
Follow-up review — PR #732 (round 7)Delta since round 6 ( New
Still open from earlier rounds (all follow-up-safe; none affect published copy or behavior)
Nothing from rounds 1–6 looks wrong on re-check. Nit: production errors now read "Agent registry write was superseded" while the thrower Verdict: Approve — copy-only delta, correctly scoped; re-run the Validation block at |
|
/claude-review |
Follow-up review — PR #732 (round 8)Delta since round 7 ( New
Still open from earlier rounds (all follow-up-safe)
Nothing from rounds 1–7 looks wrong on re-check. Nit: Verdict: Approve once the CodeQL alerts are confirmed closed at head — the delta is |
9765c54 to
d095c22
Compare
d095c22 to
9d0e29e
Compare
|
/claude-review |
Follow-up review — PR #732 (round 9)Delta since round 8 ( New
Still open from earlier rounds (all follow-up-safe; none affect published copy or behavior)
Nothing from rounds 1–8 looks wrong on re-check. Nit: the surviving 20 s timeout keeps a 2,001-candidate scan test in the standard unit Verdict: Approve — the round-8 blocker is gone with the comments; leftovers are |
Primary change type
Problem and motivation
Studio only knew agent projects that already carried
sapiom.jsonor had been connected manually. MarkerlessdefineAgentand legacydefineOrchestrationprojects therefore stayed absent from the Workflows rail and workspace graph, while broad legacy extraction could execute project code merely to recover identity.The deterministic graph path also described its per-caller literal-call scanner as a general relationship provider. That contract could only express caller-to-target invocations, so presenting it as the future relationship model would misrepresent what its evidence proves.
Summary and scope
AgentInvocationProvider,AgentInvocationCandidate, and related invocation-specific cache/lifecycle contracts.StaticInvocationGraphEdgewithkind: "invokes"andbasis: "static-invocation"; strict browser parsing rejects the obsolete"static"basis.Direct invocation analysis scans each inventoried agent source root independently. It does not create a TypeScript
ProgramorTypeChecker, inspect invocation-input provenance, follow outputs through formatter/helper/router code, or scan arbitrary workspace router modules.Intentionally out of scope: package-wide output-to-input data-flow evidence,
feedsedges, runtime lineage, LLM inference, and backend inventory ingestion. Cross-agent data flow will use a separate package-level evidence provider.Related work
Related issue or discussion: SAP-2956
SAP-2955 replacement / PR #750 is merged and defines the current package-inventory architecture.
Validation
Verified on the published PR head
9d0e29eebb0d48892e6f88eb97fe13b033e92055after rebasing onto the merged PR #750 result:pnpm --filter @sapiom/harness exec vitest run— 171 files, 2,968/2,968 tests passedpnpm --filter @sapiom/harness test:perf— 10/10 passedpnpm --filter @sapiom/harness typecheck— passedpnpm --filter @sapiom/harness lint— passed with zero warningspnpm --filter @sapiom/harness build— passedpnpm terminology:check— 465 files passed with no stale allowlist entriespnpm terminology:check:test— 10/10 passedpnpm changeset status --since=origin/main— passedgit diff --checkand changed-file Prettier audit — passedTests and documentation
Added analyzer, registry, watcher, invocation-provider, publication, no-execution, browser-ordering, mock-parity, and production-server integration coverage. The direct-invocation boundary regression proves coordinator source yields Coordinator → Research and Coordinator → Growth without manufacturing Research → Growth data flow. Cache regressions separately prove that settled provisional identity is cacheable while incomplete workspace discovery is not. Updated the agent-discovery and workspace-system-graph contracts.
Compatibility and release impact
basis: "static"tobasis: "static-invocation"; clients validating the exact edge shape must accept the new value.@sapiom/harness.Security
AI assistance
Codex implemented and reviewed the discovery, reconciliation, watcher, direct-invocation, graph, browser, test, and documentation changes. The final branch was rebased onto the merged PR #750 result and verified with the commands and results above.
Checklist