Skip to content

feat(add): rivet add stamps AI provenance at creation (REQ-203, closes #476)#477

Merged
avrabe merged 2 commits into
mainfrom
feat/req-203-rivet-add-provenance
Jun 5, 2026
Merged

feat(add): rivet add stamps AI provenance at creation (REQ-203, closes #476)#477
avrabe merged 2 commits into
mainfrom
feat/req-203-rivet-add-provenance

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Jun 5, 2026

Closes #476. From the hourly dogfooding loop — a friction I hit filing REQ-202, then traced to a correctness gap.

The gap

The AI-provenance system was wired to the editor, not to rivet's own mutation commands, so the sanctioned creation path produced unstamped artifacts:

Path Stamped?
Edit/Write tool on artifacts/** (fires the .claude/settings.json hook)
cat >> / heredoc append (a Bash call)
rivet add (cmd_add built the Artifact with provenance: None)

For a tool whose pitch is AI-artifact auditability, AI-created artifacts silently missing provenance is a correctness gap — and the recommended tool was the one that dropped it.

Compounding bug caught while implementing

mutate::render_artifact_yaml — the single serializer for the add path — did not emit the provenance block at all. So just setting artifact.provenance = Some(..) would have been a silent no-op (the exact REQ-196/REQ-200 class of bug). I verified against the written file, not the struct, and fixed both halves.

Fix

  • rivet add gains --created-by <human|ai|ai-assisted> and --model <M>; --created-by falls back to the RIVET_PROVENANCE_CREATED_BY env var so CI/agent environments set it once. Value validated up front (before project load). Absent ⇒ no block (prior behavior preserved).
  • Extract current_utc_timestamp(), shared by cmd_stamp and cmd_add, so both emit identical ISO-8601 timestamps (no chrono dep).
  • render_artifact_yaml now emits the provenance: block (field order matches yaml_edit::set_provenance).

Verification

  • Unit (rivet-core): render_artifact_yaml_emits_provenance_when_present, render_artifact_yaml_omits_provenance_when_absent — both pass.
  • End-to-end on a fresh rivet init project: rivet add --created-by ai-assisted --model claude-opus-4-8 wrote the block; plain rivet add wrote none; RIVET_PROVENANCE_CREATED_BY=ai rivet add stamped from env; --created-by robot errored; rivet validate PASS.
  • cargo fmt --all -- --check exit 0 · cargo clippy --all-targets -- -D warnings exit 0 (only the pre-existing MSRV-config warning).

Implements + Verifies REQ-203.

🤖 Generated with Claude Code

…dd serializer (REQ-203)

Closes #476. The AI-provenance system was wired to the editor, not to rivet's
own mutation commands, so the sanctioned creation path produced UNSTAMPED
artifacts: cmd_add built the Artifact with `provenance: None`, and the
.claude/settings.json stamp hook only matches Edit/Write — a heredoc append or
`rivet add` (both Bash calls) never fired it. For a tool whose pitch is
AI-artifact auditability, AI-created artifacts silently missing provenance is a
correctness gap.

Compounding bug caught during implementation: `mutate::render_artifact_yaml`
(the single serializer for the add path) did NOT emit the `provenance` block at
all, so merely setting `artifact.provenance` would have been a silent no-op (the
REQ-196/200 class of bug). Both halves are fixed:

- `rivet add` gains `--created-by <human|ai|ai-assisted>` and `--model <M>`;
  `--created-by` falls back to the RIVET_PROVENANCE_CREATED_BY env var so
  CI/agent environments can set it once. Value validated up front. Absent =>
  no provenance block (prior behavior preserved).
- Extract `current_utc_timestamp()`, shared by cmd_stamp and cmd_add, so both
  emit identical ISO-8601 timestamps with no chrono dependency.
- `render_artifact_yaml` now emits the `provenance:` block (field order matches
  yaml_edit::set_provenance).

Tests (rivet-core): render_artifact_yaml_emits_provenance_when_present and
render_artifact_yaml_omits_provenance_when_absent.

Confirmed with: cargo test -p rivet-core --lib render_artifact_yaml_ (4 passed);
end-to-end on a fresh `rivet init` project — `rivet add --created-by ai-assisted
--model claude-opus-4-8` wrote the provenance block, plain add wrote none,
RIVET_PROVENANCE_CREATED_BY=ai stamped from env, --created-by robot errored,
rivet validate PASS; cargo fmt --all -- --check (exit 0); cargo clippy
--all-targets -- -D warnings (exit 0, only pre-existing MSRV-config warning).

Implements: REQ-203
Verifies: REQ-203
Refs: REQ-007
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 5, 2026

📐 Rivet artifact delta

Change Count
Added 1
Removed 0
Modified 0
Downstream impacted (depth ≤ 5) 0

Graph

graph LR
  REQ_203["REQ-203"]:::added
  classDef added fill:#d4edda,stroke:#28a745,color:#155724
  classDef removed fill:#f8d7da,stroke:#dc3545,color:#721c24
  classDef modified fill:#fff3cd,stroke:#ffc107,color:#856404
  classDef overflow fill:#e2e3e5,stroke:#6c757d,color:#495057,stroke-dasharray: 3 3
Loading
Added
  • REQ-203

📎 Full HTML dashboard attached as workflow artifact rivet-delta-pr-477download from the workflow run.

Posted by rivet-delta workflow. The graph shows only changed artifacts; open the HTML dashboard (above) for full context.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

❌ Patch coverage is 95.65217% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
rivet-core/src/mutate.rs 95.65% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit 6f12e0f into main Jun 5, 2026
18 of 19 checks passed
@avrabe avrabe deleted the feat/req-203-rivet-add-provenance branch June 5, 2026 19:29
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Rivet Criterion Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 545376b Previous: 531f4f3 Ratio
store_insert/100 85014 ns/iter (± 288) 67153 ns/iter (± 676) 1.27
store_insert/1000 916162 ns/iter (± 6413) 736228 ns/iter (± 4489) 1.24
store_insert/10000 18030365 ns/iter (± 801889) 11632774 ns/iter (± 386214) 1.55
store_lookup/100 2120 ns/iter (± 9) 1532 ns/iter (± 7) 1.38
store_lookup/1000 27331 ns/iter (± 158) 18605 ns/iter (± 186) 1.47
store_lookup/10000 374782 ns/iter (± 2114) 262385 ns/iter (± 1625) 1.43
store_by_type/100 93 ns/iter (± 0) 75 ns/iter (± 0) 1.24
store_by_type/1000 93 ns/iter (± 1) 75 ns/iter (± 0) 1.24
store_by_type/10000 93 ns/iter (± 0) 75 ns/iter (± 0) 1.24
schema_load_and_merge 1463144 ns/iter (± 27658) 1108652 ns/iter (± 21999) 1.32
link_graph_build/100 162384 ns/iter (± 1263) 127912 ns/iter (± 1896) 1.27
link_graph_build/1000 1931586 ns/iter (± 66341) 1478194 ns/iter (± 19920) 1.31
link_graph_build/10000 40494963 ns/iter (± 2876408) 21634013 ns/iter (± 2533368) 1.87
validate/100 463293 ns/iter (± 5203) 338291 ns/iter (± 790) 1.37
validate/1000 17661270 ns/iter (± 190084) 13279552 ns/iter (± 215097) 1.33
validate/10000 1472473051 ns/iter (± 26992588) 1059688941 ns/iter (± 7886956) 1.39
traceability_matrix/100 4292 ns/iter (± 56) 3225 ns/iter (± 8) 1.33
traceability_matrix/1000 59422 ns/iter (± 184) 40497 ns/iter (± 495) 1.47
traceability_matrix/10000 739753 ns/iter (± 2845) 578239 ns/iter (± 3030) 1.28
diff/100 59111 ns/iter (± 1328) 48159 ns/iter (± 1810) 1.23
diff/1000 698281 ns/iter (± 21674) 514423 ns/iter (± 2954) 1.36
diff/10000 7746274 ns/iter (± 271083) 6054584 ns/iter (± 53019) 1.28
query/100 1195 ns/iter (± 5) 917 ns/iter (± 4) 1.30
query/1000 16001 ns/iter (± 436) 11897 ns/iter (± 156) 1.34
query/10000 346197 ns/iter (± 2419) 177307 ns/iter (± 1380) 1.95
document_parse/10 23862 ns/iter (± 1059) 17375 ns/iter (± 112) 1.37
document_parse/100 174256 ns/iter (± 1613) 125481 ns/iter (± 934) 1.39
document_parse/1000 1588603 ns/iter (± 8581) 1158417 ns/iter (± 14629) 1.37

This comment was automatically generated by workflow using github-action-benchmark.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant