Skip to content

feat(core): publish a journal phase change only under exclusive admission - #1033

Closed
qnbs wants to merge 6 commits into
mainfrom
feat/445-gate4e-e2b-phase-transition-admission
Closed

qnbs wants to merge 6 commits into
mainfrom
feat/445-gate4e-e2b-phase-transition-admission

Conversation

@qnbs

@qnbs qnbs commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

User description

What

A journal phase change is now published only by commit_phase_transition, which takes the installation's ExclusiveAdmissionGuard by mutable borrow. The ordinary progress checkpoint no longer carries a phase change.

  • commit_phase_transition commits the root below that admission; an admission that does not guard the root of its layout is refused as NotAdmitted before anything is read. A shared guard, and a shared reference to the exclusive guard, do not compile (two compile_fail doctests paired with one that compiles).
  • The progress checkpoint, the binding advance and the journal-level checkpoint publish refuse a successor that changes the phase (PhaseChangeNotACheckpoint); the transition refuses one that keeps it (NotAPhaseChange). Both refusals precede the first journal byte.
  • The root classifies the advance with a new BindingStep::PhaseTransition, so a generation promoted directly becomes authoritative only through the transition. Capture, renewal and takeover keep their own relations.
  • The conversion driver's two phase changes (enter_convert, finish_convert) use the held form of the transition; its behaviour is unchanged.

Why

The owner confirmed D1(a), D2(a) and D3 on #359 for exactly one bounded Gate 4E E2 follow-up slice: typed exclusive protection of real phase changes, separated from ordinary progress checkpoints. Contract §10.3 named this as the step that makes the exclusive-admission requirement of a phase change mechanical.

Evidence

  • Hosted CI is the authority. Locally, only cargo clippy --all-targets -D warnings for the crate, cargo fmt --check, the affected test binaries (the new file, root binding, journal durable, journal route, conversion entry) and the three commit_phase_transition doctests were run, one job at a time.
  • New tests/gate4e_phase_transition_test.rs: success under exclusive admission, both refusals writing nothing, an admission for another root, the directly promoted phase change (refused by the advance and the checkpoint, adopted without a journal write only by the transition), the journal-level publishers, and shared/exclusive admission excluding each other.
  • Existing tests that moved the phase through the checkpoint are migrated: the root-binding fixture picks the path by the committed phase, the binding-advance scenario keeps the phase of its bootstrap revision, and one rival candidate in the journal-durable tests goes through the transition publisher. Refusal tests keep their errors, because both successor relations run the progress relation first.
  • The two compile_fail doctests were checked to fail with E0308 on the guard parameter, not on an unrelated error.

Not in scope

No producer of a binding, no PREPARE/DONE window, no change to the capture, takeover or renewal writers, no writer journal locator, no E3, no Gate 5 or later. The E1 barrier is unchanged.

Part of #359. Owner: #922 / QNB-168.

Summary by Sourcery

Require exclusive admission for journal phase changes while keeping ordinary progress checkpoints phase-preserving.

New Features:

  • Add an exclusively admitted phase-transition commit path for publishing journal phase changes and making them authoritative.

Bug Fixes:

  • Prevent ordinary checkpoints, binding advances, journal checkpoint publishers, and raw production root commits from bypassing exclusive phase-transition requirements.

Enhancements:

  • Enforce distinct successor rules for progress checkpoints and phase transitions, including root admission validation and typed admission-mode guarantees.
  • Route conversion phase changes through the protected transition path while preserving existing conversion behavior.

Documentation:

  • Document the Gate 4E exclusive phase-transition contract, its limitations, and the associated evidence.

Tests:

  • Add coverage for successful and rejected phase transitions, no-write refusals, foreign and conflicting admissions, direct promotion, publisher behavior, and alias retargeting.

Chores:

  • Restrict the raw root commit API to the test-support feature.

Summary by cubic

