Skip to content

docs(cross-org): cross-git investigation — findings + SEooC AoU register + change list as Rivet artifacts#304

Merged
avrabe merged 9 commits into
mainfrom
docs/cross-git-investigation
May 20, 2026
Merged

docs(cross-org): cross-git investigation — findings + SEooC AoU register + change list as Rivet artifacts#304
avrabe merged 9 commits into
mainfrom
docs/cross-git-investigation

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 19, 2026

Summary

Three coordinated outputs from the 2026-05-19 cross-git investigation
(six AI personas, ten scenarios, three test-bed repos under different
org identities). The investigation was triggered by the observation
that the cross-org features shipped progressively through v0.10.0
(#286 supplier MVP) and v0.10.1 (#292 federation handshake) had never
been exercised end-to-end across three independent git repositories.

  • docs/research/cross-git-repo-investigation.md — 11 findings,
    persona-converging carve-into-the-wall quotes, an SEooC
    safety-property + Assumptions-of-Use register, the architectural
    commitment question (delete externals: in favour of
    external-anchor?), the missing producer-side story, and a fair
    comparison to git-submodules and Google's repo tool.

  • docs/rivet-is-not.md — Cederqvist-style "Rivet is not..." doc
    in the ISO 26262-10 SEooC Safety Manual register the project has
    converged on. Eight categorical sub-sections, each grounded in a
    real Rivet operation and naming a concrete cliff.

  • artifacts/cross-git-investigation.yaml — the change list as
    Rivet artifacts (dogfooded, not filed as GitHub issues). One
    feature anchor (FEAT-135), one design decision (DD-067), eleven
    requirements (REQ-062 → REQ-072). Each cites file:line evidence in
    the test logs + persona reactions at /tmp/rivet-cross-git/.

The unanimous "carve into the wall" finding

F2 (P0)rivet validate reports PASS (0 warnings) when
every artifact file failed to parse. Six personas converge on this
as the disqualifying defect:

  • "If rivet validate can ever PASS while files in the project
    failed to parse, the tool is lying."
    — Pragmatic Multi-Repo
    Maintainer
  • "A green PASS over a parse that failed is the same defect as a
    green PASS over a safety case that failed — the only difference
    is the layer at which the lie originates."
    — TÜV Auditor
  • "If rivet validate ever skips a file, that is an error, not a
    stderr line under a green PASS."
    — First-Time User

The change list itself is its own oracle: running rivet validate
on this repo at HEAD reproduces F2 with 140 stderr-only WARNs
on bindings.yaml, feature-model.yaml, and the variant configs.
REQ-062 names the fix. Rivet's own validate lies about Rivet's own
codebase.

Other P0/P1 findings (full set: F1–F11 in the synthesis)

  • F1 (P1): rivet init --preset {do-178c, en-50128, iec-61508, iec-62304} silently produces unvalidatable projects. The four
    broken presets are exactly the safety-critical ones. (REQ-063)
  • F5 (P1): derives-from-external structured-target link
    (advertised in feat(supplier): Phase 2 — federation handshake + FederationProvenance (#288) #292) is silently parsed as derives-from with
    zero targets. (REQ-064)
  • F6 (P1): Warning propagation is OFF — consumer's validate
    does not surface supplier diagnostics. The SEooC AoU that most
    needs documenting. (REQ-065)
  • F7 (P2): Two parallel cross-repo systems with no documented
    relationship — the OSLC trajectory the Federation Architect
    persona warns against. Open architectural question in DD-067.
  • F8 (P2): rivet supplier pull silently overwrites on
    sha256 drift with exit 0 — "destructive operation masquerading
    as a fetch" (Auditor). (REQ-068)

Documentation register adopted

Per memory seooc-safety-manual-register, the project has converged
on Cederqvist 1993 "X is not..." × ISO 26262-10 SEooC Safety Manual
register for integrator-facing prose. The goal is that v1.0 Safety
Manual production becomes a translation pass on existing docs, not
an authoring pass. docs/rivet-is-not.md is the first explicit
instance.

Test bed (not committed; reproducible)

Test repos and logs preserved at /tmp/rivet-cross-git/:

  • Setup script: scripts/00-setup-repos.sh
  • Scenarios script: scripts/01-run-scenarios.sh
  • Per-scenario logs: logs/sN-<name>.log
  • Persona reactions: personas/0[1-6]-*.md
  • Findings catalogue: findings.md

Test plan

  • rivet validate — 13 new artifacts load with zero new
    diagnostics. (The 6 errors + 140 warnings reported are pre-existing
    and constitute the empirical evidence supporting REQ-062.)
  • rivet bundle FEAT-135 --depth 1 — typed links navigable.
  • cargo build --release --bin rivet — green.
  • CI (will populate on push).

What this PR does not do

This PR ships the change list, not the changes. None of the
artifacts in cross-git-investigation.yaml are implemented by this
PR. They are typed work items that v0.11.0 planning can prioritise.
REQ-062 (the P0) is the recommended first.

Refs: FEAT-135, REQ-010, REQ-004, FEAT-001

🤖 Generated with Claude Code

…ter + change list as Rivet artifacts

Three coordinated outputs from the 2026-05-19 cross-git investigation
(6 personas, 10 scenarios, 3 test-bed repos in /tmp/rivet-cross-git/):

  • docs/research/cross-git-repo-investigation.md — full synthesis:
    11 findings, persona-converging carve-into-the-wall quotes, SEooC
    safety-property + Assumptions-of-Use register, architectural
    commitment question (which cross-repo mechanism survives), the
    missing producer-side story, and comparison to git-submodules
    and Google's `repo` tool.

  • docs/rivet-is-not.md — Cederqvist-style epistemic-honesty doc in
    SEooC Safety Manual register. Eight categorical "Rivet is not..."
    sub-sections, each grounded in a real Rivet operation and naming a
    concrete cliff. Linked from the synthesis as the doc the
    First-Time User persona wished they had found at hour zero.

  • artifacts/cross-git-investigation.yaml — the change list itself,
    dogfooded as Rivet artifacts rather than GitHub issues:
      FEAT-135 anchors the AoU register.
      DD-067 records the open architectural commitment (delete
              `externals:` in favour of `external-anchor`?).
      REQ-062  validate must surface skipped files as Errors (P0;
               unanimous persona blocker).
      REQ-063  init must not silently produce broken safety-critical
               projects (DO-178C / EN-50128 / IEC-61508 / IEC-62304).
      REQ-064  derives-from-external must parse structured-target
               end-to-end (advertised in #292, not delivered).
      REQ-065  cross-repo diagnostics propagation (the SEooC AoU).
      REQ-066  one-line schema fix: external-anchor must declare
               cited-source.
      REQ-067  doc topic must explain both mechanisms until DD-067
               decides.
      REQ-068  supplier pull must refuse-and-error on sha256 drift.
      REQ-069  rivet supplier publish + producer-readable manifest
               (the missing producer-side story).
      REQ-070  link docs/rivet-is-not.md from README.
      REQ-071  add rivet docs cross-repo-ci topic with worked GH
               Actions example + AoU register.
      REQ-072  docs/rivet-is-not.md §7 grows AoU-X1..X7 explicitly.

Each artifact cites file:line evidence in the test logs + persona
reactions. The change list IS its own oracle: running `rivet validate`
on the rivet repo itself reproduces F2 with 140 silent-skip WARNs on
bindings.yaml, feature-model.yaml, and the variant configs.

Refs: FEAT-135, REQ-010, REQ-004, FEAT-001

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

📐 Rivet artifact delta

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

Graph

graph LR
  DD_067["DD-067"]:::added
  FEAT_135["FEAT-135"]:::added
  REQ_062["REQ-062"]:::added
  REQ_063["REQ-063"]:::added
  REQ_064["REQ-064"]:::added
  REQ_065["REQ-065"]:::added
  REQ_066["REQ-066"]:::added
  REQ_067["REQ-067"]:::added
  REQ_068["REQ-068"]:::added
  REQ_069["REQ-069"]:::added
  REQ_070["REQ-070"]:::added
  REQ_071["REQ-071"]:::added
  REQ_072["REQ-072"]:::added
  REQ_073["REQ-073"]:::added
  REQ_074["REQ-074"]:::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
  • DD-067
  • FEAT-135
  • REQ-062
  • REQ-063
  • REQ-064
  • REQ-065
  • REQ-066
  • REQ-067
  • REQ-068
  • REQ-069
  • REQ-070
  • REQ-071
  • REQ-072
  • REQ-073
  • REQ-074

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

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

avrabe and others added 7 commits May 19, 2026 20:57
…ator retitle, DPIA expansion, Cederqvist close

Substantive review of docs/rivet-is-not.md returned six small-but-pointed
edits. Applied in order:

  1. Open frame trimmed to one paragraph and paired with a new "What
     Rivet is" sibling section (three sentences). Reviewer:
     "Cederqvist himself would have used one [paragraph]."
  2. Stripped the "billion-dollar products in 2026" sentence — the
     one slip from doctrinal voice into marketing-voice critique.
  3. §5 retitled "Rivet is not a semantic validator" (was "AI
     prompt-correctness checker"). The deeper claim is categorical;
     AI-authored hallucination is one instance. Body and cliff
     adjusted to keep both AI-driven and human-driven examples.
  4. §6 expanded with a paragraph on why the recording-without-
     performing failure mode is common in practice (recording is
     cheap, performing is expensive; every team defaults to the
     cheap operation under deadline pressure).
  5. §3 cliff retold for "an engineer (or an agent)" with explicit
     release-cut deadline framing. Reviewer asked for at least one
     human-driven cliff to make clear the categorical limits hold
     regardless of authorship.
  6. Closing prescription opens with a Cederqvist citation:
     "Acquire the habit of reading specs and talking to your peers"
     adapted for the agent-plus-reviewer pair. Cederqvist now bookends
     the document — once at the open, once at the close — placing it
     in a tradition rather than borrowing from one.
  7. "transposed" → "the same pattern at a different layer" (reviewer
     called the former "slightly bookish").
  8. DSGVO Art. 35 / Art. 4 first uses now carry "(GDPR Art. NN)" in
     parentheses for the non-German-speaking reader.

Reviewer's overall verdict: "Ship it after the small edits."

Refs: FEAT-135, REQ-072

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Verified the canonical GNU mirror of the "What is CVS not?" section
(part of the CVS manual maintained downstream of Cederqvist's 1993
authorship). Opening sentence: "CVS can do a lot of things for you,
but it does not try to be everything for everyone." That sentence is
the structural-honesty thesis the document inherits.

One inline link at the first Cederqvist mention. The closing
prescription keeps its bare-name attribution. Reviewer's other
annotations considered:

  - "notified body" terminology in §4 — kept; the surrounding
    vocabulary (ISO 26262-8, DO-330, GSN) is already specialist,
    and a reader who follows those terms knows "notified body".
  - Load-bearing path citations in §4 (rivet-tool-confidence.yaml,
    tool-qualification-dossier.md) and §7 (cross-org-supplier-
    traceability.md §2) all verified to resolve in this commit.
    The reviewer's broader suggestion of a rivet validate rule to
    keep them honest is a feature request, not this PR's scope.
  - Possible §6/§8 collapse into "Rivet records, it does not
    verify" — kept separate. Reviewer marked it "Not a required
    edit"; both sections currently land.

Refs: FEAT-135, REQ-072

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ters, same tool

The just-shipped docs/rivet-is-not.md and the existing
docs/what-is-rivet.md both carry a "What rivet is NOT" framing — but
in different registers. Pre-existing what-is-rivet.md §6 is a
marketing-voice bullet list ("Honesty over hype" plus seven items
mixing real limits with v0.5.0 roadmap pointers). New
docs/rivet-is-not.md is the SEooC Safety Manual draft in
Cederqvist register.

Both audiences are legitimate:
  - what-is-rivet.md is the positioning doc (carries the
    `<!-- rivet-docs-check: design-doc-aspirational-ok -->` marker)
    and is the right entry point for someone evaluating Rivet.
  - rivet-is-not.md is the integrator-facing categorical-limits
    doc and is the right reference for someone building Rivet into
    a safety case.

Adding one-sentence cross-references in each direction so a reader
landing on either doc can find the other. Neither doc is deleted or
merged — they describe the same tool from opposite directions and
serve different points in the integrator lifecycle.

Out of scope for this commit:
  - what-is-rivet.md staleness (it's still v0.4.1 / 2026-04-19
    positioning with several "planned for v0.5.0" markers that
    have shipped or rescoped in v0.10.x). Tracked as a follow-up;
    the design-doc-aspirational-ok marker acknowledges the lag.
  - Any consolidation of the two §6/bullets vs §1-§8/categorical
    treatments. Both currently land, in their respective registers.

Refs: FEAT-135, REQ-072

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… the broader docs/ structure gap

User flag 2026-05-19: "i think the whole docs folder is not well
structured and planning stuff in which might be interesting for
some time but..." The point lands. Of 19 depth-1 markdown files
under docs/, 11 lack YAML frontmatter — they are invisible to
`rivet docs`, the dashboard Documents view, and the [[ID]] linkage
layer. Rivet does not dogfood its own documents-as-artifacts model.

This commit handles three things, no more:

  1. Add frontmatter to the three docs introduced or touched in
     this PR — so the immediate output of this PR doesn't itself
     widen the dogfood gap:
       docs/rivet-is-not.md
         id: DOC-RIVET-LIMITS · type: safety-manual-draft · status: draft
       docs/research/cross-git-repo-investigation.md
         id: DOC-CROSS-GIT-INV-2026-05-19 · type: investigation · status: snapshot
       docs/what-is-rivet.md
         id: DOC-RIVET-INTRO · type: positioning · status: current

  2. Track the broader docs/ structural problem as REQ-073 in the
     existing change list (artifacts/cross-git-investigation.yaml).
     The requirement enumerates: the 11 skipped files; the
     three-subdir mixing (design/, plans/, research/); the
     ephemeral-vs-reference lifecycle question; and a candidate
     `rivet docs --check-frontmatter` CI gate that would close the
     dogfood loop. Linked back to FEAT-135.

  3. Document the lifecycle distinction explicitly via the
     `status: snapshot` field on the investigation report —
     contrasting it with `status: current` for the positioning
     doc. Future docs in docs/research/ should follow the same
     pattern until REQ-073's subdir policy lands.

Out of scope for this commit:
  - Frontmatter for the other 11 docs (REQ-073 tracks it; touching
    them now would make this PR a docs-bulk-edit).
  - Reorganising docs/ subdirs (REQ-073 (b)).
  - The `rivet docs --check-frontmatter` sub-command (REQ-073 (d)).

Refs: FEAT-135, REQ-073

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…t {useful, done-vs-planned, still-true}

User feedback 2026-05-19 after REQ-073 landed:

  "i would question to validate the need of all the documents
   against an independent subagent validating the usefulness as
   well as if it describes something done or planned or compared
   if it is still true"

Filing as REQ-074 in the same change list. The audit is a phase
distinct from acting on the audit:

  Phase 1: mechanical classification per file — KEEP / UPDATE /
           ARCHIVE / DELETE / INVESTIGATE — done by an independent
           reviewer (subagent or human, NOT the original author).
  Phase 2: act on each verdict, one PR per cluster.

REQ-074 connects to REQ-073: do the audit first, then frontmatter
the survivors — avoid stamping `id:` + `title:` onto docs we're
about to delete.

First-pass audit launched together with this commit (independent
subagent reading docs/ + spot-checking against current main +
v0.10.1 binary state). Verdict output will be captured separately
and linked back to REQ-074.

Refs: FEAT-135, REQ-074

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User feedback 2026-05-19: "ensure that these requirement have a
validation with a step which can be executed and tested against".

A REQ without acceptance criteria is a wish, not a requirement.
Adding an `Acceptance:` block to the description of every one of
the 13 requirements in artifacts/cross-git-investigation.yaml.

Each block answers the same three questions:

  1. What is the literal action / shell command that demonstrates
     the REQ is satisfied?
  2. What output / exit code / diagnostic is expected?
  3. Where is the regression-test fixture that locks the behaviour?

Examples of the register:

  REQ-062  → "Create a project with one well-formed artifact YAML
              and one malformed (top-level `id:` instead of
              `artifacts:` wrapper). Run `rivet validate --format
              json`. Verify exit code 1, `result: FAIL`, `errors
              >= 1`, and at least one entry in `diagnostics[]`
              with `rule: artifact-parse-error`..."

  REQ-072  → "`grep -c "AoU-X[1-7]" docs/rivet-is-not.md` returns
              exactly 7."

  REQ-073  → "`rivet validate 2>&1 | grep -c "no YAML frontmatter"`
              returns 0 (currently 11 on main as of this commit)."

  REQ-074  → "Re-running the audit yields zero new INVESTIGATE
              verdicts and a strictly smaller UPDATE+DELETE count
              than the previous pass."

Each criterion is testable from the shell without ambiguity. None
are aspirational; all are mechanical or doc-grep checks.

Schema note: Acceptance lives inside the description prose block,
not as a separate `acceptance:` field. That keeps the artifacts
schema-conformant (no `field-undefined` INFOs) while still letting
a reviewer find the verification step instantly via a Ctrl-F on
"Acceptance:" — 13 hits, 13 REQs.

Refs: FEAT-135, REQ-062, REQ-063, REQ-064, REQ-065, REQ-066,
      REQ-067, REQ-068, REQ-069, REQ-070, REQ-071, REQ-072,
      REQ-073, REQ-074

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…act graph-unification gap as REQ-073 side-finding

User feedback drove REQ-074 (independent audit of all 52 docs/
markdown files against {useful, done-vs-planned, still-true}).
First-pass audit completed by independent subagent:

  Verdict counts: KEEP 18 / UPDATE 11 / ARCHIVE 16 / DELETE 0 /
                  INVESTIGATE 4 / out-of-scope-this-PR 3

  Five worst offenders (most likely to mislead a reader today):
    1. docs/schemas.md     — lists 5 of 28 shipped schemas
    2. docs/architecture.md — module table omits ~half of rivet-core;
                              schema table same defect as schemas.md;
                              claims OSLC shipped as CLI surface (it isn't)
    3. docs/oracles.md     — lists 3 of 5 shipped oracles (missing
                              `sources` and `ai-defects-open` — the
                              latter is load-bearing for the
                              tool-qualification dossier's TD1 layer)
    4. docs/roadmap.md     — marks v0.4.0-and-later as "Phase 3 — Planned"
                              while v0.10.x has shipped most of it
    5. docs/audit-report.md — 2026-03-09 snapshot still indexed as
                              a current doc; claims "Fuzz/Mutation
                              NOT IMPLEMENTED" while CI runs both

  Three exemplars (use as templates for the rest):
    1. design/tool-qualification-dossier.md — §0 honest-scope
    2. design/polarion-reqif-fidelity.md   — field-by-field LOSSLESS/LOSSY/ABSENT
    3. design/status-gate-rules.md         — self-declares "shipped (date, branch)"

  Directory-structure proposal (8 subdirs by lifecycle):
    reference/ architecture/ design/ plans/ historical/
    research/ marketing/ status/

  Two CI checks that would prevent two-thirds of staleness:
    1. `last-verified:` older than 90 days → warning
       (extend the cited-source-stale rule to docs)
    2. Prose-numeric claims ("28 schemas") must either be
       `{{stats:...}}` embeds or carry `<!-- AUDIT: verified DATE -->`

  Single most cost-effective fix: move 12× `plans/2026-03-*.md` +
  `audit-report.md` to `docs/historical/`. Removes most of the rot
  in one PR.

Captured at `docs/research/2026-05-19-docs-audit.md` with
frontmatter (id: DOC-DOCS-AUDIT-2026-05-19, type: audit,
status: snapshot). Referenced from REQ-074's Evidence section via
`[[DOC-DOCS-AUDIT-2026-05-19]]` document-cross-reference syntax.

────────────────────────────────────────────────────────────────

SIDE-FINDING — recorded under REQ-073 description:

Tried to add `traces-to: DOC-DOCS-AUDIT-2026-05-19` to REQ-074's
typed links. `rivet validate` emitted:

  ERROR: [REQ-074] link 'traces-to' targets
         'DOC-DOCS-AUDIT-2026-05-19' which does not exist
  broken cross-refs: 1

Documents declared with `id:` in markdown frontmatter are NOT
addressable as typed-link targets from artifact YAML. The
artifact store and the document store share an ID namespace but
do not unify into one graph. The `[[ID]]` syntax in doc bodies
bridges from docs → artifacts; the reverse bridge does not exist.

This is a real dogfood gap — Rivet ships two graphs that look
unified at the namespace level but aren't. Recorded as a sub-clause
of REQ-073 (b)'s docs/ structure decision: when REQ-073 (b)
decides the structure, it should also decide whether documents
become first-class artifacts in the typed graph or remain a
parallel system. Workaround in this commit: artifact YAML
references the audit via prose `[[DOC-ID]]` only; typed link is
omitted.

Refs: FEAT-135, REQ-073, REQ-074

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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: 557e63f Previous: 4354d99 Ratio
query/10000 148628 ns/iter (± 798) 95590 ns/iter (± 607) 1.55

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

…acement

PR #304's CI surfaced two real failures (the other five — Playwright,
Miri, Proptest, Kani, Rocq — are the known pre-existing flakes).

── Docs Check: 7 violations across 2 files ──

  cross-git-repo-investigation.md — 6 violations:
    ArtifactCounts ×2  ("10 scenarios")
    ArtifactIdValidity ×2  (REQ-ABS-001, ANCHOR-ACME-001 — test-bed
      artifacts that live in /tmp/rivet-cross-git/, not the store)
    SubcommandReferences ×2  (rivet migrate, rivet workspace —
      referenced precisely because the findings are about their
      absence)
  rivet-is-not.md — 1 violation:
    ArtifactIdValidity  (REQ-SW-022 — an illustrative supplier
      requirement ID in §3 prose)

  Fix: the investigation doc is a `status: snapshot` research
  document — same category as docs/design/ and docs/plans/, which
  doc_check auto-treats as design docs. Added the
  `design-doc-aspirational-ok` marker (with a comment explaining the
  snapshot rationale and noting that doc_check should learn to
  auto-cover docs/research/ — a follow-up under REQ-073). For
  rivet-is-not.md, which is a reference doc and must stay
  doc-check-clean without a blanket marker, used a precise
  `<!-- rivet-docs-check: ignore REQ-SW-022 -->` on the one line.

  Result: doc-check PASS (57 files, 0 violations).

── Test: 2 failures, both from DD-067 ──

  test_dogfood_validate and stats_json_counts_match_validate both
  failed because DD-067 carried its `rationale` as a TOP-LEVEL
  artifact key. The `design-decision` schema (schemas/dev.yaml)
  declares `rationale` as a *required field* — it belongs inside
  `fields:`, not at artifact top level. Moved it in.

  Worth recording: the salsa-cached `rivet validate` path reported
  6 errors while `rivet stats` and `rivet validate --direct`
  reported 7 — the missing-required-field on DD-067 was visible to
  the direct validator and to stats but NOT to the salsa-incremental
  path. That divergence is a real salsa-incremental-correctness bug,
  F2-adjacent (two code paths disagreeing on the same input). It is
  not introduced by this PR and not in scope to fix here, but it is
  why the CI Test job caught DD-067 while a local salsa-cached
  `rivet validate` did not. Flagging for a future REQ.

  Both tests verified green locally:
    test_dogfood_validate ... ok
    stats_json_counts_match_validate ... ok

Refs: FEAT-135, REQ-073

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit 2edaf06 into main May 20, 2026
20 of 40 checks passed
@avrabe avrabe deleted the docs/cross-git-investigation branch May 20, 2026 16:08
avrabe added a commit that referenced this pull request May 20, 2026
… F2-family findings as typed work items (#307)

Two findings surfaced in conversation after the cross-git
investigation landed (#304), both confirmed empirically against the
v0.10.1 binary:

REQ-075 — duplicate artifact IDs are silently swallowed.
  Two artifacts with the same `id` (two files, or twice in one
  file) collapse via `store.upsert`'s last-write-wins; the earlier
  definition is destroyed and `rivet validate` reports PASS.
  Reproduced 2026-05-20: two files both declaring `id: REQ-DUP` ->
  `Result: PASS (0 warnings)`, one survivor. `docs/artifact-format`
  states the uniqueness invariant; nothing enforces it. Direct
  sibling of REQ-062 — detection must happen at load time, where
  both copies still exist. Emit `rule: duplicate-artifact-id`
  naming both source files. P1.

REQ-076 — orphan artifacts are invisible to `rivet validate`.
  `rivet stats` reports `Orphan artifacts (no links): N`;
  `rivet validate` never mentions orphans (grep -ic orphan -> 0).
  An artifact disconnected from the traceability graph passes
  validate clean. Rivet's own main has 5 such orphans. Fix: emit
  `rule: orphan-artifact` per orphan — Warning by default (the
  dogfood's own 5 orphans forbid a hard-error default — REQ-062's
  F2b lesson applied to severity), Error under `--strict-orphans`,
  mirroring the `cited-source-drift` strict-flag pattern.

Both carry executable `Acceptance:` blocks and link to FEAT-135;
REQ-075 and REQ-076 both `traces-to` REQ-062 as the sibling fix
whose load-report channel they reuse. Slotted into Wave 2 (P1 code
fixes) of the follow-up plan.

This commit adds the work items only — the implementations are
separate PRs per the audit-then-act discipline established by
REQ-074.

Refs: FEAT-135, REQ-075, REQ-076

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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