diff --git a/spec/attestation.yaml b/spec/attestation.yaml index e1fdf1df..a6938143 100644 --- a/spec/attestation.yaml +++ b/spec/attestation.yaml @@ -107,10 +107,10 @@ attested: F-2de65d: 84ad71574d306c81 F-315fd7: c3b042c80fa7c187 F-31eeb8: d88a9880d29ae411 - F-32b1e0: 9b29e21313d121b1 + F-32b1e0: 9792422c1c008207 F-3788c2: af9778dea8687b29 F-37b4a8: e067655bad681488 - F-3a5339: b2b2ea8775f99267 + F-3a5339: 0dfdeec23abfa841 F-3b3690: 6a36aad282d36f3a F-40327b: 8295358f7b813c8a F-417ff0: 0cc5eeefc5e08377 @@ -125,7 +125,7 @@ attested: F-570a3f: 3f60012b22c9b715 F-59f093: 26735424fba6308c F-5b188856: 92b72281c248eba3 - F-5b9f9f: 0b972209be8b642f + F-5b9f9f: 9d362a585206c5fa F-5d3ed2: 9452eac28760fb99 F-5f6b45: 15323c4f5b619de7 F-64a5c159: adedb516a257c7ec @@ -139,7 +139,7 @@ attested: F-77f7ead0: 3f8cd4feeece1abd F-78b50d: 688e6afe2352a034 F-7afbd4: 18ce48352bee0fce - F-7ce18e: 42fe8057bc8e250b + F-7ce18e: ab43c99dd2fe489c F-7fa4a7: 19b7709a0b2202e3 F-80d19d: 6e03a098269ce4c3 F-836a90: a0d57b88aafbe6e8 @@ -162,7 +162,7 @@ attested: F-aee1da: a6d7525a6c547877 F-aee61f: e009b9eb07addd30 F-af45042a: 9c61ca116a28cbb6 - F-af96b1: e75ca2cb3412a7a5 + F-af96b1: fa9c9908dd600840 F-b2094740: f379bf4feef6771a F-b43066: 9402b630adcf1eae F-b61449: 7095ce00662e987d @@ -184,7 +184,7 @@ attested: F-d2c806: b3d8668905855a6c F-d3bde4: 915d13b33258d3fc F-d49585: 11e3ac2dce796fc6 - F-d6b93648: f755a47c66e07635 + F-d6b93648: 2191277c0e5982ee F-d7312b: 000237d094145b6a F-d8223c: 0501e9564231899b F-d980359c: 8f1559276afc5c03 diff --git a/tests/self-consistency.test.ts b/tests/self-consistency.test.ts index e3071a5d..6dd3917e 100644 --- a/tests/self-consistency.test.ts +++ b/tests/self-consistency.test.ts @@ -26,13 +26,30 @@ const read = (rel: string): string => readFileSync(join(ROOT, rel), 'utf8'); describe('cladding self-consistency (no Vacuous Green against itself)', () => { test('prose detector-count claims match the actual detector count', () => { const actual = allDetectors.length; - // Files whose prose states cladding's own detector count. Each is a - // single, unambiguous claim of the form " [drift ]detector(s)". - const files = ['spec.yaml', 'docs/project-context.md', 'spec/capabilities.yaml', 'AGENTS.md']; + // Files that state cladding's own detector count. The README badge + prose + // and the ecosystem SVGs are NOT regenerated by the build, so they have + // historically lagged the shipped count (37 vs 38 — the original audit's + // Vacuous Green, recurring). Check EVERY count claim — badge `detectors-` + // and prose ` [drift ]detector(s)` — against allDetectors.length so no + // hand-maintained surface can silently lag again. + const files = [ + 'spec.yaml', + 'docs/project-context.md', + 'spec/capabilities.yaml', + 'AGENTS.md', + 'README.md', + 'README.ko.md', + 'docs/img/en/ecosystem.svg', + 'docs/img/ko/ecosystem.svg', + ]; + // group 1 = badge form (`detectors-40`); group 2 = prose (`40 drift detectors`). + const re = /detectors?-(\d+)|(\d+)\s+(?:drift\s+)?detectors?\b/gi; for (const f of files) { - const m = read(f).match(/(\d+)\s+(?:drift\s+)?detectors?\b/i); - expect(m, `${f} should state a detector count`).not.toBeNull(); - expect(Number(m![1]), `${f} detector-count claim should equal allDetectors.length`).toBe(actual); + const matches = [...read(f).matchAll(re)]; + expect(matches.length, `${f} should state a detector count`).toBeGreaterThan(0); + for (const m of matches) { + expect(Number(m[1] ?? m[2]), `${f} detector-count claim should equal allDetectors.length`).toBe(actual); + } } });