Skip to content

feat(code-index): index authenticated Git submodules - #4801

Open
ScriptedAlchemy wants to merge 60 commits into
masterfrom
fix/4593-skipped-nested-repository-audit
Open

ScriptedAlchemy wants to merge 60 commits into
masterfrom
fix/4593-skipped-nested-repository-audit

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Nov 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

Refs #4593.

Enable direct Git submodules through the default-off project setting index.include_submodules.v1, followed by a daemon restart. The parent-relative child paths participate in source walking, grep, structural search, unmounted-file audit, and graph indexing. Parent-to-child call edges remain in one graph.

Source authority

  • Live admission binds the staged parent gitlink and exact pin, staged and working .gitmodules, and child checkout to the parent-owned Git module store.
  • Child commits, local additions, edits, and removals participate in freshness. Retained readers and snapshot capture revalidate the bound authority; unreadable parent Git state is an error, not an empty result.
  • Historical capture uses the selected parent tree's registration and pinned child commit in the local parent-owned module store. Missing historical authority is unavailable, never substituted with live bytes.
  • Linked child worktrees, unrelated nested clones, deeper gitlinks, uninitialized children, and parent aliases into child repositories remain excluded. Ordinary tracked aliases within the parent remain supported.

Repairs and verification

The earlier blanket DRAFT / HOLD MERGE wording is superseded by the maintainer's request to finish and verify this PR. The prerequisite dashboard fixes and scheduler progress work are integrated. The PR is ready for review; this does not authorize bypassing required checks.

Latest commit: 6ca67c5b3669d72a60a1e6dd1379e765e355f6a2.

  • Fixed strict Clippy failures in the Unix binding witness and post-read binding check, without lint suppression or policy changes; corrected tree-capture guard formatting.
  • Strengthened the split-index corruption regression to require refusal from retained graph and lazy-walk readers, not merely a changed metadata witness.
  • Added a real-Git capture regression: revoke the staged gitlink after capture starts, refuse the snapshot, preserve the prior publication, restore authorization, and successfully publish the edited child.
  • Native macOS complete indexing suites passed on the patch before the final behavior-preserving nested-if collapse: 398 source-index tests and 714 runtime tests, with two existing opt-in tests ignored.
  • Final patch: both crate Bazel rustfmt checks and strict Clippy unit targets passed. All 6 focused runtime submodule tests reran successfully with the anti-vacuity helper after the final edit. The 19 focused source-index tests passed earlier on the same source-index test code.

Remaining merge checks

Required hosted CI and the explicitly dispatched native Windows indexing suites must pass on the latest head. The Windows runtime suite includes the formerly failing child-HEAD/add/delete transition, historical pinned graph, and restart journey. No Windows test pass is claimed yet. New actionable review findings must be addressed before merge.

No approval, merge, or completion of #4593 is claimed by these local results.

Keep parent repository source admission unchanged; use one shared
walker for exclusion evidence instead of a second filesystem scan.

Refs #4593
@changeset-bot

changeset-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: bc2ea36

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@ScriptedAlchemy
ScriptedAlchemy marked this pull request as draft November 8, 2026 01:11

Copy link
Copy Markdown
Owner Author

Refs #4593 — validation blocker at exact head 38bc131598d5d993295f97b7001811209a1b16a5.

The repository-gates job failed before Rust execution: https://github.com/ScriptedAlchemy/tracedecay/actions/runs/42433144833/job/128586224987 . The actual failures are:

  1. check-generated-rust-entrypoints: stale generated entrypoint/toolchain contract; its diagnostic names package.json packageManager/engines and the setup-pnpm node-version instruction surface.
  2. check-generated-api: unexpected generated AgentPromotionStatus.swift and AgentSignalGate.swift bridge surfaces.
  3. Domain ownership contract drift: docs/generated/domain-module-map.json, docs/generated/runtime-service-map.json, and crates/tracedecay-configuration/src/generated/project_settings_contract.rs.

git diff --check, CI-shape/scope/environment-policy checks and Bazel BUILD graph checks passed. This is NOT a rustfmt failure, and none of those passes establishes Rust compilation or behavioral correctness. Native tests were skipped by draft selection. I could not establish whether these gate failures also occur on current master: the master status/workflow requests were unavailable to this integration. Do not label them pre-existing without that comparison.

No source fix, Rust test execution, independent review, branch update, merge or issue closure was completed in this follow-up. This environment has no executable repository checkout or Bazel; direct repository retrieval failed, and no usable remote execution/workflow-dispatch capability was exposed. This is a validation limitation, not evidence that the implementation is correct.

#4801 remains diagnostic-only and draft. It does not yet satisfy authenticated submodule admission, pinned child-tree capture, child-aware freshness, or consistent retrieval/graph behavior. Retain Refs #4593; do not infer issue completion from a green diagnostic PR. Reuse this existing issue PR rather than opening a duplicate. The next implementation must use one authenticated submodule inventory across admission/capture/freshness/retrieval, invalidate parent reuse for child commits and edits, preserve linked-worktree/untrusted-repository exclusions, and add nonzero Bazel regressions including opt-in/off, spoof rejection, child changes, historical capture and restart behavior.

Coordination: the dedicated #4593 owner remains responsible for implementation; PR maintenance owns CI assistance without racing its branch. Do not repair unrelated decision-model generated paths by importing forbidden work. #4776 and all Kev/decision-model work remain draft and unmergeable by instruction; #4763 remains read-only. No protections or tests were weakened.

Copy link
Copy Markdown
Owner Author

Refs #4593 — exact-head CI repair 1f8c1997090e4631ee38f50a32af4186e8153c12 (nonforce fast-forward from 38bc131): applied the three exact Rust formatting replacements reported by hosted Bazel //crates/tracedecay-code-index:rustfmt_check_2024 in run 42433144833. Correction: my earlier comment erroneously attributed the failure to generated entrypoints/API/domain maps. The repository-gates log shows the actual failure was rustfmt_check_2024 only; 8 other Bazel test targets passed. No generated-source edits are warranted by that log. Fresh run 42437677389 was queued when last checked; no claim it passed.

The PR is still partial: it adds skipped-nested-repository diagnostics and regression source, but NOT authenticated submodule indexing, freshness, or indexed retrieval. HOLD MERGE even if its current-head diagnostics tests pass: keep this same PR open to complete #4593. Being reviewable or passing preliminary tests does not mean the issue's acceptance is met. No complete-implementation, native macOS or independent-review proof exists. Keep Refs #4593, issue open, and protected Kev/release PRs untouched.

Limit skipped-repository samples during traversal, honor directory policy
before collecting diagnostics, and quote bounded path labels. Propagate
source-walk failures instead of returning an empty successful audit.

Add behavioral coverage for bounded sampling, policy scope, preserved
ecosystem caveats, Unicode/control-character paths, and missing roots.

Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — published source repair 8d6f07e1bb326630a313e1911d8bd271f337dd6c on this same branch with expected_sha=1f8c1997090e4631ee38f50a32af4186e8153c12, force=false; independently re-read PR head confirms the update.

Fixed unbounded skipped-repository collection, diagnostics escaping configured directory exclusions, unquoted/unbounded path labels, and swallowed filesystem-walk failures. Added six behavioral regression cases (one Unix-only filename case); existing initialized-submodule and linked/nested-repository exclusions are preserved. Only source_walk.rs, unmounted_files.rs, and the new nested-repository test module changed; no scheduler, generated contract, release, infrastructure or model changes.

Current-head CI: https://github.com/ScriptedAlchemy/tracedecay/actions/runs/42442123433 — queued when inspected. These Rust regressions have NOT executed; author diff review is NOT independent review. The prior successful draft run skipped Rust/Clippy/native jobs, so it is not acceptance evidence for these changes.

The existing merge hold remains. This repairs the current audit implementation, not the still-unimplemented optional authenticated submodule indexing feature. Keep the PR draft/open and #4593 open. Continue the integrated admission/capture/freshness/retrieval implementation here rather than opening a duplicate or treating more diagnostic fixes as feature completion.

Apply the exact formatter changes reported by the hosted Bazel
rustfmt_check_2024 failure on PR #4801.

Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — published nonforce, expected-head fast-forward 8d6f07e → 1b49877, fixing the precise three rustfmt_check_2024 hunks from the current-head hosted Bazel repository-gates failure in run 42442123433 (job 128613365191). The exact diff changes only formatting in source_walk/nested_repository_tests.rs; 8 other repository-gate targets passed before the format failure. Verified #4801 now points to 1b49877, and current-head run 42447730459 was queued at last read. These behavioral Rust regressions have still not run; native/Linux/Clippy remained skipped on the draft workflow, and there is no submitted independent review. HOLD MERGE. Authenticated submodule indexing in parent capture, freshness, historical Git-tree capture, policy/configuration, and indexed/live retrieval remains unimplemented; keep PR draft, issue open and existing hourly owner enabled. Do not import protected Kev/release branches or change CI protections.

Use one source boundary for interactive walks, Git candidate classification,
worktree capture (including ignored-file admissions), and freshness. Parent
tracked files hidden by a new nested .git marker become tombstones, invalidate
clean HEAD-tree reuse, and return when the marker disappears. Reject source
paths passing through symlinked directories or lexical escapes.

Add real Git classification and filesystem regressions for nested directory,
gitdir-file, symlink, path traversal and removal behavior.

Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — published source repair 624cc833 on the existing branch, expected-head NONFORCE fast-forward from 1b498778. Four source paths changed: shared nested-repository/symlink/escape guard in source_walk, parent Git classification tombstones + dirty/freshness invalidation for tracked paths newly hidden behind nested .git, worktree capture guard including explicit ignored-source admission, and freshness roster parity. New real Git and source-boundary regression source is committed; it has not executed via Bazel. The exact-head CI run 42449422792 was still pending; native/OS Rust jobs are skipped for draft PRs. No independent review. This is a partial fail-closed security/correctness fix, NOT the registered-submodule opt-in feature. Hold #4801 DRAFT/unmerged and #4593 OPEN; next owner work must deliver canonical config + authenticated 160000/.gitmodules/topology inventory, child-aware capture, historical pinning, freshness/retrieval parity and nonzero Bazel/native acceptance. PR maintenance: assist only with exact-head CI and do not race this source branch. Preserve #4800/#4508 scheduler work, Kev/#4776 DRAFT and release #4763 read-only.

