Skip to content

feat(add): let the caller name the artifact via --id (REQ-007, #880) - #899

Open
avrabe wants to merge 1 commit into
mainfrom
fix/issue-880-add-id-flag
Open

feat(add): let the caller name the artifact via --id (REQ-007, #880)#899
avrabe wants to merge 1 commit into
mainfrom
fix/issue-880-add-id-flag

Conversation

@avrabe

@avrabe avrabe commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Closes #880.

rivet add chose the ID itself and offered no way to say what it should be. In varve — 89 distinct requirement prefixes, all descriptive of what the requirement is about — that landed a graph-wide release-packaging requirement as REQ-PIN-003 twice in one session. Title, tags, target file, and --field id= all made no difference to the derivation, so the documented workaround was to hand-edit the id: line the tool had just written — which is the thing the project's own guidance forbids.

What this changes

--id <ID> on rivet add. The caller asserts the ID, the tool shape-validates it up front and, via the existing validate_add, rejects a duplicate before any file is written. Without --id, the derived-next-in-series behavior is unchanged (regression-guarded by test 4 below).

Shape

PREFIX-NNN — the convention every existing artifact already follows (REQ-DRV-COMPONENT-001, VER-OS-WCET-001, FIND-DMA-SHM-CANONICAL-001):

  • uppercase alphanumeric segments, dash-separated
  • ends with a numeric suffix after the last dash
  • non-empty prefix carrying at least one uppercase letter
  • no leading/trailing dashes, no --

Acceptance criteria — #880

Only the ask labelled (1) is addressed here — avrabe stated "That alone closes it."

  • --id on rivet add, validated for uniqueness and shape. — Uniqueness reuses validate_add's existing check (same message a duplicate hand-edit would produce); shape validated by a new validate_explicit_id in rivet-cli/src/main.rs.
  • --prefix on next-id and add — deliberately out of scope; would fit a follow-up.
  • ID-scheme setting in rivet.yaml — out of scope for the smallest-fix path avrabe asked for.

Ask (2) and (3) from #887 (add rejects --field id=; next-id preserves hyphens) are separate PRs — one PR per issue.

Tests (rivet-cli/tests/cli_commands.rs)

Four new integration tests, one per face of the contract:

  • add_id_flag_honors_explicit_id--id REQ-DRV-GRAPH-001 on a repo whose existing series is REQ-PIN-* writes the caller's ID, not a derived one.
  • add_id_flag_rejects_duplicate_id — colliding ID fails with the existing "already exists" message; no second block is appended.
  • add_id_flag_rejects_malformed_ids — nine ill-shaped inputs are refused with actionable messages (invalid character, leading/trailing dash, double dash, missing numeric suffix, digits-only prefix).
  • add_without_id_still_derives_next_in_series — default path still returns the next ID in the existing series (REQ-PIN-002); regression guard so the shape check does not fire on derived IDs.

Gates

  • cargo fmt --all -- --check
  • cargo clippy --all-targets -- -D warnings ✅ (no error: lines; only the pre-existing MSRV meta-warning)
  • cargo test --workspace ✅ (all binaries green, including the four new tests)
  • rivet validate ✅ (Result: PASS, unchanged from base — 775 pre-existing warnings)

🤖 Generated with Claude Code

https://claude.ai/code/session_018ozkqbJopvcKoycPR8zHEW


Generated by Claude Code

`rivet add` chose the ID itself and offered no way to say what it should
be. In varve — 89 distinct requirement prefixes, all descriptive of what
the requirement is about — that landed a graph-wide release-packaging
requirement as `REQ-PIN-003` twice in one session. Title, tags, target
file, and `--field id=` all made no difference to the derivation, so the
documented workaround was to hand-edit the `id:` line the tool had just
written — which is the thing the project's own guidance forbids.

`--id <ID>` closes that path: the caller asserts the ID, the tool
shape-validates it up front and, via the existing `validate_add`, rejects
a duplicate before any file is written. Shape is `PREFIX-NNN` — the
convention every existing artifact already follows (`REQ-DRV-COMPONENT-001`,
`FIND-DMA-SHM-CANONICAL-001`): uppercase alphanumeric segments dash-
separated, ending with a numeric suffix, non-empty prefix carrying at
least one letter. Without `--id`, the derived-next-in-series behavior is
unchanged.

Tests cover the four faces of the contract in one place:
- explicit id is honored verbatim (and no derived id is picked instead);
- a colliding id is refused with the existing "already exists" message,
  no second block appended;
- nine malformed ids are refused with actionable messages;
- the default path still returns the next id in the existing series.

Only #880's ask (1) is addressed here. #887's asks (2) and (3) — reject
`--field id=` naming a first-class field, and preserve hyphens through
`next-id` — are separate PRs.

Closes #880.

Implements: REQ-007
Verifies: REQ-007

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ozkqbJopvcKoycPR8zHEW
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

📐 Rivet artifact delta

No artifact changes in this PR. Code-only changes (renderer, CLI wiring, tests) don't touch the artifact graph.

@codecov

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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.

add assigns an ID that ignores the repo's own prefix convention, and there is no --id

2 participants