Skip to content

feat(sdk): strengthen context and evidence contracts - #981

Merged
unbraind merged 7 commits into
mainfrom
feat/sdk-context-evidence-contracts
Aug 11, 2026
Merged

unbraind merged 7 commits into
mainfrom
feat/sdk-context-evidence-contracts

Conversation

@unbraind

@unbraind unbraind commented Aug 11, 2026 •

Copy link
Copy Markdown
Owner

Outcome

This broad SDK/CLI tranche makes context and evidence contracts more truthful, portable, and token-efficient across every supported surface:

  • material omission receipts charge only source-proven recoverable context
  • extension preflight ownership participates in lazy command activation
  • isAlreadyClaimedError is a supported, bundle-safe SDK primitive
  • merge results distinguish requested preference from the value actually retained
  • item history hashes carry a backward-compatible canonicalization epoch
  • assurance mutation refusals cross CLI/SDK/MCP as typed usage errors instead of unclassified Sentry faults
  • the real Codex MCP smoke now ratchets the lean mutation envelope

Canonical pm items

Closes #969
Closes #971
Closes #974
Closes #975
Closes #976

Verification

  • exact repository coverage: 486 files, 7,234 tests, 100% statements / branches / functions / lines
  • linked isolated-tracker suites for all six implementation items
  • full build, typecheck, ESLint, jscpd, static quality, SDK surface, docs/skills, contracts, security, package-artifact, token-budget, context-calibration, graph and integrity gates
  • packed npx plus strict ESM/TypeScript consumer
  • real Codex and Claude MCP lifecycle smokes
  • compatibility smoke across 10 external packages
  • temporary-project cross-version history acceptance against published 2026.8.7 and 2026.8.10
  • manual JSON and TOON projection monotonicity acceptance
  • npm audit: zero vulnerabilities
  • pm history drift: 0 across 2,442 items; pm health: 10/10 checks clean

Release policy

v2026.8.11 already exists, so this PR must not create a second automatic release today. After merge, the immutable existing npm/GitHub release will be verified independently; the next eligible daily release remains fail-closed while recent high-severity Sentry issues are unresolved.

Summary by Sourcery

Strengthen SDK and CLI context, history, merge, assurance, and claim contracts for more truthful, portable, and version-compatible evidence across runtime surfaces.

New Features:

  • Expose isAlreadyClaimedError as a stable, bundle-safe predicate from both primary SDK entrypoints.
  • Introduce explicit item history hash epochs with versioned hashing APIs and verification helpers.
  • Add material field-group registration for read results so omission receipts charge only for truly present context.
  • Extend merge receipts and driver/item results with requested_preference to distinguish caller intent from retained values.

Bug Fixes:

  • Prevent assurance mutations with malformed or unauthorized definitions from surfacing as generic failures by classifying them as usage refusals.
  • Ensure merge summaries and receipts no longer misreport preferred side under stable value order, while retaining legacy receipt compatibility.
  • Fix extension preflight activation so scoped ownership only activates for owned commands and does not incorrectly contribute to global preflight overrides.
  • Adjust Codex MCP smoke to enforce the lean mutation envelope for pm_create responses and reject stale or malformed envelopes.
  • Guard measurement and assertion validation against missing or incorrectly typed dependency_kind and field values.

Enhancements:

  • Version and cache history drift scanning to track and reuse detected item_hash_version, preserving linked-test insertion order while remaining backward compatible.
  • Tighten output omission contracts for pm get so empty bodies and zero-cardinality collections do not inflate omission receipts, and material groups retain precise restoration guidance.
  • Normalize assurance action mutations through a shared boundary that maps deterministic TypeErrors to typed usage refusals while preserving non-validation failures.
  • Refine merge driver and three-way item merge results to treat per-decision retained/discarded values as authoritative, while propagating requested_preference consistently.
  • Update runtime primitives and error-code catalog to expose new history and assurance contracts through supported SDK surfaces.

Documentation:

  • Add SDK context and evidence contracts documentation covering omission receipts, scoped preflight ownership, merge provenance, claim-race classification, versioned history hashes, and assurance mutation refusals.
  • Extend merge safety documentation to describe requested_preference semantics, legacy receipt normalization, and history item hash epochs.
  • Update README and CHANGELOG entries to reflect strengthened context, evidence, and dependency updates.

Tests:

  • Add targeted unit tests for history hash versioning, drift cache behavior, merge receipts and direction contracts, output omission materiality, assurance action error typing, claim predicate exposure, extension preflight activation, and Codex MCP smoke envelopes to lock in the new contracts and compatibility behaviors.

Chores:

  • Refresh Sentry dependency evidence with packed-consumer verification and update project agents/history fixtures for the new contracts.

Summary by cubic

Strengthens SDK and CLI context/evidence contracts to cut tokens, clarify merge receipts, and harden history verification. Tracks PR #981 delivery and docs; tightens history epoch gating and omission billing.

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

Review in cubic

Deliver a coupled SDK and CLI contract tranche across material omission receipts, scoped extension preflight activation, public claim-race recognition, truthful merge preference evidence, versioned history hashes, and typed assurance mutation refusals.

