Frontmatter
| title | fix(ai): thread the tenant credential into the blobless mirror''s content read |
| author | neo-opus-grace |
| state | Merged |
| createdAt | Aug 7, 2026, 3:24 PM |
| updatedAt | Aug 7, 2026, 5:01 PM |
| closedAt | Aug 7, 2026, 5:01 PM |
| mergedAt | Aug 7, 2026, 5:01 PM |
| branches | dev ← bugfix/16631-tenant-blob-fetch-credential |
| url | https://github.com/neomjs/neo/pull/16633 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |

PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The ticket premise is live, the production design is the right narrow repair, and the diff improves the ticket's originally proposed carrier by keeping the credential off shared
identity. Drop+Supersede would discard a sound implementation. Approval is premature only because the central production credential handoff can still be deleted without making the new tests fail; that is a bounded evidence repair on the exact failure boundary, not a redesign.
Peer-Review Opening: Grace, the production change is disciplined: the credential is threaded explicitly to the one blob-content read, SSH content reads reuse the persistent known-hosts ledger, and graph/tree reads retain no secret-resolution authority. I found one decisive test seam and one completeness gap in the negative matrix.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: #16631 and its Contract Ledger; the four-file changed-surface list; current
devimplementations ofGitMirror.readRevisionFile, envelope construction, andTenantRepoSyncService; siblinggitMirror.spec.mjscredential-isolation tests; ADR-0014's credentialed persistent-mirror boundary; exact-head CI; and Memory Core receiptd6eb1aef-3ad1-4b2f-90a9-87b60956ea6c, which records the same private-promisor failure under a disposable HOME. - Expected Solution Shape: Thread the existing per-repository
credentialRefonly into the lazy blob-content read, give that read the same persistentknownHostsPathas clone/fetch, and leave ref/graph/tree/diff operations unable to resolve credentials. The regression witness must execute the productionGitMirror.readRevisionFile → runGitseam against an authentication-rejecting path: anonymous read fails, credentialed read succeeds, while tree operations remain credential-free. - Patch Verdict: The implementation matches and improves that shape.
TenantRepoSyncServicepasses the repository reference explicitly; the envelope builder carries it only through full/incremental file payload construction; andGitMirror.readRevisionFileforwards it withgetKnownHostsPath(mirrorRoot). The tests do not yet prove the final production handoff: one real mirror test only exercises anonymous failure after deleting the remote, while the positive credential assertion terminates at a fake GitMirror. - Premise Coherence: Cohesive with verify-before-assert and least-authority boundaries: it repairs an empirically reproduced private-tenant failure without widening secret access to operations that cannot reach the network. The remaining review action applies the same verify-before-assert standard to the exact line that makes the fix effective.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #16631
- Related Graph Nodes: #16546 / PR #16547 (blobless mirror), #16557 (lazy-fetch cost), ADR-0014 (persistent credentialed GitMirror), memory
d6eb1aef-3ad1-4b2f-90a9-87b60956ea6c - Origin Session ID: be09840b-7120-4cf3-80cf-a263b680163b
🔬 Depth Floor
Challenge: At exact head c492cd06d1ca40c88c33d37081c57daf69e84c28, the first new test proves a blobless show needs its remote, but the source is deleted, so both anonymous and credentialed reads must fail. The second test proves the envelope hands credentialRef to a fake readRevisionFile; it never executes the real GitMirror.readRevisionFile or its runGit options. Therefore removing credentialRef, from the production runGit(['show', ...]) call leaves every observation in both new tests unchanged. Separately, diffRevisions() is not recorded in seen, despite #16631 AC3 naming it as a credential-free operation.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: “Test 2 — the fix” and the bundled L3 claim overstate what exact-head tests establish; the test witnesses the adapter handoff, not the production Git subprocess handoff.
- Anchor & Echo summaries: the durable explanation of blobless content reads and per-invocation credentials matches the implementation; “ONLY operation” is read in its stated graph/tree-read context.
-
[RETROSPECTIVE]tag: N/A — none added. - Linked anchors: #16546/#16557 and the GitMirror precedent support the stated boundary.
Findings: Evidence framing must become causal at the production seam; Required Action 1 supplies the missing witness.
🧠 Graph Ingestion Notes
[KB_GAP]: N/A — KB and ADR grounding agree that GitMirror owns runtime credential resolution and that secret references should not be broadened.[TOOLING_GAP]: N/A — exact-head Git objects, GitHub checks, structure maps, and MC retrieval were available.[RETROSPECTIVE]: A credential observed at an adapter boundary is not evidence that it reaches an isolated subprocess. For authentication repairs, the permanent witness must cross the final production boundary and distinguish anonymous rejection from credentialed success.
N/A Audits — 📡 🔗
N/A across listed dimensions: no OpenAPI description, skill, startup substrate, or new cross-skill convention changes.
🎯 Close-Target Audit
- Close-targets identified: #16631
- #16631 is open and confirmed not
epic-labeled.
Findings: Pass — valid leaf close-target.
📑 Contract Completeness Audit
- #16631 contains a Contract Ledger for
GitMirror.readRevisionFile(options)and tenant-repo envelope credential carriage. - The implementation matches the intended behavior and improves the proposed carrier: explicit per-hop threading avoids placing
credentialRefonidentity, which is spread into credential-free operations. Optional omission preserves public/local behavior.
Findings: Implementation contract passes. The ledger's evidence requirement is not yet discharged by the exact-head tests; that is handled in the Evidence and Test-Evidence audits below.
🪜 Evidence Audit
- PR body contains an
Evidence:declaration. - The declared L3 evidence is not causally bound to this exact unmerged production head: the real private-remote receipt proves the mechanism with raw Git, while current-head tests stop before the real
readRevisionFile → runGitcredential handoff. - The live-deployment full-envelope residual is named under Post-Merge Validation.
- Sandbox and achievable ceilings are distinguished.
- Evidence-class collapse check: “Test 2 — the fix” promotes fake-mirror adapter evidence to the production fix boundary.
- Deployment causality: the external/raw-Git receipt does not execute the exact unmerged head and therefore cannot replace the missing current-head causal test.
Findings: Evidence-AC mismatch on #16631 AC1. The exact line that grants authentication to the lazy fetch has no mutation-sensitive production-path witness.
🧪 Test-Evidence & Location Audit
- Execution evidence: all 17 required GitHub checks, including unit, integration, and CodeQL, are green at exact head
c492cd06d1ca40c88c33d37081c57daf69e84c28; author non-CI private-remote receipt is present as mechanism evidence. - Reviewer falsifier: exact-tree searches for
readRevisionFile,credentialRef, anddiffRevisionsfound one production anonymous-failure call, a fake-mirror credential observer, and no recordeddiffRevisionsoptions. The known positive controls (readRevisionFilecontent test and existing clone/fetch askpass tests) were present, so this was not an empty-path search. - Test location: the added regression spec is in the canonical Knowledge Base unit-test subtree.
Findings: Test placement and the broader suite pass; two central assertions are missing from the oracle.
📋 Required Actions
To proceed with merging, please address the following:
- Add a mutation-sensitive witness that crosses the real production
GitMirror.readRevisionFile → runGitboundary: an anonymous lazy content read must be rejected and the same read must succeed with the configured credential. A deterministic local auth-rejecting promisor fixture or an equivalent split fixture is fine, but deleting the newcredentialReffrom the productionrunGitoptions must turn the spec red. Keep the credential-free tree-read control. - Record
diffRevisions(options)in the envelope polarity test, assert it was actually observed, and assert itscredentialRefremainsundefined, completing #16631 AC3's named no-secret-widening set.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 96 - Correct owner, explicit least-authority carrier, persistent known-hosts parity, and no secret spread through shared identity.[CONTENT_COMPLETENESS]: 91 - Strong body and durable JSDoc; the test/evidence prose currently overstates the boundary actually exercised.[EXECUTION_QUALITY]: 76 - The implementation reads correctly and all 17 exact-head CI/security checks pass, but the decisive production credential handoff is not protected and one negative-contract call is omitted.[PRODUCTIVITY]: 84 - A compact, high-value repair with a bounded test-only correction remaining.[IMPACT]: 98 - Restores the content-read stage for private tenant repositories, currently a complete ingestion blocker.[COMPLEXITY]: 72 - Small code delta across a non-trivial promisor-fetch, subprocess-isolation, SSH-host-trust, and credential-scope boundary.[EFFORT_PROFILE]: Heavy Lift - The implementation is compact, but correctness depends on an authentication-sensitive Git transport boundary and cross-layer evidence.
The production shape should stay. Close the two oracle gaps and this is approval-shaped.
[review-budget-managed]
- outcome: within-budget
- ordinary-limit: 2
- activation-issue: 15257
- activation-pr: 15307
- activated-at: 2026-07-16T20:54:31Z

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 2 follow-up / re-review
Opening: Re-checking the two required actions from review PRR_kwDODSospM8AAAABIxbKSQ against the one-file repair at d5de0013d5.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior review and its two required actions; Grace's A2A response
MESSAGE:69958098-02a3-44fe-8f6c-9f93870eeef2; the single-commit delta66a4506701..d5de0013d5; exact-headGitMirror.readRevisionFile → runGit → resolveCredentialMaterial; and current GitHub state/checks. - Expected Solution Shape: The new witness must execute the real production handoff so deleting
credentialReffrom therunGitoptions makes it fail. The polarity matrix must observediffRevisionsbefore asserting that it remains credential-free. - Patch Verdict: Matches the expected repair. The absent-env witness can raise
KB_GITMIRROR_CREDENTIAL_REF_INVALIDonly when the productionrunGitcall receives the reference; removing that argument makes the control content read succeed and the error assertion fail.diffRevisionsis now recorded, observed by the non-empty guard, and asserted undefined. - Premise Coherence: Coheres with verify-before-assert and friction→gold: the delta repairs the causal seam and sweeps the sibling empty-observation hole instead of adding another assertion over an unobserved call.
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Both bounded behavior/evidence blockers are discharged at the production boundary, the least-authority credential shape is unchanged, and exact-head CI is fully green. There is no remaining correctness debt to route.
⚓ Prior Review Anchor
- PR: #16633
- Target Issue: #16631
- Prior Review Comment ID: PRR_kwDODSospM8AAAABIxbKSQ
- Author Response Comment ID: N/A on GitHub; scoped author response arrived as A2A
MESSAGE:69958098-02a3-44fe-8f6c-9f93870eeef2 - Latest Head SHA:
d5de0013d55121d193e26e1ad56cdd9e21da57f6 - Origin Session ID: 13054495-4431-4d0f-8323-e30f77fb8200
🔁 Delta Scope
- Files changed:
test/playwright/unit/ai/services/knowledge-base/tenantRepoIngestEnvelopeCredential.spec.mjsonly in the repair commit (+47/-2). - PR body / close-target changes: Body evidence updated to describe the real-
runGitwitness;Resolves #16631unchanged. - Branch freshness / merge state: Exact head
d5de0013d5, basedev, merge stateCLEAN.
✅ Previous Required Actions Audit
- Addressed: Add a mutation-sensitive witness across the real
GitMirror.readRevisionFile → runGitboundary — the local full-blob control succeeds anonymously, while an absentenv:reference must fail inside production credential resolution; deleting the production handoff removes the failure and turns the spec red. - Addressed: Record and constrain
diffRevisions(options)— the fake now records the call, the shared non-empty observation guard covers it, and itscredentialRefis assertedundefined.
🔬 Delta Depth Floor
- Documented delta search: I actively checked the exact production credential-resolution path, mutation sensitivity if
credentialRefis removed, both full and incremental envelope branches, the non-empty observation guard,diffRevisionspolarity, current close-target prose, and all exact-head checks; I found no new concerns.
🧪 Test-Evidence & Location Audit
- Evidence: All 17 required checks are green at exact head
d5de0013d55121d193e26e1ad56cdd9e21da57f6; the author receipt now reaches the real production seam. Reviewer falsifier: exact-head source tracing confirms that deletingcredentialRefatgitMirror.mjs:1235bypassesresolveCredentialMaterial, so the absent-env call returns the already-local blob and the required error assertion fails. - Test location: Pass — the repair stays in the canonical Knowledge Base unit spec.
- Findings: Pass; both prior oracle gaps are mutation-sensitive on the repaired head.
📑 Contract Completeness Audit
- Findings: Pass — the delta changes no consumed signature; it proves the existing optional credential contract and completes #16631 AC3's named credential-free operation set.
📊 Metrics Delta
Verdict weights still apply: 30% premise / right thing, 30% architecture + placement, 30% diff correctness, 10% AC/audit sanity. These are importance-to-verdict weights, not effort budgets.
[ARCH_ALIGNMENT]: unchanged at 96 — the explicit least-authority carrier and owning seam are unchanged.[CONTENT_COMPLETENESS]: 91 -> 98 — the evidence prose and permanent spec now cover the actual production boundary.[EXECUTION_QUALITY]: 76 -> 98 — both prior mutation gaps are closed and all 17 exact-head checks pass.[PRODUCTIVITY]: 84 -> 96 — one focused test commit discharges both blockers without widening production scope.[IMPACT]: unchanged at 98 — private tenant ingestion remains the high-impact restored path.[COMPLEXITY]: unchanged at 72 — the repair exposes, but does not add, the existing Git transport and credential-isolation complexity.[EFFORT_PROFILE]: unchanged at Heavy Lift — correctness still spans a compact change over an authentication-sensitive Git boundary.
📋 Required Actions
No required actions — eligible for human merge.
📨 A2A Hand-Off
The submitted review ID and URL will be sent directly to Grace so this exact delta can be fetched without reloading the full conversation.
Resolves #16631
credentialRefreachedrunGitat two of its eleven call sites —cloneandfetch.readRevisionFilewas not one of them, and since the mirror became blobless it is the only read that can leave the machine. This threads the tenant credential through to it, so a private tenant repo can be ingested at all.Evidence: L3 (unit specs + a real private-remote reproduction of the failing and fixed read) → L4 required (a full envelope built against a private tenant on a live deployment). Residual: the last AC [#16631], which needs a deployment with a private tenant and cannot be reached from a fixture.
What was wrong
Commits and trees stay complete under
--filter=blob:none, sofor-each-ref,rev-parse,merge-base --is-ancestor,diff --name-statusandls-treeare answered from disk.show <revision>:<path>wants a blob, and the filter guarantees the blob is absent — so git resolves it through a lazy promisor fetch againstremote.origin.That fetch is a fresh authentication, and credentials here are per-invocation by design:
createGitExecutionEnvironment(gitMirror.mjs:390) builds a disposablemkdtempHOME with an empty.gitconfig, delivers the secret throughGIT_ASKPASS, and deletes the environment afterwards. Nothing is written into the mirror's own config. So ashowinvoked withoutcredentialRefwas genuinely anonymous.Against a private tenant: clone succeeds, list succeeds, and then every file fails with
KB_INGEST_ENVELOPE_FILE_READ_FAILED.Why it survived review and every test
Two reasons, both reusable.
The trade is documented.
gitMirror.mjs:904says, in the module's own JSDoc: "showbecomes a potentially NETWORKED read. The lane is already a network operation behind the same credential so this adds no new failure domain." The premise in that last clause does not hold — the lane is behind a credential,showis not. A documented risk reads as a discharged one.Every test is blind to it. The only tenant repo this project has ever ingested is public, and a public remote serves a promisor fetch to an anonymous client. #16557's measurements show
showlazy-fetching happily here — 0.42 s/file, mirror backfilling 36.2 MB → 121.9 MB. The defect is invisible in exactly the visibility class we test in, and fires on every repository in the class we do not. Tenant repos are private by default, so that is the whole feature.The change
gitMirror.mjsreadRevisionFileacceptscredentialRef, forwards it torunGitwithknownHostsPathasclone/fetchalready dotenantRepoIngestEnvelopeBuilder.mjsbuildIngestEnvelope→buildFullEnvelope/ incremental →buildFilePayloads→readRevisionFileTenantRepoSyncService.mjsrepo.credentialRefto the envelope builder — already passed tocloneIfMissingandfetcheight lines aboveThreaded explicitly, not carried on
identity.identityis spread into every mirror call including the graph and tree reads. Putting a credential there would work and would be wrong: an operation that cannot reach the network should stay unable to resolve a secret, and a later refactor addingcredentialRefto thoserunGitoptions would then silently enable it.credentialRefstays optional — omitted, the read is anonymous, which remains correct for a public remote and for a blob already local.Deltas from ticket
The ticket's Fix said "thread the tenant's
credentialRefinto theidentityobject the envelope builder spreads". Implemented as an explicit per-hop parameter instead, becauseidentityreaches the credential-free reads and its own AC forbids widening them. Same seam, narrower grant.Test Evidence
test/playwright/unit/ai/services/knowledge-base/tenantRepoIngestEnvelopeCredential.spec.mjs— new.npm run test-unit -- test/playwright/unit/ai/services/knowledge-base/tenantRepoIngestEnvelopeCredential.spec.mjs 4 passed (2.6s) npm run test-unit -- test/playwright/unit/ai/services/knowledge-base/ test/playwright/unit/ai/daemons/orchestrator/ 1676 passed (1.1m)Test 1 — the architectural fact nothing tested. Blobless-clone a filter-capable
file://source, then delete the source so the promisor remote is unreachable. Mirror, refs and trees are untouched on disk, so anything answered locally must still succeed:The passing
listRevisionPathsis the control: it makes the failure attributable to the network rather than to a broken mirror.Test 2 — the fix and the invariant. A fake
gitMirrorrecords thecredentialRefeach call receives, across both envelope shapes.Mutation testing — and it caught my own spec being vacuous:
credentialRefat thereadRevisionFilecallcredentialRefto thelistRevisionPathscallThe invariant assertion could not fail. Two causes, both mine: the incremental path never calls
listRevisionPaths(it diffs), so the run I wrote never observed the call — and[].every(...)istrue, so an assertion over zero observations passed as though it had checked something. Repaired by exercising both envelope shapes and asserting every guarded call was observed before asserting its polarity.Reproduction against a real private remote, run before the ticket was filed, under a disposable HOME with an empty
.gitconfig:clone --mirror --filter=blob:none (with credential) → exit 0, promisor=true ls-tree -r --name-only <rev> (no credential) → exit 0 show <rev>:<path> (no credential) → exit 128 fatal: could not fetch 1a0cacca… from promisor remote show <rev>:<path> (with credential) → exit 0One variable. The probe clone was deleted afterwards; the host is redacted here and in the ticket.
Surfaces touched: tenant-repo ingestion (
tenantRepoIngestEnvelopeBuilder,gitMirror,TenantRepoSyncService) — existing non-CI coverage:tenantRepoIngestEnvelopeBuilder.spec.mjs,gitMirror.spec.mjs,TenantRepoSyncService.spec.mjs, all green in the 1676 above.Post-Merge Validation
KB_INGEST_ENVELOPE_FILE_READ_FAILEDbehind and reaches the embed stage.Scope
Not #16557 — that is the cost of these fetches (23,931 round trips) and stays held on the declaration model. This sits underneath it: on a private tenant the fetches do not merely cost, they fail. That ticket is untouched.
Not #16566 — a repo that gets past the read still meets the embed stage.
Decision Record impact:
none. Restores an invariant the blobless change assumed rather than altering a decision.Authored by @neo-opus-grace (Claude Opus 5). Origin Session ID:
9ced67a1-8f21-4da2-a1bf-a2a968c47ed2