Skip to content

fix(core): refuse bound lifecycle transitions before catalog reads - #1027

Merged
qnbs merged 6 commits into
mainfrom
feat/445-e2-binding-first-lifecycle-20261011
Oct 13, 2026
Merged

qnbs merged 6 commits into
mainfrom
feat/445-e2-binding-first-lifecycle-20261011

Conversation

@qnbs

@qnbs qnbs commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

User description

Scope and owner admission

Owner-approved narrow Gate-4 E2 preparation, based on main ee526cb405f9ad94b0650a9b8b1704cdccde4bb9 after #1026's complete exact-main postmerge proof. The owner confirmed the bundled locator/phase/lifecycle A/A/A direction on 2026-10-11; this PR implements only the previously admitted four-file lifecycle precedence wave.

  • Authenticate the committed root before lifecycle catalog observation. A live binding returns RecoveryPending before intact/missing/corrupt catalog pages are read.
  • Preserve genuine Catalog(AuthorityError::Root(...)) errors, unbound catalog errors, locked/idempotent behavior and refused-unlock key clearing.
  • Negative lifecycle tests prove no catalog-page reads and unchanged installation data; bound/unbound root-error and unbound missing-page controls preserve their prior errors.
  • Update §10.3's explicit error-priority contract and record the approved normative locator/phase direction.

No journal locator implementation, binding producer, PREPARE/DONE permission window, E3 transition, Gates 5–7, release or production storage-authority switch. The strict E1 ordinary-operation barrier remains. Future windows require separately admitted/proven exclusive fencing of every relevant phase-changing writer; stale journal snapshots never grant permission.

Validation and race boundary

One lifecycle authority family: existing exclusive admission covers verification, writer/root ordering unchanged, second catalog binding check retained defensively. No new retry/await/stream or data write.

Local focused Gate4B target: all 45 tests passed after the final observation-adapter correction. The adapter's own control proves interception of all four direct/bounded file-read and directory-enumeration APIs. Rustfmt, signing doctor, hooks, actual/prospective PR budget and ci:prepush passed. Four files, 270 meaningful lines / 4 signed commits. Both CodeScene complexity findings were corrected without dropping the twelve root-error scenarios. CodeAnt's catalog-directory observation gap was corrected in the same testfile; bounded methods delegate to real bounded StdFs I/O. Required full remote CI/Core Rust/platform evidence and independent completed exact-current-head Codex review remain merge prerequisites; all actual findings in all three channels must be reconciled.

Optional Sourcery NO_SIGNAL/rate limit is non-blocking. Optional CodeRabbit NO_SIGNAL/rate limit is non-blocking with completed independent exact-head Codex review. Missing signal is never PASS; deterministic/security/signing/protection/admission gates remain mandatory.

Current production/retention baseline: #627 consolidated evidence; Gate8 cap count11 including unknowns, no provider mutations.
Owner: #445 / #922 / #359, QNB-168 / QNB-11; no owner closure from this preparatory slice.

Rollback: ordinary reviewed revert; no history rewrite or provider cleanup.

Summary by Sourcery

Refuse bound migration lifecycle transitions before catalog observation while preserving existing authority and recovery error behavior.

Bug Fixes:

  • Make lifecycle transitions return RecoveryPending for committed migration bindings before reading missing or corrupt catalog pages.
  • Preserve existing root-authority, unbound-catalog, locked-provider, idempotent-lock, and refused-unlock behavior.

Enhancements:

  • Document the lifecycle error-priority contract and owner-approved future locator and phase-barrier direction without enabling migration journal windows.

Documentation:

  • Update the secure-storage contract and changelog to describe bound-root lifecycle refusals and error precedence.

Tests:

  • Add coverage proving lifecycle refusals perform no catalog-page reads, preserve installation data, retain root errors, and keep unbound catalog errors unchanged.

CodeAnt-AI Description

Refuse lifecycle transitions before reading a bound migration catalog

What Changed

  • Lock, unlock, and shutdown now return RecoveryPending for a committed migration binding without reading catalog pages, even if those pages are missing or corrupt.
  • Root-read errors keep their existing errors, and unbound roots still report catalog errors as before.
  • Ordinary operations remain blocked during migration; no new migration-phase access is enabled.

Impact

✅ Bound migrations stay blocked when catalog pages are damaged
✅ Root authority errors remain visible
✅ Unbound catalog failures keep their existing outcomes

💡 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.

Summary by CodeRabbit

  • Bug Fixes

    • Lock, unlock, and shutdown now check committed migration state before accessing the catalog. If a live migration is present, these actions return RecoveryPending, including when catalog pages are missing or corrupt.
    • Root-slot read errors retain their existing error handling. Lifecycle operations without a migration binding continue to report catalog errors as before.
  • Documentation

    • Clarified lifecycle-transition checks and error priority. The future PREPARE/DONE window remains unavailable.

@vercel

vercel Bot commented Oct 11, 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 12:23pm UTC