Publishes a journal phase change only under the installation's exclusive admission: the new commit_phase_transition takes ExclusiveAdmissionGuard by mutable borrow, and the progress checkpoint, binding advance, and journal-level checkpoint publish refuse a successor that changes the phase.

  • The root commit event is typed by its admission's mode (AdmittedRootCommitGuard<'_, Mode>), so the held transition takes the exclusive event and a shared guard or bare root lock cannot reach it.
  • commit_phase_transition resolves the root's canonical path once at admission proof and uses it for all reads and writes, so a retargeted alias cannot redirect the commit; an admission for another root is refused as NotAdmitted.
  • Refusals (PhaseChangeNotACheckpoint, NotAPhaseChange) precede the first journal byte; the transition adopts an identical directly-promoted candidate without a journal write, and the phase-transition publisher refuses a bootstrap, which stays with the ordinary publisher.
  • The raw commit_root, which publishes whatever binding it is given, is now exported only with the test-only test-support feature, so a bare root lock can no longer make a directly promoted phase change authoritative through it.
  • The conversion driver's enter_convert and finish_convert use the held transition form with unchanged behavior; capture, takeover, and renewal writers are untouched.
  • New gate4e_phase_transition_test.rs covers success, both refusals, foreign admission, direct promotion, the journal-level publishers, shared/exclusive exclusion, and Unix-only alias redirection, the alias cases in their own module.
  • Recovery of a transition that a crash interrupts after the anchor is prepared is completed forward by recover_root, which asks for no exclusive admission; that point stays open (Desktop fs-data key-rotation migration is not crash-resumable (mixed-key state possible) #359).

Written for commit 8017776. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • New Features
    • Phase changes can now be committed through exclusive installation admission, with the root linked to the new journal revision.
    • Conversion phase changes use this process while retaining their existing behavior.
  • Bug Fixes
    • Progress checkpoints and binding updates now reject phase changes, while phase transitions reject updates that keep the same phase.
    • Invalid operations are refused before journal data is written.
  • Documentation
    • Secure storage guidance now describes admission requirements and rules for phase changes and progress updates.

CodeAnt-AI Description

Require exclusive admission before changing a journal phase

What Changed

  • Journal phase changes can become authoritative only through a commit holding the installation’s exclusive admission; ordinary checkpoints reject phase changes before writing journal data.
  • The transition rejects updates that keep the same phase or use an admission for a different root.
  • Conversion phase changes use the protected transition, with conversion behavior unchanged.
  • Production callers can no longer use the raw root commit to bypass phase-transition checks.

Impact

✅ Phase changes cannot overlap ordinary operations
✅ Invalid phase updates write no journal data
✅ Wrong-root admissions cannot commit a transition

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

…sion (#445)

A phase change ends the window in which one phase admitted what the next one
forbids, so it cannot be published while an ordinary operation may be in flight.
Until now only the conversion gate held that by type; the public checkpoint and
binding advance accepted a phase change from any caller.

commit_phase_transition takes the installation's ExclusiveAdmissionGuard by mutable
borrow, so a shared guard does not compile, and commits the root below that
admission. An admission that does not guard the root of its layout is refused as
NotAdmitted before anything is read.

The progress checkpoint, the binding advance and the journal-level checkpoint publish
now refuse a successor that changes the phase (PhaseChangeNotACheckpoint), and the
transition refuses one that keeps it (NotAPhaseChange), each before a journal byte is
written. The root classifies the advance with a new BindingStep::PhaseTransition, so a
generation promoted directly becomes authoritative only through the transition.
Capture, renewal and takeover keep their own relations.

The conversion driver's two phase changes use the held form of the transition; its
behaviour is unchanged. Existing tests that moved the phase through the checkpoint are
migrated: the root-binding fixture picks the path by the committed phase, and the
binding-advance scenario keeps the phase of its bootstrap revision.

This adds no producer of a binding, opens no PREPARE/DONE window and leaves the capture
writers, the writer journal locator and E3 closed.
@sourcery-ai

sourcery-ai Bot commented Oct 13, 2026

Copy link
Copy Markdown

Sorry @qnbs, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 13 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@vercel

vercel Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
worldscript-studio Ready Ready Preview Oct 13, 2026 5:00pm UTC

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 13, 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-13T17:20:36.495906Z 8017776 Manual request
ℹ️ 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.

@codeant-ai

codeant-ai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed fec4ba1 Oct 13, 2026 · 16:21 16:21
✅ Reviewed your PR 89e2a46 Oct 13, 2026 · 14:39 14:45

@codeant-ai

codeant-ai Bot commented Oct 13, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@sourcery-ai

sourcery-ai Bot commented Oct 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR makes phase changes mechanically exclusive: ordinary checkpoints, binding advances, and journal publishers can only preserve the phase, while commit_phase_transition requires a correctly scoped mutable exclusive admission and is the only path that can publish and bind a phase-changing manifest; conversion callers, tests, and contract evidence are updated accordingly.

Sequence diagram for exclusively admitted phase transition

sequenceDiagram
    participant Caller
    participant ExclusiveAdmissionGuard
    participant Authority
    participant Journal
    participant Root

    Caller->>Authority: commit_phase_transition(admission, fs, provider, layout, checkpoint)
    Authority->>Authority: check_operation_id(operation_id)
    Authority->>ExclusiveAdmissionGuard: guards(scope)
    ExclusiveAdmissionGuard-->>Authority: admission confirmed
    Authority->>ExclusiveAdmissionGuard: try_root_commit()
    ExclusiveAdmissionGuard-->>Authority: RootCommitGuard
    Authority->>Journal: publish_phase_transition_fenced(manifest, fence, committed)
    Journal->>Journal: assert_phase_transition_successor(prev, next)
    Journal-->>Authority: PublishedManifest
    Authority->>Root: commit_planned(BindingStep::PhaseTransition)
    Root-->>Caller: RootCommitted
Loading

Flow diagram for phase-specific publication paths

flowchart TD
    M[Successor manifest] --> C{Phase changes?}
    C -->|No| P[publish_manifest_fenced]
    P --> PC[assert_checkpoint_successor]
    PC --> B[BindingStep::Checkpoint]
    C -->|Yes| T[publish_phase_transition_fenced]
    T --> PT[assert_phase_transition_successor]
    PT --> A[BindingStep::PhaseTransition]
    A --> E[Requires mutable ExclusiveAdmissionGuard]
    B --> R[Root becomes authoritative]
    E --> R
Loading

File-Level Changes

Change Details Files
Added an exclusively admitted API as the sole authority path for journal phase transitions.
  • Introduced commit_phase_transition requiring a mutable ExclusiveAdmissionGuard.
  • Validated that the admission guards the layout root before reads or writes.
  • Added root-busy and admission-related error handling and a held internal variant.
  • Added compile-time documentation proving shared guards and shared references cannot be used.
crates/worldscript-secure-storage/src/authority.rs
crates/worldscript-secure-storage/src/lib.rs
Separated phase-transition successor validation from ordinary progress checkpoints across journal and root-binding commits.
  • Added checkpoint and phase-transition successor predicates with dedicated refusal errors.
  • Rejected phase changes from checkpoints, binding advances, and ordinary journal publication before any journal write.
  • Added BindingStep::PhaseTransition so only the transition path can make a changed-phase generation authoritative.
  • Exported the new predicates and publisher APIs.
crates/worldscript-secure-storage/src/journal/succession.rs
crates/worldscript-secure-storage/src/journal/state.rs
crates/worldscript-secure-storage/src/journal/durable.rs
crates/worldscript-secure-storage/src/journal/mod.rs
crates/worldscript-secure-storage/src/authority.rs
crates/worldscript-secure-storage/src/lib.rs
Migrated conversion phase changes to the exclusive transition path while preserving existing conversion behavior.
  • Added a phase-transition step kind to conversion sessions.
  • Changed enter_convert and finish_convert to use the held transition commit.
  • Kept ordinary conversion checkpoints on the progress path.
crates/worldscript-secure-storage/src/conversion.rs
Added focused coverage and updated existing fixtures and contract documentation for the new authority boundary.
  • Tested exclusive success, wrong-root and shared/exclusive admission behavior, refusal-without-writes, direct promotion, and journal-level publisher separation.
  • Migrated existing tests that previously advanced phases through checkpoints.
  • Documented the Gate 4E E2 contract and changelog behavior.
crates/worldscript-secure-storage/tests/gate4e_phase_transition_test.rs
crates/worldscript-secure-storage/tests/gate4d_journal_durable_test.rs
crates/worldscript-secure-storage/tests/gate4d_root_binding_test.rs
docs/native/R15-SECURE-STORAGE-CONTRACT.md
docs/native/r15/GATE4D-JOURNAL-DURABLE-EVIDENCE.md
CHANGELOG.md

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codeant-ai

codeant-ai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 8017776b
Scan Time: 2026-10-13 16:58:12 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 0.0% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues

View Full Results

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Oct 13, 2026
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

[check-pr-size] PR size is over the hard tier (normal profile): 16 files, 1368 meaningful lines, 6 commits — limit ≤20 files / ≤1200 lines / ≤10 commits. Consider splitting into smaller, independently reviewable PRs.

codescene-access[bot]

This comment was marked as outdated.

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Next included review available in 23 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 63 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: qnbs/WorldScript-Studio/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: edafd4ba-f2f8-4a20-86a9-9b110ef93eaf
📥 Commits

Reviewing files that changed from the base of the PR and between fec4ba1 and 8017776.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • crates/worldscript-secure-storage/src/authority.rs
  • crates/worldscript-secure-storage/src/journal/durable.rs
  • crates/worldscript-secure-storage/tests/gate4e_phase_transition_test.rs
  • docs/native/R15-SECURE-STORAGE-CONTRACT.md
  • docs/native/r15/GATE4D-JOURNAL-DURABLE-EVIDENCE.md

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: qnbs/WorldScript-Studio/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 967f0db7-e687-41ec-971d-697d07f10fe7
📥 Commits

Reviewing files that changed from the base of the PR and between 89e2a46 and fec4ba1.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • crates/worldscript-secure-storage/src/admission.rs
  • crates/worldscript-secure-storage/src/authority.rs
  • crates/worldscript-secure-storage/src/conversion.rs
  • crates/worldscript-secure-storage/src/lib.rs
  • crates/worldscript-secure-storage/src/root_store.rs
  • crates/worldscript-secure-storage/tests/gate4e_phase_transition_test.rs
  • crates/worldscript-secure-storage/tests/gate4e_phase_transition_test/through_an_alias.rs
  • docs/native/R15-SECURE-STORAGE-CONTRACT.md
  • docs/native/r15/GATE4D-JOURNAL-DURABLE-EVIDENCE.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

📝 Walkthrough

Journal checkpoints now preserve phase, while phase changes use a separate commit path that requires exclusive installation admission. The conversion driver uses this path for its phase changes. Tests and documentation cover the commit rules, refusal cases, and admission requirements.

Changes: Journal Phase Transition

Layer / File(s) Summary
Journal successor rules and publication
crates/worldscript-secure-storage/src/journal/{state,succession,durable,mod}.rs, crates/worldscript-secure-storage/src/lib.rs
Successor checks and fenced publication distinguish phase-preserving checkpoints from phase-changing transitions. The crate exports the transition publisher and successor checks.
Admission-bound root commit
crates/worldscript-secure-storage/src/{admission,authority,root_store,lib}.rs
commit_phase_transition verifies exclusive admission for the canonical target root, publishes a phase-changing manifest, and records the matching root binding step. The raw root commit is available only with test-support.
Conversion phase-transition routing
crates/worldscript-secure-storage/src/conversion.rs
The conversion driver routes its ADMIT-to-CONVERT and CONVERT-to-VERIFY changes through the transition commit. Renewal and checkpoint steps retain their existing paths.
Transition tests and contract updates
crates/worldscript-secure-storage/tests/gate4d_*_test.rs, crates/worldscript-secure-storage/tests/gate4e_phase_transition_test*, docs/native/R15-SECURE-STORAGE-CONTRACT.md, docs/native/r15/GATE4D-JOURNAL-DURABLE-EVIDENCE.md, CHANGELOG.md
Tests cover successful transitions, refusal cases, admission and alias constraints, and journal writes. Documentation describes the checkpoint and transition rules.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to fec4b

No actionable issue is established; merge after the normal checks.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Comment thread crates/worldscript-secure-storage/src/authority.rs Outdated
@codeant-ai

codeant-ai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

CodeAnt PR Risk: Low Risk

  • The PR appears safe to merge: phase changes require exclusive admission and cannot be published as ordinary checkpoints.
  • Targeted tests cover refusal without writes, direct promotion, admission conflicts, and root-alias retargeting.

Assessed commit: fec4ba1dac86

@codecov

codecov Bot commented Oct 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

…lusive event type (#445)

The admitted root event now carries the mode of the admission it was taken from
(AdmittedRootCommitGuard<'_, Mode>). The held form of the transition takes the exclusive
event, so a shared admission or a bare root lock cannot reach it; a compile_fail doctest on
try_root_commit pairs with one that compiles. Both routes to the held form, the public
commit and the conversion driver, hand it the event of their exclusive admission.

commit_phase_transition resolves the root to its canonical path once, when the admission is
proven, and uses that path for every read and write of the commit. An alias that is retargeted
after the proof can no longer redirect the commit to another root: a test points the alias at
a second root during the call and asserts the admitted root advanced and the other one is
untouched, and a second test refuses an alias that already leads to another root before
anything is written. Both are Unix-only because they need a symbolic link.

The test helper that bundled a checkpoint takes the journal source as one argument instead of
five.
codescene-access[bot]

This comment was marked as outdated.

…attempt (#445)

CodeScene counts the receiver, so the helper that runs a transition over a chosen file system
under a chosen spelling of the root had five arguments. The two now travel as one value; the
helper takes four and the tests are unchanged.
codescene-access[bot]

This comment was marked as outdated.

@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: 32636c1bfc

ℹ️ 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".

Comment thread crates/worldscript-secure-storage/src/authority.rs
…wn module (#445)

CodeScene reports Low Cohesion for the test file once it holds the fixture, the manifest
builders, the transition cases and a hook file system with its alias cases. The alias cases
are a separate responsibility, so they move to a module file included like the submodules of
gate2_identity_test. No test changed.
codescene-access[bot]

This comment was marked as outdated.

The raw commit_root publishes whatever live-migration binding it is given. The relation of a
changed binding to the committed one (phase, owner, inventory, lease) is proven only by the
authority commits, so a caller with a bare root lock could still name a directly promoted
phase change and bypass the exclusive transition.

commit_root is now exported only with the test-only test-support feature, like load_catalog and
list_records. The production publications (the authority commits and write_key_epoch) call the
crate-private commit_root_primitive, so nothing changes for them and for bootstrap and recovery.
Tests keep the raw commit as scaffolding for states that have no production producer yet, such as
the binding that a later finalization will clear.

A first attempt to refuse a changed binding at run time broke exactly such a test and would still
be bypassed by clearing and rebinding, so the restriction is the visibility of the primitive.
@codeant-ai codeant-ai Bot added size:XXL This PR changes 1000+ lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Oct 13, 2026
codescene-access[bot]

This comment was marked as outdated.

@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: fec4ba1dac

ℹ️ 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".

Comment thread crates/worldscript-secure-storage/src/journal/durable.rs
Comment on lines +485 to +489
let event = admission
.try_root_commit()
.map_err(AuthorityError::Admission)?
.ok_or(AuthorityError::RootBusy)?;
commit_phase_transition_held(fs, provider, layout, checkpoint, &event)

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 Keep crash recovery under exclusive admission

If commit_phase_transition fails after preparing the anchor and writing the matching target slot but before step F commits the anchor, its exclusive guard is dropped while the prepared phase-changing root remains recoverable. Although the raw commit is now private, recover_root can still complete that target using only a bare RootCommitGuard; ProtectedStorage::recover_prepared_root_admitted demonstrably calls it while holding a shared admission (operations.rs:250-254). Thus the phase change can become authoritative while an ordinary operation holds shared admission, so recovery of a prepared transition must retain or reacquire exclusive admission (or otherwise distinguish and refuse phase-changing targets).

AGENTS.md reference: AGENTS.md:L31-L33

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Valid and not dismissed; this thread stays open on purpose.

Verified on the code: a transition interrupted after the anchor was prepared is completed forward by recover_root with only a RootCommitGuard, and its one production caller runs under a shared admission. A phase-precise fix is not possible at the root layer (the manifest needs the journal locator, which is not admitted); the authenticated class is "the prepared target changes the binding", which covers every journal-owner commit. A correct repair therefore changes the recovery protocol (refusal in the shared path, an exclusive recovery entry, and the conversion entry resolving a pending preparation), which goes beyond the admitted slice.

Options A/B/C with a recommendation are on #359: #359 (comment). Until the owner decides, #1033 states the point as open in the contract, the evidence and the rustdoc instead of claiming it closed.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Owner decision recorded: option B (successor PR), confirmed 2026-10-13. This finding stays VALID / DEFERRED / MUST-FIX and this thread stays open; it is not dismissed and not accepted as safe. #1033 claims exclusivity only for the start of a phase change, and merging it needs a separate final merge admission. Reproduction, call chain, impact, acceptance criteria of the successor slice (proposed, not admitted) and the blocked steps: #359 (comment)

…ecord the open recovery point (#445)

publish_phase_transition_fenced without a committed predecessor reached the journal write for the
bootstrap revision, because the successor relation was skipped when nothing was committed. A bootstrap is
no phase change: the publisher now refuses it as NotAPhaseChange before any journal I/O, and the regular
publisher keeps the bootstrap. A test asserts the refusal leaves the journal directory empty and that the
regular publisher still writes generation 0 afterwards.

The contract, the evidence and the rustdoc no longer say that the transition is the only way a phase change
becomes authoritative. It is the only way to start one in the production crate. A transition that a crash
interrupts after the anchor was prepared is completed forward by recover_root, which asks for no exclusive
admission; that is recorded as open instead of claimed closed.

@codescene-access codescene-access 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.

Gates Passed
3 Quality Gates Passed

See analysis details in CodeScene

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@qnbs

qnbs commented Oct 13, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 8017776b70

ℹ️ 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".

qnbs added a commit that referenced this pull request Oct 13, 2026
PR #1033 is closed unmerged and superseded: its six commits are part of
this stacked branch and land with the single protected squash of #1035.
qnbs added a commit that referenced this pull request Oct 13, 2026
…sive admission (#445) (#1035)

Gate 4E E2b and E2c as one protected squash (owner decision S2): a journal phase change is published only by commit_phase_transition under the typed exclusive admission, and a prepared root that changes the live-migration binding is completed only by recover_root_exclusive. Includes the six commits of PR #1033, which is closed unmerged and superseded by this PR. Issue #359.
@qnbs

qnbs commented Oct 13, 2026

Copy link
Copy Markdown
Owner Author

Closed as superseded by #1035 — not merged as its own PR. All six commits of this branch (head 8017776b) landed through the protected squash of #1035 as 2f01b8ead176bd3c77fe1f3b65423ab8ab358578 on main, under the owner's decision S2. Proof of integration: 8017776b is an ancestor of the #1035 head a31cd406, and the tree of 2f01b8ea is identical to the tree of a31cd406 (git diff is empty).

The Codex P2-B thread on this PR (a prepared binding change completed under a shared admission after a crash) was valid when raised and stays here unresolved as historical review evidence. It is repaired by the E2c commits 81a7c353 and bff6e34b in #1035: recover_root refuses to complete such a root and writes nothing (RecoveryPending for the ordinary operation), recover_root_exclusive completes it only under the typed exclusive admission, and begin_conversion resolves a pending preparation first. Tests: crash_recovery.rs (the_shared_recovery_refuses_a_prepared_phase_change_and_the_exclusive_one_completes_it, only_a_change_of_the_binding_needs_the_exclusive_recovery, an_ordinary_operation_over_a_prepared_phase_change_is_refused_and_writes_nothing, crash-window cases) and through_an_alias.rs. The resulting-main CI/CD and CodeQL on 2f01b8ea are still running; P2-B is recorded as fixed on main only after they are green.

The branch is kept (delete_branch_on_merge=false, no branch deletion). Gate 4 stays open.

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

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant