Fix #86: four AST10 incident records said things their sources do not - #89
Merged
Merged
Conversation
Every docs/*.js bundle carried a `// Generated: <today>` header. Nothing else in the generator output varies between runs, so that one line was the whole reason a regenerate on a different day showed four dirty files — and, since #30, the reason the Generator reproducibility job and the `committed entries match a fresh generation` test could only pass on the day the bundles were last committed. - generate.js: drop the run-date lines; the Source header now reads the version from package.json instead of a hard-coded, stale `v1.5.2`. - generate.test.mjs: assert no bundle header names a run or carries a date. - validate.yml: the reproducibility job now diffs every generated artefact (backlinks.json, backlinks.js, frameworks-registry.js too). - CONTRIBUTING.md: document the build contract — generated files, the determinism requirement, and why the bundles are committed (Pages serves docs/ from main; no deploy workflow exists). Determinism only. No structural, route, layout or logo change (C2). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0147wBugcuzLkswKPqgofcke
A mapping says a control addresses a risk; an incident's control_failures[]
says that control failed in the wild. This joins the two and surfaces the
result, without ever counting a claim nobody reviewed.
- scripts/evidence.js — the one place the join is defined. Rules (DRAFT,
for ratification in docs/EVIDENCE_METHODOLOGY.md): a failure supports a
mapping only when the incident exemplifies that entry and names the same
framework + control; only confirmed failures (non-empty confirmed_by)
count; the unit is the incident. Unabsorbed failures are reported as
orphans (possible missing mapping — a human call, C4).
- stats.js — new `evidence` block in data/stats.json.
- generate.js — `evidence_count` + `evidence.{confirmed,drafted}` on mapping
rows that have a linked failure; every other row is byte-identical.
Currently 6 rows, all drafted, all evidence_count 0.
- validate.js — checkEvidence(): framework and control must resolve in the
registry, basis must be quotable, a confirmed failure needs a source_url;
orphans warn. Negative-tested with three planted records (5 errors).
- compliance-report.js — "Controls that failed in the wild" per framework
and in the summary; evidence in the JSON output.
- src/index.ts — ControlFailure/ExternalRef types, evidenceFor(),
controlFailures({confirmedOnly}). Reads generated fields, so the package
cannot disagree with the data it ships.
- data/schema.json — documents the two generated fields.
Also fixes a pre-existing test race this ticket made more likely:
generate.js truncated and rewrote every output even when unchanged, so a
suite reading data/entries in parallel could see an empty file ("Unexpected
end of JSON input", observed 2 in ~15 runs). It now skips identical writes;
12 consecutive full runs after the change were clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
The composite-key separator in evidence.js was written to disk as a literal NUL byte, so git classified the file as binary: no diff, no review, and a surprise for anyone opening it. Keys are now JSON.stringify([parts]) — plain text, and no separator a framework name such as "ISO/IEC 27001:2022" could collide with. No output changes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
…cidents
DRAFT — human confirm. Every confirmed_by is empty; evidence_count stays 0
on every row until a reviewer signs a record off.
Each basis is an exact quotation, cut programmatically from the fetched
source page and re-checked as a substring; 16 of them were re-fetched and
re-checked independently before this commit. Primary disclosures were
preferred (GitHub security advisories, Oasis, Check Point-era GHSAs, Snyk,
Trail of Bits, Air Security, BlueRock, Antiy CERT) over the AST10 summary
pages. Layer and outcome are suggestions for SME review.
Selection rules:
- the source must state a control was missing or defeated; a description
of the attack alone does not qualify
- the layer must be mapped by the incident's own entries (no orphans)
- hedged quotes ("if any exists") excluded; at most two per incident
The three earlier drafts are replaced, not kept alongside:
- INC-115: its quote was verbatim but described the attacker writing to
MEMORY.md/SOUL.md, not a missing control — it failed the drafting rule
- INC-123, INC-124: quotes were not verbatim (re-capitalised; truncated
with a full stop for a comma); now quoted from the primary disclosures
Not drafted: INC-117 and INC-125 (sources state no control failure);
INC-122, INC-130 and one INC-131 candidate would be orphans (MAESTRO L5,
not mapped by their entries) — listed in the PR for a human.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
Each change below was checked against the fetched primary source. - INC-124 (ClawJacked): drop CVE-2026-28363 and "CVSS 9.9". NVD describes that CVE as a tools.exec.safeBins allowlist bypass fixed in 2026.2.23, a different bug; the Oasis Security disclosure gives no CVE or CVSS. Description now follows Oasis: brute-forced gateway password, rate limiter exempting localhost, auto-approved localhost pairing, fixed in under 24 hours in 2026.2.25, classified High by OpenClaw. - INC-117: the record said the skills were found by behavioural analysis "rather than by static review" and that registry checks had cleared them. Alice's release says Caterpillar "statically inspects skill logic" and says nothing about registry checks. - INC-119: Snyk's Leaky Skills write-up describes skills that route secrets through the LLM context and logs in plaintext (283 of 3,984), not over-permissioning; the record's reference slug was a guess. - INC-125: Hudson Rock reports one live infection whose files were taken by a broad file-grabbing routine, "not ... a specialized OpenClaw module"; Vidar is its CTO's "likely" attribution to The Hacker News. Primary-source URLs added to references/external_refs for all four. Severity, owasp_entries, MAESTRO layer/role and mitigations unchanged (C4) — where they rested on a corrected claim, that is flagged in the PR. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
This was referenced Sep 14, 2026
Conflicts were only in the four generated webapp bundles, and only in their header lines: #92 regenerated them with a `// Generated:` date that this branch removes. Resolved by re-running scripts/generate.js on the merged sources; a second run is byte-identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
No conflicts. Generated files re-run on the merged sources; a second generation is byte-identical. validate 0 errors, 60/60 tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
Generated files re-run on the merged sources; a second generation is byte-identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
#37 landed as a squash, so this branch's copies of its commits resolve as identical content. Generated files re-run on the merged sources; a second generation is byte-identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
…uracy Generated files re-run on the merged sources; a second generation is byte-identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
Generated files re-run on the merged sources; a second generation is byte-identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR
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.
Plan ID: — (data accuracy; follow-up to #29 / T-A10-02) Ticket: — Wave: —
Constraints honored:
owasp_entries, MAESTRO layer/role and mitigations are untouched. Only statements a primary source contradicts change.docs/incidents.js/docs/data.jsare regenerated with data only.Fixes #86.
Corrections
Also:
references[]andexternal_refs[]for all four. Before this, only the AST10 landing page was cited.behavioural-detection→skill-scanner; INC-124 dropscve.Human decisions — judgments that rested on a corrected claim (C4, not changed)
Critical. OpenClaw classified the issue High, and the 9.9 CVSS that likely justified Critical belonged to another CVE. Re-rate or keep?AST03(Over-Privileged Skills), with tagover-privilege. With over-permissioning gone, is AST03 still right, or does the plaintext-secrets mechanism belong elsewhere?AST04Insecure Metadata is one candidate — expert call.L5roleblind-spotwas premised on "detection came from runtime behaviour". The new note ("in use by 6,000+ users before a scanner flagged them") still supports a detection gap, but please confirm.impactdropped "context poisoning", which no source mentions. The mitigations are unchanged.Deliberately NOT changed
owasp_entries, layer ids/roles, mitigations: see the questions above.control_failureson INC-124: its two T-STRAT03: evidence loop — derive evidence_count from incident control failures (+ 18-record DRAFT pilot batch) #87 drafts quote the Oasis disclosure and are unaffected.CVE-2026-28363example inincidents-schema.json's field description: it's a format example, not a claim about any incident.Verify
🤖 Generated with Claude Code
https://claude.ai/code/session_014SfR2YzLxRH54DAVzDk8gR