@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

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: 402a5882-61ac-4721-a60e-22cf05e342ca
📥 Commits

Reviewing files that changed from the base of the PR and between b567e36 and 33ff279.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • crates/worldscript-secure-storage/tests/gate4b_operations_test.rs
🚧 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

Lifecycle transitions now authenticate the committed root before reading catalog pages. Bound roots return RecoveryPending, including when catalog pages are missing or corrupt. Tests cover root errors and unbound roots. Documentation records the behavior and a future E2 direction; PREPARE/DONE windows remain closed.

Changes: Lifecycle transition verification

Layer / File(s) Summary
Root-first verification and contract coverage
crates/worldscript-secure-storage/src/operations.rs, crates/worldscript-secure-storage/tests/gate4b_operations_test.rs, docs/native/R15-SECURE-STORAGE-CONTRACT.md, CHANGELOG.md
verify_transition checks the committed root before catalog pages. Tests cover bound and unbound roots, root-read errors, and missing or corrupt catalog pages for lock, unlock, and shutdown. The contract and changelog document this behavior and the non-admitting E2 direction.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 33ff2

No actionable issue is established for this change. Complete the stated CI and independent-review prerequisites before merging.

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

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

@sourcery-ai

sourcery-ai Bot commented Oct 11, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR changes lifecycle lock, unlock, and shutdown precedence so a committed live migration binding is authenticated first and returns RecoveryPending without reading catalog pages, while retaining genuine root and unbound-catalog errors. It adds no journal or permission-window implementation, and expands focused tests and contract documentation to enforce the read-order, error, and data-preservation boundaries.

Sequence diagram for bound lifecycle transition precedence

sequenceDiagram
    participant Caller
    participant ProtectedStorage
    participant RootStore
    participant Catalog

    Caller->>ProtectedStorage: lifecycle transition
    ProtectedStorage->>RootStore: load_committed_root(fs, provider, layout)
    alt root load error
        RootStore-->>ProtectedStorage: AuthorityError::Root(...)
        ProtectedStorage-->>Caller: Catalog(AuthorityError::Root(...))
    else live migration binding
        RootStore-->>ProtectedStorage: committed root with live_migration
        ProtectedStorage-->>Caller: RecoveryPending
    else unbound root
        RootStore-->>ProtectedStorage: committed root without live_migration
        ProtectedStorage->>Catalog: load_catalog(fs, provider, layout)
        alt catalog unavailable
            Catalog-->>ProtectedStorage: catalog error or None
            ProtectedStorage-->>Caller: existing catalog error or MigrationRequired
        else catalog loaded
            Catalog-->>ProtectedStorage: catalog
            ProtectedStorage-->>Caller: existing lifecycle behavior
        end
    end
Loading

Flow diagram for lifecycle authority and catalog read ordering

flowchart TD
    A[Lifecycle transition requested] --> B{Provider locked?}
    B -->|Yes| C[Existing provider refusal or idempotent lock]
    B -->|No| D[load_committed_root]
    D --> E{Root load succeeds?}
    E -->|No| F[Return Catalog AuthorityError Root]
    E -->|Yes| G{Committed live migration binding?}
    G -->|Yes| H[Return RecoveryPending]
    G -->|No| I[load_catalog]
    I --> J{Catalog available?}
    J -->|No| K[Return existing catalog error or MigrationRequired]
    J -->|Yes| L[Continue existing lifecycle behavior]
Loading

File-Level Changes

Change Details Files
Lifecycle transitions now authenticate the committed root binding before inspecting catalog pages.
  • Load and validate the committed root before catalog observation.
  • Return RecoveryPending immediately for live migration bindings.
  • Preserve provider, root, unbound-catalog, and idempotent/refused-unlock behavior.
crates/worldscript-secure-storage/src/operations.rs
Added regression coverage for lifecycle error precedence, read ordering, and data preservation.
  • Verify bound roots refuse before missing or corrupt catalog reads.
  • Verify root I/O errors retain their Catalog(AuthorityError::Root(...)) envelope.
  • Verify unbound missing-page behavior remains a catalog set mismatch.
  • Assert no catalog reads and no installation-data changes across lock, unlock, and shutdown.
crates/worldscript-secure-storage/tests/gate4b_operations_test.rs
Documented the E2 lifecycle error-priority contract and future locator/phase-barrier direction.
  • Specify root authentication before catalog inspection for bound roots.
  • Record preservation of genuine root errors and refusal on unusable bound catalogs.
  • Document that journal lookup, PREPARE/DONE windows, and later migration gates remain unadmitted.
docs/native/R15-SECURE-STORAGE-CONTRACT.md
Added the E2 preparation entry to the unreleased changelog.
  • Summarize bound-root refusal behavior and preserved error cases.
  • Record the owner-approved contract direction and that PREPARE/DONE windows remain closed.
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 11, 2026 •

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 33ff279b
Scan Time: 2026-10-13 12:25:17 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

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@qnbs
qnbs marked this pull request as ready for review October 11, 2026 13:17
@qnbs

qnbs commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@CodeAnt-AI review

Please independently review the exact current head 7270e7076c4769ef898dfbe250214e3ddaa04797, especially lifecycle binding-before-catalog priority, existing root-error envelope, failed-unlock key clearing and the strict unchanged E1 barrier. Owner-admitted four-file preparation only; no locator implementation or phase windows. All actual findings remain mandatory; optional reviewer quota absence is NO_SIGNAL, never PASS.

@sourcery-ai

sourcery-ai Bot commented Oct 11, 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 2 days and 19 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@codeant-ai

codeant-ai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 33ff279 Oct 13, 2026 · 12:22 12:23
✅ Incremental review completed 804def6 Oct 13, 2026 · 00:36 00:37
✅ Reviewed your PR 03b20a6 Oct 11, 2026 · 13:46 13:50
✅ Reviewed your PR b567e36 Oct 11, 2026 · 13:27 13:30
✅ Reviewed your PR 7270e70 Oct 11, 2026 · 13:17 13:22

@codeant-ai

codeant-ai Bot commented Oct 11, 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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 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-13T12:25:47.179328Z 33ff279 New commits
ℹ️ 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 added the size:L This PR changes 100-499 lines, ignoring generated files label Oct 11, 2026
@codeant-ai

codeant-ai Bot commented Oct 11, 2026

Copy link
Copy Markdown

Question: @codex review

review

please independently review the exact current head 7270e7076c4769ef898dfbe250214e3ddaa04797, especially lifecycle binding-before-catalog priority, existing root-error envelope, failed-unlock key clearing and the strict unchanged e1 barrier. owner-admitted four-file preparation only; no locator implementation or phase windows. all actual findings remain mandatory; optional reviewer quota absence is no_signal, never pass.

Answer:
No findings on the reviewed changes.

verify_transition authenticates the committed root before calling load_catalog, returns RecoveryPending for a live binding, and maps root-load failures through Catalog(AuthorityError::Root(...)). The UnlockAttempt guard still clears runtime keys when unlock is refused, while retaining the exclusive admission fence. The ordinary-operation E1 path is unchanged.

The added tests cover bound roots with intact, missing, and corrupt catalog pages; bound and unbound root-read errors; and the unbound missing-page control. I did not independently run the test suite.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 7270e7076c

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

@codeant-ai

codeant-ai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

CodeAnt PR Risk: Low Risk

  • The PR appears safe to merge; lifecycle transitions authenticate the committed root before observing catalog pages.
  • Tests verify bound roots refuse even with missing or corrupt pages, while root errors and unbound-catalog behavior remain unchanged.

Assessed commit: 33ff279b81fa

codescene-access[bot]

This comment was marked as outdated.

@qnbs

qnbs commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Exact current head b567e36bbfcf9b94329a8977ec88393c340a8d52. Both CodeScene findings (Bumpy Road Ahead and Deep, Nested Complexity) are fixed by a flat six-case selector and scenario helper; all 12 bound/unbound × lifecycle × root-error cases remain and the focused test passes. CodeScene now APPROVED this exact commit with 3 quality gates passed. Its prior inline comments are no longer present (GET 404); current paginated threads have 0 unresolved.

Please independently review this current matrix correction and unchanged lifecycle refusal/root-error-envelope/key-clearing boundary. Previous completed Codex review covered 7270e70; this request covers the new head. No journal/phase window or additional gate admission.

@qnbs

qnbs commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: b567e36bbf

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

@codeant-ai

codeant-ai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

CodeAnt Nitpicks

1 code suggestion

1. For unbound transitions, load_catalog immediately repeats this committed-root and key-epoch read, doubling durable I/O and allowing a second transient read failure to reject an otherwise valid lock, unlock, or shutdown.

Performance · crates/worldscript-secure-storage/src/operations.rs:592-594

@codecov

codecov Bot commented Oct 11, 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!

codescene-access[bot]

This comment was marked as outdated.

@qnbs

qnbs commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Exact current head 03b20a60acc788ed6a77fef56ec285a1c2eb16c4. CodeAnt finding #1027 (comment) is corrected: BarrierObservationFs in the existing testfile intercepts read/read_at_most/list_dir/list_dir_at_most, counts and rejects every catalog observation, and delegates real bounded I/O to StdFs elsewhere. Its control proves all four interception paths; all 45 Gate4B tests pass, including all 12 root-error scenarios, unchanged-tree and failed-unlock key-clearing assertions. Four files/270 meaningful lines/4 normally signed commits; no suppression or permission window.

Please independently review this exact current observation-adapter delta and the unchanged lifecycle authority boundary. Previous completed review was b567e36 and is not substituted for this head.

@qnbs

qnbs commented Oct 11, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 03b20a60ac

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

codescene-access[bot]

This comment was marked as outdated.

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

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

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant