NEC-69: No flake ledger: per-scenario e2e history does not survive a run #200

Merged
nectenda-agent merged 6 commits from worktree-nec-69-no-flake-ledger-per-scenario-e2e-history into main 2026-09-28 14:57:52 +01:00
Collaborator

Task: NEC-69 — https://projectron.nerchure.com/tasks/69

A flake ledger for the e2e suite, in two stores. Every CI run of the multi-vault suite records one row per scenario (verdict, duration, first error line, run, commit, Obsidian version) in Forgejo's generic package registry, one version per run, so history outlives logs and artifacts; scripts/e2e-ledger.mjs report gives per-scenario pass rates (infra excluded both ways) and flags duration drift. Known flakes are catalogued in a new Vikunja project, Flakes (child of Nectenda, FLAKE-1..7 seeded), with match rules; scripts/agent/flakes.mjs triage names the signature a failure matches, or NEW. card.mjs show now prints a card's comments and related cards (a related flake signature in full), which is how this card's own added requirement was first missed; create --relate links a new card to a signature. packages/e2e/README.md gains the red-run policy (stability items 2, 3, 5). Review found and this fixes a describe-scoped hook failure that would have recorded a red run as all-pass. Verified locally: 99 script tests, 22 mutations all caught, gate green with 96 e2e scenarios, and record/triage run on that real report.

Spec: docs/changes/NEC-69-flake-ledger/spec.md

Changelog

NONE

Task: NEC-69 — https://projectron.nerchure.com/tasks/69 A flake ledger for the e2e suite, in two stores. Every CI run of the multi-vault suite records one row per scenario (verdict, duration, first error line, run, commit, Obsidian version) in Forgejo's generic package registry, one version per run, so history outlives logs and artifacts; scripts/e2e-ledger.mjs report gives per-scenario pass rates (infra excluded both ways) and flags duration drift. Known flakes are catalogued in a new Vikunja project, Flakes (child of Nectenda, FLAKE-1..7 seeded), with match rules; scripts/agent/flakes.mjs triage names the signature a failure matches, or NEW. card.mjs show now prints a card's comments and related cards (a related flake signature in full), which is how this card's own added requirement was first missed; create --relate links a new card to a signature. packages/e2e/README.md gains the red-run policy (stability items 2, 3, 5). Review found and this fixes a describe-scoped hook failure that would have recorded a red run as all-pass. Verified locally: 99 script tests, 22 mutations all caught, gate green with 96 e2e scenarios, and record/triage run on that real report. Spec: `docs/changes/NEC-69-flake-ledger/spec.md` ## Changelog NONE
Before this a run's per-scenario result existed only inside a zstd job
log, so "has repro-runaway ever failed, and how often" meant paging logs
by hand. The multi-vault suite now writes a vitest JSON report, and the
e2e action turns it into one row per scenario (verdict, duration, first
error line, run, commit, ref, event, Obsidian version) and puts it in
Forgejo's generic package registry, one version per run. A version per
run rather than one file appended to, because the gate and the nightly
finish together and a pull-append-put loses one of them.

infra is only "the suite never reached the scenario" and is left out of
the rate both ways; a hook failure is a fail on (setup). Writing the
ledger never changes the job's result. `report` builds the rolling
table, with a duration-drift flag, from the registry alone.

Task: NEC-69
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpwTCLAtXqwC5vo1om4Rob
A red run can now be looked up: the Flakes project (a child of Nectenda,
FLAKE-n) holds one task per known flake, status as its bucket, each with
a flake-match rule. flakes.mjs triage matches a run's failed rows against
them and prints the signature or NEW; --record adds one occurrence
comment per run. Triage only annotates, and excludes nothing from a rate
or the gate. Seeded with seven signatures from the README, specs and
commits; the bodies are in the change folder.

card.mjs show printed only a card's description, which is how NEC-69's
own added requirement, left as a comment, was first missed. It now
prints every comment and the related cards, and a related signature in
full, so a card filed with create --relate FLAKE-n starts with its
evidence. The skill says to read comments and triages an e2e failure
before anything else.

Task: NEC-69
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpwTCLAtXqwC5vo1om4Rob
packages/e2e/README.md now says how to read the ledger and the
catalogue, and what to do when the suite goes red: triage before any
re-run, a match on an open signature is evidence not permission, a
match on a Fixed one is a regression. The change spec records where the
build departs from the plan: the owner created the Flakes project, and
NEC-87 is deliberately not catalogued.

Task: NEC-69
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpwTCLAtXqwC5vo1om4Rob
Task: NEC-69
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpwTCLAtXqwC5vo1om4Rob
Close four ways the ledger could misreport, found in review
Some checks failed
CI / e2e (pull_request) Failing after 3s
Release note / release-note (pull_request) Successful in 12s
CI / promote (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
e910d8780e
- A beforeAll or afterAll inside a describe fails the file with an
  empty message and marks its scenarios skipped (vitest 4.1.11), so the
  run was recorded as all-pass. A failed file with no failed scenario is
  now a (setup) fail whatever its message says.
- A report is moved aside once recorded, so a later local run that dies
  before vitest writes one records "no report" instead of the old result.
- triage says so when a run has infra rows, rather than "no failed
  scenarios".
- A malformed match rule matches nothing instead of throwing, and the
  most open signature wins whatever order the buckets sit in, with the
  others named.

Task: NEC-69
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpwTCLAtXqwC5vo1om4Rob
Quote the ledger step's run line as a block, which YAML can parse
All checks were successful
Release note / release-note (pull_request) Successful in 15s
e2e / multi (push) Successful in 4m48s
CI / build (pull_request) Successful in 5m3s
CI / e2e (pull_request) Successful in 5m36s
CI / promote (pull_request) Has been skipped
a4e9323aaa
":⚠️📒 record exited" has ": " in a plain scalar, which
YAML reads as a mapping; the runner rejected the whole obsidian-e2e
action for it (PR #200, run 940, task 1591), so the suite never ran.

Task: NEC-69
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpwTCLAtXqwC5vo1om4Rob
cruelacid force-pushed worktree-nec-69-no-flake-ledger-per-scenario-e2e-history from a4e9323aaa
All checks were successful
Release note / release-note (pull_request) Successful in 15s
e2e / multi (push) Successful in 4m48s
CI / build (pull_request) Successful in 5m3s
CI / e2e (pull_request) Successful in 5m36s
CI / promote (pull_request) Has been skipped
to 3d60a14180
All checks were successful
Release note / release-note (pull_request) Successful in 12s
CI / build (pull_request) Successful in 4m43s
CI / e2e (pull_request) Successful in 5m20s
CI / promote (pull_request) Has been skipped
e2e / multi (push) Successful in 4m47s
CI / build (push) Successful in 5m18s
CI / e2e (push) Successful in 5m30s
CI / promote (push) Successful in 31s
2026-09-28 14:51:51 +01:00
Compare
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Nectenda/nectenda!200
No description provided.