Build EU AI Act Article 12 reference implementation#1
Merged
Conversation
A ~30-line credit-decisioning service that:
- refuses to boot unless the training-data certificate verifies
via @certifieddata/verify, and
- appends an Article 12 event to a hash-chained Decision Ledger
on every /decide call, exposing the chain via /evidence/:id.
src/app.ts is 51 total / 33 meaningful lines (under the 50-line
ceiling). src/ledger.ts ships MemoryLedger (for the demo) and
HttpLedger (for production), both behind a common Ledger interface,
plus a public verifyChain() helper that re-walks bundles.
src/article12.ts maps Article 12(2)(a-d) onto concrete event fields;
ARTICLE_12_MAPPING.md walks each requirement field-by-field with
explicit "what this is not" non-claims.
Includes:
- 3 smoke tests covering boot-or-refuse, chain integrity, multi-
decision sequencing
- 3 numbered example scripts (log, verify-training-data, export-
evidence) all run end-to-end
- docker-compose with a Postgres scaffold for a future real ledger
- CI matrix on Node 20/22 × {linux, macos}; the workflow checks
out @certifieddata/verify as a sibling until it publishes to npm
The package.json declares @certifieddata/verify as file:../verify
for now; switch to a published version range and to `npm ci` after
the first verify@0.1.0 publish.
The workflow checked out certifieddata/verify at the default ref (main), which only contains LICENSE + README until the verify PR merges. `npm run build` then fails because there is no source. Use github.head_ref so PR builds pick up the matching feature branch on the verify repo, falling back to main for post-merge push builds.
The 'Use this template' badge links to the GitHub generate-from-template flow, which is the recommended path per the handoff doc README structure (item 7: 'gh repo create --template' instruction). It pairs with the existing copy-pasteable hero quickstart so a visitor can either run the demo locally OR fork the repo as their own scaffold in two clicks. Note: there's no npm badge here — reference-impl is intended to be cloned or used as a template, not installed from npm. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Public reference implementation showing a high-risk AI system logging EU AI Act Article 12 evidence into a hash-chained Decision Ledger and certifying its training dataset via
@certifieddata/verify.The whole demo is a credit-decisioning service that:
cert.v1document verifies (createAppcallsverifyCertificateand throws ifverdict !== "VALID")./decidecall, withdecision_id,training_cert_id,model_version,input_hash, output, and timestamp./evidence/:idand re-verifies the chain locally before returning it.What's in the repo
src/app.tssrc/ledger.tsMemoryLedger+HttpLedgerbehind a commonLedgerinterface; publicverifyChain()helper.src/article12.tssrc/server.tsnpm startentry point — boots the app and serves on:3000.src/smoke.test.tssrc/examples/01-log-decision.tssrc/examples/02-verify-training-data.tssrc/examples/03-export-evidence.tsARTICLE_12_MAPPING.mddocker-compose.yml+Dockerfilefixtures/generate.mjscert.v1, writes matching keys + decisions sample.Quality gate
npm run typecheck— cleannpm test— 3/3 smoke tests passingsrc/app.tsis 33 meaningful lines (well under the 50-line ceiling)Test plan
src/app.tsandARTICLE_12_MAPPING.mdtogether — the field-by-field map should exactly match the event shape emitted byarticle12Event.npm run example:02and confirms the verifier catches a tampered training cert (mutaterowsinfixtures/training-cert.jsonand re-run).certifieddata/reference-impland pushes there; pin to top of org page.Pre-publish caveats (deferred follow-ups)
package.jsondeclares@certifieddata/verifyasfile:../verify. Afterverify@0.1.0lands on npm, switch to a published version range (e.g.^0.1.0) and switch CI fromnpm installtonpm ci.certifieddata/verifyas a sibling repo to satisfy thefile:dep. Drop that step after publish.Dockerfilealready pins to the published@certifieddata/verify(nofile:..reference); it will start working oncev0.1.0is on npm. Until then, usenpm install && npm startdirectly.Generated by Claude Code