8000 Phase 6g: bind source records to verified portable content by Mnehmos · Pull Request #72 · Mnehmos/MathOS · GitHub
[go: up one dir, main page]

Skip to content

Phase 6g: bind source records to verified portable content - #72

Merged
Mnehmos merged 2 commits into
mainfrom
feat/71-source-content-closure
Jul 25, 2026
Merged

Mnehmos merged 2 commits into
mainfrom
feat/71-source-content-closure

Conversation

@Mnehmos
@Mnehmos Mnehmos commented Jul 25, 2026 •
Copy link
Copy Markdown
Owner

Closes #71

Summary

  • Require every non-null source/1.content_hash to resolve to registered, byte-verified CAS content with reviewed source_content provenance and compatible license/restriction metadata before CLI/MCP dry-run, persistence, or exact retry.
  • Add migration 0013 so direct SQL inserts and invalid legacy bindings fail closed instead of receiving silent trust promotion.
  • Carry retained source bytes and metadata exactly once into portable releases, and independently recheck their path, identity, bytes, and policy without SQLite.
  • Reject Windows junction/reparse-point escapes in artifact CAS and release trees.
  • Pin the BH Pilot C repository-source fixture to upstream commit 8875bef812375d7e6fd00bff95764cd5c057c7fe, tree 600f3e1230ca88f9784837933e2417c319aaad3e, Git blob c7e3805ab78327f1cd561421e2c0168a009eb161, SHA-256 249f62a4e2780235239cf9f4e781f274f8dadba7f3aeba3aab51f46b0a6fc5c5.

The issue's earlier c8209676... digest was the CRLF rendering from a Windows checkout. A direct gh api content read establishes the 1,809-byte Git object above as the platform-independent portable identity.

Trust boundary

This preserves content_hash: null and the existing source/1 schema bytes. Exact source retention creates no paper correspondence, fidelity, Lean-kernel, Comparator, mathematical-status, definition, reuse, coverage, or contribution authority; Pilot C remains incomplete.

Validation

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace (191 library, 1 default Lean-worker, 4 MCP, 21 CLI)
  • MCL_RUN_LEAN_INTEGRATION=1 cargo test --test lean_worker -- --nocapture
  • legacy Python compileall and 39 unittest cases
  • bash -n scripts/publication-candidate.sh
  • ShellCheck 0.11.0 at warning severity
  • actionlint 1.7.12
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Added verified source-content handling, requiring source hashes to resolve to matching, policy-compatible artifacts.
    • Portable releases now include and validate retained source artifacts and metadata.
    • Added a pinned formalization source fixture with licensing and attribution information.
  • Bug Fixes

    • Improved protection against unsafe symbolic links and Windows reparse points.
    • Invalid, missing, altered, or unavailable source artifacts now fail validation consistently.
    • Database migrations reject incompatible existing source bindings.
  • Documentation

    • Added decision records and trust guidance describing source-content verification and release validation.

8000
@coderabbitai
coderabbitai Bot commented Jul 25, 2026 •
Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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

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

How do review limits work?

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

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

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5714aaa6-0e4f-4ee2-a220-07c79262fa0f

📥 Commits

Reviewing files that changed from the base of the PR and between d1548fa and 433ec58.

📒 Files selected for processing (3)
  • src/app.rs
  • src/artifacts/mod.rs
  • src/release.rs
📝 Walkthrough

Walkthrough

The PR binds non-null source/1.content_hash values to verified CAS bytes and compatible metadata, enforces the rule during mutations and migration, includes source artifacts in portable releases, strengthens offline validation, adds a pinned BH fixture, and rejects symlink or Windows reparse-point traversal.

Changes

Source-content closure

Layer / File(s) Summary
Source contract and conformance fixture
docs/decisions/..., docs/trust/*, docs/implementation/*, fixtures/bh_formalization/*, .gitattributes
Documents verified source bindings and adds the pinned BH source-lock, licensing, notice, and line-ending fixture.
Mutation validation and database enforcement
src/domain/schemas.rs, src/app.rs, migrations/0013_source_content_closure.sql, src/store/mod.rs, tests/mcp_stdio.rs, tests/phase1_cli.rs, scripts/publication-candidate.sh
Validates source hashes, CAS bytes, provenance, licensing, and restrictions during create/version/retry paths and through migration-level SQL enforcement.
Portable release closure and verification
src/app.rs, src/release.rs, docs/trust/RELEASES.md
Includes source artifacts in release inventories and validates their identities and metadata during semantic and offline closure checks.
Cross-platform artifact path safety
src/artifacts/mod.rs, src/release.rs
Treats symlinks and Windows reparse points as unsafe across artifact access, materialization, scanning, and release inventory traversal.

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

Possibly related issues

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant App
  participant ArtifactStore
  participant Store
  participant ReleaseBuilder
  participant OfflineVerifier
  Client->>App: submit source create or version
  App->>ArtifactStore: verify CAS bytes and source metadata
  App->>Store: persist validated source record
  ReleaseBuilder->>Store: collect source content_hash
  ReleaseBuilder->>ArtifactStore: include exact source artifact
  OfflineVerifier->>ReleaseBuilder: validate artifact inventory and metadata
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed It clearly summarizes the main change: binding source records to verified portable content.
Description check ✅ Passed It includes the summary, trust boundary, and validation, but doesn't fully populate the template's evidence and risk sections.
Linked Issues check ✅ Passed The PR implements #71's source-content validation, migration guard, release closure, offline verification, and pinned fixture requirements.
Out of Scope Changes check ✅ Passed The added docs, migration, tests, and path-safety fixes all support the source-content binding work; no unrelated changes stand out.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/71-source-content-closure

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.

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

Caution

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

⚠️ Outside diff range comments (1)
src/artifacts/mod.rs (1)

26-31: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Error text still says "symbolic link" although reparse points are now rejected.

src/release.rs updated its parallel messages to "links or reparse points"; these two remain symlink-only, so a Windows operator hitting a junction gets a misleading diagnostic.

📝 Proposed wording fix
             return Err(AppError::new(
                 "MCL_ARTIFACT_ROOT_UNSAFE",
-                "artifact root may not be a symbolic link",
+                "artifact root may not be a link or reparse point",
                 false,
                 "Configure a real directory under the instance root.",
             ));
                 return Err(AppError::new(
                     "MCL_ARTIFACT_PATH_UNSAFE",
                     format!(
-                        "symbolic link is forbidden in artifact path: {}",
+                        "link or reparse point is forbidden in artifact path: {}",
                         current.display()
                     ),

Also applies to: 285-293

🤖 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 `@src/artifacts/mod.rs` around lines 26 - 31, Update both
MCL_ARTIFACT_ROOT_UNSAFE error messages in the artifact-root validation flow to
describe rejection of links or reparse points, matching the wording used in
src/release.rs; leave the error code and remediation guidance unchanged.
🧹 Nitpick comments (2)
src/app.rs (1)

9724-9803: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant no-op restore write before the substitution test.

Lines 9732-9736 rewrite the exact BH bytes, but they're immediately overwritten by the substituted-bytes write on the next line with no assertion between them — the "restore" has no observable effect and reads as if it verifies something it doesn't.

♻️ Suggested cleanup
-        fs::write(
-            &restarted_bh_artifact,
-            include_bytes!("../fixtures/bh_formalization/SOURCE-LOCK.md"),
-        )
-        .expect("exact BH source bytes restore");
         fs::write(&restarted_bh_artifact, b"substituted source bytes")
             .expect("test substitutes copied BH source bytes");
🤖 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 `@src/app.rs` around lines 9724 - 9803, Remove the redundant fs::write call
that restores SOURCE-LOCK.md immediately before the substitution write in the
restarted bundle integrity test. Keep the initial restoration needed after the
missing-artifact check and preserve the substituted-bytes assertion and
subsequent exact restoration.
src/artifacts/mod.rs (1)

327-341: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

is_link_or_reparse is duplicated byte-for-byte in two modules. Both copies define the same Windows reparse-point predicate, including the local FILE_ATTRIBUTE_REPARSE_POINT constant. As a security boundary check, the two can silently drift if only one is later hardened (for example to cover mount points or non-regular entries).

  • src/artifacts/mod.rs#L327-L341: keep this as the single definition, or move it to a shared path-safety module, and export it for reuse.
  • src/release.rs#L1348-L1362: delete the local copy and import the shared helper instead.
🤖 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 `@src/artifacts/mod.rs` around lines 327 - 341, The is_link_or_reparse security
predicate is duplicated across two modules and must have a single reusable
definition. In src/artifacts/mod.rs lines 327-341, retain or move
is_link_or_reparse to a shared path-safety module and export it; in
src/release.rs lines 1348-1362, remove the local copy and import and use the
shared helper instead.
🤖 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.

Outside diff comments:
In `@src/artifacts/mod.rs`:
- Around line 26-31: Update both MCL_ARTIFACT_ROOT_UNSAFE error messages in the
artifact-root validation flow to describe rejection of links or reparse points,
matching the wording used in src/release.rs; leave the error code and
remediation guidance unchanged.

---

Nitpick comments:
In `@src/app.rs`:
- Around line 9724-9803: Remove the redundant fs::write call that restores
SOURCE-LOCK.md immediately before the substitution write in the restarted bundle
integrity test. Keep the initial restoration needed after the missing-artifact
check and preserve the substituted-bytes assertion and subsequent exact
restoration.

In `@src/artifacts/mod.rs`:
- Around line 327-341: The is_link_or_reparse security predicate is duplicated
across two modules and must have a single reusable definition. In
src/artifacts/mod.rs lines 327-341, retain or move is_link_or_reparse to a
shared path-safety module and export it; in src/release.rs lines 1348-1362,
remove the local copy and import and use the shared helper instead.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a70e673d-a0b9-4ce0-8d24-bb728f7811a2

📥 Commits

Reviewing files that changed from the base of the PR and between 348f9ab and d1548fa.

📒 Files selected for processing (20)
  • .gitattributes
  • docs/decisions/ADR-0017-source-content-is-a-verified-portable-binding.md
  • docs/implementation/RELEASE_CHECKLIST.md
  • docs/implementation/STATUS.md
  • docs/trust/ARTIFACTS.md
  • docs/trust/RELEASES.md
  • docs/trust/SOURCES.md
  • fixtures/bh_formalization/LICENSE
  • fixtures/bh_formalization/NOTICE
  • fixtures/bh_formalization/README.md
  • fixtures/bh_formalization/SOURCE-LOCK.md
  • migrations/0013_source_content_closure.sql
  • scripts/publication-candidate.sh
  • src/app.rs
  • src/artifacts/mod.rs
  • src/domain/schemas.rs
  • src/release.rs
  • src/store/mod.rs
  • tests/mcp_stdio.rs
  • tests/phase1_cli.rs

@Mnehmos
Mnehmos commented Jul 25, 2026
Copy link
Copy Markdown
Owner Author

Addressed all three CodeRabbit findings in 433ec586c08a85d4069bde004031363cfb9f6c1d:

  • artifact diagnostics now name links and Windows reparse points;
  • is_link_or_reparse has one crate-shared implementation used by both CAS and release verification;
  • removed the no-op exact-byte write before the substitution probe.

Review-fix validation: format check, warnings-denied all-target Clippy, the Windows CAS-junction test, the database-free portable-release test, diff check.

@Mnehmos
Mnehmos merged commit a208205 into main Jul 25, 2026
6 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 25, 2026
19 of 25 tasks
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.

Phase 6g: bind source records to verified portable content for Pilot C

1 participant

0