Skip to content

feat(runtime): add Phase 3 development readiness - #124

Merged
aryeko merged 4 commits into
mainfrom
feat/phase3-development-readiness
Jul 31, 2026
Merged

feat(runtime): add Phase 3 development readiness#124
aryeko merged 4 commits into
mainfrom
feat/phase3-development-readiness

Conversation

@aryeko

@aryeko aryeko commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a development-semantic-only pre-Run flow with effect-free preview and separate exact proposal/provider-manifest approvals
  • add witnessed, idempotent accepted and rejected intake semantics, with no Run created on rejection
  • update GF-023/GF-024 and the delivery DAG to permit Phase 3 lifecycle development while real-provider qualification continues independently

Why

Phase 3 implementation was unnecessarily coupled to machine-specific provider and witness-root qualification. This creates the minimum safe semantic development path without weakening the production authority or recovery model.

Safety boundary and impact

The development profile uses only the scripted ledger, keeps providerEnabled and dispatchEnabled false, and fails closed with no autonomous restore. GF-020/GF-025/GF-026 remain mandatory before real-provider activation, autonomous recovery, supported-profile claims, or full Phase 2 closure.

Validation

  • test-first contract failure observed before implementation
  • runtime-contracts: 108 tests passed
  • local-file-providers: 24 tests passed
  • pnpm delivery:check
  • pnpm check (21 tasks passed)
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Added a development-only pre-run workflow for immutable previews, approvals, and witnessed intake without provider execution or effect dispatch.
    • Added fail-closed validation, readback, explicit terminal rejection handling, replay protection, and prevention of run creation for rejected intake.
  • Documentation

    • Clarified Phase 2/3 sequencing, parallel provider qualification, approval refresh requirements, and gates for real-provider activation and phase closure.
  • Tests

    • Expanded coverage for accepted and rejected intake, idempotency, approval validation, preview integrity, and readback.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@aryeko, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

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

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0d2bda2d-27f6-49e9-a0d0-8cf93db9068d

📥 Commits

Reviewing files that changed from the base of the PR and between bfe2952 and c24368f.

📒 Files selected for processing (3)
  • packages/local-file-providers/tests/local-file-ledger.test.mjs
  • packages/runtime-contracts/src/development-pre-run.ts
  • packages/runtime-contracts/tests/development-pre-run.test.mjs
📝 Walkthrough

Walkthrough

The change separates semantic-only development from real-provider qualification. It updates delivery sequencing and dependency gates, adds a development pre-run API with exact approvals, and supports witnessed terminal rejection with replay and readback behavior.

Changes

Semantic development handoff

Layer / File(s) Summary
Development posture and phase overlap
docs/delivery/README.md, docs/delivery/greenfield/README.md, docs/delivery/greenfield/decisions.md, docs/delivery/greenfield/delivery-policy.md, docs/delivery/greenfield/phase-orchestration.md, docs/delivery/greenfield/stories/README.md
Documentation separates provider-disabled semantic development from independent provider qualification and defines Phase 2-to-3 overlap conditions.
Story dependencies and exit gates
docs/delivery/greenfield/dependency-dag.md, docs/delivery/greenfield/stories/*, docs/delivery/greenfield/track.json
GF-023 and GF-024 now use semantic prerequisites. Provider qualification remains required for real-provider intake, supported profiles, and Phase 2 closure.
Terminal acknowledgement and rejection
packages/runtime-contracts/src/ledger.ts, packages/local-file-providers/src/local-file-intake.ts, packages/runtime-contracts/tests/ledger-contract.test.mjs, packages/local-file-providers/tests/local-file-ledger.test.mjs
Ledger and local-file intake support accepted or rejected terminal acknowledgements. Rejected envelopes are witnessed, replayable, readable, and do not create Runs or successor cuts.
Development pre-run API and validation
packages/runtime-contracts/src/development-pre-run.ts, packages/runtime-contracts/src/index.ts, packages/runtime-contracts/tests/development-pre-run.test.mjs
The new API validates development manifests and envelopes, creates immutable previews, requires exact Arye approvals, submits acknowledgements, and provides readback. Tests cover accepted and rejected flows and invalid mutations.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Arye
  participant DevelopmentPreRun
  participant ScriptedLedger
  Arye->>DevelopmentPreRun: create semantic-only preview
  Arye->>DevelopmentPreRun: submit exact approvals
  DevelopmentPreRun->>ScriptedLedger: submit terminal acknowledgement
  ScriptedLedger-->>DevelopmentPreRun: return witnessed intake result
  DevelopmentPreRun-->>Arye: return result or readback
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding Phase 3 development readiness to runtime.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/phase3-development-readiness

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

@aryeko
aryeko marked this pull request as ready for review July 31, 2026 20:48

@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: 852d3f4cb9

ℹ️ 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 packages/runtime-contracts/src/development-pre-run.ts Outdated
Comment thread packages/runtime-contracts/src/development-pre-run.ts Outdated
Comment thread packages/runtime-contracts/src/ledger.ts Outdated
Comment thread docs/delivery/greenfield/stories/GF-023.md

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

Actionable comments posted: 6

🧹 Nitpick comments (3)
packages/runtime-contracts/tests/development-pre-run.test.mjs (1)

155-177: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a case for a manifest approval reused across a different manifestId.

The current cases cover approval substitution and copied carriers. They do not cover a manifest approval that is reused for a second preview that keeps the same manifestDigest and changes manifestId. That case passes today, because the approval subject omits manifestId. See the root cause at Lines 128-144 of packages/runtime-contracts/src/development-pre-run.ts. Add the case so the fix stays covered.

💚 Proposed additional case
   for (const forbidden of ['configureProvider', 'enableProvider', 'dispatch', 'execute'])
     assert.equal(forbidden in profile, false);
 });
+
+test('a provider-manifest approval does not carry over to a different manifestId', () => {
+  const { profile, manifestApproval } = approvedFixture();
+  const other = profile.preview({
+    envelope: envelopeInput(),
+    providerManifest: { ...manifest(), manifestId: 'provider/development/authority/other' },
+  });
+  assert.equal(other.ok, true);
+  const proposalApproval = profile.approveProposal({ principal: 'principal/arye', preview: other.value });
+  assert.equal(proposalApproval.ok, true);
+  assert.equal(
+    profile.submit({
+      preview: other.value,
+      proposalApproval: proposalApproval.value,
+      manifestApproval,
+      terminalAck: 'accepted',
+    }).ok,
+    false,
+  );
+});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/runtime-contracts/tests/development-pre-run.test.mjs` around lines
155 - 177, Add a test case in the development intake rejection test around
profile.submit that creates a second preview with the same manifestDigest but a
different manifestId, reuses the original manifest approval, and asserts
submission is rejected. Keep the existing approval-substitution and
copied-preview cases unchanged.
packages/runtime-contracts/src/development-pre-run.ts (1)

191-215: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Return an input failure for malformed successorCut and terminalAck.

Lines 207-210 validate terminalAck and successorCut shape. A failure of these checks returns FC-AUTHORITY with EXACT_DEVELOPMENT_APPROVALS_REQUIRED. That message reports an authority denial for an input defect. ledger.intake reports the same defects as FC-INPUT / INVALID_INTAKE. Split the checks so the family matches the cause.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/runtime-contracts/src/development-pre-run.ts` around lines 191 -
215, The submit method’s malformed successorCut or terminalAck inputs currently
return the authority-denial failure; split these shape validations from the
approval checks and return FC-INPUT with INVALID_INTAKE for invalid
terminalAck/successorCut values, while preserving FC-AUTHORITY /
EXACT_DEVELOPMENT_APPROVALS_REQUIRED for missing or unrecognized approval data.
packages/local-file-providers/tests/local-file-ledger.test.mjs (1)

296-316: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add replay coverage for the local-file rejection path.

The test covers first-write and readback. It does not cover the new idempotency comparison at Lines 104-114 of packages/local-file-providers/src/local-file-intake.ts. Two cases stay untested: an identical rejected replay must return the stored result, and a replay with terminalAck: 'accepted' must fail with INTAKE_REQUEST_MISMATCH. A case for terminalAck: 'rejected' with a successorCut must fail with INVALID_INTAKE.

💚 Proposed additional assertions
   assert.equal('run' in rejected.value, false);
   assert.deepEqual(intake.read(digest('c')).value.result, rejected.value);
+  assert.deepEqual(
+    intake.create({ compositionDigest: digest('c'), acknowledgementDigest: digest('d'), terminalAck: 'rejected' }),
+    rejected,
+  );
+  const replayed = intake.create({
+    compositionDigest: digest('c'),
+    acknowledgementDigest: digest('d'),
+    terminalAck: 'accepted',
+  });
+  assert.equal(replayed.ok, false);
+  assert.equal(replayed.error.code, 'INTAKE_REQUEST_MISMATCH');
+  const invalid = intake.create({
+    compositionDigest: digest('e'),
+    acknowledgementDigest: digest('f'),
+    terminalAck: 'rejected',
+    successorCut: 'cut/one',
+  });
+  assert.equal(invalid.ok, false);
+  assert.equal(invalid.error.code, 'INVALID_INTAKE');
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/local-file-providers/tests/local-file-ledger.test.mjs` around lines
296 - 316, Extend the rejection test for local-file intake to cover replay
validation in createLocalFileIntakeForConformance: assert an identical
terminalAck:'rejected' request returns the stored result, a replay with
terminalAck:'accepted' fails with INTAKE_REQUEST_MISMATCH, and a rejected replay
including successorCut fails with INVALID_INTAKE.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/delivery/greenfield/decisions.md`:
- Around line 110-115: Rewrite the paragraph so GF-020, GF-025, and GF-026 each
have an independent start condition matching track.json: GF-020 requires GF-019
and GF-022, GF-025 requires GF-010, GF-012, and GF-022, and GF-026 requires
GF-013 and GF-022. Preserve the existing provider-gate and recompose/refresh
requirements without implying that local file ledger selection scopes all three
stories.

In `@docs/delivery/greenfield/dependency-dag.md`:
- Around line 123-130: The dependency readiness guidance must evaluate each edge
according to its declared type rather than treating every dependency as a merge
requirement. In docs/delivery/greenfield/dependency-dag.md lines 123-130,
require predecessor containment for implementation edges, exact conformance for
evidence edges, recorded owner and DR basis for decision edges, and merge
containment only for merge edges. In docs/delivery/greenfield/stories/GF-023.md
lines 82-84, require GF-014, GF-019, and GF-021 as implementation predecessors
in the execution base, while requiring the GF-022 decision basis to be recorded
and revalidated rather than merged as a story.

In `@docs/delivery/greenfield/stories/GF-023.md`:
- Around line 159-161: Update the GF-023 acceptance criteria and related
readiness text to replace the obsolete six dependency evidence/gate references
with the four current dependency records, and identify the GF-022 decision
record separately from those evidence records. Ensure all graph-count references
consistently describe the current four-edge semantic-only posture.

In `@docs/delivery/greenfield/track.json`:
- Line 91: Update the track.json exit_gate machine-readable requirements to
include providerEnabled: false, dispatchEnabled: false,
fail-closed-no-autonomous-restore, exact-preview recomposition, and refreshed
approvals against qualified manifests before real intake. Represent these as
distinct development handoff and full supported-profile closure predicates,
while preserving the existing preview, approval, witnessed intake, rejection,
and provider-qualification requirements.

In `@packages/runtime-contracts/src/development-pre-run.ts`:
- Around line 128-144: Update the provider-manifest approval flow around the
approval construction and submit validation so the approved subject includes
preview.manifestId, not just preview.manifestDigest. Add a shared helper for
deriving the provider-manifest subject, use it in both approve and submit, and
make submit compare the manifestApproval.subjectDigest against that derived
subject while preserving existing scope checks.

In `@packages/runtime-contracts/src/ledger.ts`:
- Around line 599-607: Update the validation condition in the terminal
acknowledgement intake flow to reject any defined empty successorCut by checking
request.successorCut !== undefined before applying nonEmpty. Preserve the
existing rejection of successorCut with a rejected terminalAck and all other
validation behavior.

---

Nitpick comments:
In `@packages/local-file-providers/tests/local-file-ledger.test.mjs`:
- Around line 296-316: Extend the rejection test for local-file intake to cover
replay validation in createLocalFileIntakeForConformance: assert an identical
terminalAck:'rejected' request returns the stored result, a replay with
terminalAck:'accepted' fails with INTAKE_REQUEST_MISMATCH, and a rejected replay
including successorCut fails with INVALID_INTAKE.

In `@packages/runtime-contracts/src/development-pre-run.ts`:
- Around line 191-215: The submit method’s malformed successorCut or terminalAck
inputs currently return the authority-denial failure; split these shape
validations from the approval checks and return FC-INPUT with INVALID_INTAKE for
invalid terminalAck/successorCut values, while preserving FC-AUTHORITY /
EXACT_DEVELOPMENT_APPROVALS_REQUIRED for missing or unrecognized approval data.

In `@packages/runtime-contracts/tests/development-pre-run.test.mjs`:
- Around line 155-177: Add a test case in the development intake rejection test
around profile.submit that creates a second preview with the same manifestDigest
but a different manifestId, reuses the original manifest approval, and asserts
submission is rejected. Keep the existing approval-substitution and
copied-preview cases unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4786d46a-f7f1-40d0-b995-5ccaa1a19c48

📥 Commits

Reviewing files that changed from the base of the PR and between 21cdf8d and 852d3f4.

📒 Files selected for processing (19)
  • docs/delivery/README.md
  • docs/delivery/greenfield/README.md
  • docs/delivery/greenfield/decisions.md
  • docs/delivery/greenfield/delivery-policy.md
  • docs/delivery/greenfield/dependency-dag.md
  • docs/delivery/greenfield/phase-orchestration.md
  • docs/delivery/greenfield/stories/GF-023.md
  • docs/delivery/greenfield/stories/GF-024.md
  • docs/delivery/greenfield/stories/GF-025.md
  • docs/delivery/greenfield/stories/GF-026.md
  • docs/delivery/greenfield/stories/README.md
  • docs/delivery/greenfield/track.json
  • packages/local-file-providers/src/local-file-intake.ts
  • packages/local-file-providers/tests/local-file-ledger.test.mjs
  • packages/runtime-contracts/src/development-pre-run.ts
  • packages/runtime-contracts/src/index.ts
  • packages/runtime-contracts/src/ledger.ts
  • packages/runtime-contracts/tests/development-pre-run.test.mjs
  • packages/runtime-contracts/tests/ledger-contract.test.mjs

Comment thread docs/delivery/greenfield/decisions.md Outdated
Comment thread docs/delivery/greenfield/dependency-dag.md Outdated
Comment thread docs/delivery/greenfield/stories/GF-023.md
Comment thread docs/delivery/greenfield/track.json Outdated
Comment thread packages/runtime-contracts/src/development-pre-run.ts
Comment thread packages/runtime-contracts/src/ledger.ts Outdated

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/runtime-contracts/src/development-pre-run.ts (1)

279-284: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Separate malformed input from missing approval authority.

Lines 279-282 validate the shape of terminalAck and successorCut. A malformed value returns FC-AUTHORITY/EXACT_DEVELOPMENT_APPROVALS_REQUIRED. The same class of input error returns FC-INPUT/INVALID_INTAKE in the local-file intake path. A caller that branches on family cannot tell a bad request from an unauthorized one, and an audit reader sees an authority denial that never happened.

Report the disposition and cut checks under FC-INPUT, and keep FC-AUTHORITY for the preview and approval membership checks.

♻️ Proposed split
       if (
         !data ||
         typeof data.preview !== 'object' ||
         data.preview === null ||
         !previews.has(data.preview) ||
         typeof data.proposalApproval !== 'object' ||
         data.proposalApproval === null ||
         !approvalBinding?.proposalApprovals.has(data.proposalApproval) ||
         typeof data.manifestApproval !== 'object' ||
         data.manifestApproval === null ||
-        !approvalBinding.manifestApprovals.has(data.manifestApproval) ||
-        (data.terminalAck !== 'accepted' && data.terminalAck !== 'rejected') ||
-        (data.terminalAck === 'rejected' && data.successorCut !== undefined) ||
-        (data.successorCut !== undefined &&
-          (typeof data.successorCut !== 'string' || data.successorCut.length === 0 || data.successorCut.length > 512))
+        !approvalBinding.manifestApprovals.has(data.manifestApproval)
       )
         return fail('FC-AUTHORITY', 'EXACT_DEVELOPMENT_APPROVALS_REQUIRED');
+      if (
+        (data.terminalAck !== 'accepted' && data.terminalAck !== 'rejected') ||
+        (data.terminalAck === 'rejected' && data.successorCut !== undefined) ||
+        (data.successorCut !== undefined &&
+          (typeof data.successorCut !== 'string' || data.successorCut.length === 0 || data.successorCut.length > 512))
+      )
+        return fail('FC-INPUT', 'INVALID_INTAKE');

Update the tests that assert the current family for these cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/runtime-contracts/src/development-pre-run.ts` around lines 279 -
284, Update the validation branch in the development pre-run flow around
terminalAck and successorCut so malformed disposition or cut values return
FC-INPUT/INVALID_INTAKE, matching the local-file intake path. Keep
FC-AUTHORITY/EXACT_DEVELOPMENT_APPROVALS_REQUIRED exclusively for preview and
approval membership checks, and update tests asserting the affected error
family.
packages/runtime-contracts/tests/development-pre-run.test.mjs (2)

135-162: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extend the negative manifest coverage to every validated field.

manifest in packages/runtime-contracts/src/development-pre-run.ts (Lines 120-139) rejects fourteen field conditions. This test negates only providerEnabled. A regression that drops the dispatchEnabled, recovery, lineage.kind, runtimeAuthority.kind, scope, or authority-array checks stays undetected. The manifestBytes(changes) fixture already supports each case.

💚 Proposed table-driven coverage
   assert.equal(
     profile.preview({ envelope: envelopeInput(), providerManifestBytes: manifestBytes({ providerEnabled: true }) }).ok,
     false,
   );
+  for (const change of [
+    { dispatchEnabled: true },
+    { recovery: 'autonomous-restore' },
+    { lineage: { kind: 'derived' } },
+    { runtimeAuthority: { kind: 'subprocess' } },
+    { scope: { phase: 2, purpose: 'development-only' } },
+    { scope: { phase: 3, purpose: 'production' } },
+    { credentialAuthority: ['secret'] },
+    { externalServiceAuthority: ['service'] },
+    { filesystemAuthority: ['/tmp'] },
+    { nativePermissionPostures: ['granted'] },
+    { networkAuthority: ['example.test'] },
+    { subprocessAuthority: ['sh'] },
+  ])
+    assert.equal(
+      profile.preview({ envelope: envelopeInput(), providerManifestBytes: manifestBytes(change) }).ok,
+      false,
+      `manifest must be rejected: ${JSON.stringify(change)}`,
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/runtime-contracts/tests/development-pre-run.test.mjs` around lines
135 - 162, Expand the negative manifest assertions in the provider manifest
digest test to cover every rejection condition enforced by manifest, including
dispatchEnabled, recovery, lineage.kind, runtimeAuthority.kind, scope, and all
authority-array validations. Use the existing manifestBytes(changes) fixture in
table-driven cases, and assert each modified manifest preview returns ok false
while preserving the existing providerEnabled and providerManifest rejection
checks.

233-252: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a regression case for a verifier consumed by an unusable profile.

This case reuses the verifier on a second profile that has a valid ledger, so it passes today. It does not cover construction with an invalid or missing ledger. That path also consumes the verifier, as flagged in packages/runtime-contracts/src/development-pre-run.ts Lines 210-219. Add a case that constructs a profile with an invalid ledger and then asserts a later valid profile still accepts approvals from the same authority.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/runtime-contracts/tests/development-pre-run.test.mjs` around lines
233 - 252, The tests currently cover verifier reuse after a valid profile but
not after failed construction. Add a regression case near the existing
secondProfile scenario that creates a development pre-run profile with an
invalid or missing ledger using the same authority.verifier, then constructs a
valid profile with a scripted ledger and verifies its preview approvals and
submit path succeed with that authority.
packages/local-file-providers/tests/local-file-ledger.test.mjs (1)

355-363: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add negative coverage for an unknown terminalAck value.

The terminalAck: 'rejected' with successorCut case is already covered. Add a test that expects INVALID_INTAKE and confirms that no entry persists.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/local-file-providers/tests/local-file-ledger.test.mjs` around lines
355 - 363, Add a negative test alongside the existing intake validation tests
that calls create with an unknown terminalAck value such as “rejected” together
with successorCut, asserts the FC-INPUT/INVALID_INTAKE error, and verifies via
intake.read that no entry was persisted.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/runtime-contracts/src/development-pre-run.ts`:
- Around line 210-219: Only add the verifier to claimedApprovalVerifiers after
confirming the configuration has a usable scripted ledger. Update the claim
condition near approvalBinding to require ledger in addition to verifier and
approvalBinding, while preserving the existing one-time claim behavior for valid
configurations.

---

Nitpick comments:
In `@packages/local-file-providers/tests/local-file-ledger.test.mjs`:
- Around line 355-363: Add a negative test alongside the existing intake
validation tests that calls create with an unknown terminalAck value such as
“rejected” together with successorCut, asserts the FC-INPUT/INVALID_INTAKE
error, and verifies via intake.read that no entry was persisted.

In `@packages/runtime-contracts/src/development-pre-run.ts`:
- Around line 279-284: Update the validation branch in the development pre-run
flow around terminalAck and successorCut so malformed disposition or cut values
return FC-INPUT/INVALID_INTAKE, matching the local-file intake path. Keep
FC-AUTHORITY/EXACT_DEVELOPMENT_APPROVALS_REQUIRED exclusively for preview and
approval membership checks, and update tests asserting the affected error
family.

In `@packages/runtime-contracts/tests/development-pre-run.test.mjs`:
- Around line 135-162: Expand the negative manifest assertions in the provider
manifest digest test to cover every rejection condition enforced by manifest,
including dispatchEnabled, recovery, lineage.kind, runtimeAuthority.kind, scope,
and all authority-array validations. Use the existing manifestBytes(changes)
fixture in table-driven cases, and assert each modified manifest preview returns
ok false while preserving the existing providerEnabled and providerManifest
rejection checks.
- Around line 233-252: The tests currently cover verifier reuse after a valid
profile but not after failed construction. Add a regression case near the
existing secondProfile scenario that creates a development pre-run profile with
an invalid or missing ledger using the same authority.verifier, then constructs
a valid profile with a scripted ledger and verifies its preview approvals and
submit path succeed with that authority.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1862e6bf-3c27-4aab-974e-a1e256a46d9a

📥 Commits

Reviewing files that changed from the base of the PR and between 852d3f4 and b2c1c25.

📒 Files selected for processing (7)
  • docs/delivery/greenfield/stories/GF-023.md
  • packages/local-file-providers/src/local-file-intake.ts
  • packages/local-file-providers/tests/local-file-ledger.test.mjs
  • packages/runtime-contracts/src/development-pre-run.ts
  • packages/runtime-contracts/src/ledger.ts
  • packages/runtime-contracts/tests/development-pre-run.test.mjs
  • packages/runtime-contracts/tests/ledger-contract.test.mjs
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/runtime-contracts/src/ledger.ts
  • packages/runtime-contracts/tests/ledger-contract.test.mjs
  • packages/local-file-providers/src/local-file-intake.ts
  • docs/delivery/greenfield/stories/GF-023.md

Comment thread packages/runtime-contracts/src/development-pre-run.ts
@aryeko

aryeko commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Review-body nitpicks are also covered in bfe2952: local-file rejected-intake replay, accepted/rejected mismatch, and rejected-with-successor-cut now have regression assertions; malformed development terminal dispositions and successor cuts now return FC-INPUT/INVALID_INTAKE with tests. The suggested different-manifest-ID reuse case is not representable on the current head because preview derives manifestId deterministically from canonical manifest bytes and accepts no caller ID/digest. Full pnpm check passes 21/21 tasks.

@aryeko

aryeko commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

Latest review-body coverage is complete in c24368f: every development-manifest authority/posture field has a negative case; an invalid profile construction is proven not to consume the owner verifier; and local-file intake rejects an unknown terminal disposition without persistence. The repeated malformed-input classification note was already fixed and tested in bfe2952. Full pnpm check remains green (21/21 tasks).

@aryeko
aryeko merged commit 0c2a8d2 into main Jul 31, 2026
2 checks passed
@aryeko
aryeko deleted the feat/phase3-development-readiness branch July 31, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant