A second implementation

machin‑bkn

A clean-room reimplementation of bkn in machin (MFL), built from the published contract alone and held to bkn's own test suite.

This is not a product, and you should not run it. Run bkn. This exists to answer one question: is bkn's published contract complete enough that somebody could rebuild it from the contract alone? Anything this cannot reproduce is something that was only ever written down in Go.
191contract assertions from bkn's own test/, all passing
279further assertions covering the CLI, which the contract suite never touches
79/87commands; the 8 missing are deliberately out of scope
7.6 MBone static binary, ~6,200 lines of MFL

The clean-room rule

Absolute, and the whole basis of the exercise:

Never read ~/ai/bkn/**/*.go, or any file under ~/ai/bkn/internal/.

What may be read is exactly what any other reader gets:

SourceWhy it is legitimate
contract/help-json.jsonthe machine-readable command catalog — literally designed as the contract
contract/guide.jsonthe embedded mental model, concepts, gotchas and examples
contract/llms.txtthe public front door
contract/spec-*.mdthe agent-first CLI specs the tool is built to
test/ and examples/the assertions and the userland scripts, both published
the live HTTP surfacewhat any caller can observe

What the check actually found

A second implementation earns its keep by finding things the first one cannot see about itself.

About the harness

The suites cannot run from a cold start

Found by being the first thing other than the live instance to run them

bkn's suites were written against a deployment whose fixtures had been seeded by hand, so a fresh instance scores nonsense — t-files read 1/12 for want of two namespaces. dog.sh also takes its admin token from $SP/admin.tok rather than the environment, so a mismatch turns every write into a 403 and cascades into failures that look like missing features. The seed is now written down.

About the port

Six gaps only visible once fixtures existed

Script access, bkn.caller, admin reset, hook content types, two query bugs

Three of them were invisible until the fixtures were there, because without seed data every suite failed for the wrong reason. Two were the same shape and both presented as "the query found nothing": a where clause that only understood the flat string form, and a find() that dropped its criteria entirely and answered with whatever happened to be first in the collection.

About machin

Two compiler and runtime bugs

Writing a real backend in MFL is what turns a language gap into a bug report

#672 — sqlite_query returns [] for a query that failed, indistinguishable from one that matched nothing; it silently broke three features in a day. #673 — a goroutine satisfies its own unbuffered channel send, so the keeper-lock idiom (the only way to write a lock when every channel is unbuffered) spins at 100% CPU.

About the CLI

Commands that worked but did not exist

A catalog is a contract, not a courtesy

Six commands were fully implemented and simply absent from help-json. Since that catalog is how an agent discovers the surface, a working-but-unlisted command does not exist for any caller — and the contract suite is blind to it, because it drives HTTP. A test now checks all three directions: everything listed runs, everything the guide teaches is listed, everything listed is taught.

The contract moves, and this is how you find out. Re-snapshotting contract/ from a current bkn turned up four commands added since the last sync — backup, files sign, store access and store count. Nothing was wrong with either build; the snapshot had gone quietly out of date, and a score measured against it read better than the truth. A second implementation is the thing that notices, provided its copy of the contract is refreshed rather than trusted. All four are now implemented, and files sign brought signed links with it: a URL that is its own credential, so a private namespace can be opened without handing out a token.

Build and run

Needs the machin compiler and libssl-dev. QuickJS is vendored and linked as a static archive, so the result is one file with no runtime dependencies.

./build.sh cmd/serve.mfl -o bin/bkn # BKN_DATA names the database; BKN_ADMIN_TOKEN gates every admin route bin/bkn serve --host 127.0.0.1 --port 7799 bin/bkn guide # the whole mental model, embedded in the binary bin/bkn help-json # the command catalog

Checking it yourself

There is a live one at machin-bkn.vps1.intrane.fr, so you can point bkn's own suite at it rather than take any of this on trust. It holds the test fixtures and nothing else; every admin route is behind a token, so the public surface is the guide, the health probe and the seeded hooks.

curl -s https://machin-bkn.vps1.intrane.fr/llms.txt curl -s https://machin-bkn.vps1.intrane.fr/guide | jq .guide.one_liner # and the suite itself, if you have bkn checked out cd ~/ai/bkn/test SP=$PWD BKN_TEST_URL=https://machin-bkn.vps1.intrane.fr bash t-store.sh

./test/deploy-gate.sh --on-host runs all 191 against that deployment in one command, and answers with a number rather than a wall of output:

=== machin-bkn deploy gate === --- over HTTPS, from the host (client last mile excluded) --- t-store 36 · t-access 31 · t-kv 7 · t-auth 22 · t-files 12 t-forms 11 · t-runtime 14 · t-stripe 10 · t-cms 15 · t-headless 14 --- on the host, against the deployed binary --- t-scriptaccess 19 === 191 passed, 0 failed ===

Two parts, because t-scriptaccess starts its own server on its own throwaway database: a script can only be created by the CLI on the machine holding the data, so running it against the live instance would mean leaving a publicly-runnable fixture script on a public host — and its last act closes a script it opened, so the gate would rewrite the deployment every time. The claim is therefore exact: the instance answers 172 over HTTPS and the binary passes the other 19.

Why --on-host, and the mistake it came from. Run from a laptop this gate flakes: t-access gave 31/31, 16/15, 28/3 and 30/1 on consecutive runs. The symptom is an empty response body rather than an error status, and when the empty one lands on a request that yields a token or a record id, every later assertion fails with it — which is why the count swings between one and fifteen. It looks exactly like a protocol bug, and I had a tidy explanation ready.

Two controls killed it. The Go bkn behind the same proxy stalled worse — two thirty-second timeouts in 200 requests. And the same probe run from the host was 200/200, median 0.081s, nothing over a second. TLS, the proxy, the routing and both implementations were fine; the client's last mile was not. --on-host runs the HTTPS half from the server: same TLS, same proxy, same routing, minus the flaky hop.

When a distributed test flakes, probe a second implementation and a second vantage point before blaming the code under test.

To run it against your own build instead, seed the fixtures first or the score means nothing:

./test/seed-fixtures.sh bin/bkn ~/ai/bkn/examples ~/ai/bkn/test echo -n "$BKN_ADMIN_TOKEN" > ~/ai/bkn/test/admin.tok # dog.sh reads THIS file bin/bkn serve --host 127.0.0.1 --port 7799 & cd ~/ai/bkn/test SP=$PWD BKN_TEST_URL=http://127.0.0.1:7799 bash t-store.sh # and the CLI suites, which the contract cannot reach ./test/catalog.sh bin/bkn # the catalog agrees with the code and the guide ./test/auth-cli.sh bin/bkn # sessions, rotation, revocation ./test/cli-surface.sh bin/bkn # store, kv, events, files, locks, cron, hooks, scripts

And t-scriptaccess.sh, which owns its own server for the reason above — point it at the binary with BKN_BIN.

Conformance

Built to the agent-first CLI spec family. This is a verification instrument rather than a distributed tool, so the three specs that exist to ship and support a product are deliberately out of scope.

SpecStatus
cli-guide-specYes — bkn guide [--human] (embedded, never fetched), GET /guide, GET /llms.txt
cli-output-specYes — stdout = data, help-json, a version on every success, and typed errors whose code equals the exit code: 80 invalid/unknown, 85 validation, 92 not found, 95 already exists, 110 internal, each with type, recoverable and, where there is one, the command that fixes it
cli-daemon-specYes — serve --host --port (loopback default, announced on stderr), GET /_health with a real pid, POST /_shutdown that answers before it exits and needs a token when bound off-loopback, and idempotent daemon start|stop|status
cli-update-specOut of scope — nothing here is distributed, so there is nothing to self-update
cli-feedback-specOut of scope — feedback on the contract belongs on bkn
cli-telemetry-specOut of scope — a test instrument counting its own runs measures nothing
MIT, the same as bkn · github.com/javimosch/machin-bkn · bkn · machin