Preserve legacy merge receipts and unversioned history readers, expose the new primitives through supported SDK entrypoints, add exact regression and packed-consumer coverage, document the contracts, and close the canonical pm/GitHub lineage with generated changelog evidence.
@sourcery-ai

sourcery-ai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Strengthens SDK and CLI context/evidence contracts by versioning history item hashes, tightening merge and omission receipts, formalizing assurance mutation refusal semantics, scoping extension preflight activation, enforcing lean MCP mutation envelopes, and exposing a stable claim-race predicate on the public SDK surface.

Sequence diagram for versioned history hash verification and drift scan

sequenceDiagram
  actor Client
  participant HistoryReplay
  participant DriftScan

  Client->>HistoryReplay: verifyHistoryChainWithVersion(entries)
  loop for each entry
    alt explicit item_hash_version present
      HistoryReplay->>HistoryReplay: [check SUPPORTED_HISTORY_ITEM_HASH_VERSIONS]
      opt [unsupported version]
        HistoryReplay-->>Client: { ok: false, errors: ["verify_failed:unsupported_item_hash_version:..."] }
      end
    end
    HistoryReplay->>HistoryReplay: replayHash(replay, candidateVersion)
    HistoryReplay->>HistoryReplay: hashDocumentForVersion(replayToItemDocument(replay), candidateVersion)
  end
  HistoryReplay-->>Client: { ok, errors, item_hash_version? }

  Client->>DriftScan: scanHistoryDrift(workspace)
  DriftScan->>DriftScan: verifyHistoryStream(entries)
  DriftScan->>HistoryReplay: verifyHistoryChainWithVersion(entries)
  HistoryReplay-->>DriftScan: { ok, item_hash_version? }
  DriftScan->>DriftScan: hashDocumentForVersion(itemDocument, item_hash_version)
  DriftScan-->>Client: DriftScanResult with item_hash_version and driftedItems
Loading

Sequence diagram for material omission receipts derived from output field groups

sequenceDiagram
  actor Agent
  participant GetQuery as runGet
  participant OutputProj as outputProjection
  participant Omission as attachOutputOmissionReceipt

  Agent->>GetQuery: runGet(pmRoot, id, options)
  GetQuery->>GetQuery: itemMaterialFieldGroups(metadata, body)
  GetQuery->>OutputProj: registerOutputMaterialFieldGroups(result, groups)
  GetQuery-->>Agent: result

  Agent->>Omission: attachOutputOmissionReceipt(command, result)
  Omission->>Omission: resolveOutputOmissionReceipt(command, result)
  Omission-->>Agent: result with omission_receipt
Loading

File-Level Changes

Change Details Files
Version history item hashes and make history replay, drift-scan, and runtime primitives epoch-aware while preserving legacy stream compatibility.
  • Introduce CURRENT_HISTORY_ITEM_HASH_VERSION, SUPPORTED_HISTORY_ITEM_HASH_VERSIONS, and HistoryItemHashVersion type plus hashDocumentForVersion and versioned canonicalization, including legacy linked-test sort for v1.
  • Augment HistoryEntry with optional item_hash_version and update createHistoryEntry to stamp the current epoch.
  • Teach replayHash, verifyHistoryChainWithVersion, verifyHistoryChain, and reanchorHistoryEntries to accept/auto-detect epochs, reject unsupported versions, and surface detected item_hash_version.
  • Update drift-scan to use verifyHistoryChainWithVersion, bump drift cache version, store item_hash_version per entry, default pre-epoch rows to the current version, and hash current items with the recorded epoch.
  • Export the new history primitives through sdk/runtime-primitives and add focused unit coverage for hash-version behavior and drift-cache migration.
src/core/history/history.ts
src/core/history/replay.ts
src/core/history/drift-scan.ts
src/types.ts
src/sdk/runtime-primitives.ts
tests/unit/core/history/drift-scan.spec.ts
tests/unit/core/history/history-hash-version.spec.ts
docs/MERGE_SAFETY.md
docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
Refine output omission receipts so get receipts only charge for material, source-proven context and allow packages to register non-serialized materiality evidence.
  • Add registerOutputMaterialFieldGroups with a WeakMap to track material field groups per result without serializing them.
  • Change resolveGetReceipt to filter field groups against registered material groups and actual presence on item/result, avoiding charges for empty bodies and zero-cardinality collections.
  • Have runGet compute material field groups based on body, collection_counts, linked artifacts, children, claim_state, and schedule, and register them before attaching the omission receipt.
  • Extend tests to assert material-only charging and non-charging when the body is present.
src/sdk/output-projection.ts
src/sdk/query/get.ts
tests/unit/sdk/output-projection.spec.ts
tests/fixtures/contracts/full.json
docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
Make merge receipts and merge driver results truthfully represent requested preference vs retained values while maintaining compatibility with legacy receipts.
  • Evolve MergeDecisionReceipt and MergeDecisionReceiptSummary to use requested_preference (with legacy preferred kept only for reading) and adjust summarizeMergeReceipt to normalize requested_preference from requested_preference/preferred with a default of "ours".
  • Update writeMergeReceipt, mergeItemDocuments, and MergeDriverResult to emit requested_preference instead of preferred in new receipts and driver results.
  • Normalize legacy receipts in readReceiptsFromDirectory by lifting preferred into requested_preference and ensuring conflict_resolution defaults to preferred_side.
  • Refresh merge-related docs to explain requested_preference semantics and add tests to cover summaries, listMergeReceipts behavior, merge-direction contract outputs, and legacy receipt shapes.
src/sdk/merge/receipts.ts
src/sdk/merge/three-way.ts
src/sdk/merge/driver.ts
tests/unit/sdk/merge-receipts.spec.ts
tests/unit/sdk/merge-direction-contract.spec.ts
docs/MERGE_SAFETY.md
docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
Normalize assurance mutation behavior so malformed, referenced, or unauthorized mutations surface as typed usage refusals across SDK/CLI/MCP while non-validation failures remain generic faults.
  • Strengthen validateMeasurementDefinition and validateAssertionDefinition to enforce non-empty, string-typed dependency_kind, graph/validate/health fields, and assertion.owner_item_id, throwing TypeError with precise messages.
  • Introduce normalizeAssuranceMutation in assurance-action to wrap put/remove operations, reclassifying TypeError validation failures as PmCliError with exitCode USAGE and code invalid_argument_value while letting other errors bubble.
  • Wire normalizeAssuranceMutation into runAssuranceAction for put/remove actions, preserving show behavior and id consistency checks.
  • Add unit tests ensuring malformed assertions and unauthorized/removal mutations are typed as usage refusals, and that non-validation registry failures preserve their original generic_failure classification.
  • Register assurance-action as an error source in the generated error code catalog and document the assurance mutation refusal contract.
src/sdk/governance/assurance.ts
src/sdk/governance/assurance-action.ts
tests/unit/sdk/assurance.spec.ts
tests/unit/sdk/assurance-action.spec.ts
src/sdk/generated-error-code-catalog.ts
docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
.agents/pm/issues/pm-v0a0un.toon
.agents/pm/history/pm-v0a0un.jsonl
Scope extension preflight activation and global-contribution detection using declared preflight_ownership, keeping health diagnostics aligned with lazy command activation.
  • Refactor extensionActivationCommands to prefer explicit activation.commands, then derive commands from contributions including preflight_ownership and renderer_ownership via helper functions.
  • Introduce entriesOrEmpty and ownershipCommands helpers for safer, DRY handling of optional arrays and ownership command extraction.
  • Adjust hasGlobalExtensionContributions to treat preflight_overrides minus preflight_ownership count as the global preflight contributions and to use entriesOrEmpty for all array-based counts.
  • Add focused CLI unit tests to validate that scoped preflights activate only for owned commands and that unscoped preflights remain global once ownership subtraction is considered.
src/cli/main.ts
tests/unit/cli/extension-preflight-activation.spec.ts
docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
.agents/pm/issues/pm-zryb9d.toon
.agents/pm/history/pm-zryb9d.jsonl
Tighten MCP smoke tests and script to enforce a lean mutation envelope for pm_create and robustly validate claim-race classification and item status/links.
  • Update smoke-codex-plugin-mcp tests to expect pm_create to return lean envelopes (changed_field_count, id, status) and add negative tests for stale and id-less envelopes.
  • Enhance pm-smoke MCP script to assert the lean envelope shape and non-empty id before invoking claim/update/comments tools, throwing explicit errors when the envelope contract is violated.
  • Ensure downstream pm_get validations still check smoke item status and linked artifacts, with updated expectations around lean mutation responses.
  • Add tests around rejection of malformed envelopes to ratchet the mutation envelope contract for real Codex MCP integration.
tests/unit/scripts/smoke-codex-plugin-mcp.spec.ts
scripts/smoke-codex-plugin-mcp.mjs
.agents/pm/issues/pm-fb0lkg.toon
.agents/pm/history/pm-fb0lkg.jsonl
Expose a bundle-safe claim-race predicate on the public SDK surface and harden its implementation against cross-bundle Error instances.
  • Refine isAlreadyClaimedError to first check an Error with name PmCliError and then inspect a loosely-typed context.code property, making it work across bundles, while narrowing matches to the canonical already_claimed_by code.
  • Export isAlreadyClaimedError from both sdk/index and sdk/core, and update the public-surface manifest accordingly.
  • Add unit tests to validate the predicate for direct PmCliError instances and cross-bundle Error objects with PmCliError-like shape, as well as negative cases.
  • Document the claim-race classification contract in the new SDK context/evidence docs.
src/sdk/lifecycle/claim.ts
src/sdk/index.ts
src/sdk/core.ts
sdk/public-surface.json
tests/unit/sdk/claim-public-surface.spec.ts
docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
.agents/pm/issues/pm-hfqju5.toon
.agents/pm/history/pm-hfqju5.jsonl
Update changelog, docs, agents, and fixtures to reflect strengthened context/evidence contracts and dependency evidence refresh.
  • Extend CHANGELOG with entries for material omission receipts, scoped preflight ownership, merge preference correction, claim-race predicate export, versioned history hashes, assurance mutation refusals, and Sentry dependency refresh.
  • Add SDK_CONTEXT_EVIDENCE_CONTRACTS.md and link it from the main docs README.
  • Refresh pm agent issue and history files for the six canonical implementation items plus the Sentry dependency-update chore to match the new behavior.
  • Touch test fixtures and contracts to remain aligned with the updated public surface and omission/merge/history behaviors.
CHANGELOG.md
docs/README.md
docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
.agents/pm/issues/pm-gok2km.toon
.agents/pm/issues/pm-qckpnq.toon
.agents/pm/issues/pm-hfqju5.toon
.agents/pm/issues/pm-2htk4p.toon
.agents/pm/issues/pm-zryb9d.toon
.agents/pm/issues/pm-v0a0un.toon
.agents/pm/chores/pm-fb0lkg.toon
.agents/pm/history/pm-gok2km.jsonl
.agents/pm/history/pm-qckpnq.jsonl
.agents/pm/history/pm-hfqju5.jsonl
.agents/pm/history/pm-2htk4p.jsonl
.agents/pm/history/pm-zryb9d.jsonl
.agents/pm/history/pm-v0a0un.jsonl
.agents/pm/history/pm-fb0lkg.jsonl

Assessment against linked issues

Issue Objective Addressed Explanation
#969 Change omission receipt behavior so that brief item reads only bill materially omitted field groups (do not include empty or default-valued fields like empty body or unclaimed claim_state), ensuring pm show/pm get --depth brief does not exceed --depth standard for small items. ✅
#969 Add tests and documentation that capture the new omission-receipt/materiality contract so the brief-vs-standard context behavior is preserved. ✅
#971 Update pm health’s preflight collision detection so that extension_preflight_override_collision respects declared preflight_ownership (ScopedPreflightOverrideDefinition), treating only unscoped/global preflights as colliding while disjoint scoped registrations do not collide. ✅
#971 Integrate preflight ownership into the CLI’s lazy extension activation logic so that scoped preflights activate only for their owned commands and global preflights remain global, aligning activation behavior with the ownership model used by pm health. ✅
#974 Ensure merge receipts no longer misrepresent the retained side under stable_value_order by separating the caller’s requested preference from the actual retained values, and stop emitting a misleading constant preferred:"ours" while maintaining backward compatibility when reading old receipts. ✅
#974 Update documentation to describe the corrected merge receipt semantics, including the requested_preference field and legacy preferred handling. ✅
#975 Export isAlreadyClaimedError from at least one supported SDK subpath (e.g. @unbrained/pm-cli/sdk and/or @unbrained/pm-cli/sdk/core) so that extensions can import it without using internal paths. ✅
#975 Treat isAlreadyClaimedError as a stable, documented public API (including typings, public surface metadata, and tests confirming its availability and behavior for claim race detection). ✅
#976 Make item history hashing backward-compatible across versions by introducing a versioned hash/canonicalization scheme that preserves linked-test insertion order while still validating legacy streams. ✅
#976 Update history verification, drift scanning, and repair tooling to use the hash version, avoid treating version differences as drift, and clearly surface unsupported hash versions instead of silently corrupting or misclassifying streams. ✅
#976 Add regression coverage for multi-tests_add histories (multiple linked tests on one item) to ensure cross-version verification and drift behavior remain stable. ✅

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

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 29 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

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: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 59e3f18b-8189-4fe0-8050-e56299c835ea

📥 Commits

Reviewing files that changed from the base of the PR and between 1b31551 and c893687.

📒 Files selected for processing (8)
  • .agents/pm/history/pm-ajj4r7.jsonl
  • .agents/pm/tasks/pm-ajj4r7.toon
  • src/core/history/history.ts
  • src/sdk/governance/assurance.ts
  • src/sdk/query/get.ts
  • tests/unit/core/history/history-hash-version.spec.ts
  • tests/unit/sdk/assurance-action.spec.ts
  • tests/unit/sdk/output-projection.spec.ts
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added SDK support for detecting already-claimed errors across bundles.
    • Added version-aware history hashing and verification with legacy compatibility.
    • Added material-field tracking for more accurate omission receipts.
  • Bug Fixes
    • Assurance mutation refusals now return structured usage errors while preserving unexpected failures.
    • Corrected merge preference reporting and retained compatibility with older receipts.
    • Improved scoped preflight activation and collision handling.
  • Documentation
    • Expanded guidance for SDK evidence, merge receipts, and history verification.
  • Chores
    • Updated the changelog and refreshed Sentry integration.

Walkthrough

The PR records release closeout for several PM items and adds SDK behavior for versioned history hashes, merge receipt semantics, output materiality, claim detection, assurance errors, scoped extension ownership, and lean MCP mutation responses.

Changes

Versioned history integrity

Layer / File(s) Summary
Hash versions and replay compatibility
src/core/history/*, src/types.ts, src/sdk/runtime-primitives.ts, tests/unit/core/history/*
History hashing supports versions 1 and 2. New entries record version 2. Replay detects legacy streams and rejects unsupported repair versions.
Drift cache propagation
src/core/history/drift-scan.ts, tests/unit/core/history/drift-scan.spec.ts
Drift caches store the hash version and use version-aware document hashing. Older cache entries default to the current algorithm.

SDK contracts and projections

Layer / File(s) Summary
Merge receipt semantics
src/sdk/merge/*, sdk/public-surface.json, tests/unit/sdk/merge-*
Merge results use requested_preference. New receipts omit preferred, while legacy receipts remain readable and normalize missing values to "ours".
Output materiality
src/sdk/output-projection.ts, src/sdk/query/get.ts, tests/unit/sdk/output-projection.spec.ts
Get results register material field groups before omission receipts are resolved. Empty collection groups are excluded from omission receipts.
Claim and mutation envelopes
src/sdk/lifecycle/claim.ts, src/sdk/index.ts, src/sdk/core.ts, scripts/smoke-codex-plugin-mcp.mjs, tests/unit/sdk/claim-public-surface.spec.ts, tests/unit/scripts/smoke-codex-plugin-mcp.spec.ts
isAlreadyClaimedError is exported from supported SDK entry points. MCP smoke tests validate lean top-level mutation responses.

Activation and assurance behavior

Layer / File(s) Summary
Scoped extension ownership
src/cli/main.ts, tests/unit/cli/extension-preflight-activation.spec.ts
Scoped preflight ownership affects activation and global contribution detection.
Typed assurance refusals
src/sdk/governance/assurance*.ts, src/sdk/generated-error-code-catalog.ts, tests/unit/sdk/assurance*.spec.ts
Expected assurance mutation refusals use structured usage errors. Unexpected runtime and registry failures remain unchanged.

Release records and documentation

Layer / File(s) Summary
Closeout and delivery evidence
.agents/pm/{issues,history,tasks,chores}/*, CHANGELOG.md, docs/*
PM records document implementation, validation, closure, release, changelog generation, and PR delivery lineage. Documentation covers merge provenance, hash versions, SDK evidence contracts, and verification requirements.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.56% 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
Linked Issues check ✅ Passed The implementation addresses all direct issues: omission materiality, scoped preflight ownership, merge semantics, claim detection, and versioned history hashes.
Out of Scope Changes check ✅ Passed The changes remain within the stated SDK and CLI contract objectives; documentation, tests, generated artifacts, and release evidence support them.
Title check ✅ Passed The title clearly summarizes the PR's primary change to strengthen SDK context and evidence contracts.
Description check ✅ Passed The description directly covers the PR's SDK, CLI, history, merge, assurance, and verification changes.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Create and claim the canonical review/merge coordination item, connect it to all coupled implementation items, and record the published PR lineage plus release/review runbooks.

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

Hey - I've found 1 issue, and left some high level feedback:

  • The normalizeAssuranceMutation helper currently reclassifies all TypeErrors as usage refusals, which may mask unexpected internal type bugs; consider narrowing the check to only validation-originated errors (e.g., by tagging or originating function) to avoid overcatching.
  • The filtering logic in resolveGetReceipt combining materialGroups, itemGroups, and Object.hasOwn is hard to reason about and subtly changes omission behavior; splitting this into clearly named predicates or intermediate variables would make the materiality rules and edge cases easier to audit.
  • The history hash version comparison helpers (e.g., compareJsonValues using JSON.stringify) rely on stringified JSON ordering and default fallbacks; if ordering or representation changes, hashes will drift, so it may be safer to centralize and document the canonicalization assumptions or reuse a shared stable stringify to avoid accidental changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `normalizeAssuranceMutation` helper currently reclassifies all `TypeError`s as usage refusals, which may mask unexpected internal type bugs; consider narrowing the check to only validation-originated errors (e.g., by tagging or originating function) to avoid overcatching.
- The filtering logic in `resolveGetReceipt` combining `materialGroups`, `itemGroups`, and `Object.hasOwn` is hard to reason about and subtly changes omission behavior; splitting this into clearly named predicates or intermediate variables would make the materiality rules and edge cases easier to audit.
- The history hash version comparison helpers (e.g., `compareJsonValues` using `JSON.stringify`) rely on stringified JSON ordering and default fallbacks; if ordering or representation changes, hashes will drift, so it may be safer to centralize and document the canonicalization assumptions or reuse a shared stable stringify to avoid accidental changes.

## Individual Comments

### Comment 1
<location path="tests/unit/sdk/assurance-action.spec.ts" line_range="152-149" />
<code_context>
+  it("types malformed, referenced, and unauthorized mutations as usage refusals", async () => {
</code_context>
<issue_to_address>
**suggestion (testing):** Add an explicit assertion on the typed refusal context to fully lock the assurance mutation contract

The new tests verify the correct `PmCliError` and `EXIT_CODE.USAGE` vs `GENERIC_FAILURE` behavior. Since `normalizeAssuranceMutation` now sets a structured context `{ code: "invalid_argument_value", reason: "assurance_mutation_refused" }` for validation `TypeError`s, please extend one expectation to assert on `error.context` as well (e.g. `toMatchObject({ exitCode: EXIT_CODE.USAGE, context: { code: "invalid_argument_value", reason: "assurance_mutation_refused" } })`) so the typed refusal contract is fully covered, not just the exit code.

Suggested implementation:

```typescript
  it("types malformed, referenced, and unauthorized mutations as usage refusals", async () => {
    await withTempPmPath(async ({ pmPath }) => {
      const global = { path: pmPath };
      await seedRegistry(pmPath);
      await expect(
        runAssuranceAction(
          {
            action: "put",
            kind: "assertion",
            id: "malformed-floor",
            definition: {

```

```typescript
          },
        ),
      ).rejects.toMatchObject({
        exitCode: EXIT_CODE.USAGE,
        context: {
          code: "invalid_argument_value",
          reason: "assurance_mutation_refused",
        },
      });

```

1. Ensure this expectation is specifically on the path that exercises a validation TypeError produced by `normalizeAssuranceMutation`, so the structured refusal context is asserted where the contract applies.
2. If there are multiple expectations in this test that all hit the same TypeError path, you may optionally mirror the `context` assertion on those as well for consistency, but the core contract is covered by at least one explicit `context` check as shown.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread tests/unit/sdk/assurance-action.spec.ts Resolved
@codspeed

codspeed Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 1.76%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

❌ 1 regressed benchmark
✅ 10 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ createQueryFingerprint 1.4 ms 1.5 ms -1.76%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing feat/sdk-context-evidence-contracts (c893687) with main (9455e9b)

Open in CodSpeed

Preserve the strict 3,400-line source ceiling after adding the assurance refusal producer by rendering generated string arrays up to 100 columns deterministically. Add boundary coverage and record the exact-head preflight remediation on pm-ajj4r7.
@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai please review the exact current head cc74fa7.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 53 minutes.

@codecov

codecov Bot commented Aug 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!

Cover the generated catalog branch above the compact 100-column boundary with a real multi-source fixture and record exact 100/100/100/100 remediation evidence on pm-ajj4r7.
@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai please re-review the exact current head 2f31fb9 after the coverage fix.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 37 minutes.

Tag expected assurance declaration and policy refusals explicitly so CLI and MCP transports do not mask unexpected TypeErrors. Clarify material omission ownership, document legacy hash byte compatibility, and assert the complete typed refusal context while retaining exact repository-wide coverage.
@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai Please review the exact current head 1bb1af4, including the typed assurance mutation-refusal boundary and its negative control.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review Please review the exact current head 1bb1af4 after the assurance boundary remediation.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

@unbraind I will perform a full review of the current head 1bb1af4b5. I will include the assurance mutation-refusal boundary remediation and its negative control.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 24 minutes.

@unbraind

Copy link
Copy Markdown
Owner Author

Useful review. Commit 1bb1af4 narrows normalization to a dedicated AssuranceMutationRefusalError, adds an unexpected-TypeError negative control, clarifies resolveGetReceipt ownership, and documents why v1 must retain JSON.stringify byte ordering for immutable hash compatibility.

@unbraind

Copy link
Copy Markdown
Owner Author

Acknowledged: the guide accurately identifies the broad SDK/context/evidence changes and was used to structure the exact-head review.

@unbraind

Copy link
Copy Markdown
Owner Author

Acknowledged as a provider limitation, not approval: CodeRabbit hit its review limit and supplied no findings. A new exact-head full review was requested for 1bb1af4.

@unbraind

Copy link
Copy Markdown
Owner Author

Acknowledged: this is another rate-limit notice without a review. It is recorded as unavailable feedback, and exact-head review was re-requested.

@unbraind

Copy link
Copy Markdown
Owner Author

Addressed on the current head: the missing multiline generator branch has a real fixture, and local canonical coverage is exactly 100/100/100/100 across 52,193 statements, 38,348 branches, 10,745 functions, and 50,414 lines.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed and classified as non-actionable benchmark noise: createQueryFingerprint and src/sdk/pagination.ts are unchanged by this PR; the reported 1.76% shift was on an older head and below a 0.1 ms rounded delta. Exact-head CodSpeed remains required before merge.

@unbraind

Copy link
Copy Markdown
Owner Author

Acknowledged as an unavailable review provider: this invocation was rate limited and produced no findings, so it is not counted as approval.

@unbraind

Copy link
Copy Markdown
Owner Author

Acknowledged: despite the initial status line, the action ended rate limited and did not review 1bb1af4. This remains a documented limitation, not approval.

@unbraind

Copy link
Copy Markdown
Owner Author

CodSpeed exact-head update acknowledged: the edited report now shows all 11 benchmarks untouched for 1bb1af4, superseding its older transient signal. Reaction corrected to 👍.

Regenerate the error catalog and full runtime contract fixture after moving assurance mutation normalization into its dedicated typed boundary. Record the exact CI diagnosis and verification on the active PR delivery item.
@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai Please review the exact current head 1b31551, including the typed assurance refusal boundary and regenerated error provenance contracts.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

@unbraind I will perform a full review of the exact current head 1b3155142. I will include the generated contract provenance fix and its affected contracts.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 13 minutes.

@unbraind

Copy link
Copy Markdown
Owner Author

Acknowledged as unavailable feedback: the exact-head 1b31551 request was rate limited and produced no findings, so it is not approval.

@unbraind

Copy link
Copy Markdown
Owner Author

CodeRabbit summary edit acknowledged: the exact-head 1b31551 attempt remains rate limited with no review findings. This is recorded as a provider limitation, not approval.

@unbraind

Copy link
Copy Markdown
Owner Author

CodSpeed exact-head edit acknowledged: all 11 benchmarks remain untouched on 1b31551.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review Please perform the final full review of exact head 1b31551 now that the stated rate-limit window has elapsed.

@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai Final exact-head review request for 1b31551; please report any remaining actionable findings before merge.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

@unbraind I will perform the final full review of exact head 1b3155142. I will assess the typed assurance mutation-refusal boundary and the regenerated contract provenance.

✅ Action performed

Full review finished.

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

🤖 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 @.agents/pm/history/pm-hfqju5.jsonl:
- Around line 19-23: Reopen and reclaim pm-hfqju5, preserving its append-only
history, and keep it in_progress until PR `#981` has merged-head verification;
then add current delivery evidence before running pm close followed by pm
release. Regenerate .agents/pm/issues/pm-zryb9d.toon through pm after reopening
and reclaiming pm-zryb9d, applying the same deferred-transition and evidence
requirements; both affected sites require these lifecycle updates rather than
direct manual history edits.

In `@src/core/history/history.ts`:
- Around line 231-236: Update hashDocumentForVersion to validate that version is
a supported HistoryItemHashVersion before calling canonicalHashDocument or
hashing; reject any unsupported runtime value instead of implicitly treating it
as version 2, while preserving existing behavior for valid versions.

In `@src/sdk/governance/assurance.ts`:
- Around line 686-690: Update the validation around the retire branch in the
assurance mutation logic to verify that definition.retire_reason is a string
before invoking trim, routing non-string or missing values through
AssuranceMutationRefusalError with the existing invalid_argument_value
classification. Add an action-level regression test covering a numeric
retire_reason and assert the structured refusal response.

In `@src/sdk/query/get.ts`:
- Around line 159-175: Update itemMaterialFieldGroups in
src/sdk/query/get.ts:159-175 to include claim_state only when the source item
contains non-default claim information, not merely because the field group
exists. In tests/unit/sdk/output-projection.spec.ts:331-366, add an
unclaimed-item regression case asserting no claim_state omission and retain the
omission expectation for a fixture with material claim data.
🪄 Autofix

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: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d96cc062-85fa-45c3-9976-97a41e9e065e

📥 Commits

Reviewing files that changed from the base of the PR and between 9455e9b and 1b31551.

📒 Files selected for processing (54)
  • .agents/pm/chores/pm-fb0lkg.toon
  • .agents/pm/history/pm-2htk4p.jsonl
  • .agents/pm/history/pm-ajj4r7.jsonl
  • .agents/pm/history/pm-fb0lkg.jsonl
  • .agents/pm/history/pm-gok2km.jsonl
  • .agents/pm/history/pm-hfqju5.jsonl
  • .agents/pm/history/pm-qckpnq.jsonl
  • .agents/pm/history/pm-v0a0un.jsonl
  • .agents/pm/history/pm-zryb9d.jsonl
  • .agents/pm/issues/pm-2htk4p.toon
  • .agents/pm/issues/pm-gok2km.toon
  • .agents/pm/issues/pm-hfqju5.toon
  • .agents/pm/issues/pm-qckpnq.toon
  • .agents/pm/issues/pm-v0a0un.toon
  • .agents/pm/issues/pm-zryb9d.toon
  • .agents/pm/tasks/pm-ajj4r7.toon
  • CHANGELOG.md
  • docs/MERGE_SAFETY.md
  • docs/README.md
  • docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md
  • scripts/generate-error-code-catalog.mjs
  • scripts/smoke-codex-plugin-mcp.mjs
  • sdk/public-surface.json
  • src/cli/main.ts
  • src/core/history/drift-scan.ts
  • src/core/history/history.ts
  • src/core/history/replay.ts
  • src/sdk/core.ts
  • src/sdk/generated-error-code-catalog.ts
  • src/sdk/governance/assurance-action.ts
  • src/sdk/governance/assurance-mutation-error.ts
  • src/sdk/governance/assurance.ts
  • src/sdk/index.ts
  • src/sdk/lifecycle/claim.ts
  • src/sdk/merge/driver.ts
  • src/sdk/merge/receipts.ts
  • src/sdk/merge/three-way.ts
  • src/sdk/output-projection.ts
  • src/sdk/query/get.ts
  • src/sdk/runtime-primitives.ts
  • src/types.ts
  • tests/fixtures/contracts/full.json
  • tests/unit/cli/extension-preflight-activation.spec.ts
  • tests/unit/core/history/drift-scan.spec.ts
  • tests/unit/core/history/history-hash-version.spec.ts
  • tests/unit/scripts/generate-error-code-catalog.spec.ts
  • tests/unit/scripts/smoke-codex-plugin-mcp.spec.ts
  • tests/unit/sdk/agent-runtime-primitives.spec.ts
  • tests/unit/sdk/assurance-action.spec.ts
  • tests/unit/sdk/assurance.spec.ts
  • tests/unit/sdk/claim-public-surface.spec.ts
  • tests/unit/sdk/merge-direction-contract.spec.ts
  • tests/unit/sdk/merge-receipts.spec.ts
  • tests/unit/sdk/output-projection.spec.ts

Comment thread .agents/pm/history/pm-hfqju5.jsonl Resolved
Comment thread src/core/history/history.ts Resolved
Comment thread src/sdk/governance/assurance.ts Resolved
Comment thread src/sdk/query/get.ts Resolved
Reject unsupported history hash epochs before producer hashing, keep malformed assurance retirement metadata inside the typed refusal boundary, and stop billing default unclaimed state as material context. Add source-backed TDD coverage and record exact review remediation evidence on pm-ajj4r7.
@unbraind

Copy link
Copy Markdown
Owner Author

The requested full review completed and produced four concrete findings. They have all been evaluated, reacted to, answered inline, and resolved; three fixes are in c893687 and the lifecycle recommendation is declined with live PM evidence.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed all four actionable comments from this review. Commits through c893687 implement the three valid contract fixes with 7,235 tests at exact 100/100/100/100 and an 88-command isolated dogfood pass; the PM lifecycle recommendation is documented as declined because the dedicated delivery item owns merge closeout.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review\n@greptileai please review\n\nFinal remediation head: c893687. Please re-review the three CodeRabbit contract fixes (hash epoch producer validation, non-string assurance retire_reason refusal, source-material claim-state omission) and confirm no new findings. All prior bot threads have been reacted to, answered, and resolved.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai please review exact head c893687

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 33 minutes.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

@unbraind I will perform a full review of exact head c89368724ef7f69aaebec905299818f096d040bc. I will verify the three remediated contracts and check for new findings.

⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 33 minutes.

@unbraind

Copy link
Copy Markdown
Owner Author

This final exact-head review request was rate limited and produced no findings. It is recorded as unavailable feedback, not approval; the remediation head is instead covered by all hosted gates, prior actionable review remediation, exact 100/100/100/100 coverage, and isolated dogfood.

@unbraind

Copy link
Copy Markdown
Owner Author

The bot identified the exact remediation head but the requested full review was rate limited before analysis. This is an explicit provider limitation, not approval; no new findings were supplied.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed empty CodeRabbit review container PRR_kwDORSgRDc8AAAABJJ3sRA; it introduced no standalone findings. Its companion inline confirmation/withdrawal has been reacted to and answered on the resolved thread for exact head c893687.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed empty CodeRabbit review container PRR_kwDORSgRDc8AAAABJJ4Dxg; it introduced no standalone findings. Its companion inline confirmation/withdrawal has been reacted to and answered on the resolved thread for exact head c893687.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed empty CodeRabbit review container PRR_kwDORSgRDc8AAAABJJ4E7A; it introduced no standalone findings. Its companion inline confirmation/withdrawal has been reacted to and answered on the resolved thread for exact head c893687.

@unbraind

Copy link
Copy Markdown
Owner Author

CodeRabbit summary edit at c893687 reviewed: its linked-issues, scope, title, and description checks pass. The 55.56% docstring warning is not actionable because the repository's authoritative static gate measures 100% source/export/member docstring coverage and the exact-head hosted Gates (static) job passed.

@unbraind

Copy link
Copy Markdown
Owner Author

CodSpeed exact-head edit reviewed: createQueryFingerprint is untouched by this PR, the report explicitly detected different runtime environments, the rounded shift is 0.1 ms / 1.76%, 10 benchmarks are untouched, and the hosted CodSpeed job passed. Reaction records the noisy regression signal without treating it as a code defect.

@unbraind

Copy link
Copy Markdown
Owner Author

Codecov exact-head edit acknowledged: all modified coverable lines and tests pass; the independent canonical suite is 7,235/7,235 at exact 52,196/52,196 statements, 38,355/38,355 branches, 10,746/10,746 functions, and 50,417/50,417 lines.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed final empty CodeRabbit confirmation container PRR_kwDORSgRDc8AAAABJJ4W7A; its companion inline acknowledgement confirms the addressed contract and carries a thumbs-up reaction. No new finding or code change is requested.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed final empty CodeRabbit confirmation container PRR_kwDORSgRDc8AAAABJJ478g; its companion inline acknowledgement confirms the addressed contract and carries a thumbs-up reaction. No new finding or code change is requested.

@unbraind

Copy link
Copy Markdown
Owner Author

Reviewed final empty CodeRabbit confirmation container PRR_kwDORSgRDc8AAAABJJ4_1w; its companion inline acknowledgement confirms the addressed contract and carries a thumbs-up reaction. No new finding or code change is requested.

@unbraind
unbraind merged commit b02ee51 into main Aug 11, 2026
32 checks passed
@unbraind
unbraind deleted the feat/sdk-context-evidence-contracts branch August 11, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment