Repository navigation
feat(core): gate the conversion driver on exclusive admission (#445) - #1013
Conversation
begin_conversion takes the installation's exclusive admission by mutable borrow, derives the root layout from the admitted scope, re-reads the committed binding, the registry-routed journal key and the root-named manifest, and returns a ConversionSession only for the owner of the lease while the operation is in ADMIT or CONVERT with the final inventory captured. It reads no clock, holds no key and writes nothing.
Contract paragraph, evidence section with the disclosed decisions and the mutation checks, gap-matrix line and changelog entry for the entry gate of the exclusive conversion driver.
🤖 CodeAnt AI — Review Status
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@codex review |
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Reviewer's GuideThis PR implements the mutation-free C2a conversion entry gate: exclusive admission is enforced by the type and lifetime of the API, committed journal authority is reread from the authenticated root and key registry, and conversion begins only for an eligible phase, captured inventory, and matching lease owner, with extensive refusal and integrity coverage. Sequence diagram for the exclusive conversion entry gatesequenceDiagram
participant Caller
participant Gate as begin_conversion
participant Admission as ExclusiveAdmissionGuard
participant Authority as read_committed_journal
participant Root as CommittedRoot
participant Registry as KeyEpochRegistry
participant Journal as JournalManifest
Caller->>Gate: begin_conversion(&mut guard, fs, provider, begin)
Gate->>Admission: guards(scope)
alt NotAdmitted
Admission-->>Gate: false
Gate-->>Caller: ConversionError::NotAdmitted
else Admitted
Admission-->>Gate: true
Gate->>Authority: read_committed_journal(root(scope), journal)
Authority->>Root: load_committed_root
Root-->>Authority: LiveMigration binding
Authority->>Registry: route_journal_key
Registry-->>Authority: journal key or JournalRoute error
Authority->>Journal: load_authoritative_manifest(exact root-named path)
Journal-->>Authority: authenticated manifest
Authority-->>Gate: CommittedJournal
Gate->>Admission: guards(scope)
alt Admission changed
Admission-->>Gate: false
Gate-->>Caller: ConversionError::NotAdmitted
else Still admitted
Gate->>Gate: check_convertible(manifest, owner_id)
alt Eligible phase, final inventory captured, matching owner
Gate-->>Caller: ConversionSession holding &mut guard
else Refusal
Gate-->>Caller: phase, inventory, or lease-owner error
end
end
end
Flow diagram for conversion entry refusal checksflowchart TD
A[begin_conversion] --> B{"guards(scope) before reads?"}
B -- No --> X[NotAdmitted]
B -- Yes --> C[Read committed root binding]
C --> D[Route journal key through key registry]
D --> E[Load exact root-named authenticated manifest]
E --> F{"guards(scope) after reads?"}
F -- No --> X
F -- Yes --> G{"Phase is ADMIT or CONVERT?"}
G -- DONE --> H[TerminalPhase]
G -- RECOVERY_REQUIRED --> I[RecoveryRequired]
G -- Other --> J[PhaseNotConvertible]
G -- Yes --> K{"final_inventory_captured?"}
K -- No --> L[FinalInventoryNotCaptured]
K -- Yes --> M{"Lease owner equals owner_id?"}
M -- No --> N[ForeignLeaseOwner]
M -- Yes --> O[ConversionSession]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
🏁 CodeAnt Quality Gate ResultsCommit: ✅ Overall Status: PASSEDQuality Gate Details
|
|
[check-pr-size] PR size is over the target tier (normal profile): 9 files, 859 meaningful lines, 3 commits — limit ≤8 files / ≤400 lines / ≤6 commits. Consider splitting into smaller, independently reviewable PRs. |
|
Warning Review limit reachedEnable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Next included review available in 49 minutes. View limit detailsLimit details: You’ve used the included review currently available. Your 67 included PR review attempts over the past 7 days set your current allowance at 1 review per hour. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (2)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (9)
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. 📝 WalkthroughWalkthroughAdds a read-only conversion entry gate. It checks exclusive installation admission and committed journal state, then admits only eligible phases with captured final inventory and a matching lease owner. ChangesConversion Entry Gate
Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to The read-only conversion entry gate is mergeable after normal checks; no actionable merge-blocking risk remains.
Comment |
CodeAnt PR Risk: Medium Risk
Assessed commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1683433016
ℹ️ 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".
…ts (#445) Windows creates operation-admission.lock when an admission is acquired, so a baseline taken before the acquire differed from the tree after it even though the gate wrote nothing. The snapshot helpers of the conversion entry test and the key-route test skip that file, whose bytes have no authority.
|
@codex review |
There was a problem hiding this comment.
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.
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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 review |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
CodeAnt PR Risk "Medium" on 636dda8: classified INVALID_WITH_EVIDENCE as a defect, and recorded as the open question the PR body already flags. (1) Accepting a lease past its expiry is the contract merged in D3b (contract §10.1, "The renewal operation": no clock is read, the owner may still act after expiry while nobody has taken over, because a takeover advances the fence and the root lock serialises the two); the gate does not change that, it re-reads the committed manifest and refuses a foreign owner, so an owner that was taken over is refused. (2) The gate is read-only: it writes nothing, holds no key and cannot move the journal; every later mutation (C2b) goes through the fenced journal-owner operations that refuse a stale token before any write. (3) The unresolved part, whether exclusive admission may replace lease expiry as the proof that a former owner is gone (a takeover question, not a gate question), is a maintainer decision recorded as an acceptance criterion on #359 and is deliberately not decided here. No code change. |
User description
What
The entry gate of the exclusive conversion driver (C2, first of three slices). Maintainer decision D: conversion must require exclusive admission by construction, re-read the authenticated root-bound manifest, and require
final_inventory_captured = true. Until now the journal-owner operations took no admission guard, and nothing could read the committed journal state without a key in the caller's hands.&mut ExclusiveAdmissionGuard(a shared guard does not type-check:compile_faildoctest, with a positive twin proving it fails for that reason) andConversionBegin{scope, journal, owner_id}; the root layout is derived fromscope, so the root cannot differ from the one admittedguards(scope)is checked before anything is read and again after the readsread_committed_journal: binding from the committed root alone (NoLiveMigrationif none), key through the key-epoch registry (JournalRouteerrors), manifest by the exact root-named path authenticated against the binding digest; no sibling generation is read.begin_streamed_captureshares the binding readADMITorCONVERT(TerminalPhase,RecoveryRequired,PhaseNotConvertibleotherwise),final_inventory_captured(FinalInventoryNotCaptured), committed lease owner equal to the caller (ForeignLeaseOwner; an absent lease is foreign)ConversionSessionthat keeps the&mutborrow (one session per admission) and exposes the manifest, binding and fence it read; no key heldDecisions to review (mine, flagged on the admission): three slices for the driver, this one mutating nothing so that the exclusivity proof lands before any conversion write; the layout is derived from the admitted scope; a foreign lease owner is refused rather than taken over, and whether exclusive admission may replace lease expiry as the proof that a former owner is gone is left open for the maintainer (the cross-process lease CAS stays residual); no clock is read. One correction to the admission text: it listed "operation mismatch" as a refusal, but the journal source's operation is a write-operation identifier for staging names, not the migration operation; the manifest is opened under the binding's operation identity, so that case is already covered by the authenticated load and is not a separate refusal.
Boundary matrix
Not in this PR
Entering
CONVERT, advancing the cursor and renewing the lease through the gate (C2b), the cursor-driven iteration with a per-entry step and the crash/resume evidence (C2c), inheriting unchanged pages, bounded adapter defaults, reclaiming pending directories, the write barrier. Real record conversion stays Gate 5. No production authority switch.Verification
Local:
gate4d_conversion_entry_test(the owner inADMITandCONVERTgets the committed manifest, fence and binding with every file unchanged; every other phase refused with its own reason; no final inventory; lease of another owner, of the empty owner and of none; no binding; a root-named generation that is not the bound bytes; a guard for another installation refused with zero reads; an installation moved away during the reads refused; a newer sibling generation never read), the gate as a further operation in the key-route refusal table (revoked, unregistered, route to another key), and the root-binding, streaming-capture and route suites unchanged. Mutation-checked: each of the two admission checks (separately), each phase arm, the final-inventory requirement and the owner check, removed one at a time, fails the test that owns it.cargo clippy --locked -p worldscript-secure-storage --all-targets -D warnings,cargo fmt --check,pnpm run docs:check. Size: 9 files (one over the target of 8) and about 770 meaningful lines (over the 400 target, inside the hard tier): about 200 of them code and about 570 tests, of which about 240 are the compact root-bound fixture and the read-watching file system the two admission checks need; 2 commits.Part of #359 and #445 (Linear QNB-11). Admission: #359 issuecomment-6071546090.
PRODUCTION_AUTHORITY_SWITCH_ALLOWED = NO.Summary by Sourcery
Require exclusive admission and authenticated committed journal state before allowing conversion to begin.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Tests:
Chores:
Summary by cubic
Gates the conversion driver's entry behind exclusive admission and authenticated committed journal state, so conversion cannot begin against an installation that is not admitted or whose journal is not what the committed root vouches for.
Previously the journal-owner operations took no admission guard, and nothing read committed journal state without a key in hand.
begin_conversionnow takes&mut ExclusiveAdmissionGuard, derives the root layout from the admitted scope, checks admission before and after the reads, and re-reads the binding, the registry-routed key, and the root-named manifest. It returns aConversionSessiononly when the operation is inADMITorCONVERT, the final inventory was captured, and the committed lease belongs to the caller. The gate writes nothing, holds no key, and reads no clock;begin_streamed_capturenow shares the committed-root binding read.Refusals
Written for commit 636dda8. Summary will update on new commits.
Summary by CodeRabbit
CodeAnt-AI Description
Require exclusive access and a ready journal before migration conversion
What Changed
Impact
✅ Blocks conversion while other operations are active✅ Rejects conversion without a captured inventory or matching lease owner✅ Prevents sibling journal files from overriding committed conversion state💡 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:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
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:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
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.