Apply four exact replacements from hosted Bazel rustfmt_check_2024
at PR #4801 head 624cc83; no behavioral source change.

Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — published exact-head CI repair 9beb7b8 to the existing DRAFT #4801, using expected head 624cc8338a1cfe8486b0638ba88fbbae0df9fa33 and force=false. Hosted run 42449422792 failed Bazel rustfmt_check_2024 for exactly four formatting hunks (two in source_walk.rs, two in classification.rs); eight unrelated repository tests passed. This patch makes exactly those four formatting replacements in those two files, with no behavior changes. PR/ref readback confirms the new head. Fresh current-head run 42455645684 was QUEUED at inspection; no pass is claimed. The draft workflow skips Linux/Windows/macOS Rust tests and Clippy; zero new behavioral Rust tests have executed, and no independent review exists. HOLD MERGE: the integrated authenticated submodule feature (canonical default-off setting, gitlink + .gitmodules + child topology, dirty/historical child capture, freshness, graph/live parity, toggles and restarts) remains unimplemented. Keep issue OPEN and owner schedule unchanged. No Kev/#4776, release/#4763, or peer PR changes.

Sample .git marker evidence for tracked and explicitly admitted source
ancestors even when Git dirwalk never recurses into tracked-only folders.
Test marker creation and removal against a real Git parent index.

Refs #4593
Directory metadata changes when the marker is removed, so the original
cached roster must not be treated as restored merely by marker absence.

Refs #4593
A registered gitlink remains an untrusted nested source boundary even if
its child .git marker is absent. Keep live grep and audit in default-deny
parity with the parent index; include/glob cannot lift repository trust.

Exercise a real registered Git submodule with its marker removed.
Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — published narrow default-deny source fix 704a9aac135046fe1d720242a482561a61eb5274 to #4801 with an expected-head NONFORCE fast-forward from 0119cf9 (remote PR ref verified). Parent 160000 gitlinks now remain excluded by the shared live source walker even if the child .git marker is removed; the real registered-submodule regression fixture now exercises that missing-marker case and explicit glob refusal. Production uses the existing in-process gix opener (no shell Git or network); no child indexing is enabled. Source diff changes one file only: crates/tracedecay-code-index/src/source_walk.rs.

Current-head run: https://github.com/ScriptedAlchemy/tracedecay/actions/runs/42466514013 (queued at check). NO Bazel behavioral Rust pass or independent review claim. Do not merge or mark ready. Feature acceptance remains integrated authenticated opt-in, pinned historical child capture, child status/freshness and cross-boundary graph/index/live retrieval, with nonzero Bazel/native validation. Preserve #4800 and protected Kev/release lanes.

Apply the two exact rustfmt_check_2024 hunks from hosted run 42466514013.
No source behavior changes; authenticated submodule indexing remains pending.

Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — narrow hosted Bazel formatting repair published at 1899d261 by nonforce, expected-head fast-forward from 704a9aac, independently verified against the remote Git ref and PR head.

Exact-head run 42466514013, repository-gates job 128687191524, failed only //crates/tracedecay-code-index:rustfmt_check_2024, with two exact hunks in source_walk.rs (line wrapping around the workdir and index reads). The other 8 repository-gate targets passed, most cached; these were not code-index behavioral Rust regressions. Commit 1899d261 applies only those two reported formatting replacements in one file, no behavior changes. New-head CI and nonzero Bazel Rust test evidence have not yet been established.

HOLD MERGE: this PR remains DRAFT and contains only exclusion/diagnostic/freshness hardening. The requested default-off authenticated submodule inventory, selected historical child-tree capture, dirty child freshness, and graph/indexed/live retrieval parity remain unimplemented. No independent review. #4593 stays open. Please do not merge or change the draft selection to conceal missing behavior, and preserve #4800/#4508, protected #4776 Kev and read-only #4763.

Copy link
Copy Markdown
Owner Author

Refs #4593 — new source-review boundary mismatch, regression needed; not a claimed exploit or passing test (reviewed at exact head 1899d261c9c6486f572a0cbdf619d07315b65378).

The default-deny live walker now checks parent stage-0 gitlink roots through source_walk.rs::parent_gitlink_paths, including when the child's .git marker is absent. But code_index_scheduler/reconcile.rs::capture_admitted_candidate (around 3977–3983) and freshness_witness.rs::source_candidates (around 135–143) still validate explicitly admitted ignored paths using only source_walk::has_nested_repository_ancestor. That helper checks nested .git markers and symlink/path ancestry, not parent-index gitlink roots. Therefore the new deny boundary is not yet shared by these capture/freshness paths.

Test the concrete scenario with a real parent 160000 gitlink under node_modules/<package>, a registered .gitmodules entry, child source still present but its .git marker missing, and an ignored-dependency admission/retained roster. The admission must fail closed or retire before child bytes enter a parent generation, even when the package path matches .gitignore. Check ignored_dependencies.rs::prove_gix_ignored (exact-path lookup plus ignore match) against gitlink ancestor semantics rather than assuming it already prevents this. Also assert live grep/AST and freshness parity across marker removal and restart. This is an actionable trust-boundary test requirement, not evidence that the runtime admission exploit has reproduced: no nonzero Bazel Rust test can be executed in this environment.

Current-head hosted workflow 42468887836 has passed repository gates, but Rust native/OS tests and Clippy were skipped for this draft; the Dashboard job remained queued when checked. Do not push a speculative fix that cancels that run. Fix via the one canonical authenticated submodule boundary, not a third independent scanner, and keep DRAFT/HOLD MERGE, Refs #4593, and issue open until full integrated acceptance.

A parent stage-0 gitlink remains tracked repository source even when its
child checkout loses the .git marker. Check every indexed ancestor before
an ignored dependency is admitted or revalidated, preserving the existing
proof for ordinary ignored sources.

Add a real local Git submodule regression that removes the child marker
and checks both the admission proof and production source-read refusal.

Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — published 77332ede0f9b9cb557bd41185203eba9500c3f0a by expected-head, NONFORCE fast-forward from 1899d261 on this existing draft PR.

The ignored-dependency gix proof now checks every parent index ancestor for mode-160000 gitlinks, not only the exact candidate path. This closes the omitted-marker admission path discussed in comment 6720823044 for verified ignored dependencies, including the production source read and existing ignored-roster revalidation. Added a real local Git submodule regression source: verified stage-0 gitlink and .gitmodules, removed the child .git marker, asserted typed refusal by proof and read, plus a normal ignored-source control. Only ignored_dependencies.rs changed; candidate diff and live remote head were read back.

No Rust regression has executed through Bazel, and there is no independent review. Current-head hosted CI 42482445184 was queued. Previous-head run 42468887836 completed successfully after re-running a Dashboard job blocked by a transient download timeout; draft native Rust/Clippy remained skipped. I independently checked the disposable Git fixture commands locally, but that is not a repository Rust test or acceptance evidence.

HOLD MERGE / keep DRAFT / #4593 OPEN. The default-off authenticated submodule inventory, selected child-commit historical capture, child-aware freshness, and indexed/graph/live retrieval parity remain undone. Protected Kev/release PRs, #4800/#4508, and CI protections were not changed.

Refs #4593. Full authenticated child indexing still incomplete.

Copy link
Copy Markdown
Owner Author

Refs #4593 — guarded source repair on existing DRAFT #4801, HOLD MERGE.

Commit 2b230e8232f6ffd23675223c261fcfbd0a26e80a addresses a concrete remaining default-deny gap: a child checkout with its .git marker removed and its parent gitlink staged for removal disappears from the index but remains a mode-160000 gitlink in the parent's HEAD tree. The interactive source walker previously checked only index gitlinks and the current marker, so an explicit include/glob could admit those live child bytes. It now unions parent index gitlinks with parent HEAD-tree gitlinks, handles unborn HEAD, and fails closed on unreadable committed-tree authority. The existing real-Git submodule test now commits the parent, stages removal without deleting the child, verifies index absence plus HEAD's 160000 entry, and checks ordinary and explicitly scoped walks still exclude the child. A real Git fixture was independently probed for these Git semantics; that is not a repository Rust/Bazel test.

One file changed: crates/tracedecay-code-index/src/source_walk.rs. Published via expected-head 77332ede nonforce fast-forward, verified by direct branch and PR REST reads. Exact-head hosted CI run 42499856015 was queued on last check. No nonzero Bazel Rust regression pass, native OS test, or independent code review is claimed. Draft workflow selection skips native Rust/Clippy.

The integrated canonical default-off authenticated submodule opt-in, shared inventory across child candidate capture/freshness, pinned historical submodule trees, and parent-relative graph/retrieval are not implemented. Do not mark ready, merge, or close #4593. Protected #4776 Kev, #4763 release and #4800/#4508 peers untouched.

Refs #4593. Reuse the parent's index-plus-HEAD boundary for ignored
sources and cover the real staged-removal checkout scenario.

The authenticated opt-in indexing feature remains incomplete.

Copy link
Copy Markdown
Owner Author

Refs #4593 — source repair published on existing DRAFT PR; HOLD MERGE.

Commit f925fe65 is a guarded, nonforce fast-forward from 2b230e8232f6ffd23675223c261fcfbd0a26e80a. It corrects another default-denial discrepancy: the ignored-dependency proof used only the staged parent index. After staging removal of a registered gitlink and removing the child's .git marker, live search still denies the child through the parent HEAD but explicitly admitted ignored-source reads could treat the same child files as ordinary ignored dependencies.

Ignored-source proof now calls the same index-plus-HEAD parent gitlink boundary as the source walker. The real-Git fixture commits a parent with a 160000 submodule, stages removal with git rm --cached, verifies the index no longer has that gitlink while HEAD still does, and asserts ignored admission and source-read refusal; its ordinary ignored-source control remains. Exactly two changed files: source_walk.rs (exports the existing boundary) and ignored_dependencies.rs (uses it and adds the regression).

Verification limit: read back the exact commit and diff; no nonzero Bazel Rust test executed locally. Current-head hosted run 42503394287 was queued and chooses native=none because the PR is draft, so it cannot establish Rust behavior. No independent review. This remains a partial fail-closed repair only; canonical default-off authenticated submodule inventory, child capture/freshness, pinned historical-tree capture, graph/indexed/live parity, and acceptance tests are outstanding. Keep Refs #4593, PR DRAFT/unmerged, issue open. Preserve scheduler #4800/#4508 and protected Kev/release PRs.

Copy link
Copy Markdown
Owner Author

Refs #4593 — exact-head hosted Bazel formatting repair published on existing DRAFT #4801.

At bfe14a24e51106c061dbc163b20e2817ac6adfd7, CI 42761466450 failed the repository-gates job's Bazel //crates/tracedecay-code-index:rustfmt_check_2024. I read job 129647895677: the only reported formatting hunk was in src/source_walk/submodules/tests.rs:153, expanding the assertion for the still-existing child source into rustfmt's multiline form. All eight repository script tests passed (one executed, seven cached); these are not Rust behavioral acceptance.

Published 5f2d9f3 by an expected-head (bfe14a24) NONFORCE fast-forward, checked the one-commit ancestry and one-file, formatting-only diff, and independently verified the branch and PR head. No assertions or production behavior were changed, no native test was claimed. New exact-head CI 42769058413 was QUEUED when checked; draft-native Rust/Windows/Clippy are not selected by this PR workflow.

HOLD MERGE / keep DRAFT / issue #4593 OPEN. Exact-head nonzero Bazel source-walk/authentication, live graph/pinned-history and previously failing Windows child-commit regression, performance measurement of per-entry parent-authentication checks, independent approval and integration onto master remain outstanding. No peer, protected model/release work or CI policy was modified.

Refs #4593

Reject existing child source walks and graph reads when the child Git
administration changes core.worktree without changing the .git marker.
Reuse the initial pinned-store topology proof on every bound read.

Add a real-Git regression that changes only the child repository worktree
configuration after source and graph readers were created. The native
Git fixture demonstrates the mismatch; Rust acceptance still needs
nonzero Bazel tests on this exact commit.

Copy link
Copy Markdown
Owner Author

Refs #4593 — published narrow submodule authority repair on existing DRAFT #4801, HOLD MERGE.

Commit d245259 is a verified, expected-head nonforce fast-forward from 5f2d9f307ad0b83724702ba56c84dd6a3b715a89. It changes only crates/tracedecay-code-index/src/source_walk/submodules.rs and source_walk/submodules/tests.rs; remote branch/ref and PR head were independently read back.

Concrete issue: after a child source walker or graph reader is constructed, changing the parent-owned child Git repository's core.worktree redirects its advertised checkout while leaving the child app/.git marker, parent's staged gitlink, registration and source bytes unchanged. The earlier liveness check could still accept the stale binding even though fresh admission would reject it. A disposable native-Git fixture confirmed the same marker with a changed worktree path (Git behavior, not a Rust/Bazel test).

Repair: existing bound reads reuse the initial pinned-store topology verification, including child Git/common directory and current checkout identity. The added real-Git Rust regression first proves positive parent/child access, changes only the child repository worktree configuration, checks that fresh admission rejects it, and requires both an already-open graph reader and lazy source walk to refuse further child access with a typed error.

Validation hold: these new Rust tests have not executed through Bazel. The prior-head CI passed applicable repository/dashboard gates but skipped native Rust; current-head native Windows (including the prior failed child-HEAD regression), Linux/macOS, performance of per-entry binding checks, and independent approval are still required. Do not mark ready, merge, claim completion or close #4593. No protected/peer refs, CI settings or release work were changed.

Copy link
Copy Markdown
Owner Author

Refs #4593 — new actionable capture-time authorization gap; DRAFT / HOLD MERGE (reviewed at exact remote head d245259e78419ca1c401d6b606465c5f37c60f4f).

The existing source_walk::submodules::AuthenticatedSubmodule::checkout_is_live correctly rechecks the parent's staged stage-0 gitlink/pin, staged+working .gitmodules, child .git marker and child core.worktree for lazy walks and foreground LiveSourceBoundaries::resolve. The indexed worktree capture path does not use that retained binding at read time:

  1. source_walk/classification.rs::for_policy calls live_submodules and records child paths as strings via child_sources, but does not retain the authenticated child capability.
  2. code_index_scheduler/reconcile.rs::capture_authoritative_snapshot_with_active_generation_reuse builds that classification, then later fans out reads through capture_admitted_candidate(..., classification.child_root(logical_path)).
  3. In reconcile.rs::capture_admitted_candidate the Some(prefix) branch checks the canonical filesystem child directory and regular leaf. It then checks nested markers/symlinks relative to that child root and calls read_bounded_snapshot_source. It does not revalidate parent stage-0 gitlink/pin, either .gitmodules registration, child .git binding or core.worktree at capture time. read_bounded_snapshot_source streams bytes without Git authorization checks.

Falsifiable stale-inventory scenario: classify an authorized app/file.ts, then before that candidate's read do git rm --cached app without deleting app/.git or app/file.ts. A disposable native Git fixture confirmed the index gitlink is now absent, HEAD still has mode 160000 app, and the original .git marker and child bytes remain readable. A retained child_root=Some("app") passes the present capture branch's filesystem checks. This is source-traced capture-level risk, not a claim that a full publication exploit or any Rust test has executed; later publication/freshness fences might independently reject the outcome.

Required narrow repair/test: pass the original authenticated child binding/inventory through the concurrent worktree capture, revalidate it at the actual bounded child read (and when relying on the resulting snapshot), and refuse or retire a revoked child rather than accepting bytes on a stale string prefix. Regression must exercise successful authorized capture, revoke staged parent gitlink, registration, or child core.worktree after inventory creation while bytes remain, then verify no child file can be captured; positive reauthorization should work. Run exact-head nonzero Bazel cases on Linux/macOS/Windows. Native Git probes do not substitute for them.

reconcile.rs is also touched by peer #4800/#4508 (alongside git_tree_capture.rs and scheduler coordination paths). No speculative source push or competing edit here while its owner is active. Reuse #4801, preserve the existing draft hold, do not touch model/decision/release branches, and coordinate the shared-file patch before a guarded nonforce commit.

@ScriptedAlchemy
ScriptedAlchemy marked this pull request as ready for review November 10, 2026 21:16
Refs #4593

Retain canonical submodule checkout authority alongside classified source
paths. Reject stale parent or child binding before/after each child file
read and around snapshot reuse, including the clean-HEAD shortcut. Add
real-Git staged-gitlink revocation/recovery regression coverage.

Native exact-head Bazel verification and independent review remain pending.
@ScriptedAlchemy
ScriptedAlchemy marked this pull request as draft November 10, 2026 21:20

Copy link
Copy Markdown
Owner Author

Refs #4593 — narrow capture-time authorization repair published on existing DRAFT / HOLD MERGE branch.

Commit f1e2f5c is a verified expected-head NONFORCE fast-forward from d245259e78419ca1c401d6b606465c5f37c60f4f; branch and PR readbacks agree, with exactly four changed files and no rewritten peer commits.

  • source_walk/classification.rs now retains the original AuthenticatedSubmodule capability for each admitted child, rather than passing only its string prefix to indexed worktree capture.
  • reconcile.rs rechecks that same bound parent gitlink/pin, staged+live registration, marker, child store and worktree before/after reading each child file. It also rechecks all retained child bindings around active-row reuse and the clean-HEAD fast path, refusing capture when a binding changes.
  • submodules/tests.rs adds a real-Git regression that classifies a valid initialized child, stages removal of the parent's gitlink while leaving the marker and source bytes readable, requires the retained binding to fail, and checks restoration after re-adding the link.

This addresses the stale-inventory capture finding in comment #6779062117. Not accepted yet: no exact-head Rust behavior has run through Bazel; CI 42904015316 was queued with native=none. The earlier Windows child-HEAD regression, native Linux/macOS/Windows acceptance, performance of repeated parent/child probes, independent review, prerequisite integration and proof ON master remain outstanding. This is a capture-layer mitigation, not a claim of atomic filesystem snapshots.

PR #4801 was restored to DRAFT and remains unmerged; #4593 remains open. reconcile.rs also overlaps peer #4800's separate preseal progress instrumentation: integration must retain both behaviors. No peer branches, release or Kev model were changed.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

Devin Review

Comment on lines +100 to +105
&& self.parent_registration_is_live()
// The child gitdir marker is unchanged if its repository config
// redirects core.worktree. A fresh binding would refuse that store;
// an existing graph reader or lazy walk must do the same.
&& open_pinned_store(&self.git_dir, self.pin)
.and_then(|child| child.workdir()?.canonicalize().ok())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Submodule walks repeatedly parse the parent index

For every child entry, checkout_is_live reopens both repositories and parses the parent index. Ordinary scans repeat this work per file and directory, slowing searches and indexing as repositories grow.

Learn more

CheckoutWalk::next calls checkout_is_live before each child directory entry, and graph readers call it for each resolved child file. That check opens the parent repository, loads its index, reads the registration, and reopens the pinned child store. The work therefore grows with both the number of child entries and the size of the parent index, even without a binding change.

Example: A scan of a child with 5,000 files performs at least 5,000 parent index loads and pinned child opens instead of validating a stable binding once per scan.

Recommended fix: Preserve per-entry revocation checks, but separate cheap change detection from the full repository, index, and pinned-object validation. Revalidate on a detected change and on any uncertain metadata state; measure the ordinary scan with a populated parent index.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +58 to +60
let Ok(index) = parent.index_or_empty() else {
return false;
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Parent Git errors silently hide child sources

If the parent index becomes unreadable, parent_registration_is_live returns false without preserving the error. LiveSourceBoundaries::resolve then returns Ok(None) for existing child files, hiding unavailable Git authority as absent source.

Learn more

A graph reader can retain LiveSourceBoundaries after its initial successful open. On later reads, the new parent-registration check reopens the parent and reads its index. An index read error takes the same false path as a revoked registration, and resolve converts both to Ok(None). The repository's production-failure rule requires unavailable authorities to remain typed rather than become successful empty results.

Example: Open boundaries while app/first.rs is valid, then make the parent's index unreadable before resolving that path. The read returns Ok(None) even though the child still exists; an index error is expected.

Recommended fix: Return a typed result from registration validation and propagate Git open, index, and registration read errors through resolve. Preserve a distinct refusal outcome for an actual revoked registration, and adapt the lazy walker to surface its existing typed walk error.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Apply the two exact formatting hunks from CI 42904015316 without
changing source semantics or weakening the staged-revocation regression.

Refs #4593

Copy link
Copy Markdown
Owner Author

Refs #4593 — exact-head CI formatting repair published; #4801 remains DRAFT / HOLD MERGE.

CI 42904015316 ran on f1e2f5c and failed only the Bazel //crates/tracedecay-code-index:rustfmt_check_2024 target in Repository gates. The actual failing job reported exactly two formatting hunks: source_walk/classification.rs at bound_child, and source_walk/submodules/tests.rs at the real-Git staged-gitlink revocation regression. Its eight repository-script tests passed; this was not a Rust behavioral-test pass. Native Linux, Clippy, Windows, and macOS were skipped on this draft run.

Published eed23c361c9f as a single nonforce expected-old-head fast-forward from f1e2f5c. Compared commit objects: only those two paths changed (3+1 and 6+5 formatting lines), with no source semantics/test expectations altered and no concurrent peer commits dropped. Readback confirms both branch and PR head at eed23c3; PR remains OPEN DRAFT, not merged. New exact-head CI 42909622442 is queued, not a pass.

The newest review has two further unresolved findings: per-entry full parent Git/index revalidation may amplify a 5,000-file child scan; parent index/Git read errors currently collapse into false and can make a previously authorized live child appear Ok(None) rather than typed unavailable. Do not treat the formatting repair as resolving either. The capture-time authorization fix from f1e2f5c still needs nonzero cross-platform Bazel regression execution and a source-reviewed performance/typed-error solution before merge. #4593 remains OPEN; peer #4800, mixed draft #4776, and release history untouched.

Refs #4593

Keep unreadable parent index and malformed registration errors distinct
from revoked child identities. Propagate through live graph, lazy source
walk, and indexed capture. Add a real-Git regression for index corruption.

Copy link
Copy Markdown
Owner Author

Refs #4593 — published focused unavailable-Git-authority repair, still DRAFT / HOLD MERGE.

Commit 49fcebc is an exact expected-head NONFORCE fast-forward from eed23c361c9f38f287618633d6600e8a0937de35 on the existing #4801 branch. Remote PR/ref readback agrees at 49fcebc99047, with exactly four changed source/test files and no rewritten peer history.

Actionable review finding repaired in source: AuthenticatedSubmodule::parent_registration_is_live previously converted parent Git open/index/.gitmodules read errors to false; LiveSourceBoundaries::resolve consequently returned Ok(None) for an unreadable previously authenticated child. The existing child-boundary check now distinguishes explicit revocation (Ok(false)) from unreadable Git authority (Err(io::Error)). The lazy CheckoutWalk yields its existing typed walk failure; live graph reads propagate I/O refusal; child_bindings_live and both indexed candidate/reuse paths propagate failures rather than accepting an absent child or clean reused snapshot. All old Boolean callers were migrated; no new compatibility facade.

New real-Git Rust regression in source_walk/submodules/tests.rs: construct an authorized parent/child graph boundary and lazy walk; corrupt only the parent's real index while the child marker/source bytes remain; demand errors from both retained readers, never Ok(None)/empty walk. Original revocation tests retain their expected InvalidData behavior.

Verification: These changed Rust sources/tests have not executed under Bazel on this commit; the new exact-head workflow was queued at publication with native jobs skipped in draft mode. No passing Rust/Clippy/macOS/Windows claim, independent approval, or #4593 acceptance. Do not merge or close the issue. The other unresolved reviewer finding — O(files × parent-index verification) during child walks — remains actionable and needs a safe, measured bounded solution without weakening per-entry revocation.

#4800 remains peer-owned: this commit touches code_index_scheduler/reconcile.rs only to propagate the new typed child-binding check; preserve peer's progress instrumentation and this branch's pre/post-read auth when integrating. #4776 Kev and other decision-model work remain DRAFT/no merge; #4763 release untouched. No CI/protection, infrastructure, credentials, tags or schedules changed.

Apply the pinned formatter's line wrapping and indentation to the
submodule checkout and scheduler checks flagged by repository gates.
Refs #4593

Avoid reloading the parent Git index and reopening the child store for
all entries of an unchanged authenticated checkout on Unix. Compare native
inode, size and change-time identity on the parent, registration, child
administration and object pack paths before every source read. Revalidate
through the exact Git authority on mutation, with no cache for alternates
or uncertain filesystem evidence. Windows retains full validation.

Exercise 128 repeated real child reads, staged revocation and same-length
working registration changes without weakening existing source refusals.

Copy link
Copy Markdown
Owner Author

Refs #4593 — published focused per-entry submodule-authentication performance repair on the existing #4801 branch, DRAFT / HOLD MERGE.

Commit 5c481097 is an exact expected-old-head, force=false fast-forward from 9875a9e2. Independent Git ref/PR readback agrees at 5c481097; Git comparison shows exactly two submodule source/test files and one forward commit, with the prior formatter fix and all peer history preserved.

Code change: On Unix, repeated CheckoutWalk::next and live-source resolution no longer reopen the parent Git/index, parse working registrations, and reopen the pinned child store for every unchanged entry. An initial full binding verification may be reused only while per-entry native metadata witnesses match for parent Git/index/registration, child checkout marker/config, parent-owned object store, loose pin and existing pack files. A changed/uncertain witness clears the cache before re-running the original full Git authority; an alternate object store explicitly disables memoization. Windows continues full validation. No new registry, persisted compatibility shape, source policy or indexing route.

Falsifiable Rust regressions added: 128 real child-source resolutions must perform exactly one full Git-binding validation on an unchanged checkout, then a staged gitlink removal must immediately refuse and force a fresh validation; a same-length working .gitmodules path change must also refuse. Existing mid-walk marker/gitlink/config/repository replacement and typed unreadable-index regressions remain unchanged.

Evidence limits: The new exact-head CI is 42922412852, queued at readback. The authored Rust tests have not run under Bazel, nor have cross-platform native CI or independent approval. Keep both review threads open pending test evidence, source/security review and any necessary correction. #4593 remains OPEN; no merge, release, model or infrastructure mutation.

Refs #4593

Track secondary shared-index file identities in the per-entry submodule
binding witness. Main index and Git-dir stamps alone cannot detect an
in-place corrupted/replaced shared index, allowing stale authenticated
sources to be reused. Add a real Git split-index mutation regression.

Copy link
Copy Markdown
Owner Author

Refs #4593 — published a focused split-index authority repair on existing #4801 DRAFT; HOLD MERGE.

Commit 21ece5e was fast-forwarded from exact previously-read head 1bd73d4 using expected SHA + force=false. Remote ref/PR head and single-parent compare agree: exactly two paths (source_walk/submodules.rs and its existing test module), 12 production insertions and 39 test insertions, no peer commits removed.

New actionable defect fixed: the newly added Unix per-entry binding cache watched .git/index and the Git admin directory, but Git split-index stores a staged gitlink's backing entries in .git/sharedindex.*. Rewriting one existing shared-index file does not modify the main index or directory metadata, so unchanged witnesses could let stale/invalid Git authority continue to grant child-source reads. The binding witness now includes every named sharedindex.* file in the parent/private and common administrative roots; the already-watched directory identity invalidates the cache on additions/removals, while each file witness catches in-place corruption or substitution. It keeps the existing full Git verification on detected/uncertain changes and does not add a second registry or compatibility path.

Falsifiable regression committed: create a real parent/child Git fixture, enable split-index with git update-index --split-index, capture the actual secondary-index file's witness, corrupt only that file without changing the main index or parent-directory witness, and require the cached authority to invalidate. A disposable Git CLI-only probe confirmed the split-index file is distinct and a corrupted secondary index causes Git to reject it; this is not a Rust/Bazel test pass.

New exact-head CI was queued at readback. Draft workflow's native lanes are ordinarily skipped; no exact-head Linux/macOS/Windows Bazel behavioral pass, Clippy, formatter success or independent approving review is claimed. Preserve both unresolved review threads until genuinely verified. #4801 remains OPEN DRAFT and unmerged, #4593 OPEN until full acceptance on master. #4800 peer branch, protected #4776/decision-model drafts, and release #4763 untouched. No CI/protection, deployment, infrastructure or schedule changes.

Refs #4593

A retained child can outlive a change to the parent's effective core.worktree
in .git/config.worktree. The old cache watched the shared config and index
but not the per-worktree configuration: an in-place edit leaves those stamps
unchanged. Include both parent administrative config.worktree witnesses and
regress a real Git parent/child checkout with an unchanged index/directory.
Keep the original full Git validation and typed revocation, without granting
any new source identity. Exact-head nonzero Bazel validation remains owed.
Refs #4593

Use real newline and tab escapes in the new on-disk config.worktree
fixture. The parent worktree redirection must be parsed by Git, not written
as literal escape sequences. Preserve the same revocation assertions.

Copy link
Copy Markdown
Owner Author

Refs #4593 — new parent worktree-config authorization gap repaired and pushed on the existing #4801 branch; DRAFT / HOLD MERGE.

Published f3d0f385 and the test-fixture escape correction 72f91dad, both exact expected-head NONFORCE fast-forwards, with PR/ref readback at 72f91dad. Two paths only: source_walk/submodules.rs and its existing real-Git Rust tests; no peer history was rewritten.

New concrete stale-auth hazard: the Unix cached child-binding witness watched the parent Git index and shared config, but omitted .git/config.worktree. With extensions.worktreeConfig=true, an in-place edit of core.worktree can redirect the parent's effective checkout while retaining the exact index, parent Git-directory metadata, registered child marker, and on-disk child source bytes. A disposable native Git CLI probe confirmed before/after git rev-parse --show-toplevel changes from the parent to a foreign worktree while all previously watched index/Git-dir/config metadata remain identical. This is Git evidence, not Bazel/Rust verification.

Repair: witness both parent Git/private and common administrative config.worktree files, forcing existing complete parent/child Git revalidation on a change; no new source authority or policy. A new falsifiable Rust behavioral regression enables worktree-local configuration in a real parent/submodule fixture, primes a successful cached child read, rewrites only that config to a foreign worktree, requires the retained reader to refuse despite unchanged prior witnesses, and requires successful recovery when the original config is restored. Tests are authored but not yet executed by Bazel. Exact-head CI 42941525747 was queued on 72f91dad; draft native Linux/macOS/Windows and Clippy remain unverified. Independent approval, performance measurement, prerequisite integration and acceptance ON MASTER are still required.

Keep #4801 OPEN DRAFT / unmerged, #4593 OPEN, and preserve #4800's separate progress-code changes when reconciling reconcile.rs. Protected mixed/decision-model #4776 stays DRAFT/unmerged; release #4763 untouched. No CI policy, timeout, protection, infrastructure, credentials, tag or schedule change.

Apply the pinned formatter layout reported by repository gates.

Validation: owning Bazel formatter target passed; independent review completed.
@ScriptedAlchemy
ScriptedAlchemy changed the base branch from codex/dashboard-fixture-listener to master November 11, 2026 18:01
@ScriptedAlchemy
ScriptedAlchemy marked this pull request as ready for review November 11, 2026 19:51
Fix strict Clippy type complexity and nested binding checks, and format the reconciled tree-capture guard. Exercise split-index corruption through retained readers and revoke a real staged gitlink during snapshot capture, asserting refusal, preserved publication, and recovery.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

The historical blanket hold is superseded by the maintainer request to finish this PR. Pushed 6ca67c5: fixed two strict Clippy failures plus reconciled guard formatting, strengthened split-index refusal through retained readers, and added mid-capture staged-gitlink revocation/refused-publication/recovery coverage. Native macOS passed 398 source-index and 714 runtime cases (two existing opt-in cases ignored) before the final behavior-preserving nested-if collapse; final rustfmt and strict Clippy passed and all six focused runtime submodule cases reran with the anti-vacuity helper. Latest-head Windows indexing suites are dispatched: https://github.com/ScriptedAlchemy/tracedecay/actions/runs/43094396000 . The description now states these actual remaining CI/Windows checks rather than an indefinite do-not-merge instruction. No merge or Windows pass is claimed.

Refresh the existing canonical manifest expectation for the required
include_submodules policy field. Preserve all segment-byte and round-trip
assertions. Also apply the measured canonical batch setup repair for the
10,001-row global-db overlap fixture without changing its acceptance or
timeout. Exact-head CI verification remains required.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant