release(v0.11.1): Mythos silent-failure hunt — REQ-078..082#311
Merged
Conversation
…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>
📐 Rivet artifact delta
Graphgraph 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
Added
Posted by |
There was a problem hiding this comment.
⚠️ 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 Report❌ Patch coverage is
📢 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 newdegraded-input oracle (
discover-silent-failure.md) targeting the F2silent-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 withan executable Acceptance block,
derives-from FEAT-135).Fixes
rivet commits— malformed/typo'd artifact trailers(
Implements: REQ-O1) were silently classed as benign orphans; nowflagged as broken references.
<TYPE>was silently typed
unknown; import now rejected naming the object.enum value-check; the renamed path now hits the conflict path.
needs.jsonimport — duplicate artifact IDs silentlycollided; importer now rejects, reusing REQ-075's
detect_duplicate_ids.rivet validate— linked external repos' own schemaviolations 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-validateremains 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 --workspacegreen (full suite passed locally)cargo clippy --workspace --all-targets— no new warningscargo fmt --all --checkcleanrivet validatePASS;rivet commitsPASSrivet validateafterrivet synccounts only the consumer's own artifacts
🤖 Generated with Claude Code