check:done-evidence knew one card schema and failed the best-evidenced cards on the board
A done card with no record is the reporting failure this loop exists to avoid — so a gate that mis-identifies WHICH cards lack a record is worse than none: it teaches the next agent to pad the field the checker reads. ★ THE THREE FLAGGED CARDS WERE AMONG THE BEST-EVIDENCED THERE ARE. Each carried one_line, why, and a `verify` block naming the probe, its assertion count and its negative tests — "74 files match byte for byte, all three drift classes exit 1", "9 assertions, all pass", "two new assertions, both negative-tested". The gate looked only for `bluf` or `fields`. MEASURED across 443 done cards: 40 carry `verify`, 41 carry `one_line`, and ALL THREE flagged cards had one or both. `verify` is if anything the STRONGER signal — it names how the claim was checked, which is what evidence means here. Fixing the CARDS by adding a redundant bluf would have been gaming the check. Fixing the GATE to recognise the evidence already there is the honest repair. ★ THE BASELINE IS NOW EMPTY. All ten exemptions reported STALE — every one had since gained evidence — so the list exempted nothing while implying ten cards still owed a record. An EMPTY set is not an unset one: every done card must now carry evidence with NO exemptions, and the gate fails outright for a single card that does not. Keeping ten satisfied ids would mean the same today and quietly permit a regression the moment someone reused an entry. Same reasoning as emptying the i18n DEBT map. MUTATION-TESTED both directions: a done card with NOTHING in any of the four fields FAILS by name; the same card with ONLY a `verify` entry PASSES. Wired into gates:post (30 -> 31) after confirming it reads only backlog JSON, which the build does not mutate. The doc quotes gates:post, so it is re-transcribed in the same commit — the self-referential update noted last tick, handled in one pass this time. Build: 7/7 pre, 23/23 bundles, 31/31 post, exit 0.
This commit is contained in:
parent
670a2dc3f7
commit
28ce04f6ac
3 changed files with 30 additions and 17 deletions
|
|
@ -49,7 +49,7 @@ The scripts these commands are grounded in (from this branch's `package.json`):
|
|||
"build": "bash internal/build-lock.sh",
|
||||
"build:unlocked": "bun run gates:pre && bun run library-index && bun run check:library-index && bun run clean && bun run token && bun run build:bundles && bun run tree && bun run gates:post && bun run gallery",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:wp-embed check:doc-scripts",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:done-evidence",
|
||||
"build:bundles": "node internal/run-parallel.mjs --bundles", // the 22 vite builds, 4 at a time
|
||||
"preview": "bun x vite preview",
|
||||
"serve": "node internal/serve-strict.mjs", // 404s a directory, like production
|
||||
|
|
|
|||
|
|
@ -59,19 +59,18 @@ const BACKLOGS = [
|
|||
]
|
||||
|
||||
// Pre-existing, from before the rule. Verified 2026-09-21. SHRINK ONLY.
|
||||
// ★ THE BASELINE IS NOW EMPTY, and that is the strongest state this gate can be in.
|
||||
// All ten exemptions had since gained evidence — the gate reported every one of them
|
||||
// as STALE on 2026-09-24 — so the list was pure dead weight: ten ids that exempted
|
||||
// nothing while implying ten cards still owed a record.
|
||||
// An EMPTY set is not an unset one: every done card must now carry evidence, with no
|
||||
// exemptions, and the gate fails outright for a single card that does not. Keeping
|
||||
// `{ ... }` full of satisfied ids would mean the same today and quietly permit a
|
||||
// regression the moment someone "reused" an entry.
|
||||
// If a genuinely un-reconstructable card ever needs an exemption, add its id here WITH
|
||||
// the reason — and the gate will tell you the day it becomes stale.
|
||||
const BASELINE = new Set([
|
||||
'BUILD-AGENT-SKILLS',
|
||||
'BUILD-CAP1-SINGLE-ELEMENT-SHOWCASE',
|
||||
'BUILD-PLUGIN-STUDIO-VUE-SPA',
|
||||
'BUILD-README-CLI-COMMANDS',
|
||||
'BUILD-README-DEDUP-BLUF',
|
||||
'BUILD-README-SCREENSHOT-MATRIX',
|
||||
'BUILD-RENAME-PLUGIN-DESIGNS',
|
||||
'BUILD-RESTORE-MOBILE-SPA',
|
||||
'BUILD-STARTER-TEMPLATE',
|
||||
'BUILD-UNIFIED-RESEARCH-DASHBOARD',
|
||||
])
|
||||
|
||||
let checked = 0, done = 0
|
||||
const offenders = []
|
||||
const staleBaseline = []
|
||||
|
|
@ -87,7 +86,19 @@ for (const rel of BACKLOGS) {
|
|||
done++
|
||||
const hasBluf = String(c.bluf || '').trim().length > 0
|
||||
const hasFields = c.fields && Object.keys(c.fields).length > 0
|
||||
if (hasBluf || hasFields) {
|
||||
// ★ THE BOARD USES TWO CARD SCHEMAS, and this gate only knew one. Older cards carry
|
||||
// `bluf` + `fields`; a second family carries `one_line` (what was done), `why`, and
|
||||
// `verify` (the artifact and how it was checked). MEASURED 2026-09-24 across 443 done
|
||||
// cards: 40 carry `verify` and 41 carry `one_line`, and ALL THREE cards this gate was
|
||||
// failing had one or both — with named probes, assertion counts and negative tests.
|
||||
// They were among the best-evidenced cards on the board.
|
||||
// `verify` is if anything the STRONGER signal: it names how the claim was checked,
|
||||
// which is exactly what "evidence" means here. Demanding a redundant `bluf` alongside
|
||||
// it would have taught the next agent to pad the field the checker reads rather than
|
||||
// write the record — the gate training the behaviour it exists to prevent.
|
||||
const hasVerify = String(c.verify || '').trim().length > 0
|
||||
const hasOneLine = String(c.one_line || '').trim().length > 0
|
||||
if (hasBluf || hasFields || hasVerify || hasOneLine) {
|
||||
// A baselined id that now HAS evidence is stale — report it so the list shrinks.
|
||||
if (BASELINE.has(c.id)) staleBaseline.push(`${c.id} (${rel})`)
|
||||
continue
|
||||
|
|
@ -104,13 +115,15 @@ for (const s of staleBaseline) {
|
|||
}
|
||||
|
||||
if (offenders.length) {
|
||||
console.error(`\nDONE-EVIDENCE: FAIL — ${offenders.length} card(s) are done with NO bluf and NO fields:`)
|
||||
console.error(`\nDONE-EVIDENCE: FAIL — ${offenders.length} card(s) are done with NO evidence in any field:`)
|
||||
for (const o of offenders) console.error(` ✗ ${o}`)
|
||||
console.error(
|
||||
'\n Add ONE of: a `bluf` saying what was done, or a `fields` entry naming the artifact and how\n' +
|
||||
'\n Add ONE of: `bluf` or `one_line` saying what was done, `verify` naming how it was checked,\n' +
|
||||
' or a `fields` entry naming the artifact. Any ONE of the four is enough — the point is a\n' +
|
||||
' record a reader can reconcile against the code, not a particular field name.\n' +
|
||||
' it was verified. Write it now, while the work is fresh — reconstructing it later produces a\n' +
|
||||
' plausible story indistinguishable from a real record.'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('DONE-EVIDENCE: PASS — every newly-done card carries a bluf or fields.')
|
||||
console.log('DONE-EVIDENCE: PASS — every done card carries evidence (bluf, one_line, verify or fields).')
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@
|
|||
"check:doc-scripts:self-test": "node internal/check-doc-quotes-scripts.mjs --self-test",
|
||||
"check:legend-source": "node internal/check-legend-matches-source.mjs # the numbers the maps SHOW must match the numbers the live SOURCE has. Every other gate checks INTERNAL consistency — a page can agree with itself perfectly while its legend has stopped describing reality. Offline SKIPs (exit 0); only a reachable endpoint that disagrees fails.",
|
||||
"gates:pre": "node internal/run-parallel.mjs --label=pre -- check:template-literal check:mjs-parse check:sfc-parse check:tab-radius check:synced-css check:wp-embed check:doc-scripts",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts",
|
||||
"gates:post": "node internal/run-parallel.mjs --label=post -- check:drop check:parse verify check:sri check:public-hygiene check:label-joins check:facet-cascade check:facet-one-field check:heartbeat check:kpi-unit check:composite-reg check:descriptions check:no-abs-paths check:no-codename check:dep-names check:composite-srcs check:embed-targets check:nested-token check:i18n-parity check:tabs-localized check:packets-all check:packet-strings-parity check:zone-census check:share-policy check:library-index check:csv-shape check:capability-citations check:catalog-identity check:no-orphan-gates check:quoted-scripts check:done-evidence",
|
||||
"build:bundles": "node internal/run-parallel.mjs --bundles",
|
||||
"check:maplibre-drops": "node internal/check-maplibre-layer-drops.mjs",
|
||||
"check:tabs-localized": "node internal/check-tabs-localized.mjs # a chosen locale must CHANGE the rendered tab text. check:i18n-parity compares catalogs to each OTHER, so it cannot tell a shipped translation from a dead one; tabs.json is reached only via a DYNAMIC key (SemanticTreeLegend.vue:40), invisible to any grep. Renders it and reads the result.",
|
||||
|
|
|
|||
Loading…
Reference in a new issue