<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Council of AI — corrections ledger</title>
  <link>https://councilof.ai/</link>
  <atom:link href="https://councilof.ai/feeds/corrections.xml" rel="self" type="application/rss+xml"/>
  <description>Every entry is something we got wrong, how it was caught (usually by our own instrument), and the fix — dated. Derived from GET /api/corrections; nothing here is typed into the feed. An entry is a fact about our own history, not a measurement and not a claim about anyone else.</description>
  <language>en-gb</language>
  <item>
    <title>C-2026-0905-02 — 26 SWIFT rail cards were published under public/interop/swift-signed-2026-09/ as signed-swift-&lt;bank&gt;.json with a populated sig_ed25519 field and signed_at timestam</title>
    <link>https://councilof.ai/api/corrections#C-2026-0905-02</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0905-02</guid>
    <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: 26 SWIFT rail cards were published under public/interop/swift-signed-2026-09/ as signed-swift-&lt;bank&gt;.json with a populated sig_ed25519 field and signed_at timestamp. The field held base64(sha256(card)), not a signature; sig_algo said SHA256-placeholder and the index said the same. A relying party reading the field name, the file name or the directory name was told these were Ed25519-signed. They were not. Nothing verifies.

HOW IT WAS CAUGHT: Outside review of the estate on 2026-09-05 named the 26 placeholder cards as the single most damaging thing an inspector could find. Confirmed against master: 26 of 26 files, sig_algo SHA256-placeholder, producer scripts/badger/csoai-swift-aware.py writing a digest when no key was present.

FIX: Producer changed: with no key it now writes sig_ed25519 null, sig_algo UNSIGNED, signed_at null, a signature_note, into swift-staged-2026-09/ as staged-swift-*.json; the OIDC board-sign path is the only signer. The 26 artifacts were rewritten the same way and moved; swift-signed-index.json is superseded by swift-staged-index.json (total_signed 0, total_staged_unsigned 26). No card here is signed or MEASURED.

STATUS: CORRECTED — 0 signed, 26 staged and labelled; placeholder producer removed

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0905-03 — Three public endpoints turned a source they could not read into a number, and two of them published a figure that was wrong while they did it.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0905-03</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0905-03</guid>
    <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Three public endpoints turned a source they could not read into a number, and two of them published a figure that was wrong while they did it. (1) /api/hub-cards fans out to four Hub index files and totalled whatever came back. Two of the four were answering nothing to the Worker, and both held ONLY UNMEASURED rows, so the endpoint served 682 cells / 647 MEASURED / 35 UNMEASURED when the published population was 717 / 647 / 70. It understated the unmeasured count by exactly half, and the error therefore ran in the flattering direction — the one direction a measurement body may never round. The endpoint did disclose the partial read, but it did so in an honesty field while counts kept publishing quotable integers beside it; a disclosure next to a wrong number does not repair the number, and downstream quotes the number. (2) /api/dashboard/stats derived fleet.online from `.online ?? .nodes?.length ?? 0`. /api/oracle-fleet emits neither field — it answers 200 with a single host's health — so the dashboard published online: 0, meaning no nodes online, against a fleet that was up and answering with 26.9 days of uptime. That is a claim the fleet endpoint never made, invented from two absent keys. The same file coalesced every other aggregate with `?? 0`, so an unreadable /api/gspc would have published measured_axes: 0 while the board carries 22, under a header that claimed honest empty states — but zero is a measurement, not an empty state. (3) /api/hf-spaces returned an empty list on any non-OK response and counted the survivors, so one upstream throttle would publish models: 0, indistinguishable from the org having no models. That one was latent: it agreed with the Hub on the day it was found.

HOW IT WAS CAUGHT: A top-down alignment pass on 2026-09-05 re-ran the estate brief's own verification commands instead of trusting the brief, and /api/hub-cards disagreed with it. Reading all four Hub index files directly showed all four answering 200 and non-empty to a plain client at dataset commit c52587b, while the endpoint's own indexes_read field said 2 of 4. A sweep for the same shape — any endpoint that fans out to N sources and reports whatever came back — found the other two. The dashboard defect had a passing test over it: the fixture mocked /api/oracle-fleet as an object carrying online and nodes, a shape the real endpoint does not return, so a test that invented the upstream could not catch a misread of the real one.

FIX: Every one of the three now distinguishes an unread source from an empty one. A total is published only when all of its sources answered; otherwise the totals are null, what was actually read is offered under a separate name documented as a floor, and each missing source is named with its reason. An index or listing that answers with zero rows counts as READ — the previous code treated any empty result as unreachable, which would have let a legitimately empty source suppress the totals forever. hub-cards additionally retries a failed index once outside the Cloudflare cache, because the fetch carried cacheEverything and a cached non-OK response keeps a source dark for the whole ten-minute window. dashboard/stats gained a sources block naming each upstream's state and a note stating that a null is an unread value and never a measured zero; its fleet.online carries its own note explaining why it is null, so a bare null cannot be re-read as zero. The dashboard UI already rendered a missing value as an em dash, so the honest empty state was available all along and was simply not being sent. Tests were watched failing against the unpatched handlers before being accepted.

STATUS: CORRECTED IN SOURCE — hub-cards under PR #1294, dashboard/stats and hf-spaces under PR #1297, recorded as issue #1295. The wrong figures were live until those deploy. Whether the hub-cards retry restores the two dark indexes is not yet established: it cannot be tested from outside the Worker, and if they stay dark the endpoint now reports that instead of a flattering subtotal.

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0905-04 — Six public manifests under /interop advertised 36 endpoint references that do not exist: custom-gpt-bridge.json told Custom GPTs to POST /api/measure, /api/verify </title>
    <link>https://councilof.ai/api/corrections#C-2026-0905-04</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0905-04</guid>
    <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Six public manifests under /interop advertised 36 endpoint references that do not exist: custom-gpt-bridge.json told Custom GPTs to POST /api/measure, /api/verify and /api/xrpl/evidence; chatgpt-features-finish.json listed 14 'features' (/api/voice, /api/vision, /api/calendar, /api/email, ...) each with an endpoint; deep-research-integration.json described a four-endpoint /api/research pipeline; persona-tests.json, chatgpt-skills.json and anchor.json cited /api/anchor, /api/insurance/attest, /api/xrpl/rlusd, /api/xrpl/usdc and /api/scheduler. Every one answered HTTP 404 to GET and POST on 2026-09-05. All six were written by two generators under scripts/badger/ that assemble manifests from a wish-list and never probe a route.

HOW IT WAS CAUGHT: A top-down pass on 2026-09-05 found /api/verify returning 404 and followed the references: three files first, then every /api/ path in the six generated manifests, each probed live with GET and POST.

FIX: Each artifact now carries claims_audit_2026-09-05 naming the dead paths; every dead reference is marked NOT_IMPLEMENTED in place, and the three Custom GPT actions a client would actually call were removed and listed under actions_removed. Both generators now exit at main() with the reason and cannot regenerate the fiction. The rule (an endpoint advertised outward must answer non-404 live) is the one scripts/outward-claims-guard.mjs enforces post-deploy.

STATUS: CORRECTED IN ARTIFACT AND PRODUCER. Whether any Custom GPT or agent acted on the dead manifests is unknown; no request log is kept for those paths. Nothing was ever measured, signed or anchored through them.

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0905-05 — A merged commit and its PR (#1321) stated that a confirmed x402 settlement never reached the revenue ledger: &quot;a real payment settled and the ledger never saw it&quot;.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0905-05</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0905-05</guid>
    <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: A merged commit and its PR (#1321) stated that a confirmed x402 settlement never reached the revenue ledger: &quot;a real payment settled and the ledger never saw it&quot;. That is false. The settlement WAS recorded. The reading behind the claim was taken 6 seconds after the settle, and Cloudflare KV list operations are eventually consistent — the record had not propagated yet. Re-read ~20 minutes later, /api/revenue one_number showed settlements 1, all_time 1, records_unreadable 0. No payment was ever lost.

HOW IT WAS CAUGHT: Re-checking the same endpoint later in the same session instead of trusting the first reading. curl -s https://councilof.ai/api/revenue | python3 -c &quot;import sys,json;print(json.load(sys.stdin)['one_number'])&quot; — run twice, minutes apart, and the two disagree while nothing else changed.

FIX: This entry records the false claim; the commit message cannot be rewritten. The code change that shipped with it stands on its own merits and is unaffected: recordSettlement had swallowed every KV error into an empty catch, so a failed write and no settlement really were indistinguishable, and it now returns {stored,reason}. What was wrong was the diagnosis, not the fix. A second defect found while re-reading IS real and is corrected in the same change: one zero-value settle from an ephemeral wallet moved one_number.all_time from 0 to 1, counting a wallet we created and controlled, paying nothing, as a distinct non-self buyer — so settlement records now carry zero_value, because the payer-exclusion list can never enumerate a throwaway key.

STATUS: RECORDED — the claim was a measurement error (KV eventual consistency read at 6s); no settlement was lost

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0905-01 — The ONE root (public/root.json) is documented as republished hourly.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0905-01</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0905-01</guid>
    <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The ONE root (public/root.json) is documented as republished hourly. Between 2026-09-02T04:14Z (last successful public-root run) and 2026-09-03T06:20Z (first successful run after GitHub reinstated Actions on the CSOAI-ORG account) it was not republished at all: the hourly runs from 05:14Z to 19:58Z on 2 Sep never started (Actions disabled for the account, Support ticket #4720908), and the eight runs from 2026-09-02T20:58Z to 2026-09-03T06:16Z failed at runner start. Cards signed in that window were not in any root a reader could fetch, and the witness pointer kept reporting the 04:14Z root as current, which it was — but nothing said the cadence had stopped.

HOW IT WAS CAUGHT: Run history of .github/workflows/public-root.yml read back on 2026-09-05 after reinstatement: one success at 04:14Z, a gap with no runs at all, eight failures, then success at 06:20Z on 3 Sep. The gap is visible only in the run list; the root, the pointer and the site all looked normal during it.

FIX: This entry records the window. No root bytes were edited (none existed to edit). The as_of field on the root and the checked_at field on the pointer are the only honest freshness signals; HOW-TO-VERIFY-ROOT.md already tells a reader to re-fetch and compare rather than trust a MATCH observation. Structural fix, same day: the witness now also reports a CONFLICT state when two witnessed roots carry the same as_of and different merkle_root values, so a stalled or forked cadence is named rather than inferred.

STATUS: RECORDED — a 26-hour publication gap, 2026-09-02T04:14Z to 2026-09-03T06:20Z; no bytes changed, cadence documented as not guaranteed

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0903-01 — The Layer-0 ceremony artifact (/interop/layer0-ceremony-2026-09-03.json, v0.2) listed /api/intoto as one of 15 machine rails, recorded it as returning 404, and exp</title>
    <link>https://councilof.ai/api/corrections#C-2026-0903-01</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0903-01</guid>
    <pubDate>Thu, 03 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The Layer-0 ceremony artifact (/interop/layer0-ceremony-2026-09-03.json, v0.2) listed /api/intoto as one of 15 machine rails, recorded it as returning 404, and explained the 404 as 'the handler exists in master but is inside an undeployed window'. There is no handler. functions/api/intoto.ts exports only helpers (subjectDigest, toInTotoStatement, toDsse) and is imported by functions/api/detect.ts and functions/api/detector-interop.ts, both of which serve 200. No deploy would ever have turned it into a route. A ceremony whose purpose is to attest our own machine surface had invented a door and then explained away its absence.

HOW IT WAS CAUGHT: Live sweep of 25 published surfaces on 2026-09-03: exactly one non-200, /api/intoto. Tracing it showed the file has no onRequest export, and that the ONLY thing on the estate advertising /api/intoto as an endpoint was the ceremony artifact itself.

FIX: Ceremony superseded at v0.3: the rail is removed and the correction is stated in the artifact's own what_this_does_not_claim, first line. The count becomes 14 of 14 serving rather than 14 of 15. in-toto capability is real and reachable through /api/detect and /api/detector-interop. v0.2 was superseded in place rather than kept, because it had no external reference and its OpenTimestamps stamp was still PENDING with no Bitcoin attestation to preserve; had the stamp been upgraded, the bytes would have been kept and a new file issued.

STATUS: CORRECTED — 14 of 14 rails; the invented door is gone

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-09 — After C-2026-0902-08, live GET /api/gspc and /api/state headlines were 22 axis · 22 measured, but public/signed/gspc-board.signed.json was still the earlier 22/15/</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-09</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-09</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: After C-2026-0902-08, live GET /api/gspc and /api/state headlines were 22 axis · 22 measured, but public/signed/gspc-board.signed.json was still the earlier 22/15/7 freeze, so signed_snapshot_agrees stayed false and the snapshot was labelled do-not-file.

HOW IT WAS CAUGHT: Owner MPC ceremony on the Oracle custody host: live /api/gspc snapshot (site_attestation stripped) signed with did:web:csoai.org#gspc-board-22axis-2026 (3-party Coinbase cb-mpc Ed25519 additive). Offline verify (scripts/gspc-board-verify.mjs) returned VERIFIED; content_id 72ba8a3371fcc895be835f4283fefca0c2edd1e1fc857b3e49276277f94ccb10.

FIX: The verified 22/22 freeze replaced public/signed/gspc-board.signed.json. /api/state now reports signed_snapshot_agrees from the count match (22 slots · 22 measured). The 15/7 file is superseded, not edited. The Pages /api/board-sign path was not used — it is a 3KB card-sign and cannot carry this snapshot.

STATUS: CORRECTED — signed freeze is 22/22 and agrees with the live axis arrays

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-08 — /api/state quoted public/signed/gspc-board.signed.json totals (22 slots · 15 measured · 7 empty) as the number to file, and said that when that snapshot disagreed </title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-08</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-08</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: /api/state quoted public/signed/gspc-board.signed.json totals (22 slots · 15 measured · 7 empty) as the number to file, and said that when that snapshot disagreed with live /api/gspc neither figure was quotable. Live GET /api/gspc (and the committed axis arrays it derives from) is 22 axis · 22 measured · 0 empty. A VRO map mailed 1 Sep used the 15/7 freeze; the correction that actually transited SMTP is Sent 82 (2 Sep 14:50Z) pointing at /api/gspc.

HOW IT WAS CAUGHT: Recipient audit of the VRO table: /api/gspc and the homepage said 22/22; /signed/gspc-board.signed.json and /api/state still said 15/7 with signed_snapshot_agrees false.

FIX: /api/state board headlines now derive from the same axis arrays as GET /api/gspc. The signed snapshot stays on disk as a historical freeze (MPC key did:web:csoai.org#gspc-board-22axis-2026, three shares, not re-derived here) and is labelled do-not-file. Re-signing that 38KB file is an owner MPC ceremony — the Pages /api/board-sign path is a 3KB card-sign and cannot carry the snapshot.

STATUS: CORRECTED — live 22/22 is the quotable count; snapshot 15/7 is historical pending owner MPC re-sign

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-10 — The published verification rule (/signed/HOW-TO-VERIFY.md and HOW-TO-VERIFY-ROOT.md) did not state that a verifying signature says nothing about whether the signin</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-10</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-10</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The published verification rule (/signed/HOW-TO-VERIFY.md and HOW-TO-VERIFY-ROOT.md) did not state that a verifying signature says nothing about whether the signing key is still valid. A reader verifying with yesterday's trust anchor would get the same VALID verdict after a revocation this morning, and nothing in the text said so.

HOW IT WAS CAUGHT: IETF agentproto list, 31 Aug–2 Sep 2026: an objection to the offline-verification sentence in a proposed charter amendment (offline verification is a computation over the past; revocation is a fact about the present). CSOAI committed on the list to add the sentence and note the correction.

FIX: Both rules now carry a section stating what a verifying signature does not establish, that no revocation mechanism or key-freshness requirement is defined here, that a consumer must not treat a verifying signature as evidence the key is still valid, and that key-resolution path and accepted staleness are deployment parameters the card does not carry.

STATUS: CORRECTED — rule amended; second unstated property caught by that thread (the first was a signed flag with no signature bytes behind it)

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-07 — On 2026-08-28 a commit edited the text of a signed card in place (public/signals/cross-border-card.signed.json, field measured_axes: the 18 Aug count was replaced </title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-07</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-07</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: On 2026-08-28 a commit edited the text of a signed card in place (public/signals/cross-border-card.signed.json, field measured_axes: the 18 Aug count was replaced with a pointer to the live count) without re-signing. The content_id no longer derived and the Ed25519 signature no longer verified — a silent edit of a signed artefact, which this ledger's own policy forbids.

HOW IT WAS CAUGHT: The unit suite (cardVerify: content_id derives and signature verifies) failed on master; found during the 2 Sep test-truth pass.

FIX: The original signed bytes are restored so the card verifies again. The caveat lives here instead: the card's measured_axes text quotes the 18 Aug 2026 count; the live count is only ever GET https://councilof.ai/api/gspc totals. Signed bytes are never edited — they are superseded by a new signed card or annotated in this ledger.

STATUS: CORRECTED — signed bytes restored; caveat carried by this entry

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-01 — The Switchboard research brief recorded OUSG's XRPL domain check as unverified (directory only) while GET /api/xrpl showed it bidirectional with a signature.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-01</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-01</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The Switchboard research brief recorded OUSG's XRPL domain check as unverified (directory only) while GET /api/xrpl showed it bidirectional with a signature.

HOW IT WAS CAUGHT: Owner reconciliation of the 2 Sep research briefs against the live API.

FIX: GET wins. /api/xrpl is the authority: OUSG verified_via 'Bidirectional domain match'. The brief's cell is superseded; no data change.

STATUS: RECONCILED — live API authoritative

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-02 — A secondary planning state file attributed USDB to Bitstamp.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-02</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-02</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: A secondary planning state file attributed USDB to Bitstamp. USDB is issued by Braza Bank (issuer address rB3y9EPnq1ZrZP3aXgfyfdXQThzdXMrLMc).

HOW IT WAS CAUGHT: Owner reconciliation; the Switchboard brief confirms Braza.

FIX: GET /api/xrpl already carries issuer 'Braza Bank'; the mis-attribution lived only in a planning file and is corrected there.

STATUS: CORRECTED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-03 — The OpenAI incident post-mortem was cited as 37 pages by one source and 38 by an internal state file.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-03</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-03</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The OpenAI incident post-mortem was cited as 37 pages by one source and 38 by an internal state file.

HOW IT WAS CAUGHT: Owner reconciliation of the incident-card inputs.

FIX: No incident card hashes that artefact until the primary PDF is fetched, hashed and its page count read from the file itself.

STATUS: PENDING VERIFICATION — card withheld until the primary PDF is hashed

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-04 — GPAI Code of Practice signatory counts differed: 26 per the Commission's 1 Aug 2025 list versus '28 frozen' in secondary sources.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-04</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-04</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: GPAI Code of Practice signatory counts differed: 26 per the Commission's 1 Aug 2025 list versus '28 frozen' in secondary sources.

HOW IT WAS CAUGHT: Owner reconciliation.

FIX: Only the live, dated Commission page is carded (interop/gpai-signatory-2026-09). Secondary counts are not quoted.

STATUS: CORRECTED — primary source only, dated

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-05 — One playbook stated 2 Feb 2027 as the Article 50 detector-interoperability date as fact; a market-map brief records it as unsettled.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-05</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-05</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: One playbook stated 2 Feb 2027 as the Article 50 detector-interoperability date as fact; a market-map brief records it as unsettled.

HOW IT WAS CAUGHT: Owner reconciliation.

FIX: The date is not published anywhere until verified against Regulation (EU) 2026/1744 in the Official Journal.

STATUS: UNVERIFIED — withheld

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0902-06 — councilof.ai states a £5M professional-indemnity policy while the Series A pack's infrastructure-gaps sheet says insurance is unknown.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0902-06</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0902-06</guid>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: councilof.ai states a £5M professional-indemnity policy while the Series A pack's infrastructure-gaps sheet says insurance is unknown. One of them is wrong in a data room.

HOW IT WAS CAUGHT: Owner reconciliation.

FIX: Owner to confirm the policy document; the losing statement is corrected in place and this entry updated. 2026-09-05: no policy document, certificate or insurer correspondence was found in the business mailbox or the repository, so the public assertion (About: 'operates with full professional indemnity insurance'; Disclaimers: 'maintains professional indemnity insurance') was withdrawn to the evidenced state — both pages now say cover is not stated until the policy document is on file. The assertion is restored, with insurer, limit and dates, the day the document is filed.

STATUS: CORRECTED — public assertion withdrawn pending the policy document; restore on receipt

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-12 — The board attestation's sig_input was ambiguous, and the ambiguity was live rather than theoretical.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-12</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-12</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The board attestation's sig_input was ambiguous, and the ambiguity was live rather than theoretical. It read &quot;canonical JSON (recursively sorted keys, no whitespace) of this payload with the site_attestation field removed&quot; — six words that do not pin a preimage. The natural first reading in a Python-flavoured estate is json.dumps(sort_keys=True, separators=(',',':')), whose default is ensure_ascii=True, and that FAILS: the signer emits non-ASCII literally, i.e. ensure_ascii=False. The signed payload carries 81 non-ASCII code points (middle dot, multiplication sign, en dash, em dash, right arrow, greater-than-or-equal), and the two readings differ by about 256 bytes. Two implementers reading the same sentence get two different preimages and one of them reports a bad signature on a good artefact. The sentence also never said whether the signature is over the raw bytes or over a digest of them.

HOW IT WAS CAUGHT: Outside audit of the live site, 2026-08-26 (finding A2). The auditor's first and more natural reading failed; the signature verified on the second attempt, after guessing.

FIX: sig_input now states the rule as bytes: Ed25519 over the RAW UTF-8 bytes (not a digest) of canonical JSON with keys sorted by code point recursively, no whitespace, non-ASCII emitted literally as UTF-8 and never as \\uXXXX escapes (ensure_ascii=False, with ensure_ascii=True named explicitly as the wrong reading), and numbers serialised by ECMAScript Number::toString so an integral float renders 0 and not 0.0. Two machine-readable fields, sig_input_ensure_ascii: false and sig_input_is_digest: false, carry the same facts for a parser. CRITICALLY, THE CARDS ARE THE OPPOSITE AND STAY THAT WAY: the 150 measurement cards were minted with ensure_ascii=TRUE and CPython float repr, and each card states so in its own preimage field. Neither rule can be migrated to the other without invalidating signatures over bytes that already exist, so nothing was harmonised — both rules are now stated explicitly wherever each is published, and /signed/HOW-TO-VERIFY.md carries a table putting them side by side so a reader who verifies both is not burnt by the difference.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-11 — The public MCP `measure` tool returned ok:true for every subject, including subjects that do not exist.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-11</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-11</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The public MCP `measure` tool returned ok:true for every subject, including subjects that do not exist. Passing a nonsense model name produced {&quot;ok&quot;:true,&quot;claim&quot;:&quot;measurement&quot;,&quot;subject&quot;:&quot;&lt;the nonsense name&gt;&quot;} with a note explaining that nothing had actually been measured. No measurement ran, no axes came back, no credential was issued, and the tool's own description promised &quot;a signed measurement credential&quot;. A measurement tool that succeeds on a nonexistent subject cannot distinguish MEASURED from DID NOTHING — which is exactly what our own /api/mcp honesty_contract forbids: unknown is null or unmeasured, never a plausible-looking value. We applied that doctrine to the registry and not to the tool.

HOW IT WAS CAUGHT: Outside audit of the live site, 2026-08-26 (finding P1). The auditor called the tool with THIS-MODEL-DOES-NOT-EXIST-xyz and got the same ok:true as for gpt-4o. Nothing on our side was checking; the tool was listed as `probed` because tools/list returned its name, and `probed` was reading as `works`.

FIX: `measure` now returns ok:false with a named state on every call, because no call to it ever succeeds: INVALID_ARGUMENT when no subject is given, NOT_MEASURED otherwise, each with the reason and a pointer to where published measurements actually live (/signed/card_index.json and /api/gspc). It also states plainly that it did NOT check whether the subject exists rather than implying it did. The tool description in tools/list is rewritten to what the endpoint does — return the contract — so an honest result no longer sits behind a description that over-promises. PARTIAL, AND SAID SO: the upstream worker's source is not in this repository, so the correction is applied at councilof.ai/mcp, the address published in .well-known/mcp.json and agent-card.json. The worker's own workers.dev origin still returns ok:true and needs an owner-side deploy to close.

STATUS: FIXED AT THE PUBLISHED ENDPOINT; UPSTREAM WORKER FIX PENDING (owner)

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-10 — The jail axis published a dataset_url that is not a URL, directly beneath a note asserting that every such URL is fetchable.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-10</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-10</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The jail axis published a dataset_url that is not a URL, directly beneath a note asserting that every such URL is fetchable. The axis's `dataset` field — an identifier field, resolved to a link by string concatenation against https://huggingface.co/datasets/ — held a prose sentence: &quot;published: csoai/gspc-jail-goldbank (frozen 71-cell gold bank, HF 2026-08-25)&quot;. The resulting dataset_url contained a colon, spaces and parentheses and was rejected by curl as malformed. Twelve other banked axes resolved fine, and the bank itself was always fine and always public. The bank_note above it read &quot;Every axis WITH a frozen bank carries dataset_url — the bank resolved to a fetchable URL&quot;: a blanket assertion with nothing deriving it, false for as long as it stood.

HOW IT WAS CAUGHT: Outside audit of the live site, 2026-08-26 (finding D10). The auditor fetched all fourteen; thirteen returned HTTP 200 and one would not parse.

FIX: `dataset` now holds the bare slug csoai/gspc-jail-goldbank and the prose moved to dataset_note. The resolver no longer concatenates blind: a value that is not a bare &lt;owner&gt;/&lt;name&gt; slug now publishes dataset_url: null with dataset_url_state UNRESOLVABLE and the raw value, so the fault is visible on the surface that carries it instead of shipping a string that looks like a link. bank_note is now derived from that same predicate and reports counted totals (banked_axes, banked_axes_resolvable, banked_axes_unresolvable), so the sentence and the bytes cannot disagree again. The same correction is applied to the packaged /signed/gspc-measurement.json, which carried the identical prose.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-09 — We published recall: null for council-inhouse-ft on the jail axis where the measured value is 0.0.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-09</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-09</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: We published recall: null for council-inhouse-ft on the jail axis where the measured value is 0.0. That model has tp=0 and fn=38, so recall = tp/(tp+fn) = 0/38 = 0.0 — defined, measured, and the single most damaging number on the axis: our own fine-tune detected zero of 38 escapes. null reads as NOT MEASURED. Publishing it in place of a real zero is this estate's own defect class inverted: instead of inventing a number where none exists, we erased a number that did. It sat on a row whose note says &quot;published, not hidden&quot;. precision on the same row is legitimately null (0/0 is undefined, nothing was predicted positive), so two fields carrying the identical value meant opposite things with nothing distinguishing them.

HOW IT WAS CAUGHT: Outside audit of the live site, 2026-08-26 (finding D11). Every other cell of the jail axis reproduced to the item — seven confusion matrices, precision, recall, accuracy and the fleet mean — and this was the one arithmetic exception the auditor found.

FIX: recall is 0.0 on /api/gspc and in /signed/gspc-measurement.json. The axis now carries a null_grammar field stating which null means UNDEFINED and which zero means MEASURED, so the distinction is published rather than left to be inferred. The frozen /signed/gspc-board.signed.json still contains recall: null and is NOT edited: its MPC custody signature is over those exact bytes, so correcting it at source is an owner-supervised re-sign. Until then this ledger and the live board carry the correction where a reader will meet it.

STATUS: FIXED ON THE LIVE BOARD; FROZEN SIGNED SNAPSHOT AWAITS RE-SIGN (owner)

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-08b — The living_stamp was presented as a valid attestation and cannot be checked by anyone.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-08b</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-08b</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The living_stamp was presented as a valid attestation and cannot be checked by anyone. It shipped signed: true and a sig_input recipe, rendering exactly like the two attestations on this site that do verify. It does not verify. Three faults compound: TWO different signatures are published for one stamp, with the same signer and the same `updated` — one in /signed/board_living.json, a different one in /api/gspc measured_on.living_stamp, and at most one can be over the bytes the other is over; the signer is in NONE of the four verification methods in our own did.json, so even a reproducing preimage would prove only self-consistency, the unfalsifiable shape our own HOW-TO-VERIFY tells strangers to refuse; and board_living.json states in its own note that its axes were re-snapshotted from the live board at package time, six days after the signature date, so the signed bytes are not the published bytes.

HOW IT WAS CAUGHT: Outside audit of the live site, 2026-08-26 (finding A3): roughly fifty readings attempted, none verified. Re-run in this lane the same day at wider scope — both published signatures, all five published keys, nine candidate payloads, raw/sha256-digest/sha256-hex message forms, both ensure_ascii settings, every drop-set of up to three fields: 58,184 attempts, 0 verified.

FIX: The stamp is marked UNVERIFIABLE wherever it is published — /api/gspc, /signed/board_living.json and /signed/gspc-measurement.json — carrying verification_state UNVERIFIABLE, verifiable: false, signer_anchored: false, the attempt count, and a note stating that it must not be treated as a valid attestation and pointing at the two attestations that do verify. It is NOT withdrawn and its bytes are NOT altered: a row saying &quot;we published this and nobody can check it&quot; is worth more than a quietly deleted one, and if a preimage rule is ever recovered it must still verify against these bytes. We do not claim the stamp is invalid — only that it is uncheckable, which for a relying party is the same outcome. To close: anchor the signer in did.json, publish the exact preimage (which fields are signature fields, raw bytes versus digest, encoding), and publish ONE signature. Owner-gated; this lane does not hold the key.

STATUS: MARKED UNVERIFIABLE; REPRODUCIBLE SIGNATURE PENDING (owner)

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-07b — The claims register described bytes that do not exist.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-07b</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-07b</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The claims register described bytes that do not exist. CR-002 gave as its evidence &quot;Cards declare timestamp_authority: 'none'&quot;. Zero of the 150 published cards contain that field; the string &quot;timestamp&quot; appears in no card, not in card_index.json and not in the cross-border card. The substance was honest — there genuinely is no timestamp authority behind any card — but the register asserted a positive declaration as its evidence for an absence, and the claims register is the one page whose entire purpose is claim-to-evidence fidelity. A correction that misdescribes the thing it corrects is worse than the original gap.

HOW IT WAS CAUGHT: Outside audit of the live site, 2026-08-26 (finding D8). One grep over the published cards.

FIX: CR-002 now describes what the cards actually declare: nine body fields, none of them a timestamp authority; the only time a card carries is `created`, an instant the issuer asserted from its own clock and then signed, which attests assertion and not independent observation; and `prev` gives ordering, not time. The superseded wording is kept on the row under a dated `amended` note and rendered on /claims-register — a published claim is amended in the open, never rewritten in silence. Adding an explicit timestamp_authority: &quot;none&quot; to the card schema would be the stronger answer and is recorded as a change for the NEXT card format, not as a thing already done: each card id is the SHA-256 of its own body, so a new field re-mints every id and invalidates every published signature.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-06b — /claims-register announced &quot;20 claims&quot; and rendered 19, immediately beneath its own sentence &quot;This page renders that exact file — there is no second copy to drift</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-06b</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-06b</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: /claims-register announced &quot;20 claims&quot; and rendered 19, immediately beneath its own sentence &quot;This page renders that exact file — there is no second copy to drift.&quot; The header printed claims.length while the sections were built from a hardcoded four-status order — live, devnet, planned, retired — and claims-register.json declares five. The fifth is `unmeasured`, and the one claim carrying it (CR-020) had no case in the renderer, so it was silently filtered out of the page and out of the legend. On a site whose banner is &quot;UNMEASURED shown honestly&quot;, the register dropped the only unmeasured row. The wrong count was the visible defect; the dropped row was the worse one.

HOW IT WAS CAUGHT: Outside audit of the live site, 2026-08-26 (finding D9). The auditor diffed the rendered ids against the JSON. Nothing on our side compared the two — the drift the sentence rules out was never checked.

FIX: The page now derives its status order from the file's own statuses[] and appends any status that appears on a claim but was not declared, so a row can never be dropped for wearing an unexpected label; `unmeasured` has a real chip and a real legend entry. The header count is the length of the rows actually rendered, not claims.length — a number on that page is now derived from what a reader can scroll to. If a row ever does fall out, the page says so in a visible RENDER DEFECT banner naming the id. scripts/claims-register-lint.mjs re-derives the grouping at build time and fails the build on any drift between the file and the page, including a declared status with no legend entry or a typed number back in the header.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-08 — For twelve days the verify page told strangers to pin a signing key that does not exist.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-08</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-08</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: For twelve days the verify page told strangers to pin a signing key that does not exist. The page's authorship note named a published key by an eight-character fingerprint beginning f4b4278d. That fingerprint matches none of the four keys in our DID document, not the card-attestation key the 150 board cards are actually signed with, not the board key, not the living-stamp key. It appears in exactly one place in the entire estate — that sentence — and in no signed artifact, no key file and no commit that produced key material. It was introduced on 2026-08-14 in a bulk copy reconciliation, alongside an OpenTimestamps anchoring claim that was itself later walked back. We cannot establish what it was, so we are not going to invent a story for it: it was a fabricated fingerprint, and a fingerprint is the one string on a page telling people which key to trust that has to be right. The real card-attestation key, beginning d4cb0eaa, appeared nowhere on that page.

HOW IT WAS CAUGHT: An outside auditor with no CSOAI code and no CSOAI credentials grepped the fingerprint across every page, the DID document and the card index, and found one occurrence and no key. Not self-caught. The estate had published a key-pinning instruction it had never once executed against its own page.

FIX: The fabricated fingerprint is removed from both surfaces that carried it, the verify page and the agent registry. Both now name the anchor by its DID identifier, link the DID document so a reader can read the key out for themselves, and print the real key prefix. No provenance has been invented for the removed string, because none could be established.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-07 — Our own published verifiers rejected our own genuine cards, and our tamper detector rendered its failure in green.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-07</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-07</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Our own published verifiers rejected our own genuine cards, and our tamper detector rendered its failure in green. Three separate defects on the one surface whose entire purpose is that a stranger does not have to take our word for anything. First, the single-record verifier on the verify page hashed the whole card envelope minus the signature instead of the body sub-object the signature actually covers, so it could never verify any card, ever — and it reported that preimage bug as no published key verifies this signature, which is a statement about key publication and was false, sending readers to hunt for a key that was published all along. Second, the same form fed its verdict to a public opt-in tally, so every honest visitor who verified a real card and clicked the button filed a false failure into a public counter. Third, the MCP verify tool answered unrecognized card family to every card family we publish, including the cross-border card that verifies fine under our own recipe, because it looked for a content_id field on cards that carry id. Fourth, the client-side chain verifier's headline label was a constant string reading chain intact regardless of outcome; only the tick flipped to a cross, so a successfully detected tamper announced that the chain was intact, in the success colour, on the page that promises a broken row is reported as BROKEN, visibly.

HOW IT WAS CAUGHT: An outside SCITT implementer followed our post to the IETF list, verified a card in Python against our published recipe, then clicked our own verify button to cross-check and was told our card was invalid. Every one of these was reachable from the public site with a browser and curl. None was caught by us.

FIX: There is now one verification implementation, shared by the browser form and the MCP endpoint, so the two surfaces cannot disagree again. It implements the published rule exactly, including the CPython number representation that renders an integral accuracy as 0.0 rather than 0 — 56 of the 150 cards carry such a value, and a verifier without that rule reports a false failure on 37 percent of a corpus that is sound. It recognises both published card families rather than rejecting both. Critically, it reports three failures as three different failures: the bytes do not hash to the declared id, the signature does not verify over those bytes, and the signer is not a key published in our DID document mean different things and are never collapsed into each other. The signer is pinned against the live DID document, so a card carrying an attacker's own key is reported as an untrusted signer even when its signature is internally valid. The tamper label now states the outcome in words and a failure no longer renders in the success colour. All 150 published cards verify through the fixed path, a tampered card fails as a hash mismatch, and a re-signed forgery fails as an untrusted signer. Regression tests read the real published bytes so these cannot silently return.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-06 — We repeated a human-versus-machine benchmark contrast without checking whether both sides were scored under the same rule.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-06</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-06</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: We repeated a human-versus-machine benchmark contrast without checking whether both sides were scored under the same rule. The metrology deck cites the ARC Prize project's ARC-AGI-3 result — a human panel solving essentially all environments while frontier systems average well under one percent. The attribution was correct and careful: labelled reported-not-measured, never placed on the board. The number is not the defect. The defect is that we published a comparison between a human figure and a machine figure without asking the question our own first rating-the-raters result exists to ask, which is whether the two figures were produced under the same scoring rule. Having now recomputed ARC's published participant rows for ARC-AGI-2, we know that on that benchmark the human figure is computed under unlimited submissions while machines are scored at two trials, and that the rule-matched human figure is about eleven points lower. We had no basis to assume ARC-AGI-3 was free of the same gap, and no basis to assume it had it.

HOW IT WAS CAUGHT: Self-caught, by our own instrument, on its first run. Building the RTR-A1 human-reference rule-match measurement against ARC-AGI-2 meant asking of another organisation a question we had not asked of our own published page. Sweeping our surfaces for prior statements about the same publisher is what surfaced it. This is the intended failure mode of a rating-the-raters programme: the first thing a new instrument should catch is its owner.

FIX: The deck passage now carries the caveat, stated as a limit rather than a finding: a human-versus-machine contrast only means what it appears to mean if both sides were scored under the same rule; on ARC-AGI-2 we measured that gap; whether ARC-AGI-3 shares it is UNMEASURED because its scoring formula is not published, so we cannot check and will not assume either way. The general rule this establishes for every surface: CSOAI does not republish a human-versus-machine comparison without either verifying rule-match or marking it unverified. Nothing was removed and no third-party number was restated as ours.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-05 — Two published index artifacts claimed a measurement they did not have.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-05</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-05</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Two published index artifacts claimed a measurement they did not have. /interop/ai-economy-index.v0.1.json and /interop/human-labour-index.v0.1.json each carry a status label of MEASURED-INDEX-v0.1, while each also states in its own body that half its input components are bank gaps and that no index value is computed. The axis register had already been reverted to UNMEASURED for both; the artifacts were not, so a live surface kept asserting the retracted status. Existing reference components are not a measured index.

HOW IT WAS CAUGHT: Reading the evidence behind every financial axis before wiring it into the board, rather than trusting the axis register's summary of it. The register said UNMEASURED; the artifact it pointed at said MEASURED-INDEX-v0.1. Following the pointer is what surfaced the disagreement.

FIX: Both axes are wired into the signed board as UNMEASURED, and the board — which is the authority — states on each axis and in its limitations that the v0.1 artifacts' status label was an over-claim and is superseded. Neither index contributes to any measured count. The artifacts themselves are signed under a key this lane deliberately does not hold, so correcting them at source is a separate owner-supervised re-sign; until then the board carries the correction where a reader will meet it.

STATUS: FIXED ON THE BOARD; ARTIFACT RE-SIGN PENDING (owner)

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-04 — The public board contradicted the estate's own ruling for two days.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-04</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-04</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The public board contradicted the estate's own ruling for two days. An owner ruling of 2026-08-24 set the canonical axis count at 22 (14 behavioural + 8 financial/domain), but GET /api/gspc kept reporting '14 measured of 14 quotable' because the 8 financial axes existed only in the ruling and in a side register — never in the signed board payload the count is derived from. Downstream, the estate's own claims register recorded '22' as an internal figure that was 'not corroborated by any live surface', and a source comment instructed authors to 'not invent 22 axes'. The estate simultaneously ruled the number, forbade the number, and published a different one.

HOW IT WAS CAUGHT: Self-reported, not discovered. The ruling document itself recorded that the sweep was authorized but unexecuted, and named the reason. The delay was deliberate and is the point of this entry: a public count must be backed by the signed artifact it summarises, so the fix could not be a copy edit on the pages. Editing the number without the data behind it would have put a figure on a public surface that the signed payload could not support — the same defect class as a score published without its measurement. The board was behind the ruling, never ahead of it.

FIX: The 8 financial/domain axes were wired into the board DATA and the payload re-signed. The board now derives '22 axes · 15 measured' from the axis array: 22 slots, 15 with a real run behind them, 7 declared slots with none. The ruling's own wording applied the word 'measured' to the full slot count, and the evidence does not support that word — only one of the eight financial axes (provenance-controls, a deterministic mainnet read of 6 issuer accounts) carries a measurement. Per this ledger's redaction rule the exact phrase is described rather than reproduced: it is now the forbidden form the build gate catches, and reprinting it here would republish the sentence this correction exists to retire. No axis was marked MEASURED to make the two numbers agree; the grammar changed instead, and both numbers now travel together. Separation statistics and every mean are scoped to model-comparison axes, so a financial axis can neither enter a sentence about statistical separation nor drag an absent value into an average as a zero. The claims register was re-authored from 'internal, not corroborated' to a live claim with the endpoint as its authority, and now names the forbidden form '22 measured axes' explicitly.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-03 — Our own published MCP fleet was silently paywalled and self-scoring.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-03</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-03</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Our own published MCP fleet was silently paywalled and self-scoring. A monetization layer injected into 318 of 363 vendored servers capped the ENTIRE fleet at 10 anonymous tool calls per day from one shared counter; past that, every tool returned a purchase link instead of a result. The injected code was spliced mid-function in 49 files, leaving original function bodies unreachable (256 undefined names). Five scorecard checks awarded points for carrying a purchase link — the system scored itself higher for being paywalled. The paywall also masked quality: a first probe found 1 stub because refusals and stubs were indistinguishable.

HOW IT WAS CAUGHT: Building a remote MCP server for other AI platforms; the first real tools/call returned a purchase upsell instead of a result. Verified twice independently by direct grep and by probing all 338 servers with real MCP sessions.

FIX: Monetization layer removed fleet-wide: 318 -&gt; 0 servers carrying a purchase link, 0 price strings, 0 upsell symbols. Capability preserved and proven, not assumed: all 338 servers re-probed with real initialize/tools/list/tools/call — handshakes 336/338 unchanged, 1869 tools unchanged, 0 broken; undefined names fell 256 -&gt; 16 because removing the injected code repaired what it had broken. Honest stub register published (13 fully stubbed, 10 partial, 2 dead) determined by CALLING every tool, not grepping. scripts/no-paywall-guard.mjs added with a --selftest so the layer cannot return; it caught 48 residuals we had missed.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-02 — Five sector pages asserted, in present tense, that our measurement 'is recognised under mutual recognition agreements with' CISA, NCSC, ANSSI, BSI, BEREC, ENISA, n</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-02</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-02</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Five sector pages asserted, in present tense, that our measurement 'is recognised under mutual recognition agreements with' CISA, NCSC, ANSSI, BSI, BEREC, ENISA, national transport authorities and others — named public bodies, implying an endorsement we do not hold. It shipped in the deployed bundle. Separately, /layer0 served a retracted fault-tolerance claim as a live capability, contradicting our own DR-0007 retraction (measured effective independence 1.21 of 3).

HOW IT WAS CAUGHT: Claims-substantiation audit of the prerendered output, prompted by the FTC's own recommended exercise: inventory every public claim and map it to evidence.

FIX: Replaced with: we crosswalk our measurement output to those compliance pathways, and hold no mutual-recognition agreement with, and are not endorsed or accredited by, any of these bodies. The retracted claim removed from /layer0, /poc-showcase and /competitors. A machine-readable claims register now publishes every claim with its evidence link and a live/planned/devnet/retired status.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0826-01 — Our own prerender verification could not observe failure.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0826-01</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0826-01</guid>
    <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Our own prerender verification could not observe failure. prerender-report.json records a failed route in a field named 'err', but every check in the repository read 'errored' — a field that has never existed. A run in which the browser died on 515 of 581 routes reported '0 errored' and looked clean.

HOW IT WAS CAUGHT: A downstream gate disagreed: brand-gate scanned 71 pages when it should have scanned 603. The upstream report was lying and the layered gate caught it.

FIX: scripts/check-prerender.mjs reads the real fields AND cross-checks the report against the HTML actually written to disk, because a report is a claim and the files are the evidence. It fails loudly on the exact run that had been called clean.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0822-01 — The homepage industry grid still said '15-slot instrument' while the scoreboard, API and canon say '14-slot board, 13 measured of 14' (16 GSPC axes, 13 quotable + </title>
    <link>https://councilof.ai/api/corrections#C-2026-0822-01</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0822-01</guid>
    <pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The homepage industry grid still said '15-slot instrument' while the scoreboard, API and canon say '14-slot board, 13 measured of 14' (16 GSPC axes, 13 quotable + jail floor per the GSPC ruling). A crawler reading the grid would see 15 slots — the exact internal-count inconsistency the count-gating canon exists to prevent.

HOW IT WAS CAUGHT: Text audit of live surfaces against canon (machine-contract style sweep of the homepage and fleet-sweep pages).

FIX: Killed both stale 15-slot references in NewHome-v3 (section comment + industry-grid subtitle) to '14-slot / 13 measured of 14'; verified 0 x '15-slot' remains. (PR #284.)

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0820-01 — Multiple live public surfaces (index.html JSON-LD, GSPCVerify, Insurers, AgentRegistry, Methodology, Agents, ProvBench, measure.html, and the provbench pack) state</title>
    <link>https://councilof.ai/api/corrections#C-2026-0820-01</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0820-01</guid>
    <pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Multiple live public surfaces (index.html JSON-LD, GSPCVerify, Insurers, AgentRegistry, Methodology, Agents, ProvBench, measure.html, and the provbench pack) stated measurement cards are 'anchored with OpenTimestamps' / RFC-3161 / 'Bitcoin block 954857, independently verifiable' as a present capability. The only anchor implemented is Ed25519 + SHA-256 hash-chain; verify.ts checks no timestamp proof and no .ots/Rekor artifact exists.

HOW IT WAS CAUGHT: Internal honesty audit of anchoring claims vs implementation.

FIX: OTS/RFC-3161/Bitcoin claims demoted to roadmap wording across all surfaces; provbench pack corrected; the ML-DSA 'built, not shipped' discipline applied to OpenTimestamps.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-01 — Three public surfaces stated three different item counts at once (llms.txt 819, agent card 890, live API 966).</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-01</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-01</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Three public surfaces stated three different item counts at once (llms.txt 819, agent card 890, live API 966). The banks grew under the hardcoded numbers.

HOW IT WAS CAUGHT: External live-surface audit; confirmed by direct curl.

FIX: llms.txt and the agent card now DEFER to GET /api/gspc as the live source; no public surface hardcodes a count.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-02 — The public board API payload carried internal specialist identifiers — an internal specialist-id prefix — a banned-vocabulary string inside a machine contract, not</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-02</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-02</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The public board API payload carried internal specialist identifiers — an internal specialist-id prefix — a banned-vocabulary string inside a machine contract, not just a human page. (The prefix itself is redacted here: naming it would re-leak the string this entry records as removed.)

HOW IT WAS CAUGHT: K3 lane curl sweep of machine surfaces.

FIX: Renamed to council-* public names in /api/gspc; a machine-contract guard now sweeps API payloads for banned strings on every deploy.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-03 — The single-record verifier initially checked only one content_id envelope; the carder signs a second (signature-included) generation, so valid carder cards could h</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-03</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-03</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The single-record verifier initially checked only one content_id envelope; the carder signs a second (signature-included) generation, so valid carder cards could have read as MISMATCH.

HOW IT WAS CAUGHT: Testing the verifier against a real carder card before shipping.

FIX: The verifier now tries both deterministic envelope generations and names which one matched.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-04 — Two open-source repos (carder, codabench-gspc) shipped with no LICENSE file, and the board API payload stated no licence — while the estate claims openness.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-04</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-04</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Two open-source repos (carder, codabench-gspc) shipped with no LICENSE file, and the board API payload stated no licence — while the estate claims openness.

HOW IT WAS CAUGHT: The carder's own valve-2 benchmark fact-card, run on the estate's own artifacts.

FIX: Apache-2.0 added to both repos; CC-BY-4.0 licence field added to the board payload, with the self-catch admitted in the payload note.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-05 — The did:web trust root at csoai.org intermittently served an orphan key document because two repositories deployed the same Cloudflare Pages project with no owner </title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-05</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-05</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The did:web trust root at csoai.org intermittently served an orphan key document because two repositories deployed the same Cloudflare Pages project with no owner of record.

HOW IT WAS CAUGHT: The did-liveness daemon, then the machine-contract guard's DID split-brain check comparing the authoritative root against the mirror.

FIX: One deployer of record (csoai-site-deploy.yml) builds from the source repo's main with a hard gate: the build fails if did.json lacks the canon keys, and the run fails if the live apex doesn't serve them after deploy.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-06 — An hourly API guard asserted endpoints (/api/tools, /api/mcp) that never existed in the repository's functions tree — a ghost from an older deployment — so it fail</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-06</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-06</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: An hourly API guard asserted endpoints (/api/tools, /api/mcp) that never existed in the repository's functions tree — a ghost from an older deployment — so it failed forever.

HOW IT WAS CAUGHT: Reading the failing run rather than trusting the guard's own claim.

FIX: Rewritten to assert the endpoints the deployment actually ships (/api/health, /api/leaderboard).

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-07 — A banned brand token shipped live on /library as a CamelCase concatenation of the token with 'Training', because a word-boundary regex anchored on the bare token m</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-07</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-07</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: A banned brand token shipped live on /library as a CamelCase concatenation of the token with 'Training', because a word-boundary regex anchored on the bare token missed the concatenation. Two priced strings ($0.005/card, a per-hour range) also shipped, against the no-pricing rule. (The token itself is redacted here for the same reason as C-2026-0819-02.)

HOW IT WAS CAUGHT: A full front-end QA sweep.

FIX: The brand gate's pattern for that token dropped its trailing word boundary so CamelCase concatenations are caught; a pricing-leak pattern was added so a currency amount bound to a subscription or per-unit cadence is now a hard build-fail.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-08 — Estate pages described EU AI Act high-risk obligations as in force from 2 August 2026.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-08</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-08</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Estate pages described EU AI Act high-risk obligations as in force from 2 August 2026. The Digital Omnibus (Reg (EU) 2026/1744) deferred them to 2 December 2027 (Annex III) and 2 August 2028 (Annex I). Serving the dead date would be our own credibility wound.

HOW IT WAS CAUGHT: A commissioned regulation-calendar verification against primary law.

FIX: The /api/regulation feed carries the corrected staged timeline with legal bases; page copy is being swept to match.

STATUS: IN_PROGRESS

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-09 — Two internally-named datasets remained publicly visible on Kaggle under a banned naming class.</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-09</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-09</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Two internally-named datasets remained publicly visible on Kaggle under a banned naming class.

HOW IT WAS CAUGHT: End-user test sweep with anonymous probes.

FIX: Flagged for the owner to set private — the platform gates dataset visibility behind the account login.

STATUS: OPEN

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-10 — The estate's own date-correction fix (C-08) initially ALSO mis-stated the GPAI date — a follow-on error that moved GPAI duties from 2 Aug 2025 to 2026 while correc</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-10</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-10</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: The estate's own date-correction fix (C-08) initially ALSO mis-stated the GPAI date — a follow-on error that moved GPAI duties from 2 Aug 2025 to 2026 while correcting the high-risk date. A correction that introduces a new error is the worst kind.

HOW IT WAS CAUGHT: Self-audit of the fix against the EU official page (digital-strategy.ec.europa.eu) — the estate caught its own owner mid-correction.

FIX: GPAI 2 Aug 2025 restored; Article 50 2 Aug 2026 and high-risk 2 Dec 2027 (Annex III) / 2 Aug 2028 (Annex I) stated distinctly. This entry is that admission, appended not edited.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-11 — mcp.json advertised three server URLs on csoai.org/api/* — every one returned 404 because the API is served from councilof.ai, and one route (corpus-watch) pointed</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-11</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-11</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: mcp.json advertised three server URLs on csoai.org/api/* — every one returned 404 because the API is served from councilof.ai, and one route (corpus-watch) pointed at a non-existent path.

HOW IT WAS CAUGHT: End-user MCP handshake test — a real JSON-RPC initialize probe against the advertised endpoints.

FIX: mcp.json now advertises councilof.ai URLs and the real /api/corpus-watch/status route; the advertised endpoints were verified 200/JSON-RPC-responsive after the fix.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-12 — A measurement wave was queued with sample=24, below the harness's 30-usable-item threshold — all 8 jobs returned UNMEASURED (honestly, but wasted a full wave).</title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-12</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-12</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: A measurement wave was queued with sample=24, below the harness's 30-usable-item threshold — all 8 jobs returned UNMEASURED (honestly, but wasted a full wave).

HOW IT WAS CAUGHT: Reading the signed board's status_note ('no model reached 30 usable items') rather than assuming the bank size was the constraint.

FIX: Requeued at sample=30; all 8/8 came back MEASURED and signed. The threshold is now documented in the job-spec contract.

STATUS: FIXED

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
  <item>
    <title>C-2026-0819-13 — Two measure-chain daemons ran simultaneously after a restart race, double-logging jobs; the restart script's pkill pattern matched its own command line and killed </title>
    <link>https://councilof.ai/api/corrections#C-2026-0819-13</link>
    <guid isPermaLink="false">https://councilof.ai/api/corrections#C-2026-0819-13</guid>
    <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
    <description>WHAT WAS WRONG: Two measure-chain daemons ran simultaneously after a restart race, double-logging jobs; the restart script's pkill pattern matched its own command line and killed its own launch.

HOW IT WAS CAUGHT: Duplicate 'daemon start' markers in the log; the self-kill was traced to the unanchored pkill pattern.

FIX: Anchored process pattern (^python3 /workspace/measure_chain.py) in the restart script; single-daemon verified after relaunch.

This is a correction we issued about ourselves. Measurement, not certification.</description>
  </item>
</channel>
</rss>
