Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
240 commits
Select commit Hold shift + click to select a range
47a707a
docs: the ADR link 404s for everyone reading on the web
Aug 8, 2026
b288b55
docker: actually publish `latest`, which the comment claimed and the …
Aug 8, 2026
d101624
docs: bump stale version references from 1.5.0/1.5.2 to 1.5.3
Aug 8, 2026
b02d06d
ci: close the gaps the 1.5.3 release found, at the root (#49)
MattJackson Aug 8, 2026
7b9880a
gitignore: a failing proptest should not also trip the clean-tree gate
Aug 8, 2026
3387c3f
config/overlay: make the RootSettings field list compiler-enforced (#53)
MattJackson Aug 8, 2026
ceb7104
ci: make consumer verification the release's last step, and make a fa…
MattJackson Aug 8, 2026
fcca721
fix(1.5.4): the documented Docker quickstart boots again on a read-on…
MattJackson Aug 8, 2026
dba43dd
test: B9 wall-clock tests, all three instances (#61)
MattJackson Aug 8, 2026
5992a96
ci: verify before tagging, and never release from a red branch (#60)
MattJackson Aug 8, 2026
bbf4b98
ci: strike the production-red half of the Verify deploy exclusion, an…
MattJackson Aug 8, 2026
389ee29
checks that could report green without checking: floors, and a skippe…
MattJackson Aug 9, 2026
12732f2
fix(config-gate): the frozen-grammar gate could not see two grammars,…
MattJackson Aug 9, 2026
4879e54
ci: mirror the pinned CI service images into GHCR (step 1 of 3) (#63)
MattJackson Aug 9, 2026
58daa8c
ci: the qa-gate dispatcher on main can drift from the commit it gates…
MattJackson Aug 9, 2026
3e082f3
ci: one build path per target, and a contract each artifact passes 10…
MattJackson Aug 9, 2026
c75a3a1
config_validate: `secret_refs` failed OPEN, and it was already missin…
MattJackson Aug 9, 2026
06209ee
ci: Docker packages the release binary instead of building its own (#70)
MattJackson Aug 9, 2026
0084440
lint: enforce tests-in-their-own-file, and move the 72 inline bodies …
MattJackson Aug 9, 2026
f71cd6a
fix(overlay): named_maps was durable and API-writable with no way to …
MattJackson Aug 9, 2026
b5c6415
build: one version requirement per dependency, in [workspace.dependen…
MattJackson Aug 9, 2026
8b10705
1.5.5 MCP + 1.5.6 A2A: both planes onto dev (#78)
MattJackson Aug 9, 2026
5a4f019
1.5.5 MCP: close the anonymous front door, and make the wire match th…
MattJackson Aug 9, 2026
857c9a7
a2a: the transport pin is a pin that is checked, and busbar signs wha…
MattJackson Aug 9, 2026
3f389d3
security: the MCP SSRF guard let [::169.254.169.254] through to cloud…
Aug 9, 2026
f2d7453
fix: rustfmt the SSRF commit
Aug 9, 2026
6ac304c
fix(mcp): a conformant upstream's input-required ask reached busbar's…
Aug 9, 2026
4bf5741
feat(mcp): busbar asks its own caller for input, and an upstream's as…
Aug 9, 2026
eaa8343
chore(mcp): the caller-ask prose tripped public-hygiene's audit-round…
Aug 9, 2026
171fcb5
deps: bump smallvec from 1.15.1 to 1.15.2 (#75)
dependabot[bot] Aug 9, 2026
f7b34ec
deps: bump zeroize from 1.8.2 to 1.9.0 (#76)
dependabot[bot] Aug 9, 2026
d65cfce
deps: bump jsonschema from 0.49.2 to 0.49.6 (#77)
dependabot[bot] Aug 9, 2026
83120e1
mcp: SSE on the POST, notifications/message, binary resources, resolv…
MattJackson Aug 10, 2026
6da0bf5
a2a: the final hop exists — busbar relays a task to a backend agent a…
MattJackson Aug 10, 2026
469a852
mcp: a resource is addressable by the URI the protocol defines, and t…
MattJackson Aug 10, 2026
df87196
docs(architecture): the three planes, how it deploys, what the store …
MattJackson Aug 10, 2026
2a67b1e
mcp(conformance): expose the three SEP-2575 diagnostic tools (#85)
MattJackson Aug 10, 2026
64b7d72
docs: the circuit breaker is one state machine on all three planes (#86)
MattJackson Aug 10, 2026
f9e2717
mcp: a minted ask the caller cannot answer is -32021, not -32000 (#87)
MattJackson Aug 10, 2026
afde081
mcp: progress relayed end to end — conformance 37/37 (#88)
MattJackson Aug 11, 2026
f3c1de0
mcp(conformance): json-schema-2020-12 green — 39/50 to 40/50, require…
Aug 11, 2026
4adec5a
test(abi): the RED proof that a plugin store silently drops every task
Aug 11, 2026
74a1f9f
fix(abi): a task written through a plugin store is no longer discarded
Aug 11, 2026
3f1bc09
test(abi): an already-signed plugin predating the ten variants still …
Aug 11, 2026
b529477
fix(config): the `tools:` grammar gets a fingerprint, and the bare-na…
Aug 11, 2026
9aa1f4c
a2a: one address predicate for every guard, and busbar's own card at …
Aug 11, 2026
3e3529e
a2a(conformance): arm the subject leg from the commit under test — th…
Aug 11, 2026
b6ed848
structure-lint: enforce §A7 request-path purity and §A6 plane coherence
Aug 11, 2026
f46cfec
mcp: arm the in-house battery from the binary — first number 40 pass …
Aug 11, 2026
7c60d7d
feat(mcp): the rug-pull defence runs on a timer, with no operator pre…
Aug 11, 2026
443e25a
a2a: outbound mutual TLS — `mtls` connects instead of refusing
Aug 11, 2026
e3f8608
ci: a step no caller has ever armed is not an integration leg
Aug 11, 2026
e00c625
mcp: the SEP-2663 tasks extension — conformance 40/50 to 47/50, requi…
Aug 11, 2026
55cb4ce
a2a: push notifications are DELIVERED, and the SSRF guard runs again …
Aug 11, 2026
12bdccd
a2a: a fronted agent can leave Pending, and reach a loopback backend
Aug 11, 2026
5e95952
mcp: `publish_as` — conformance 47/50 to 50/50, required stays 37/37
Aug 11, 2026
aa1f437
merge: the plugin ABI carries the task and call-log methods
Aug 11, 2026
40c367a
Merge branch 'feat/1.5.5-mcp-publish-as' into dev
Aug 11, 2026
292840e
Merge branch 'fix/1.5.6-a2a-connect-admin-verbs' into dev
Aug 11, 2026
48665c9
Merge branch 'fix/1.5.5-a2a-wellknown-push-delivery' into dev
Aug 11, 2026
5384b3c
Merge branch 'feat/mcp-refresh-timer-and-config-fingerprint' into dev
Aug 11, 2026
4b0ad12
Merge branch 'feat/a2a-subject-armed' into dev
Aug 11, 2026
eb717e2
Merge branch 'feat/structure-lint-plane-coherence' into dev
Aug 11, 2026
7cb78ee
Merge branch 'feat/arm-inhouse-battery' into dev
Aug 11, 2026
f431f8d
Merge branch 'ci/no-silently-skipped-sibling-step' into dev
Aug 11, 2026
f7fbfb4
Merge branch 'feat/a2a-outbound-mtls' into dev
Aug 11, 2026
5f26ff3
wip(oauth-as): mounting the authorization server — INCOMPLETE
Aug 10, 2026
afcaee6
docs(oauth_as): the config block, documented where an operator reads …
Aug 10, 2026
6e639ea
fix(oauth_as): the signing key is WALKED, not read through an accessor
Aug 11, 2026
e664187
gate: close the three gates the ten-branch merge moved
Aug 11, 2026
6289bcf
ci: prove a plugin against the busbar its release actually builds
Aug 8, 2026
5911ed2
ci: a phase that did not run must never read as a phase that passed
Aug 8, 2026
3306722
admin: a hook's stage scoping was writable over the API and not readable
Aug 8, 2026
ffc7d47
ci: digest-pin plugin-ci's service images, the fleet's widest float
Aug 8, 2026
3b688c1
1.6.0: the release number, and the 48 in-code markers the sweep missed
Aug 12, 2026
bbfc0e2
a2a: a busbar co-located with the agent it fronts can serve its card
Aug 12, 2026
ccfa432
hooks: one plugin load per resolution, not one per control-plane call…
Aug 11, 2026
c494892
Merge branch 'chore/salvage-1.5.4-prs' into dev
Aug 12, 2026
e112993
hooks: make the shipped claims about the hook path true, and pin the …
Aug 12, 2026
026f7a6
test(oauth_as): prove the config gate, red before green
Aug 12, 2026
b218999
Merge branch 'fix/hook-path-truth-gaps' into dev
Aug 12, 2026
173b37f
Merge branch 'chore/1.6.0-renumber-sweep' into dev
Aug 12, 2026
6f95f34
fix(jsonrpc): refuse `"id": null`, and never answer a notification — …
Aug 12, 2026
e51d8e3
metrics: put MCP and A2A traffic on the same request series as model …
Aug 12, 2026
be32e2e
Merge branch 'feat/oauth-as-builtin-config-gated' into dev
Aug 12, 2026
464662e
Merge branch 'feat/metrics-across-planes' into dev
Aug 12, 2026
1ea5627
Merge branch 'fix/jsonrpc-id-null' into dev
Aug 12, 2026
780ad5a
a2a: the plane's own endpoint is mounted, and it answers JSON-RPC errors
Aug 12, 2026
d82a5e8
Merge branch 'fix/dlopen-configure-ack-flake' into dev
Aug 12, 2026
abe4133
a2a: the JSON-RPC error envelope A2A section 5.4 defines
Aug 12, 2026
754ed62
a2a(conformance): the subject leg fronts a REAL agent, promoted by th…
Aug 12, 2026
fbcff4e
hygiene: state what the test proves, not the process that produced it
Aug 12, 2026
07b24a9
plane: one trust sweep job and one admin trust verb surface, paramete…
Aug 12, 2026
1909825
Merge branch 'feat/unify-plane-scheduler-adminverbs' into dev
Aug 12, 2026
520af2e
mcp: the per-call log gets a production writer, and a real tools/call…
Aug 12, 2026
afeab38
mcp: delete the stdio child supervisor, because this release has no s…
Aug 12, 2026
2304aef
a2a: the relay finds the payload, reads the state, and carries the ba…
Aug 12, 2026
d93b291
qa-gate: the sibling policy rides the commit, not the default branch
Aug 12, 2026
97c2b31
Merge branch 'feat/calllog-writer-and-stdio-arm' into dev
Aug 12, 2026
8f896b2
a2a: A2A streaming has never worked, and the test fixture is why
Aug 12, 2026
0b946ea
correlate every JSON-RPC response to the request that was sent
Aug 12, 2026
41ddf3e
Merge branch 'fix/jsonrpc-response-correlation' into dev
Aug 12, 2026
c23a29c
a2a: the task identity busbar issues is one busbar can resolve
Aug 12, 2026
8930f2a
test: refuse to judge a stale plugin cdylib, and correct why
Aug 12, 2026
3c44798
a2a: a request that names a task is about THAT task
Aug 12, 2026
92ab3be
a2a: rustfmt and one clippy lint over the conformance work
Aug 12, 2026
ba48951
a2a(test): assert the no-second-row property through the answer, not …
Aug 12, 2026
842d9e6
ir: the eighth operation, and the parent interface that was already t…
Aug 12, 2026
7df7a06
mcp: a protocol in the matrix, not a plane beside it
Aug 12, 2026
c102860
breaker: the attributed outcome belongs to every operation, not to chat
Aug 12, 2026
4f25fbf
Merge branch 'feat/ir-parent-interface' into dev
Aug 12, 2026
4a5d823
openapi: regenerate the committed document after a doc-comment reword
Aug 12, 2026
5f6c4e0
mcp(battery): two wrong clauses and one unarmed one, fixed where the …
Aug 12, 2026
a949604
a2a: merge the TCK conformance work onto the correlated relay
Aug 12, 2026
374d524
a2a(ci): the negative control proves discrimination, and stops racing…
MattJackson Aug 12, 2026
eecd464
a2a(ci): the subject leg's arm is resolved before the cd that invalid…
MattJackson Aug 12, 2026
6b0a34e
Merge branch 'fix/a2a-conformance-legs' into dev
Aug 12, 2026
9188179
Merge branch 'merge/a2a-tck' into dev
Aug 12, 2026
e79ee4c
mcp: an upstream that failed is not busbar refusing, and a dropped ou…
Aug 12, 2026
47ecc3b
hooks: a dead registry's address is not an identity, and two CI-only …
Aug 12, 2026
38a4e5d
Merge branch 'fix/no-default-features-and-windows' into dev
Aug 12, 2026
1057c9e
mcp(seam): the six seam clauses, armed — and two defects in the batte…
Aug 12, 2026
b003593
mcp: satisfy the two repo lints this branch tripped
Aug 12, 2026
481ff14
Merge branch 'fix/mcp-battery-nine-clauses' into dev
Aug 12, 2026
f61880c
a2a: the two facts on the request line are busbar's to answer, not th…
Aug 12, 2026
69d2bda
Merge branch 'feat/a2a-toward-100' into dev
Aug 12, 2026
a3ffafd
hygiene: spell the spec citation the way this repo spells it
Aug 12, 2026
71e01e8
mcp(ci): the differential never had a control to compare against
Aug 12, 2026
78f7ef6
mcp(ci): put the control-report download in the battery job, not the …
Aug 12, 2026
044c227
a2a: terminate ListTasks, push-config CRUD and two subscribe refusals…
Aug 12, 2026
a4e5369
Merge branch 'feat/a2a-local-verbs' into dev
Aug 12, 2026
983fa9f
hygiene: state the invariant, not the private doc it came from
Aug 12, 2026
549b3c8
a2a: front the conformance subject with an agent that can interrupt
Aug 12, 2026
661216b
Merge branch 'feat/a2a-interrupting-fronted-agent' into dev
Aug 12, 2026
e8ae06e
deps: pin the MCP and A2A protocol vocabulary, ahead of any caller
Aug 12, 2026
7215bc8
a2a-tck: PUSH-DELIVER-001/002/003 fail on the SCHEME, not on the topo…
Aug 12, 2026
c4683f6
ir: all three opaque reasoning shapes read as opaque from the IR
Aug 12, 2026
42b8bc6
coverage: the method matrix is derived from the SDKs, and a missing c…
Aug 12, 2026
1929cd9
hooks: the projection and the IR disagree on twelve fixtures, and her…
Aug 12, 2026
93bf760
bench: C1 and C2 have an instrument, and it is the first one in this …
Aug 12, 2026
e335044
operation: thirteen variants, and `ToolCall` is now `Invoke`
Aug 12, 2026
71a6886
Merge branches 'test/1.6.0-u0-differential' and 'fix/1.6.0-u2-ir-opac…
Aug 12, 2026
ae0f2c1
Merge branch 'feat/1.6.0-sdk-pin' into dev
Aug 12, 2026
79d0c2b
Merge branch 'feat/1.6.0-coverage-gate' into dev
Aug 12, 2026
43a63ed
Merge branch 'fix/1.6.0-u2-ir-opacity' into dev
Aug 12, 2026
8505986
Merge branch 'feat/1.6.0-operation-13' into dev
Aug 12, 2026
e2d2531
Merge branch 'test/1.6.0-u0-differential' into dev
Aug 12, 2026
cc20cf2
docs: no em dashes in the published documentation
Aug 12, 2026
ab68eb5
changelog: punctuation only, no em dashes
Aug 12, 2026
313c60e
mcp: a parameterised address refuses an ambiguity where a literal one…
Aug 12, 2026
de60c28
a2a: a served card advertises only the bindings busbar serves
Aug 12, 2026
5729b5b
Merge branch 'fix/1.6.0-card-advertises-unserved-bindings' into dev
Aug 12, 2026
745e48f
ir: the projection moves onto the spine, and the differential says th…
Aug 12, 2026
9e8d8db
wip(fix/1.6.0-a2a-mtls-verify): in-flight agent work, committed for s…
Aug 12, 2026
dd74a25
plane: one mount-aware resolver answers which plane and which dialect…
Aug 12, 2026
c5352c1
Merge branch 'feat/1.6.0-u3-ir-facts' into dev
Aug 12, 2026
3f5ca5b
transport: the matrix has a third axis, and one variant proves it
Aug 12, 2026
a8b236e
Merge branch 'fix/1.6.0-u1-mount-aware-resolver' into dev
Aug 12, 2026
ebfa46b
Merge branch 'feat/1.6.0-transport-axis' into dev
Aug 12, 2026
c066ae0
a2a: verify the mutual half of `mtls` instead of refusing it uncondit…
Aug 12, 2026
03064b4
mcp: an approval is spent once, and a quarantine outlives the thing t…
Aug 12, 2026
e7f2b7a
Merge branch 'fix/1.6.0-a2a-mtls-verify' into dev
Aug 12, 2026
a5b48fd
Merge branch 'fix/1.6.0-mcp-security-findings' into dev
Aug 12, 2026
af50de3
hygiene: five public lines described how the code was built, not what…
Aug 12, 2026
59e4f88
Merge branch 'fix/1.6.0-push-deliver-rig-topology' into dev
Aug 12, 2026
ecb1b5a
a2a: the served card names a scheme a client can classify, and the ba…
Aug 12, 2026
d52270e
Merge branch 'fix/1.6.0-a2a-battery-auth-and-card' into dev
Aug 12, 2026
e85d0b4
guards: the source-scanning tests owe an enforcement that survives th…
Aug 12, 2026
b2b9410
test(proto): the linearity verdict compares two runs that were never …
Aug 12, 2026
0b00c7a
Merge branch 'feat/1.6.0-sourcescan-enforcement' into dev
Aug 12, 2026
9f045dc
mcp: the subscription verbs, and the notifications that make them wor…
Aug 12, 2026
f84b39e
a2a: the extended agent card, the webhook credential, and the deliver…
Aug 12, 2026
886f88e
Merge branch 'feat/1.6.0-a2a-method-coverage' into dev
Aug 12, 2026
1daec4f
Merge branch 'feat/1.6.0-mcp-rmcp-cells' into dev
Aug 13, 2026
c63c966
feat(a2a): arm the HTTP+JSON transport binding
Aug 13, 2026
1759ce9
a2a: the specification's gRPC binding, over busbar's own admission an…
Aug 13, 2026
bba2709
mcp: arm the client-role leg, and read the first number it produces
Aug 13, 2026
3e9af05
Merge branch 'feat/1.6.0-a2a-httpjson' into dev
Aug 13, 2026
f3be005
Merge branch 'feat/1.6.0-mcp-client-role-armed' into dev
Aug 13, 2026
51db82e
mcp: the channel this revision notifies over, and the streamable-HTTP…
Aug 13, 2026
f041bfb
breaker: the attributed outcome comes from the operation codec, not t…
Aug 13, 2026
22b10f3
Merge branch 'feat/1.6.0-mcp-coverage-tail' into dev
Aug 13, 2026
3209f84
Merge branch 'feat/1.6.0-breaker-repoint' into dev
Aug 13, 2026
82d943c
a2a: the canonical status of the error the extended card added
Aug 13, 2026
5908e57
hooks: the firing sites the MCP and A2A grammars never had
Aug 13, 2026
057e678
hooks: one answer to "what is the text in this request"
Aug 13, 2026
f93ae4d
feat(mcp): stdio transport — busbar spawns and supervises a local MCP…
Aug 13, 2026
b5995fd
audit: one hash chain in core, three streams on top of it
Aug 13, 2026
9ece9f8
feat(hooks): lazy request IR behind a boot-computed content-hook gate
Aug 13, 2026
333af36
Merge branch 'feat/1.6.0-a2a-grpc' into dev
Aug 13, 2026
d4577ca
Merge branch 'feat/1.6.0-u4-lazy-ir' into dev
Aug 13, 2026
d326926
Merge branch 'feat/1.6.0-u5-cutover' into dev
Aug 13, 2026
2b4b9ba
Merge branch 'feat/1.6.0-core-audit-one-chain' into dev
Aug 13, 2026
7cd5462
Merge branch 'feat/1.6.0-hooks-fire-all-planes' into dev
Aug 13, 2026
2346fc5
mcp: a quarantine and a spent approval both outlive the process that …
Aug 13, 2026
ebd6058
Merge branch 'feat/1.6.0-mcp-stdio' into dev
Aug 13, 2026
a6ef5d0
Merge branch 'feat/1.6.0-durable-trust-state' into dev
Aug 13, 2026
51b218f
fix: the two cross-unit conflicts the compiler caught after six merges
Aug 13, 2026
c59367e
docs+mcp: retire headers that outlived their subject, and pin the fro…
Aug 13, 2026
56ddc9d
core: the one guarded fetch, and the two planes that stopped keeping …
Aug 13, 2026
9196f72
Merge branch 'feat/1.6.0-core-guarded-fetch' into dev
Aug 13, 2026
3a9c9ab
Merge branch 'fix/1.6.0-stale-headers-and-key-freeze' into dev
Aug 13, 2026
4bd9df7
docs(transport): the stale-header fix was itself stale on the merged …
Aug 13, 2026
7b58127
refactor(egress): one egress gate in core; a plane keeps its grant ki…
Aug 13, 2026
5d85744
fix(admin): a runtime-registered hook's `signals:` declaration was in…
Aug 13, 2026
51ad925
conformance: an unarmed ROLE is a named refusal, not a smaller denomi…
Aug 13, 2026
987ac09
Merge branch 'feat/1.6.0-conformance-both-ways' into dev
Aug 13, 2026
23ded83
fix(hygiene): dev was red, and the claim that it was green was stale
Aug 13, 2026
8590a6d
Merge branch 'feat/1.6.0-core-egress-gate' into dev
Aug 13, 2026
a690e8e
Merge branch 'fix/1.6.0-requested-signals-staleness' into dev
Aug 13, 2026
c77f969
core: one ordered request validator, and the generation check A2A did…
Aug 13, 2026
ca59531
core(operation): six SHAPES plus a carried verb, so a protocol's meth…
Aug 13, 2026
4a57ff2
Merge branch 'feat/1.6.0-operation-verb' into dev
Aug 13, 2026
64f381f
ir(facts): the dead-code allowance outlived its own condition
Aug 13, 2026
c417b46
Merge branch 'feat/1.6.0-core-request-validator' into dev
Aug 13, 2026
b4a72eb
refactor(plane): one parse-time plane-boundary rule, with its section…
Aug 13, 2026
d09172c
Merge branch 'feat/1.6.0-core-plane-config' into dev
Aug 13, 2026
4b15dce
failover, reroute and the breaker on the MCP and A2A planes
Aug 13, 2026
9e7c9a8
refactor(proto): protocol_for becomes a registry, and a protocol beco…
Aug 13, 2026
5b58237
Merge branch 'feat/1.6.0-failover-all-planes' into dev
Aug 13, 2026
3a9eb2c
docs: say what lossless covers, and what it does not cover yet
Aug 13, 2026
0c310e0
docs: providers.yaml header drops the bare 'losslessly'
Aug 13, 2026
9a0fb03
docs: stop documenting a breaker config the engine does not parse
Aug 13, 2026
606e007
a2a: one outbound dispatch, three bindings — the client leg busbar di…
Aug 13, 2026
1f440ba
a2a: the served direction, driven — fourteen cells, and the gRPC card…
Aug 13, 2026
f3988d5
mcp: close the stdio CLIENT leg — 34 cells, 108 -> 74 MISSING
Aug 13, 2026
c4b484a
Merge branch 'feat/1.6.0-cov-server-cells' into dev
Aug 13, 2026
b597519
Merge branch 'docs/ir-lossless-claims' into dev
Aug 13, 2026
9b9ea33
Merge branch 'feat/1.6.0-cov-mcp-stdio-client' into dev
Aug 13, 2026
60f3810
ir: attachments, usage attribution and citations stop being left on t…
Aug 13, 2026
ae957d4
Merge branch 'feat/1.6.0-protocol-registry' into dev
Aug 13, 2026
b0d3353
Merge branch 'feat/1.6.0-cov-a2a-client' into dev
Aug 13, 2026
60c430c
Merge branch 'fix/1.6.0-ir-lossless' into dev
Aug 13, 2026
e194d66
feat(catalogue): one catalogue walk in core; a plane supplies an item…
Aug 13, 2026
ca9806b
chore(oauth_as): take oauth-as 0.9.1, a security release under a patc…
Aug 13, 2026
b2353cd
Merge branch 'chore/1.6.0-oauth-as-0.9.1' into dev
Aug 13, 2026
fc90568
Merge branch 'feat/1.6.0-core-catalogue' into dev
Aug 13, 2026
d2b4e6b
docs: rebuild both GitHub READMEs around measured figures
Aug 13, 2026
e178384
docs(readme): the argument before the instructions, and no wall of prose
Aug 13, 2026
0b1d69c
docs(readme): the argument first, the instructions last, and a table …
Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
232 changes: 232 additions & 0 deletions .github/artifact-contract.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
{
"_comment": [
"THE ARTIFACT CONTRACT: what must be true of EVERY shipped busbar binary, as DATA.",
"",
"Owner, 2026-08-08: \"should just be 1 build pipeline that takes what its building: arm, windows,",
"mac, but it does the same thing for each no way for 1 to be different\", and \"100% or 0% for",
"each build\".",
"",
"WHY THIS IS A FILE AND NOT A SEQUENCE OF `run:` STEPS. Through 1.5.3 every property a release",
"binary was supposed to have was asserted on the INPUT side -- an env var set on a build step --",
"and never on the OUTPUT. `BUSBAR_RELEASE_PUBKEY` was set on both build steps, the workflow was",
"green, a comment in release.yml stated the key was baked in, and",
"busbar-aarch64-unknown-linux-gnu 1.5.3 shipped with no key at all: `option_env!` is a",
"COMPILE-time read that fails silently to `None`. Setting an env var says what was intended.",
"Only inspecting the shipped bytes says what happened.",
"",
"Because the rows are data, adding a property is ONE ENTRY here plus its check function in",
"scripts/verify-artifact.py, and it then applies to every target automatically -- there is no",
"per-target list to forget a platform in, which is how the aarch64 leg went three releases",
"without a key. scripts/verify-artifact.py asserts SET EQUALITY between the ids declared here",
"and the checks it implements, so a row added here with no implementation is a hard failure",
"rather than a silently-skipped property, and an implementation with no row here is too.",
"scripts/tests/test_verify_artifact.py additionally requires every row to own BOTH a RED",
"fixture it flags and a GREEN twin it passes: a row nobody has watched fail is not a row.",
"",
"`applies_when` is the ONLY way a row may be conditional, it is matched against the target's",
"own declaration in .github/release-targets.json, and a row that applies to a target CANNOT be",
"skipped for any other reason -- there is no waiver field and no exception list. Every target",
"now builds and verifies on a NATIVE runner, so `exec: true` rows run for every platform,",
"Windows included; nothing is statically approximated because a runner could not execute it.",
"",
"`min_rows` is a floor. A loop over a discovered set with no floor is a check that passes",
"without executing: an empty or truncated contract file would otherwise verify every artifact",
"against nothing and report green."
],
"min_rows": 14,
"rows": [
{
"id": "archive_shape",
"title": "the archive contains exactly the declared executable, at a plausible size",
"exec": false,
"why": [
"GitHub creates an asset row the moment an upload starts, so a truncated or empty upload",
"lists identically to a good one, and an archive that unpacks to the wrong name (or to a",
"directory) breaks install.sh and the documented `tar -xzf && ./busbar` in the same silent",
"way a missing asset does. Assert the members, not the presence."
],
"applies_when": {
"kind": "binary"
}
},
{
"id": "binary_format",
"title": "architecture, object format and linkage are what the target declares",
"exec": false,
"why": [
"An asset named `aarch64` that contains x86_64 bytes is 100% broken for everyone who",
"downloads it, and it is invisible to every check that only executes the binary on the",
"runner that built it. Parsed straight out of the ELF/Mach-O/PE headers so the check is one",
"implementation on all three operating systems rather than `file` here and `ldd` there.",
"The linkage half folds in docker.yml's hard failure on a dynamically-linked binary where a",
"static one was intended (FROM scratch has no loader): linkage is now a declared property of",
"the target and a row that applies to every artifact, not an `ldd | grep` in one workflow."
],
"applies_when": {
"kind": "binary"
}
},
{
"id": "release_pubkey",
"title": "the release public key is embedded in the shipped bytes",
"exec": false,
"why": [
"THE 1.5.3 DEFECT, ASSERTED ON THE ARTIFACT. busbar-aarch64-unknown-linux-gnu shipped with",
"no embedded key in 1.5.1, 1.5.2 and 1.5.3 while the other four assets had one. On ARM Linux",
"-- Graviton, Raspberry Pi, ARM containers -- every correctly-signed first-party plugin was",
"refused, and the only workaround was `plugins.trust.allow_unsigned: true`, which switches",
"the requirement off rather than trusting first-party selectively.",
"This row is the cheap static half: the 64-hex public key must appear verbatim in the binary.",
"`first_party_plugin` is the half that proves it is the RIGHT key and that it works."
],
"applies_when": {
"kind": "binary"
}
},
{
"id": "first_party_plugin",
"title": "a real signed first-party plugin verifies as first-party and is ready",
"exec": true,
"why": [
"Functional, not a grep. The plugin is a REAL release of a REAL first-party plugin repo,",
"signed by the REAL private half of the release key, downloaded and handed to the SHIPPED",
"binary, which must report `SIGNATURE: first-party` and `STATUS: ready` from --list-plugins.",
"A grep proves 64 bytes are present; only this proves the embedded key verifies the",
"signatures the plugin repos actually produce. Run against the real 1.5.3 aarch64 asset it",
"reports, verbatim: `SIGNATURE: unsigned STATUS: SKIPPED: manifest claims first-party",
"publisher 'busbar' but this build embeds no busbar release key`.",
"The check also asserts `plugins.enabled: true` and a non-empty inventory in the output,",
"because --list-plugins falls back to the DEFAULT plugins block with a mere [warn] when the",
"config is unreadable, and a naive check would then read `no plugin tarballs found` and see",
"no failure text at all."
],
"applies_when": {
"kind": "binary",
"published": true
}
},
{
"id": "version_anchored",
"title": "--version reports exactly the version being released",
"exec": true,
"why": [
"ANCHORED on both ends. A substring or prefix match lets `1.5.4` be satisfied by `1.5.40`,",
"and lets a stale binary from a previous matrix leg pass while claiming to be this release.",
"The bytes must run and identify themselves as this exact version, nothing more."
],
"applies_when": {
"kind": "binary"
}
},
{
"id": "quickstart_boots",
"title": "the documented quickstart boots this binary and answers on /healthz",
"exec": true,
"why": [
"The minimal config.yaml from docs/getting-started.md, the documented default listen address,",
"and the documented `curl localhost:8080/healthz` -> `ok`. A new user's first five minutes,",
"run against the artifact they will actually download. This used to be checked for exactly",
"ONE platform -- verify-deploy.yml hardcodes busbar-x86_64-unknown-linux-gnu.tar.gz -- which",
"is the same shape of gap as the missing key: a property established on one artifact and",
"assumed for the rest."
],
"applies_when": {
"kind": "binary"
}
},
{
"id": "attestation",
"title": "the build-provenance attestation verifies against these exact bytes",
"exec": false,
"why": [
"`gh attestation verify <archive> --repo GetBusbar/busbar` is the command the docs tell users",
"to run, so it is the command that must be proven to pass -- on the bytes downloaded from the",
"release, not on a local copy of the file the build step happened to still have. An",
"attestation that covers a different digest than the asset a user downloads is worse than",
"none, because it looks like provenance.",
"Gated on `published`: an artifact packaged into an image rather than",
"uploaded has no release asset to attest against, and a row that cannot",
"run must not be quietly satisfied."
],
"applies_when": {
"kind": "binary",
"published": true
}
},
{
"id": "build_evidence",
"title": "the build's own evidence is bound to the shipped bytes by digest",
"exec": false,
"why": [
"The build step records the SHA-256 of the archive it produced. This row asserts that digest",
"equals the digest of the archive that was actually downloaded from the release. Without it",
"every evidence-based row below is unanchored: a build could report a verified PGO profile",
"for bytes that never reached the release, which is a certificate for the wrong artifact."
],
"applies_when": {
"kind": "binary"
}
},
{
"id": "pgo_applied",
"title": "PGO really was applied where the target declares it",
"exec": false,
"applies_when": {
"pgo": true,
"kind": "binary"
},
"why": [
"scripts/pgo-build.sh writes its proof marker ONLY after a non-empty merged profile fed a",
"successful -Cprofile-use build. This row turns that marker into a contract row rather than",
"an assertion living in one workflow step: the marker must exist, be marked verified, name",
"THIS target, and record a non-zero merged-profile size and .profraw count -- and it is bound",
"to the shipped archive's digest by `build_evidence`, so it certifies these bytes and not",
"some other build's.",
"`applies_when` is checked against .github/release-targets.json, and that file carries a",
"`pgo_floor` scripts/tests/test_release_contract.py enforces, so a target cannot quietly flip `pgo` to false to",
"make this row stop applying to it."
]
},
{
"id": "image_boots_documented_quickstart",
"applies_when": {
"kind": "image"
},
"why": "busbar 1.5.3's image did NOT boot under any documented invocation: USER 65532:65532 against a root-owned /etc/busbar, so the overlay backend was unwritable and boot refused. The build was green and nothing ran the image. This row runs it."
},
{
"id": "image_runs_as_nonroot",
"applies_when": {
"kind": "image"
},
"why": "the image ships a non-root UID deliberately; a fix that restores boot by running as root would trade a boot failure for a privilege regression and look identical in CI."
},
{
"id": "image_release_pubkey",
"applies_when": {
"kind": "image"
},
"why": "the same embedded-key property the binaries owe. The image carries its own musl build, so a key present in the tarballs proves nothing about it."
},
{
"id": "image_version_anchored",
"applies_when": {
"kind": "image"
},
"why": "anchored so 1.5.4 cannot be satisfied by 1.5.40, and read from the running image rather than from the tag that labels it."
},
{
"id": "image_matches_packaged_binary",
"applies_when": {
"kind": "image"
},
"why": [
"the binary INSIDE the image must be byte-identical to the musl artifact the single",
"build path produced for it. This is what makes the image a PACKAGE rather than a",
"second build: without it the image could be assembled from a differently-built",
"binary and every other row would still pass \u2014 which is how one artifact came to",
"embed the plugin release key while its sibling did not."
]
}
]
}
Loading
Loading