LearnNewsExamplesServices
Frontmatter
id16045
titleTenant-repo sync can certify ambient authority and an empty bootstrap
stateClosed
labels
bugaitestingarchitecturesecurity
assigneesneo-gpt
createdAtJul 27, 2026, 8:17 AM
updatedAtJul 27, 2026, 10:59 AM
githubUrlhttps://github.com/neomjs/neo/issues/16045
authorneo-gpt
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 27, 2026, 10:59 AM

Tenant-repo sync can certify ambient authority and an empty bootstrap

Closed Backlog/active-chunk-10 bugaitestingarchitecturesecurity
neo-gpt
neo-gpt commented on Jul 27, 2026, 8:17 AM

Context

This is the outbound follow-up preserved by PR #16038's Approve+Follow-Up disposition. That PR correctly closed inbound Streamable-HTTP admission and explicitly did not absorb outbound tenant-repo acquisition.

A live latest-created sweep of the 20 newest open issues at 2026-07-27T06:02Z found no equivalent ticket. A recent all-state A2A claim sweep found no overlapping lane. Focused Memory Core searches for ambient Git authority and empty bootstrap checkpointing returned no prior decision. The closest shipped predecessors are:

  • #15748 / PR #15752 — error-bearing Knowledge Base ingestion summaries fail closed and preserve the last good revision.
  • #15760 / PR #15773 — supported credential references are explicit; unresolved references and unreadable repositories fail preflight.
  • #15761 / PR #15766 — legacy checkpoints revalidate through the current ingestion contract.
  • #11731 — the closed pull-ingestion epic whose AC2 defined the credentialed repository-access contract.

Those contracts are still correct, but two source-level falsifiers expose one residual: the checkpoint can be certified by Git authority the tenant did not declare, and a full acquisition can be certified without materializing any corpus effect.

Scoping: this is one standalone post-close bug linked to #11731. It is not a new epic, and it is not a child of #15798: local/cloud parity owns runtime topology, while this defect belongs to the existing cloud tenant-repo pull boundary.

The Problem

GitMirror.createGitEnv() calls its environment narrow but copies the process HOME. For credentialRef: none, createCredentialEnvironment() adds no overrides. Git therefore still reads authority-bearing host state such as global Git config, URL rewrites, credential helpers, .netrc, SSH config, and default SSH identities.

The direct falsifier created a temporary HOME/.gitconfig with:

url.file:///tmp/<readable-repo>.insteadOf=https://ambient.invalid/private.git

Then probeRemoteAccess({cloneUrl: 'https://ambient.invalid/private.git', credentialRef: 'none'}) returned:

{
  "status": "ready",
  "code": "KB_TENANT_REPO_ACCESS_READY"
}

The configured URL was unreadable on its own; ambient process-home config supplied the effective authority and destination.

The second falsifier exercised TenantRepoSyncService with an initial full envelope, a proved head revision, no materialized files or deletions, and an error-free zero-work ingestion summary. Current dev recorded:

{
  "status": "completed",
  "completedCount": 1,
  "failedCount": 0,
  "repoStatus": "active",
  "checkpointStatus": "complete",
  "lastIngestedRev": "0123456789abcdef"
}

The next run starts from that checkpoint even though the bootstrap produced no Knowledge Base effect.

Together, these are a false-certification path: credentialRef: none does not prove anonymous access, and a zero-effect bootstrap/full/revalidation run can still become the durable good revision.

The Architectural Reality

  • ai/services/knowledge-base/helpers/gitMirror.mjs:84-97,277-300 owns repository authority. Tenant-repo config declares exactly one credential mode; host-user Git state is not another implicit mode.
  • credentialRef: none means deliberately anonymous access. It must not mean “use whatever credentials, rewrites, helpers, or SSH identities happen to exist in the orchestrator account.”
  • The explicit env, file, and ssh modes remain transient subprocess authority. Their current no-secret persistence/redaction contract stays intact.
  • ai/services/knowledge-base/helpers/tenantRepoIngestEnvelopeBuilder.mjs:212-233,283-321 already distinguishes full materialization from incremental change: bootstrap, non-linear history, manual full replay, and legacy revalidation produce a manifest-carrying full envelope.
  • ai/services/knowledge-base/IngestionService.mjs:149-222 is intentionally fail-soft, so the tenant-repo caller owns the commit decision after validating the returned summary.
  • ai/daemons/orchestrator/services/TenantRepoSyncService.mjs:1062-1143 performs clone/fetch, validates the error-free summary, advances lastIngestedRev, and records COMPLETE; this is the commit boundary the zero-effect falsifier crosses.
  • A current-checkpoint incremental no-op is healthy and may report ingested=0, deleted=0.
  • A deletion-only transition is also healthy. The full-materialization gate must run after ingestion and accept a positive delete effect; rejecting an empty manifest before reconciliation would preserve stale rows.
  • A zero-effect full materialization is not enough evidence to certify a tenant corpus. It must fail with a stable bounded cause and preserve the last known-good checkpoint.

The Fix

  1. Make every tenant-repo Git subprocess independent of ambient host-user authority:
    • ignore system/global Git config and credential helpers;
    • isolate HOME-derived .netrc, SSH config, and default keys;
    • add back only the selected none, env, file, or ssh authority;
    • preserve explicit local-path and genuinely public anonymous repositories as credentialRef: none positive controls.
  2. Treat the existing manifest-carrying envelope as full-materialization evidence. After the error-free ingestion-summary check, require a positive ingested or deleted effect before a bootstrap, non-linear fallback, manual full replay, or legacy revalidation may advance its checkpoint.
  3. Surface a stable bounded code such as KB_TENANT_REPO_SYNC_EMPTY_MATERIALIZATION through the existing per-repo failure path. Preserve the previous revision, increment isolated failure/backoff state, and expose the code without URLs, credential references, home paths, Git config, or secret material.
  4. Keep current-checkpoint zero-delta completion and delete-only completion as explicit positive controls.
  5. Clarify the anonymous-authority and full-materialization commit contracts in the cloud tenant-ingestion guide.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
Git subprocess environment gitMirror.mjs No system/global config, helper, .netrc, user SSH config, or default identity crosses the boundary; only the selected credential mode is added Local-path and genuinely public anonymous access still work under none Tenant ingestion credential boundary Real Git insteadOf/helper negative controls plus anonymous-local and explicit-credential positives
Access preflight + clone/fetch Shared GitMirror runner Probe and mutation use the same isolated authority No probe-ready / clone-fails split caused by different environments Troubleshooting contract Probe, clone, and fetch tests
Full-materialization commit TenantRepoSyncService + manifest-carrying envelope Advance only after an error-free summary proves ingested > 0 or deleted > 0 Incremental current-head no-op remains success; delete-only full reconciliation remains success Pull-mode lifecycle Initial/full/revalidation zero-effect negatives; no-op and delete-only positives
Failure diagnostics Tenant-repo sync error taxonomy + deployment state Stable bounded empty-materialization cause; previous checkpoint retained Per-repo isolation and backoff unchanged Troubleshooting map State, health outcome, and redaction assertions

Source Discussion Cross-Check

Discussion #11782 already selected explicit credential authority and a full-bootstrap/incremental-refresh pull model; #11731 mapped those decisions into AC2–AC4. This ticket repairs an implementation hole in that selected contract. No new architectural fork or fresh Ideation Sandbox is required.

Decision Record impact

Aligned with ADR 0014's cloud-deployable tenant-repo-sync lane and ADR 0019's leaf-owned config authority. No ADR amendment and no new AiConfig leaf are required.

Acceptance Criteria

  • Tenant-repo Git subprocesses ignore ambient system/global Git config, URL rewrites, credential helpers, .netrc, user SSH config, SSH agents, and default SSH identities.
  • A fake HTTPS URL made readable only through HOME/.gitconfig url.*.insteadOf does not become ready, clonable, or fetchable under credentialRef: none.
  • Existing explicit env, file, and ssh credential modes still pass through the shared isolated runner without leaking secret values or reference metadata.
  • Explicit local-path and genuinely public anonymous repository access remain valid credentialRef: none positive controls.
  • A bootstrap, non-linear fallback, manual full replay, or legacy revalidation with an error-free zero-effect summary fails with a stable bounded code, preserves the last good revision, and does not increment completedCount.
  • A current-contract incremental no-op (ingested=0, deleted=0) remains completed and checkpoint-stable.
  • A full/delete-only reconciliation that removes existing rows remains completed and may advance the checkpoint.
  • Existing error-bearing-summary, lease-fence, per-repo isolation, retry/backoff, and deep-redaction behavior remains green.
  • Cloud tenant-ingestion docs state that none is anonymous rather than ambient and that full materialization requires a non-zero ingest/delete effect.

Evidence: L3 required — real local Git subprocess falsifiers for ambient authority plus the production-shaped tenant-repo service/checkpoint path. A hosted redeploy receipt is useful post-merge evidence, not a pre-merge substitute.

Out of Scope

  • Inbound Streamable-HTTP authentication (#15990 / #15992).
  • Provider-specific PAT type/scope inference, credential issuance, or rotation.
  • New credential-reference schemes.
  • Treating every ingested=0 result as failure.
  • Incremental changed-file parsers that intentionally emit zero chunks; that requires a separate parser-yield contract if evidence shows it is unsafe.
  • Declaring an intentionally empty repository a healthy tenant corpus. This lane fails zero-effect full materialization closed until an explicit empty-repository policy exists.
  • Updating any external deployment or publishing its private configuration.

Avoided Traps

  • Do not “fix” only credentialRef: none; ambient URL rewrites can also change the destination underneath an explicit credential.
  • Do not clear only credential.helper; global url.*.insteadOf, .netrc, SSH config, and default keys are independent authority sources.
  • Do not reject an empty full envelope before ingestion; a full empty manifest may need to delete an existing corpus.
  • Do not use a blanket ingested === 0 predicate; current-checkpoint no-op and delete-only transitions are valid.
  • Do not expose the clone URL, credential ref, env name, home path, Git config, or raw stderr in diagnostics.
  • Do not widen #15798's topology-parity epic with cloud-ingestion authority work.

Related

  • #11731 — closed server-side tenant-repo ingestion epic; this is a post-close AC2–AC4 residual.
  • #11787 / PR #11880 and #11788 / PR #11881 — credential and GitMirror substrate.
  • #15748 / PR #15752 — error-bearing ingestion summaries fail closed.
  • #15760 / PR #15773 — credential/read-capability preflight.
  • #15761 / PR #15766 — checkpoint contract revalidation.
  • #15990 / PR #16038 — inbound PAT admission predecessor whose approved follow-up preserved this outbound boundary.

Origin Session ID: 019f9b00-d596-7e22-b8f1-31433ddb5838

Retrieval Hint: tenant repo credentialRef none ambient HOME git config empty full materialization checkpoint