Skip to content

Derive ledger roster modules without mutating source roots - #13609

Closed
briansrls wants to merge 5 commits into
mainfrom
seed/derived-rosters-in-memory
Closed

briansrls wants to merge 5 commits into
mainfrom
seed/derived-rosters-in-memory

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

Central claim

Source acquisition no longer mutates the checkout, and deploy candidate admission needs no roster exception. This is a prerequisite for the srv1 dashboard rollout.

Before this change, every source walk wrote gitignored roster.dag files (gunbc.recurring_failure_mode.roster, gunbc.rung_drop.roster) into the checkout it read. So every gunbc invocation left its own checkout dirty, and gunbc.live_deploy.candidate refused it (CandidateCheckoutNotClean ... ignored-deployed=dag/gunbc/rung_drop/roster.dag). The earlier fix exempted one of the two files in deployed_tree_excluded_derived_files.

What changed

  • One acquisition boundary, no writes. derived_row_roster::acquire_dir_files takes a directory's own .dag listing and returns AcquiredDag sources. For a ledger row directory it also adds the roster rendered by render_roster from the same sibling bytes it just read. Selection is unchanged: declares_row picks rows by declared type, helper modules are never members, order is sorted, and rostered_row_join's DeclaredNotRostered is still the authority. AcquiredDag has no Deref<Target=Path>, so the compiler rejects any consumer that tries to read a derived module from disk.
  • Deleted: ensure_if_row_dir, ensure_if_row_dir_or_panic, ensure_derived_roster, write_atomically, row_stems.
  • Every consumer cut over together: collect_dag_files_result, collect_dag_files_tolerant (now returns a located refusal instead of swallowing roster failures), run_dag_parse_sweep, main.rs collect_dag_files, compiler_tests collect_dag_recursive (its .dag authority and stage0 mirror were regenerated), and every path-then-read_to_string consumer downstream of them. That covers module indexing (try_build_module_index, try_index_source_root_into_module_index, for_each_parsed_module_binding), import/reference discovery, entry_source_from_index_or_disk (an entry naming a derived roster is answered from the index), decl_facts_corpus_walk, decls_parse_only_from_disk, and the rostered-row join's source accounting. Source roots and their precedence are unchanged.
  • Legacy physical roster: a file at a reserved roster identity is refused with its path. It is never consumed, never silently overridden, and never deleted by the loader.
  • Historical revisions: namespace_baseline still reads a base revision's committed roster.dag as source and does not synthesize a competing module. Absent and present-empty are still distinguished (roster_from_path_listing).
  • Deploy: removed the deployed_tree_excluded_derived_files exemption. All candidate gate categories are kept, and no rung-drop or deploy-time regenerate step was added. Corrected the stale deployed_tree_scope / candidate explanations that said the deploy rsyncs the working tree: convergence is git-native.
  • Migration of legacy files: the two roster paths are now gunbc.repo_workspace rows with reason SupersededAuthority (still ignored). repository_converge_wet runs retire_superseded_workspace_files after the reset. Its population is derived from the file-grain SupersededAuthority rows, so no new list was added. Each file is deleted and then read back absent through filesystem_exact_read. A failure is the typed outcome ConvergenceSupersededFileNotRetired.
  • gunbc.derived_row_roster_seed_growth has been re-stated for the new boundary. The declaration-value-binding trigger is still outstanding.

Evidence (on the committed head, with binaries built from it)

  • cargo test --release -p v1-compiler --lib -- derived_row_roster rostered_row_join namespace_baseline entry_resolve coproduct_reflection: 38 passed. This includes new controls for:
    • in-memory contribution with the whole tree unchanged across two invocations
    • add/remove row changes the roster; a helper module is never a member
    • a legacy roster refuses with its location and is left untouched
    • an unreadable row refuses
    • read-only source roots
    • parse sweep indexes the derived roster and writes nothing (producer to consumer)
  • cargo test --release --test declaration_index_integrity --test dag_parse_sweep_refusal_location: 36 passed.
  • cargo clippy --all-targets -- -D warnings: clean. cargo fmt --all --check: clean.
  • claim_executor --required-ci --source-root dag --source-root src/v2 --required-lane build: OK (first_generation_equal=true).
  • claim_executor ... --required-lane witnesses:
    • Parse OK over 8158 files.
    • rostered-row-join matched both ledgers (RFM 624/624, RungDrop 118/118).
    • Changed hermetic witnesses passed.
    • The lane exited 1. Its 16 refusals are all local-repo-wet host premises that have nothing to do with this change: mtcollins1 KVM browser, roadmap allocation browser client, and the srv8 history arm.
    • It also blocked on the new wet convergence row as a route gap. That row is now enrolled in floor_route_gap like its seven siblings, but the lane was not re-run after that commit.
  • claim_batch --wet ... repository_convergence_wet_witness_test --functions a_legacy_derived_roster_file_is_retired_and_read_back_absent,detached_primary_transition_...: both PASS.
  • Live check with the real loader and the real observe_candidate_checkout on this clean checkout:
    • Both roster modules were non-empty and the candidate was clean (exit 0).
    • git status --ignored showed only target/, and no roster file exists.
    • With a planted dag/gunbc/rung_drop/roster.dag, loading refused and named the path, and the file was left intact.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 4 commits October 9, 2026 01:39
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T03:28:38.988495Z 6d2668d PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d2668d41e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

here.push(path);
}
}
files.extend(derived_row_roster::acquire_dir_files(dir, here)?);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route standalone corpus walkers through roster acquisition

When bootstrap_witness runs ci_full_dag or the documented type_occurrence_binding_census dag runs after a normal compiler walk, their private walkers in src/v1/stage0/src/bin/ still enumerate and read only on-disk PathBufs before compiling the corpus. Those corpora import gunbc.recurring_failure_mode.roster and gunbc.rung_drop.roster; because this change stops materializing those files and only callers of acquire_dir_files receive the virtual modules, these binaries now compile an unresolved corpus and fail in the intended file-free steady state. Update the standalone walkers to consume AcquiredDag sources through the shared acquisition boundary as well.

Useful? React with 👍 / 👎.

…ane; typed resolve refusal for a legacy roster

The changed-witness gate admits a hermetic route gap only when the same
identity has a wet terminal on this candidate (HermeticRouteGapHeldAndWetPassed),
so the wet witness is scheduled in local_repo_wet_terminal. resolve_entry_graph
uses the fallible shared index, so a legacy physical roster is a typed exit 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Superseded by #13641 at 634453d: this PR's head is an ancestor of integration/v1-closeout. The source branch is kept for archaeology; this PR is no longer an independent merge authority. — sent from neat-wolf-604

@gunbai-bot gunbai-bot Bot closed this Oct 9, 2026
@gunbai-bot gunbai-bot Bot mentioned this pull request Oct 10, 2026
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