Skip to content

feat(core): advance v0.1 contract evidence and retention#371

Open
flyingrobots wants to merge 7 commits into
mainfrom
stack/v0.1-contract-evidence-retention-proof
Open

feat(core): advance v0.1 contract evidence and retention#371
flyingrobots wants to merge 7 commits into
mainfrom
stack/v0.1-contract-evidence-retention-proof

Conversation

@flyingrobots
Copy link
Copy Markdown
Owner

@flyingrobots flyingrobots commented May 22, 2026

Summary

This PR completes the next five v0.1.0 contract-host slices:

  1. Contract-aware receipts and readings
  2. Contract reading identity and bounded payloads
  3. Contract artifact retention in echo-cas
  4. Contract retention and semantic lookup seams
  5. External contract proof fixture

Changes

  • Adds ContractEvidenceIdentity to installed QueryView ReadingEnvelopes and installed mutation receipt correlations.
  • Adds QueryReadingIdentity for QueryView readings, binding query id, vars digest, resolved basis digest, aperture digest, observer plan, and installed contract evidence when present.
  • Adds echo-cas semantic retention primitives above content-only CAS: SemanticBlobCoordinate, RetainedBlobIndex, descriptors, typed retention errors, and bounded range lookup.
  • Adds a generic external contract proof fixture covering scheduler-owned mutation execution, bounded QueryView reading, retained reading/receipt evidence, and replay to the same observed outcome.
  • Adds design docs for each slice and updates BEARING/backlog status for the completed batch.

Authority boundaries preserved

  • Application dispatch still does not tick.
  • Query observers remain read-only.
  • Mutation handlers run only during scheduler-owned ticks.
  • CAS byte identity remains separate from semantic reading/retention identity.
  • No app/editor/jedit/Graft nouns were added to Echo core.

Verification

  • cargo test -p echo-wasm-abi
  • cargo test -p echo-cas
  • cargo test -p warp-core --features native_rule_bootstrap --test installed_contract_registry_tests installed_contract_package_binds_supported_mutation_and_query
  • cargo test -p warp-core --features native_rule_bootstrap,host_test --test installed_contract_intent_pipeline_tests
  • cargo clippy -p warp-core --features native_rule_bootstrap,host_test --test installed_contract_intent_pipeline_tests
  • cargo fmt --check
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Added contract evidence metadata tracking to installed contract receipts and query readings, including package identity and operation details.
    • Introduced stable query reading identity to track how query results vary by inputs, basis, and budget.
    • Added semantic artifact retention layer supporting typed error handling and bounded byte-range lookups for retained payloads.
  • Updates

    • Bumped ABI version to 11 with backwards-compatible reading envelope fields.
    • Updated observation contract to version 3 with improved artifact versioning.
    • Added comprehensive external contract proof fixture validating mutations, queries, and artifact retention with replay.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

This PR implements semantic retention indexing above echo-cas, attaches optional contract evidence to observation readings and receipts, introduces stable QueryReadingIdentity for query observations, bumps the ABI and observation contract to version 11/v3 respectively, and refactors the ingestion pipeline to thread evidence through staged records.

Changes

Semantic Retention, Contract Evidence, and Reading Identity

Layer / File(s) Summary
Semantic Retention Foundation
crates/echo-cas/src/retention.rs, crates/echo-cas/src/lib.rs
Introduces RetainedBlobIndex mapping semantic coordinates (namespace, schema, artifact, role, digest) to retained byte descriptors; implements retain (with conflict detection and CAS pinning), load (coordinate-exact), load_by_hash, and load_range (with budget and bounds enforcement); defines RetentionError variants for missing coordinates, budget/bounds violations, and semantic conflicts.
Semantic Retention Boundary Tests
crates/echo-cas/tests/semantic_retention.rs
Validates coordinate-based indexing, idempotent retain, conflict rejection, content-hash vs coordinate loading, bounded range extraction with budget enforcement, and error precedence.
Contract Evidence Types and Helpers
crates/warp-core/src/contract_registry.rs, crates/warp-core/src/engine_impl.rs
Adds ContractOperationKind, ContractEvidenceIdentity (package/registry/operation metadata), and InstalledContractPackageRecord::evidence_identity; provides engine helpers to look up evidence by query or mutation id.
Ingestion Pipeline and Receipt Threading
crates/warp-core/src/coordinator.rs
Refactors ingest_ticketed_invocation to accept optional contract evidence; extends TicketedRuntimeIngressRecord and ReceiptCorrelationRecord with contract field; installed-contract ingestion resolves mutation evidence via Engine and threads it through staging.
Observation Contract v3, Reading Identity, and Evidence
crates/warp-core/src/observation.rs
Bumps observation artifact domain from v2 to v3; introduces QueryReadingIdentity (reading_id, query_id, domain-separated vars/basis/aperture digests); extends ReadingEnvelope with optional contract and query_identity; computes identity from query inputs and contract evidence for QueryView observations.
ABI Version 11 Shape and Backward Compatibility
crates/echo-wasm-abi/src/kernel_port.rs, crates/echo-wasm-abi/src/lib.rs
Bumps ABI_VERSION to 11; adds ContractOperationKind, ContractEvidenceIdentity, QueryReadingIdentity types; extends ReadingEnvelope with optional contract and query_identity fields (serde defaults for compatibility); legacy decoding test verifies fields absent in v10 envelopes remain unset.
Public API Alignment
crates/warp-core/src/lib.rs, crates/warp-core/Cargo.toml
Re-exports ContractEvidenceIdentity, ContractOperationKind from contract_registry and QueryReadingIdentity from neighborhood; adds echo-cas dev dependency.
Fixture Updates and Evidence Assertions
crates/echo-wasm-abi/src/lib.rs, crates/echo-wesley-gen/tests/generation.rs, crates/warp-wasm/src/lib.rs, crates/warp-wasm/src/warp_kernel.rs, crates/warp-core/src/optic/tests.rs
Updates reading envelope fixtures to populate contract and query_identity fields (both None in test stubs).
End-to-End Contract Mutation, Query, Retention, and Replay
crates/warp-core/tests/installed_contract_intent_pipeline_tests.rs
Extends test fixture with query operation and observer; adds helpers for semantic blob coordinates, length-prefixed encoding, and receipt serialization; augments mutation test to assert contract evidence in correlations; introduces external_contract_fixture_proves_mutation_query_retention_and_replay test executing installed mutation → query observation → semantic retention/load → witnessed replay validation.
Registry Test Evidence Validation
crates/warp-core/tests/installed_contract_registry_tests.rs
Extends registry test to extract and assert contract evidence fields (package identity, registry info, operation metadata) from observed query readings.
Design Specifications and Roadmap
docs/design/v0.1.0-contract-artifact-retention-in-echo-cas.md, docs/design/v0.1.0-contract-aware-receipts-and-readings.md, docs/design/v0.1.0-contract-reading-identity-and-bounded-payloads.md, docs/design/v0.1.0-contract-retention-and-semantic-lookup-seams.md, docs/design/v0.1.0-external-contract-proof-fixture.md, docs/BEARING.md, docs/design/v0.1.0-release-plan.md, docs/method/backlog/v0.1.0/*.md, docs/spec/SPEC-0009-wasm-abi-v3.md, crates/warp-wasm/README.md
Adds comprehensive design docs for retention indexing, contract evidence rules, reading identity, external proof fixture, and retention/lookup seams; updates BEARING roadmap; marks completed slices in release-plan and backlog; bumps observation artifact domain tag to v3; updates ABI documentation.

Sequence Diagram(s)

sequenceDiagram
    participant Test
    participant Coordinator
    participant Engine
    participant ObsService
    participant RetIndex
    
    Test->>Coordinator: ingest_ticketed(mutation)
    Coordinator->>Coordinator: dispatch via scheduler
    Test->>ObsService: observation_request(query)
    ObsService->>Engine: contract_query_observer_package_evidence(query_id)
    Engine-->>ObsService: Some(contract_evidence)
    ObsService->>ObsService: execute query observer
    ObsService->>ObsService: compute query_reading_identity
    ObsService-->>Test: ReadingEnvelope { contract, query_identity, ... }
    Test->>RetIndex: retain(semantic_coord_reading, payload)
    Test->>RetIndex: retain(semantic_coord_receipt, correlation)
    Test->>RetIndex: load(semantic_coord_reading)
    Test->>RetIndex: load(semantic_coord_receipt)
    Test->>Coordinator: replay witnessed submissions
    Coordinator-->>Test: same observed intent outcome
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • flyingrobots/echo#370: This PR implements multiple v0.1.0 release-bar features (semantic retention in echo-cas, contract evidence on readings/receipts, QueryReadingIdentity, external contract proof fixture, ABI/observation version bumps) that directly satisfy and modify the same code paths and types referenced by the v0.1.0 release-plan tracking issue.

Possibly related PRs

  • flyingrobots/echo#360: Both PRs modify crates/warp-core/src/coordinator.rs around ticketed-runtime ingress and ReceiptCorrelationRecord/TicketedRuntimeIngressRecord, with the main PR extending those receipt-correlation records to propagate optional ContractEvidenceIdentity fields.
  • flyingrobots/echo#368: The main PR's warp-core changes (adding contract: Option<ContractEvidenceIdentity> onto ReceiptCorrelationRecord and extending the installed-contract intent pipeline integration tests with contract/query evidence retention/replay) overlap directly with PR #368's warp-core/src/coordinator.rs intent-outcome/receipt-correlation wiring and installed-contract intent pipeline tests.
  • flyingrobots/echo#302: The main PR's changes to warp-core observation/reading identities (e.g., QueryReadingIdentity, ReadingEnvelope.contract/query_identity) and the corresponding echo-wasm-abi ABI fields are directly tied to the retrieved PR's broader "explicit observe/observation contract" work, which also updates the observation types surfaced through the kernel ABI.

Poem

🏗️ Semantic coordinates index the retained,
Evidence threads through receipts, unfated,
Query identity binds query inputs tight,
Retention loads bounded—budget in sight,
V3 domain hashes separate the past,
ABI version 11 marks the boundaries fast. 🎯

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(core): advance v0.1 contract evidence and retention' directly describes the main change—implementing contract evidence and retention features for v0.1.0. It is concise, specific, and clearly summarizes the primary focus of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch stack/v0.1-contract-evidence-retention-proof

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 and usage tips.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: 94018001f9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/echo-cas/src/retention.rs
@flyingrobots
Copy link
Copy Markdown
Owner Author

@codex Self-review findings for PR #371. Please confirm the severity/mitigation before merge.

Severity File / lines Infraction Evidence Recommended mitigation prompt
P1 crates/echo-cas/src/retention.rs:128-143 Semantic retention coordinates can be silently remapped. retain(...) always inserts a new descriptor for the same SemanticBlobCoordinate and returns success. A semantic coordinate is supposed to name the question/evidence identity; silently changing the content hash for the same coordinate breaks auditability. Because MemoryTier pins are set-based, this also cannot be repaired safely with naive unpinning. Make RetainedBlobIndex::retain fail closed on same-coordinate/different-content writes. Add RetentionError::SemanticCoordinateConflict (or equivalent), make same-coordinate/same-content idempotent, and add tests for idempotent re-retain plus conflict rejection.
P2 crates/echo-cas/src/retention.rs:185-205 load_range(...) returns budget errors before proving the semantic coordinate exists. The docs say the semantic coordinate must match first, but code checks len > max_bytes before self.load(...). A missing retained coordinate with an over-budget range reports RangeExceedsBudget, masking missing retention. Add a regression test proving missing semantic coordinates take precedence over range budget errors, then load the semantic coordinate before budget/range validation in load_range(...).
P2 docs/BEARING.md:77-90 Current bearing contradicts this PR’s completed slice batch. The “What Is Not Yet True” section still says contract-aware identities, semantic retention, and external proof fixtures are not yet present, while the same file later records those as completed slices. Update BEARING so the not-yet-true list reflects the branch: durable submission persistence, product API, reference host loop, broader replay/DIND proof, and release-grade quickstart remain; contract evidence/retention/generic external fixture should move out of stale missing-state wording.
P2 docs/design/v0.1.0-release-plan.md:100-130,341-350 v0.1 feature/status tables still mark newly implemented capabilities as missing. The release plan lists contract-aware receipts/readings, bounded reading identity, local retention, and external proof fixture as Missing after this PR implements local boundaries/proofs for them. Change these release-plan rows to Partial or Complete local proof as appropriate, with caveats for remaining durable persistence, obstruction taxonomy, full receipt identity, and release-grade external consumer proof.
P3 crates/warp-core/tests/installed_contract_intent_pipeline_tests.rs:954-963 External proof fixture overclaims receipt retention by retaining only the receipt digest bytes. RetainedBlobRole::ContractReceipt is populated with &correlation.tick_receipt_digest, not a serialized TickReceipt, receipt correlation record, or retained receipt envelope. This proves digest retention, not receipt material retention. Either retain actual receipt/correlation material under the ContractReceipt coordinate, or rename the fixture/docs to say receipt-digest evidence only and leave full receipt material retention as a follow-up.

Validation run during review: git diff --check origin/main...HEAD and markdownlint over touched design/BEARING docs both passed.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: 94018001f9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/echo-cas/src/retention.rs
Comment thread crates/echo-cas/src/retention.rs
Comment thread docs/BEARING.md
@flyingrobots
Copy link
Copy Markdown
Owner Author

Self-review fixes addressed in commit 021dc59.

Finding Severity Outcome Commit Regression / verification
Semantic retention coordinates could be remapped P1 RetainedBlobIndex::retain(...) now returns Result, is idempotent for same-coordinate/same-content, and rejects same-coordinate/different-content with RetentionError::SemanticCoordinateConflict. 021dc59 same_semantic_coordinate_and_content_retain_idempotently; same_semantic_coordinate_with_different_content_is_rejected; cargo test -p echo-cas --test semantic_retention
load_range(...) masked missing coordinates with budget errors P2 Semantic coordinate lookup now happens before range-budget checks. 021dc59 missing_semantic_coordinate_takes_precedence_over_range_budget; cargo test -p echo-cas --test semantic_retention
docs/BEARING.md contradicted completed branch work P2 Stale missing-state claims were replaced with the actual remaining gaps: durable persistence, product-facing APIs, obstruction taxonomy, durable retention, and serious app-owned consumer proof. 021dc59 markdownlint-cli2 on touched docs; git diff --check
v0.1 release plan still marked implemented local boundaries as missing P2 Release-plan feature clusters and checklist now distinguish implemented local proof from remaining release-grade work. 021dc59 markdownlint-cli2 on touched docs; git diff --check
External proof fixture retained only receipt digest bytes P3 Fixture now retains deterministic receipt-correlation material under the contract receipt coordinate and docs name the narrower proof precisely. 021dc59 external_contract_fixture_proves_mutation_query_retention_and_replay; cargo test -p warp-core --features native_rule_bootstrap,host_test --test installed_contract_intent_pipeline_tests

Verification run locally:

  • cargo test -p echo-cas
  • cargo test -p warp-core --features native_rule_bootstrap,host_test --test installed_contract_intent_pipeline_tests
  • cargo clippy -p echo-cas --lib --tests
  • cargo clippy -p warp-core --features native_rule_bootstrap,host_test --test installed_contract_intent_pipeline_tests
  • cargo fmt --check
  • git diff --check
  • pnpm exec markdownlint-cli2 docs/BEARING.md docs/design/v0.1.0-release-plan.md docs/design/v0.1.0-contract-artifact-retention-in-echo-cas.md docs/design/v0.1.0-external-contract-proof-fixture.md CHANGELOG.md

✅ Addressed in commit 021dc59.

@flyingrobots
Copy link
Copy Markdown
Owner Author

@codex Second self-review findings for PR #371. Please confirm before merge.

Severity File / lines Infraction Evidence Recommended mitigation prompt
P1 crates/warp-core/src/observation.rs:40-41, crates/warp-core/src/observation.rs:880-893, crates/warp-core/src/observation.rs:1993-2010 Observation artifact hash input changed without advancing the observation hash/version domain. compute_artifact_hash(...) hashes reading.to_abi(). This PR adds ReadingEnvelope.contract and ReadingEnvelope.query_identity, so canonical artifact bytes and hashes change, but OBSERVATION_VERSION remains 2 and OBSERVATION_ARTIFACT_DOMAIN remains echo:observation-artifact:v2. That means different hash semantics are published under the old domain/version. Bump the observation artifact contract to v3: update OBSERVATION_VERSION, OBSERVATION_ARTIFACT_DOMAIN, docs/spec references to observation-artifact:v2, and add a regression test proving QueryView contract evidence/query identity are under the new observation version/domain.
P1 crates/echo-wasm-abi/src/kernel_port.rs:13-43, crates/echo-wasm-abi/src/kernel_port.rs:1681-1692, crates/warp-wasm/README.md:15-18 Public WASM ABI response shape changed without bumping ABI_VERSION. ReadingEnvelope now exposes contract and query_identity in echo-wasm-abi, but ABI_VERSION still reports 10 and warp-wasm docs still advertise ABI 10. New clients expecting these fields cannot distinguish a pre-PR runtime from a post-PR runtime through the registry/version handshake. Bump echo-wasm-abi ABI_VERSION to 11, update module docs and warp-wasm README references, and add/update tests asserting registry_info.abi_version reports the new ABI after ReadingEnvelope schema expansion.
P2 crates/echo-wasm-abi/src/kernel_port.rs:1688-1692 Newly optional ABI fields are not decode-compatible with older retained envelopes. The new fields are typed as Option<...> but lack #[serde(default)]. In serde, missing fields are still errors unless defaulted, so old retained ReadingEnvelope/ObservationArtifact bytes cannot decode as None for these optional fields. That undermines local retention/replay compatibility exactly where this PR adds retained reading evidence. Add #[serde(default)] to ReadingEnvelope.contract and ReadingEnvelope.query_identity, then add an echo-wasm-abi regression test that decodes a legacy ReadingEnvelope/ObservationArtifact value with those fields omitted and observes None.
P3 docs/design/v0.1.0-release-plan.md:160-177, docs/design/v0.1.0-release-plan.md:348-356 Release-plan retention status still over-compresses remaining work. The Retention Layer section still lists semantic contract artifact refs, retained reading refs, retained receipt/witness refs, and missing-retention obstruction as missing, while the checklist says local retention for artifacts/readings/receipts is complete with only durable recovery remaining. That is too broad and will mislead release tracking. Split the checklist status into precise rows or caveats: semantic RetainedBlobIndex boundary complete; retained artifact/receipt/reading refs and missing-retention obstruction still partial; durable recovery remains missing.

No files changed during this review. Validation run during review: git diff --check origin/main...HEAD and markdownlint over touched docs passed.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: 021dc592a6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/warp-core/src/observation.rs
Comment thread crates/echo-wasm-abi/src/kernel_port.rs
@flyingrobots
Copy link
Copy Markdown
Owner Author

@codex Follow-up self-review fixes are pushed.

Issue Severity File(s) Addressed by Regression coverage Outcome
Retention accepted same semantic coordinate with different bytes P1 crates/echo-cas/src/lib.rs 021dc59 same_semantic_coordinate_and_content_retain_idempotently; same_semantic_coordinate_with_different_content_is_rejected RetainedBlobIndex::retain now returns typed errors, is idempotent for identical content, and rejects semantic-coordinate/content drift.
Range lookup checked budget before semantic coordinate existence P2 crates/echo-cas/src/lib.rs 021dc59 missing_semantic_coordinate_takes_precedence_over_range_budget Missing semantic coordinate now reports NotFound before range-budget validation.
External proof fixture retained only digest-shaped bytes P2 crates/warp-core/tests/external_contract_proof_fixture.rs 021dc59 external_counter_contract_submit_tick_query_retain_and_replay_proof Fixture now retains deterministic receipt-correlation material with submission/ticket/receipt/package evidence.
Observation artifact hash schema changed without artifact-version/domain bump P1 crates/warp-core/src/observation.rs, docs/spec/SPEC-0009-wasm-abi-v3.md c7aa63e contract_query_identity_changes_when_plan_query_vars_or_basis_change Observation artifacts now use version 3 and echo:observation-artifact:v3, with a regression proving v2-domain hashes no longer match.
Public WASM ABI response shape changed without ABI bump P1 crates/echo-wasm-abi/src/kernel_port.rs, crates/warp-wasm/README.md c7aa63e kernel_port_abi_version_tracks_reading_envelope_contract_fields; registry_info_has_abi_version ABI_VERSION is now 11 and registry info reports the updated ABI.
Optional ReadingEnvelope contract/query fields lacked legacy defaults P2 crates/echo-wasm-abi/src/kernel_port.rs, crates/echo-wasm-abi/src/lib.rs c7aa63e test_optic_read_identity_round_trip Legacy CBOR reading envelopes with omitted optional fields decode to None.
v0.1 retention status overclaimed complete retained refs/obstructions P3 docs/design/v0.1.0-release-plan.md c7aa63e markdownlint-cli2; lint-dead-refs Release plan now splits implemented RetainedBlobIndex pieces from remaining retained refs, missing-retention obstruction, and durable recovery work.

Verification run locally:

  • cargo test -p echo-wasm-abi kernel_port_abi_version_tracks_reading_envelope_contract_fields
  • cargo test -p echo-wasm-abi test_optic_read_identity_round_trip
  • cargo test -p warp-core --lib contract_query_identity_changes_when_plan_query_vars_or_basis_change
  • cargo test -p warp-wasm --features engine --lib registry_info_has_abi_version
  • cargo clippy -p echo-wasm-abi --lib --tests -- -D warnings
  • cargo clippy -p warp-core --lib -- -D warnings
  • cargo fmt --check
  • git diff --check
  • pnpm exec markdownlint-cli2 CHANGELOG.md crates/warp-wasm/README.md docs/spec/SPEC-0009-wasm-abi-v3.md docs/design/v0.1.0-release-plan.md
  • cargo xtask lint-dead-refs --file CHANGELOG.md --file crates/warp-wasm/README.md --file docs/spec/SPEC-0009-wasm-abi-v3.md --file docs/design/v0.1.0-release-plan.md
  • pre-push narrowed exact Rust slices: echo-wasm-abi --lib, warp-core --lib observation::tests, plus Prettier check

@chatgpt-codex-connector
Copy link
Copy Markdown

Summary

Testing

  • cd /workspace/echo && git status --short && git log --oneline -n 8
  • cd /workspace/echo && rg -n "OBSERVATION_VERSION|OBSERVATION_ARTIFACT_DOMAIN|ABI_VERSION|serde\\(default\\)|SemanticCoordinateConflict|missing_semantic_coordinate_takes_precedence" crates/warp-core/src/observation.rs crates/echo-wasm-abi/src/kernel_port.rs crates/echo-wasm-abi/src/lib.rs crates/echo-cas/src/lib.rs crates/echo-cas/tests/semantic_retention.rs docs/spec/SPEC-0009-wasm-abi-v3.md docs/design/v0.1.0-release-plan.md crates/warp-wasm/README.md

View task →

@flyingrobots
Copy link
Copy Markdown
Owner Author

Code Lawyer pass complete. No new branch-caused self-audit issues were found. All previously unresolved review threads are resolved against pushed commits.

Issue Severity Source File Addressed by Outcome
Same-coordinate retention remapped content and left unreachable pins P1 PR thread PRRT_kwDOQH8Wr86EHEIT crates/echo-cas/src/retention.rs 021dc59 Same-coordinate/different-content writes now return SemanticCoordinateConflict; same-coordinate/same-content is idempotent.
Coordinate overwrite could leave superseded pinned roots P2 PR thread PRRT_kwDOQH8Wr86EG_bo crates/echo-cas/src/retention.rs 021dc59 Coordinate overwrites are no longer permitted, eliminating the superseded-root path.
load_range reported budget before missing semantic coordinate P2 PR thread PRRT_kwDOQH8Wr86EHEIW crates/echo-cas/src/retention.rs 021dc59 load_range resolves the semantic coordinate first, then applies range/budget checks.
BEARING contradicted completed contract evidence/readings work P3 PR thread PRRT_kwDOQH8Wr86EHEIa docs/BEARING.md 021dc59 Stale “not yet true” wording now distinguishes completed local proof from remaining product/API/durable work.
Observation hash input changed without artifact contract bump P1 PR thread PRRT_kwDOQH8Wr86EIoGQ crates/warp-core/src/observation.rs c7aa63e Observation artifacts now use version 3 and echo:observation-artifact:v3, with regression coverage against the old domain.
Public ReadingEnvelope ABI shape changed without ABI bump P1 PR thread PRRT_kwDOQH8Wr86EIoGR crates/echo-wasm-abi/src/kernel_port.rs c7aa63e ABI_VERSION is now 11; legacy omitted optional fields decode to None; docs/spec/changelog updated.

Verification evidence remains the pushed local run set from c7aa63e, plus this pass confirmed git diff --check, clean worktree, zero unresolved review threads, and green GitHub checks except CodeRabbit still in progress.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/warp-core/src/coordinator.rs (1)

1497-1508: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject same-id replays when contract differs.

This duplicate path is now too weak for the new record shape. ticketed_ingress_id does not include contract, and the duplicate check never compares it, so the first staged value wins silently. A submission first staged with None and later staged through ingest_installed_contract_invocation() will keep the wrong record and propagate missing/stale contract evidence into ReceiptCorrelationRecord.

Suggested fix
         if let Some(existing_id) = self
             .ticketed_runtime_ingress_by_submission
             .get(&submission_id)
             .copied()
         {
             let Some(record) = self.ticketed_runtime_ingress.get(&existing_id).cloned() else {
                 return Err(RuntimeError::TicketedIngressAlreadyStaged(submission_id));
             };
             if existing_id == ticketed_ingress_id {
+                if record.contract != contract {
+                    return Err(RuntimeError::TicketedIngressAlreadyStaged(submission_id));
+                }
                 return Ok(TicketedRuntimeIngressDisposition::Duplicate { record });
             }
             return Err(RuntimeError::TicketedIngressAlreadyStaged(submission_id));
         }
🤖 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 `@crates/warp-core/src/coordinator.rs` around lines 1497 - 1508, The current
duplicate-path only compares IDs (existing_id vs ticketed_ingress_id) and so
allows replayed submissions with the same id but different contract to silently
win; update the logic in the block that looks up
self.ticketed_runtime_ingress_by_submission / self.ticketed_runtime_ingress to
also compare the existing record's contract with the incoming record's contract
(the new record created by ingest_installed_contract_invocation path) and treat
any mismatch as a conflict by returning
Err(RuntimeError::TicketedIngressAlreadyStaged(submission_id)); specifically,
when you fetch record (bound to record) and before returning
TicketedRuntimeIngressDisposition::Duplicate { record }, check record.contract
(or the appropriate contract field on the incoming record) and if they differ,
return the same error instead of Ok::Duplicate so stale/missing contract
evidence cannot be propagated into ReceiptCorrelationRecord.
🤖 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 `@crates/echo-cas/src/retention.rs`:
- Around line 148-158: The current retain path always calls store.put(bytes)
even when self.descriptors already maps coordinate to the same content, causing
redundant hashing/writes; modify the block handling if let Some(existing) =
self.descriptors.get(&coordinate) so that when existing.content_hash ==
content_hash and existing.byte_len == bytes.len() as u64 you skip store.put and
only call store.pin(&content_hash) and return Ok(existing.clone()), and keep the
SemanticCoordinateConflict error branch unchanged for mismatches; locate and
update the code around self.descriptors, existing, content_hash, bytes,
store.put, store.pin to short-circuit the idempotent case.

In `@crates/warp-core/src/observation.rs`:
- Around line 2103-2110: The current basis_digest computation encodes full ABIs
from resolved.to_abi() and parent_basis_posture.to_abi(), which include
freshness like observed_after_global_tick and breaks stable-question identity;
instead serialize and hash only the causal-basis fields (exclude
observed_after_global_tick/freshness) before push_len_prefixed. Modify the code
around resolved.to_abi() and parent_basis_posture.to_abi() so you either call a
helper that returns a causal-only ABI (e.g., to_causal_abi or
strip_freshness_from_abi) or clone and clear observed_after_global_tick from the
structs, then encode_cbor those causal-only objects and feed them to the hasher
with QUERY_READING_BASIS_DOMAIN to produce the basis_digest.

---

Outside diff comments:
In `@crates/warp-core/src/coordinator.rs`:
- Around line 1497-1508: The current duplicate-path only compares IDs
(existing_id vs ticketed_ingress_id) and so allows replayed submissions with the
same id but different contract to silently win; update the logic in the block
that looks up self.ticketed_runtime_ingress_by_submission /
self.ticketed_runtime_ingress to also compare the existing record's contract
with the incoming record's contract (the new record created by
ingest_installed_contract_invocation path) and treat any mismatch as a conflict
by returning Err(RuntimeError::TicketedIngressAlreadyStaged(submission_id));
specifically, when you fetch record (bound to record) and before returning
TicketedRuntimeIngressDisposition::Duplicate { record }, check record.contract
(or the appropriate contract field on the incoming record) and if they differ,
return the same error instead of Ok::Duplicate so stale/missing contract
evidence cannot be propagated into ReceiptCorrelationRecord.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ffef2b57-94ca-4c7d-b628-93e446ff0373

📥 Commits

Reviewing files that changed from the base of the PR and between 1d29edd and c7aa63e.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (32)
  • CHANGELOG.md
  • crates/echo-cas/src/lib.rs
  • crates/echo-cas/src/retention.rs
  • crates/echo-cas/tests/semantic_retention.rs
  • crates/echo-wasm-abi/src/kernel_port.rs
  • crates/echo-wasm-abi/src/lib.rs
  • crates/echo-wesley-gen/tests/generation.rs
  • crates/warp-core/Cargo.toml
  • crates/warp-core/src/contract_registry.rs
  • crates/warp-core/src/coordinator.rs
  • crates/warp-core/src/engine_impl.rs
  • crates/warp-core/src/lib.rs
  • crates/warp-core/src/observation.rs
  • crates/warp-core/src/optic/tests.rs
  • crates/warp-core/tests/installed_contract_intent_pipeline_tests.rs
  • crates/warp-core/tests/installed_contract_registry_tests.rs
  • crates/warp-wasm/README.md
  • crates/warp-wasm/src/lib.rs
  • crates/warp-wasm/src/warp_kernel.rs
  • docs/BEARING.md
  • docs/design/v0.1.0-contract-artifact-retention-in-echo-cas.md
  • docs/design/v0.1.0-contract-aware-receipts-and-readings.md
  • docs/design/v0.1.0-contract-reading-identity-and-bounded-payloads.md
  • docs/design/v0.1.0-contract-retention-and-semantic-lookup-seams.md
  • docs/design/v0.1.0-external-contract-proof-fixture.md
  • docs/design/v0.1.0-release-plan.md
  • docs/method/backlog/v0.1.0/KERNEL_contract-aware-receipts-and-readings.md
  • docs/method/backlog/v0.1.0/KERNEL_contract-reading-identity-and-bounded-payloads.md
  • docs/method/backlog/v0.1.0/PLATFORM_contract-artifact-retention-in-echo-cas.md
  • docs/method/backlog/v0.1.0/PLATFORM_contract-retention-and-semantic-lookup-seams.md
  • docs/method/backlog/v0.1.0/PLATFORM_external-contract-proof-fixture.md
  • docs/spec/SPEC-0009-wasm-abi-v3.md

Comment on lines +148 to +158
if let Some(existing) = self.descriptors.get(&coordinate) {
if existing.content_hash != content_hash || existing.byte_len != bytes.len() as u64 {
return Err(RetentionError::SemanticCoordinateConflict {
coordinate: Box::new(coordinate),
existing_content_hash: existing.content_hash,
new_content_hash: content_hash,
});
}
store.put(bytes);
store.pin(&content_hash);
return Ok(existing.clone());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Avoid unconditional put on idempotent retain path.

When the coordinate already maps to the same content, Line 156 still recomputes/stores bytes. This creates avoidable hashing/write work on repeated retains.

Suggested patch
         if let Some(existing) = self.descriptors.get(&coordinate) {
             if existing.content_hash != content_hash || existing.byte_len != bytes.len() as u64 {
                 return Err(RetentionError::SemanticCoordinateConflict {
                     coordinate: Box::new(coordinate),
                     existing_content_hash: existing.content_hash,
                     new_content_hash: content_hash,
                 });
             }
-            store.put(bytes);
+            if !store.has(&existing.content_hash) {
+                let restored_hash = store.put(bytes);
+                debug_assert_eq!(restored_hash, existing.content_hash);
+            }
             store.pin(&content_hash);
             return Ok(existing.clone());
         }
🤖 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 `@crates/echo-cas/src/retention.rs` around lines 148 - 158, The current retain
path always calls store.put(bytes) even when self.descriptors already maps
coordinate to the same content, causing redundant hashing/writes; modify the
block handling if let Some(existing) = self.descriptors.get(&coordinate) so that
when existing.content_hash == content_hash and existing.byte_len == bytes.len()
as u64 you skip store.put and only call store.pin(&content_hash) and return
Ok(existing.clone()), and keep the SemanticCoordinateConflict error branch
unchanged for mismatches; locate and update the code around self.descriptors,
existing, content_hash, bytes, store.put, store.pin to short-circuit the
idempotent case.

Comment on lines +2103 to +2110
let resolved_bytes = echo_wasm_abi::encode_cbor(&resolved.to_abi())
.map_err(|err| ObservationError::CodecFailure(err.to_string()))?;
let posture_bytes = echo_wasm_abi::encode_cbor(&parent_basis_posture.to_abi())
.map_err(|err| ObservationError::CodecFailure(err.to_string()))?;
let mut hasher = Hasher::new();
hasher.update(QUERY_READING_BASIS_DOMAIN);
push_len_prefixed(&mut hasher, &resolved_bytes);
push_len_prefixed(&mut hasher, &posture_bytes);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Exclude freshness metadata from basis_digest.

resolved.to_abi() includes observed_after_global_tick, so the same QueryView against the same resolved commit can produce a different query_identity.reading_id after unrelated runtime progress. That breaks the stable-question identity contract. Hash only causal basis fields here, and add a regression that advances the runtime global tick without changing the observed commit.

As per coding guidelines, crates/warp-core/** is the deterministic kernel and every non-determinism risk must be flagged.

🤖 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 `@crates/warp-core/src/observation.rs` around lines 2103 - 2110, The current
basis_digest computation encodes full ABIs from resolved.to_abi() and
parent_basis_posture.to_abi(), which include freshness like
observed_after_global_tick and breaks stable-question identity; instead
serialize and hash only the causal-basis fields (exclude
observed_after_global_tick/freshness) before push_len_prefixed. Modify the code
around resolved.to_abi() and parent_basis_posture.to_abi() so you either call a
helper that returns a causal-only ABI (e.g., to_causal_abi or
strip_freshness_from_abi) or clone and clear observed_after_global_tick from the
structs, then encode_cbor those causal-only objects and feed them to the hasher
with QUERY_READING_BASIS_DOMAIN to produce the basis_digest.

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