Skip to content

feat(core): commit a staged inventory (#445) - #1011

Merged
qnbs merged 3 commits into
mainfrom
feat/445-gate4d-streaming-capture-promote
Oct 8, 2026
Merged

qnbs merged 3 commits into
mainfrom
feat/445-gate4d-streaming-capture-promote

Conversation

@qnbs

@qnbs qnbs commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

User description

What

Stage two (a) of the streaming capture: the step that makes a staged inventory reachable. Stage one (#1010) leaves the pages of a finished inventory in a private inventory/pending-* directory; nothing could promote them, so commit_inventory_capture (every page in memory) was still the only way to capture.

Step Rule
promote_staged_inventory_fenced under the journal mutex, before any read or write: the caller is the committed owner writing under the committed manifest (refused before anything is read); then the exact root-named predecessor, the capture successor relation, and the staged references against the page set the successor names. Then, one page at a time: load_staged_page (digest first, then open), the entries absorbed into the inventory digest, store_page_at into inventory/<digest>/page-<i>/ (an identical page is adopted, a different file never replaced). Finally the inventory digest must equal the successor's
commit_streamed_inventory_capture commit_inventory_capture's order and guarantees: operation id, fence, root lock, committed binding, journal key routed from the root, the promotion, publish_manifest_fenced as the capture, BindingStep::Capture. The staged files are removed (best effort) only after the root has committed, so a retry after a failed root commit still has them and adopts pages and manifest; after a success the handle is spent

commit_inventory_capture and the new commit share one core (commit_capture) that takes the step storing the pages as an argument, so the order of operations under the root lock exists once. Memory stays one page.

Decisions to review (mine, flagged on the admission): one pass, so a staged page found wrong midway leaves an inert verified prefix under the digest directory (as an I/O failure partway through the in-memory store already does) and no manifest is published, instead of two passes over the staged data; the commit takes &StagedCapture so a retry has the files; a second entry point beside commit_inventory_capture, not a replacement.

Boundary matrix

Mutation the digest directory under the journal, the manifest generation and the root binding, only through the new commit; additive API; the existing commit's behaviour is unchanged
Order operation id, fence, root lock, committed binding, routed key, promotion (authority first, then page by page), publish, binding step, then removal of the staged files
Refusal stale or foreign owner (before anything is read), a manifest the root does not name, a successor that is not the capture successor, a staged page that changed or is missing (Corrupt, never RecoveryRequired), an unroutable key epoch, no bound migration, a token that is not the successor's: each before a manifest is published

Not in this PR

Stage two (b), the authority-level staging session that routes the journal key from the root (staging still takes the key from its caller), the C2 driver, reclaiming abandoned pending directories, inheriting unchanged pages, the write barrier. No production authority switch.

Verification

Local: on the journal alone, a promoted capture publishes and binds as a stored set that verify_stored_inventory accepts with the same references and manifest, a repeated promotion adopts what is stored, a stale owner and another revision are refused before anything is read, a manifest the root does not name and a capture built over another phase are refused with nothing created, and a changed or missing staged page stops the promotion with only a verified prefix stored. With a real root, the commit names the successor, its pages verify and the staged files are gone; a stale token and an unbound migration are refused with the journal tree and the root unchanged and the staged files kept; a changed staged page refuses the commit before any manifest is published; a failed root commit is retried with the same staged capture, which writes nothing new into the journal. The key route refuses the new commit with a revoked or unregistered epoch and a route to another key, beside the other journal-owner operations. Mutation-checked: the root-named, capture-successor and promote-authority checks (the last one made observable by asserting that nothing is read before it refuses), the digest directory, the inventory digest absorption, keeping the staged files after a success, removing them before the root commit, and a fixed journal key in the shared core each fail the test that owns them. Disclosed: two checks have no test that fails without them through the public API (the staged references against the successor's page set, and the final inventory-digest comparison), because StreamedCapture::finish cannot produce a successor that disagrees with its staged references; both mutations were run and survive, and the evidence says so. The whole crate suite (50 passing results), cargo clippy --all-targets -D warnings, cargo fmt --check, pnpm run docs:check.

Part of #359 and #445 (Linear QNB-11). Admission: #359 issuecomment-6067292231. PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NO.

Summary by Sourcery

Enable streamed inventory captures to be promoted and committed page by page with fenced validation, durable retry behavior, and root binding.

New Features:

  • Add an API to commit finished streamed inventory captures directly from staged pages.
  • Promote staged pages into durable inventory storage and bind the resulting successor manifest to the root.

Bug Fixes:

  • Prevent promotion of stale, foreign, cross-journal, altered, missing, or otherwise invalid staged captures before publishing a manifest.
  • Preserve staged files across failed commits so root-commit retries can reuse already durable pages and manifests.

Enhancements:

  • Share the capture commit ordering and guarantees between in-memory and streamed captures through a common commit path while keeping memory bounded to one page.
  • Make staged-page promotion idempotent by adopting identical durable pages without replacing conflicting files.

Documentation:

  • Document the staged inventory promotion contract, retry behavior, validation guarantees, and remaining streaming-capture scope.

Tests:

  • Add coverage for successful promotion, refusal before reads or writes, page tampering and loss, repeated promotion, journal binding, key routing, and retries after journal or root commit failures.

Chores:

  • Record staged inventory commit support in the unreleased changelog.

Summary by cubic

Adds commit_streamed_inventory_capture, which promotes a staged capture's pages into the digest directory, publishes the successor manifest, and advances the root binding β€” in the same order and under the same guarantees as commit_inventory_capture. Both commits now share one core, commit_capture, which takes the page-storing step as an argument.

promote_staged_inventory_fenced refuses before any read or write unless the caller is the committed owner of the exact root-named manifest, the successor is its capture successor, and the capture belongs to the journal directory being promoted into. A finished capture now remembers the directory it was staged in, so a byte-identical copy of the root-named manifest in another directory can no longer trap the promotion into copying its pages elsewhere. Each staged page is then read back, confirmed against its reference, absorbed into the inventory digest, and stored one page at a time; an identical page already there is adopted, a different file is never replaced. A staged page found wrong midway leaves an inert verified prefix and publishes nothing. The staged files are removed only after the root has committed, so a retry after a failed root commit still has them and adopts what is already durable; after a success the handle is spent.

Tests cover the promotion on the journal alone and the composed commit against a real root: refusal before any read or write, a wrong context holding an identical manifest, changed, swapped or missing staged pages, a partial publish retried with the same staged capture, a failed root commit retried without new journal writes, and exact page-set parity with the in-memory capture.

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

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • New Features
    • Streamed inventory captures can now be committed page by page, with the resulting inventory published and its root binding updated after validation.
    • If a commit fails before the root is updated, staged pages remain available for retry. Modified or mismatched pages prevent publication.
  • Documentation
    • Updated secure-storage guidance to describe streamed capture, validation, commit behavior, and retry handling.

CodeAnt-AI Description

Commit staged inventory captures with safe retries

What Changed

  • Finished page-by-page inventory captures can now be committed without loading the full inventory into memory.
  • Pages are checked as they are promoted; a missing or changed page prevents the inventory from being published.
  • Staged pages remain available until the root commit succeeds, allowing failed commits to be retried using already-written data.

Impact

βœ… Lower memory during inventory commits
βœ… Fewer lost captures after commit failures
βœ… Prevents incomplete inventories from being published

πŸ’‘ 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.

Stage one left a finished inventory in a pending directory that nothing
could use. commit_streamed_inventory_capture promotes its pages into the
digest directory of the successor one page at a time, publishes the
successor and advances the root binding, in the order and under the
guarantees of commit_inventory_capture.

promote_staged_inventory_fenced refuses before anything is read or
written unless the caller is the committed owner of the exact root-named
manifest and the successor is its capture successor, then reads each
staged page back, confirms it against its reference, absorbs its entries
into the inventory digest and stores it where the in-memory store would
have put the same bytes. A page found wrong midway leaves an inert
verified prefix and publishes nothing. The staged files are removed only
after the root has committed, so a retry after a failed root commit still
has them and adopts what is already durable.

commit_inventory_capture and the new commit now share one core, which
takes the step that stores the pages as an argument.
@sourcery-ai

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

@codeant-ai

codeant-ai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

πŸ€– CodeAnt AI β€” Review Status

Status Commit Started (UTC) Finished (UTC)
βœ… Reviewed your PR 5241868 Oct 08, 2026 Β· 20:51 20:57
βœ… Reviewed your PR c9af414 Oct 08, 2026 Β· 20:12 20:18
βœ… Reviewed your PR c0b7765 Oct 08, 2026 Β· 19:52 19:56

@vercel

vercel Bot commented Oct 8, 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 8, 2026 8:52pm UTC

@codeant-ai

codeant-ai Bot commented Oct 8, 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 8, 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-08T20:55:13.048366Z 5241868 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.

@sourcery-ai

sourcery-ai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR completes streaming capture stage two (a): it promotes staged pages into the successor’s durable inventory set, then publishes and binds that successor through a new root-committed API while retaining staged files for safe retries and sharing commit ordering with the existing in-memory capture path.

Sequence diagram for committing a staged inventory capture

sequenceDiagram
    participant Caller
    participant Authority
    participant Root
    participant Journal
    participant StagedCapture

    Caller->>Authority: commit_streamed_inventory_capture()
    Authority->>Authority: check_operation_id()
    Authority->>Root: acquire root_commit_mutex
    Authority->>Root: read committed binding
    Authority->>Journal: resolve_journal_key()
    Authority->>Journal: promote_staged_inventory_fenced()
    Journal->>Journal: assert_page_promote_authority()
    Journal->>Journal: assert_root_named_manifest()
    Journal->>Journal: assert_capture_successor()
    loop each staged page
        Journal->>StagedCapture: load_staged_page()
        Journal->>Journal: store_page_at()
    end
    Journal->>Journal: publish_manifest_fenced()
    Authority->>Root: advance binding as Capture
    Root-->>Authority: committed
    Authority->>StagedCapture: remove_files()
    Authority-->>Caller: RootCommitted
Loading

Flow diagram for staged inventory promotion and retry safety

flowchart TD
    A[Finished StreamedCapture in inventory/pending-*] --> B[commit_streamed_inventory_capture]
    B --> C{Metadata and ownership checks pass?}
    C -- No --> D[Refuse before reading or writing]
    C -- Yes --> E[load_staged_page]
    E --> F{Page matches its reference?}
    F -- No --> G[Return Corrupt; keep staged files]
    F -- Yes --> H[Absorb entries into inventory digest]
    H --> I[store_page_at in successor digest directory]
    I --> J{More pages?}
    J -- Yes --> E
    J -- No --> K{Inventory digest matches successor?}
    K -- No --> L[Do not publish manifest]
    K -- Yes --> M[publish_manifest_fenced]
    M --> N[Commit root binding as Capture]
    N --> O[Best-effort remove staged files]
    N --> P[Retry can reuse staged files if root commit fails]
Loading

File-Level Changes

Change Details Files
Add a fenced promotion path that makes stage-one streamed pages durable and reachable in the successor’s inventory digest directory.
  • Validate ownership, root binding, capture successor, staged references, page integrity, page generation, and final inventory digest before publication.
  • Load and store staged pages one at a time, adopting identical existing files without replacing conflicting files.
  • Leave partial verified prefixes inert and return corruption errors without publishing a manifest.
crates/worldscript-secure-storage/src/journal/stream_promote.rs
crates/worldscript-secure-storage/src/journal/inventory_store.rs
crates/worldscript-secure-storage/src/journal/mod.rs
crates/worldscript-secure-storage/src/lib.rs
Expose a streamed inventory commit that composes promotion, manifest publication, and root binding advancement with existing capture guarantees.
  • Introduce StreamedInventoryCapture and commit_streamed_inventory_capture as an additive public API.
  • Route the journal key from the root and preserve operation-id, fencing, locking, publication, and binding-step ordering.
  • Remove staged files only after a successful root commit, allowing failed-root retries to reuse staged data.
  • Refactor in-memory and staged capture commits through the shared commit_capture core.
crates/worldscript-secure-storage/src/authority.rs
crates/worldscript-secure-storage/src/journal/stream_capture.rs
Verify promotion and composed commit behavior across successful, rejected, corrupted, and retry scenarios.
  • Test durable page promotion, repeated adoption, authority checks before reads or writes, changed and missing staged pages, and verified-prefix behavior.
  • Test root publication and binding advancement, staged-file cleanup timing, unchanged state on refusal, key-routing failures, and retry after a failed root commit.
crates/worldscript-secure-storage/tests/gate4d_stream_capture_test.rs
crates/worldscript-secure-storage/tests/gate4d_root_binding_test.rs
crates/worldscript-secure-storage/tests/gate4d_journal_route_test.rs
Document the stage-two streaming capture contract, implementation decisions, evidence, and remaining stage-two work.
  • Describe promotion ordering, digest verification, retry semantics, and one-pass partial-failure behavior.
  • Update the changelog and Gate 4D gap/evidence documentation to distinguish stage two (a) from the future key-routing staging session.
CHANGELOG.md
docs/native/R15-SECURE-STORAGE-CONTRACT.md
docs/native/r15/GATE4D-JOURNAL-DURABLE-EVIDENCE.md
docs/native/r15/GATE4D-SLICE-B-GAP-MATRIX.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 8, 2026 •

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: 52418681
Scan Time: 2026-10-08 21:17:00 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 8, 2026
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

[check-pr-size] PR size is over the target tier (normal profile): 13 files, 1027 meaningful lines, 3 commits β€” limit ≀8 files / ≀400 lines / ≀6 commits. Consider splitting into smaller, independently reviewable PRs.

codescene-access[bot]

This comment was marked as outdated.

@coderabbitai

coderabbitai Bot commented Oct 8, 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 44 seconds.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 68 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: ffa1eb8a-8d1a-4cd8-8c99-0b12ca7b2b60
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between c0b7765 and 5241868.

πŸ“’ Files selected for processing (5)
  • crates/worldscript-secure-storage/src/journal/stream_capture.rs
  • crates/worldscript-secure-storage/src/journal/stream_promote.rs
  • crates/worldscript-secure-storage/tests/gate4d_root_binding_test.rs
  • crates/worldscript-secure-storage/tests/gate4d_stream_capture_test.rs
  • 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: 88ded853-dc11-4999-8fde-261571ac7131
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between edcd953 and c0b7765.

πŸ“’ Files selected for processing (13)
  • CHANGELOG.md
  • crates/worldscript-secure-storage/src/authority.rs
  • crates/worldscript-secure-storage/src/journal/inventory_store.rs
  • crates/worldscript-secure-storage/src/journal/mod.rs
  • crates/worldscript-secure-storage/src/journal/stream_capture.rs
  • crates/worldscript-secure-storage/src/journal/stream_promote.rs
  • crates/worldscript-secure-storage/src/lib.rs
  • crates/worldscript-secure-storage/tests/gate4d_journal_route_test.rs
  • crates/worldscript-secure-storage/tests/gate4d_root_binding_test.rs
  • crates/worldscript-secure-storage/tests/gate4d_stream_capture_test.rs
  • docs/native/R15-SECURE-STORAGE-CONTRACT.md
  • docs/native/r15/GATE4D-JOURNAL-DURABLE-EVIDENCE.md
  • docs/native/r15/GATE4D-SLICE-B-GAP-MATRIX.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

Walkthrough

The change adds fenced promotion of staged inventory pages and a streamed capture commit that shares the existing capture commit sequence. Staged files remain available when the commit fails and are removed after root commitment. Key-routing staging remains separate work.

Changes

Streamed Inventory Capture

Layer / File(s) Summary
Fenced staged-page promotion
crates/worldscript-secure-storage/src/journal/stream_promote.rs, crates/worldscript-secure-storage/src/journal/inventory_store.rs, crates/worldscript-secure-storage/src/journal/mod.rs, crates/worldscript-secure-storage/tests/gate4d_stream_capture_test.rs, docs/native/R15-SECURE-STORAGE-CONTRACT.md
The promotion function validates authority, manifest state, successor, and staged references before storing pages sequentially. It checks the resulting inventory digest and leaves staged files untouched. Tests cover refusal cases, modified or missing pages, partial promotion, and repeat promotion.
Composed streamed capture commit
crates/worldscript-secure-storage/src/authority.rs, crates/worldscript-secure-storage/src/journal/stream_capture.rs, crates/worldscript-secure-storage/src/lib.rs, crates/worldscript-secure-storage/tests/gate4d_root_binding_test.rs, crates/worldscript-secure-storage/tests/gate4d_journal_route_test.rs, CHANGELOG.md, docs/native/r15/GATE4D-JOURNAL-DURABLE-EVIDENCE.md, docs/native/r15/GATE4D-SLICE-B-GAP-MATRIX.md
The streamed API and in-memory capture path use shared commit logic. The streamed path removes staged files only after root commitment. Tests cover successful commits, routing and authority refusals, modified staged pages, and retry after root-commit failure. The documentation describes promotion and identifies key-routing staging as a separate stage.

Priority: ⬇️ Low

Merge Risk: βšͺ Minimal Β· up to c0b77

No concrete issue remains that needs resolution before merge; the documented promotion and retry behavior can proceed through normal checks.

  • Autopilot Β· Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

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

ℹ️ 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/stream_promote.rs
@codeant-ai

codeant-ai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

CodeAnt PR Risk: Medium Risk

  • The PR needs attention before merging because streamed commits can reject valid captures when equivalent journal paths use different spellings.
  • The promotion compares stored and supplied paths directly, so a relative staging path and an absolute commit path to the same directory do not match.

Assessed commit: 524186810cab

@codecov

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

…ed in (#445)

A finished StagedCapture did not remember its journal directory. Handed to
a context for another directory that held an identical copy of the
root-named manifest, every manifest check passed, the staged pages were
read from the original directory by absolute path, and they were written
and published into the other one. The finished handle now carries the
directory it was staged in and the promotion refuses any other before it
reads anything.

With that binding in place the old capture-successor case, which promoted
into another journal, is refused earlier than it intended; it now tests
the relation the way it can actually fail, a journal that moved on after
the capture began.
@qnbs

qnbs commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@qnbs

qnbs commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

codescene-access[bot]

This comment was marked as outdated.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: c9af414a1b

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

The maintainer's S2a acceptance text asks for a wrong context, a changed,
missing or swapped staged page, a partial publish, a retry and exact
page-set parity with the in-memory capture. The earlier head covered most
of it; this adds what was missing: a promotion under another key, a
swapped staged page (the three wrong-page cases are now one table), a
failure between the promoted pages and the manifest that is retried with
the same staged capture, and the parity of the committed manifest and of
every stored page with what the in-memory capture builds from the same
sealed pages.
@qnbs

qnbs commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@qnbs

qnbs commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

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

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 524186810c

ℹ️ 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/stream_promote.rs
@qnbs

qnbs commented Oct 8, 2026

Copy link
Copy Markdown
Owner Author

Final disposition census β€” head 52418681

HEAD = 524186810caba495a9df56082c84aa70db10b901   3 signed commits   exact-head CI + CodeQL: success (39 pass / 3 skipped / 0 fail)
REVIEW THREADS = 2 / 2 resolved, 0 unresolved
Codex = exact head, no major issues (πŸ‘)   CodeScene = 3/3 gates passed (approved)   CodeAnt = gates pass, one low-severity finding deferred below
Codecov patch = success   Sourcery / DeepSource / cubic = rate-limited or skipped: NO_SIGNAL
SIZE = 13 files, 1027 meaningful lines, 3 commits β€” over the target (8 / 400 / 6) and inside the checker's hard tier (20 / 1200 / 10); the size job passes
Finding Disposition
Codex P2: a finished StagedCapture did not remember its journal directory, so a context for another directory that held an identical copy of the root-named manifest would have copied the staged pages across VALID_AND_FIXED in c9af414a β€” the handle carries its directory and the promotion refuses any other before reading anything; tested with exactly that identical-copy directory; mutation-checked. The old capture-successor case promoted into another journal and was refused earlier than it meant to, so it now tests the relation as it can fail (a journal that moved on after the capture began) and is mutation-checked again
CodeAnt (Major label): the directory binding compares path spellings, so a relative and an absolute spelling of one directory are refused VALID_AND_DEFERRED_WITH_ACCEPTANCE_CRITERION β€” fails closed (refused before any read, the original spelling works); a canonicalisation is a file-system call outside DurableFs; the structural fix is S2b's session, which holds the directory value once for staging and promotion

Acceptance list from the maintainer's rewrite of the QNB-11 S2a section (19:24, after the admission): wrong context, tampered / missing / swapped page, partial publish / crash, retry, exact committed page-set parity with the in-memory capture. The first head lacked a promotion under another key, a swapped staged page, a failure between the promoted pages and the manifest, and the parity check; 52418681 adds them, each mutation-checked.

Decisions flagged on the admission and not changed by review: one pass; the commit takes &StagedCapture; a second entry point beside commit_inventory_capture (they now share one core, commit_capture).

Disclosed limits of the proof: two checks have no test that fails without them through the public API (the staged references against the successor's page set, and the final inventory-digest comparison), because StreamedCapture::finish cannot produce a successor that disagrees with its staged references; both mutations were run and survive, and the evidence says so. The authority check and the root-named check overlap in the error class they give for a stale owner, so the authority check is pinned by asserting that nothing is read before it refuses.

Proof: the whole crate suite (50 passing results), clippy -D warnings, fmt --check, docs:check.

Scope: promotion and the composed commit only. No key-routed staging session (S2b), C2, reclamation, graphify. PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NO.

@qnbs
qnbs merged commit abd49cf into main Oct 8, 2026
54 checks passed
@qnbs
qnbs deleted the feat/445-gate4d-streaming-capture-promote branch October 8, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant