Skip to content

release(v0.11.1): Mythos silent-failure hunt — REQ-078..082#311

Merged
avrabe merged 9 commits into
mainfrom
feat/v0.11.1-mythos-silent-failure
May 22, 2026
Merged

release(v0.11.1): Mythos silent-failure hunt — REQ-078..082#311
avrabe merged 9 commits into
mainfrom
feat/v0.11.1-mythos-silent-failure

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 21, 2026

Summary

v0.11.1 — a patch release shipping the five fixes from the post-v0.11.0
Mythos silent-failure hunt. After v0.11.0 closed the cross-git
investigation (FEAT-135), scripts/mythos/ was re-run with a new
degraded-input oracle (discover-silent-failure.md) targeting the F2
silent-failure class across the ingest/parse subsystems the FEAT-135
waves did not cover. Four discovery agents → four confirmed findings;
in every case the subsystem already had a sibling check doing the right
thing and one code path that forgot to. A fifth fix (REQ-082) addresses
a user-reported v0.11.0 regression.

Findings filed as typed Rivet artifacts in
artifacts/mythos-silent-failure-findings.yaml (REQ-078..082, each with
an executable Acceptance block, derives-from FEAT-135).

Fixes

  • REQ-078 rivet commits — malformed/typo'd artifact trailers
    (Implements: REQ-O1) were silently classed as benign orphans; now
    flagged as broken references.
  • REQ-079 ReqIF import — a SPEC-OBJECT with missing/dangling <TYPE>
    was silently typed unknown; import now rejected naming the object.
  • REQ-080 Schema migration — field-map-renamed fields skipped the
    enum value-check; the renamed path now hits the conflict path.
  • REQ-081 needs.json import — duplicate artifact IDs silently
    collided; importer now rejects, reusing REQ-075's detect_duplicate_ids.
  • REQ-082 rivet validate — linked external repos' own schema
    violations were counted against the consumer's gate (user-reported,
    ~5800 spurious errors after rivet sync). External (prefix:)
    artifacts now stay in the store only so cross-links resolve; every
    per-artifact validation pass skips them. --with-externals-validate
    remains the opt-in path for the supplier's diagnostics (AoU-X1).

Patch-shaped: localized fixes, no new flags, no schema change.

Test plan

  • cargo test --workspace green (full suite passed locally)
  • cargo clippy --workspace --all-targets — no new warnings
  • cargo fmt --all --check clean
  • CI: Kani / Playwright / Rocq green
  • rivet validate PASS; rivet commits PASS
  • REQ-082 regression: consumer rivet validate after rivet sync
    counts only the consumer's own artifacts

🤖 Generated with Claude Code

avrabe and others added 8 commits May 21, 2026 18:56
…ndings

Adjusts the Mythos slop-hunt pipeline for the silent-failure class the
2026-05-19 cross-git investigation surfaced (FEAT-135), and files the
findings of the first run.

scripts/mythos/:
  - discover-silent-failure.md — a new discovery prompt with the
    degraded-input oracle: construct a malformed/duplicate/ambiguous
    input, show the command reports success over it. (The standard
    discover.md hunts reachability slop via excision; this hunts the
    Cederqvist green-PASS-over-broken class.)
  - HOWTO.md — silent-failure added as a fifth slop class.

artifacts/mythos-silent-failure-findings.yaml — five confirmed
findings from the first run, anchored on FEAT-135:
  REQ-078  commits.rs   — typo'd trailer ID silently classified orphan
  REQ-079  reqif.rs     — SPEC-OBJECT missing/dangling TYPE -> "unknown"
  REQ-080  migrate.rs   — field-map rename skips the enum value-check
  REQ-081  needs_json.rs— duplicate inner ids silently collide
  REQ-082  validate     — linked external repos' own violations counted
                          against the consumer (user-reported, v0.11.0)

Refs: FEAT-135

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…umer (REQ-082)

User-reported against v0.11.0: after `rivet sync`, `rivet validate` on a
consumer reported thousands of errors — all from the linked external
repos' own artifacts (link-target-type, cardinality, rule violations on
`prefix:ID` artifacts). `rm -rf .rivet/repos && rivet validate` -> PASS.

`ProjectContext::load` upserts every external artifact into the same
store `validate` runs on; the external (prefixed) artifacts therefore
received the consumer's full per-artifact validation. A supplier project
that is not itself error-free failed the consumer's gate — directly
contradicting REQ-065 / AoU-X1 ("the consumer's PASS does not reflect the
supplier's validation state"). Issue #245's "type-check prefixed
artifacts" intent is superseded by that deliberate AoU-X1 design.

Fix, two layers:
  - rivet-core/src/validate.rs: a new `is_external_artifact` helper; the
    five per-artifact diagnostic loops (type/fields/cardinality/
    link-target-type, unknown-link-type, unknown-fields, shorthand-link,
    variant-key) skip prefixed artifacts.
  - rivet-cli/src/main.rs `cmd_validate`: the definitive path-agnostic
    catch-all — `diagnostics.retain(...)` drops any diagnostic keyed to
    a `prefix:ID` external ID, regardless of which pass produced it
    (structural / conditional / traceability, salsa or direct). The
    orphan and lifecycle passes likewise skip prefixed artifacts.

External artifacts stay in the store so `prefix:ID` cross-links still
resolve (a consumer link to a missing external is still a broken ref).
`rivet validate --with-externals-validate` remains the opt-in way to
see the supplier's own diagnostics, separately (REQ-065).

Regression test: validate_does_not_count_external_repo_violations.

Implements: REQ-004
Verifies: REQ-082
Refs: FEAT-135, REQ-065
…nt orphan (REQ-078)

`parse_commit_message` dropped a malformed trailer ID such as
`Implements: REQ-O1` (capital letter O for a zero), leaving
`artifact_refs` empty so `analyze_commits` classified the commit as a
benign `Orphan` (warning, exit 0). A well-formed-but-unknown ID was
already caught as `BrokenRef` — the malformed case was the un-fixed
asymmetry.

`extract_artifact_refs` now also returns tokens that look like a botched
artifact-ID attempt (a token containing a hyphen and at least one ASCII
digit that is not a valid ID); ordinary prose and bare numbers are left
untouched. `parse_commit_message` additionally flags a trailer KEY that
is within Levenshtein edit-distance 1 of a configured key
(`Implments:` vs `Implements:`). Both feed a new `malformed_refs` list
threaded through `CommitParse` / `ParsedCommit`; `analyze_commits`
records them as `BrokenRef` (with a `malformed` flag) so `rivet commits`
exits non-zero and `commit-msg` check rejects the commit.

Verified the rivet repo's own history is unaffected: no real trailer
key is edit-distance 1 from a configured key, and parenthetical
annotations like `REQ-004 (validation)` produce no malformed tokens.

Implements: REQ-004
Verifies: REQ-078
Refs: FEAT-135
…silent 'unknown' (REQ-079)

parse_reqif resolved a SPEC-OBJECT's type with .unwrap_or("unknown") — a
SPEC-OBJECT with no <TYPE> element, or a SPEC-OBJECT-TYPE-REF pointing at
an undeclared type, silently became artifact_type: "unknown" and the
import returned Ok. ReqIF 1.2's XSD makes <TYPE> mandatory. Collect
untyped/dangling-typed SPEC-OBJECTs and reject the import after the loop,
mirroring the existing dangling-SPEC-RELATION rejection in the same
function. Also folds in the SPEC-RELATION-TYPE-REF .unwrap_or("traces-to")
sibling.

Implements: REQ-004
Verifies: REQ-079
Refs: FEAT-135
…EQ-080)

`diff_artifacts` skipped the `allowed_values` enum check whenever a
field was renamed via the recipe's `field_map`: it pushed a
`FieldRename` and `continue`d before reaching the enum check, which was
only wired into the identity-named path. An out-of-enum source value
renamed into an enum target field (e.g. `prio: 7` -> enum `priority`)
produced zero conflicts, so `has_conflicts()` was false and the
migration completed COMPLETE having written an invalid value.

Factor the enum-conflict check into a shared `enum_conflict_for` helper
and call it from both the field-map-renamed path (against the renamed
TARGET field name) and the identity-named path, so the renamed path is
now consistent with its sibling. No new flag, rule, or schema change --
`FieldValueConflict`, the `Conflict` action class, and the
marker-writing path already exist.

Also fold in the neighbour: `apply_to_file` returned `Ok(original)`
with no diagnostic when the YAML lacked a top-level `artifacts:` key,
reporting success having migrated nothing. It now returns an `Err`
describing the wrong-shaped file.

Adds regression tests in `migrate.rs`: a field-map-renamed out-of-enum
value emits a `FieldValueConflict` and `has_conflicts()` is true; an
in-enum renamed value stays a clean mechanical rename; `apply_to_file`
on an `artifacts:`-less file errors instead of silently succeeding.

Implements: REQ-004
Verifies: REQ-080
Refs: FEAT-135

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ilent collision (REQ-081)

import_needs_json built a Vec<Artifact> from the sphinx-needs needs map
without enforcing ID uniqueness: two needs sharing one inner `id` produced
two artifacts both claiming that ID, import returned Ok. Reuse the REQ-075
duplicate rule (detect_duplicate_ids_for_validate) and return Err naming
the colliding IDs. Also reject needs missing the `type` field rather than
silently typing them "unknown".

Implements: REQ-004
Verifies: REQ-081
Refs: FEAT-135, REQ-075
…sts to REQ-082

`cmd_stats` independently tallies errors/warnings from the diagnostic
vector, so the REQ-082 filter that `cmd_validate` got must be mirrored
here or `stats_json_counts_match_validate` drifts. Add the identical
`prefix:ID` retain before the count.

Reconcile `externals_schemas.rs`: three tests pinned issue #245's
"type-check prefixed artifacts against the external's schema" design,
which REQ-082 deliberately supersedes — prefixed external artifacts are
skipped by every per-artifact validation pass. Rewrite them to assert
the REQ-082 behaviour and retag `verifies REQ-007` -> `verifies REQ-082`.

Fixes: REQ-082
Verifies: REQ-082

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bump workspace + VS Code extension to 0.11.1 and add the CHANGELOG
section. v0.11.1 ships the five fixes from the post-v0.11.0 Mythos
silent-failure hunt: REQ-078 (commits malformed trailers), REQ-079
(reqif missing TYPE), REQ-080 (migrate enum bypass), REQ-081 (needs.json
duplicate IDs), and REQ-082 (external repos' violations counted against
the consumer — user-reported). Patch-shaped: localized fixes, no new
flags, no schema change.

Refs: FEAT-135

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

github-actions Bot commented May 21, 2026

📐 Rivet artifact delta

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

Graph

graph LR
  REQ_078["REQ-078"]:::added
  REQ_079["REQ-079"]:::added
  REQ_080["REQ-080"]:::added
  REQ_081["REQ-081"]:::added
  REQ_082["REQ-082"]:::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-078
  • REQ-079
  • REQ-080
  • REQ-081
  • REQ-082

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

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

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: 9cc8a41 Previous: 8e08ff4 Ratio
store_insert/10000 18444532 ns/iter (± 1305326) 14345427 ns/iter (± 342990) 1.29
link_graph_build/10000 38387722 ns/iter (± 4736106) 25804436 ns/iter (± 929269) 1.49
validate/10000 17777566 ns/iter (± 884913) 14680947 ns/iter (± 177650) 1.21

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

@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 97.46434% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
rivet-core/src/migrate.rs 95.56% 7 Missing ⚠️
rivet-core/src/commits.rs 97.18% 6 Missing ⚠️
rivet-core/src/reqif.rs 98.75% 2 Missing ⚠️
rivet-core/src/validate.rs 94.44% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

…x install

The Rocq and Verus jobs used DeterminateSystems/nix-installer-action@main
with `init: none`, intending a daemonless single-user Nix install (the
self-hosted runners run NoNewPrivileges=true with no sudo, so the
multi-user daemon path cannot work).

The action's `determinate` input default flipped false->true between v17
and v22, so the unpinned `@main` started installing Determinate Nix.
Its `determinate-nixd` daemon ignores `init: none` and fails on no-sudo
runners — missing daemon socket, root-owned store lock — which broke the
Rocq job (toolchain fetch aborts before any proof compiles) and silently
degrades the Verus job on our own runners (continue-on-error: true).

Pin both to the v22 commit SHA and set `determinate: false`, restoring
the plain upstream daemonless install these jobs were written for and
stopping future drift.
@avrabe avrabe merged commit f9ac472 into main May 22, 2026
21 of 40 checks passed
@avrabe avrabe deleted the feat/v0.11.1-mythos-silent-failure branch May 22, 2026 04:15
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