@brutalsystems/muster 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CANONICAL_ID.md +13 -1
- package/CONTRACT_PROVENANCE.md +111 -0
- package/README.md +13 -7
- package/package.json +1 -1
- package/test/fixtures/canonical-id.json +1 -1
package/CANONICAL_ID.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tin Can — Address Format
|
|
2
2
|
|
|
3
|
-
> **Normative for `@brutalsystems/tincan` 1.
|
|
3
|
+
> **Normative for `@brutalsystems/tincan` 1.9.2.**
|
|
4
4
|
>
|
|
5
5
|
> This describes what Tin Can does today, precisely enough for another tool to
|
|
6
6
|
> produce addresses Tin Can will resolve. It is a write-down of shipped
|
|
@@ -140,6 +140,18 @@ The separator is `.` so that an address needs no shell quoting.
|
|
|
140
140
|
`canonical_id` is always fully qualified, whether or not there is a collision.
|
|
141
141
|
It is the form to record in logs and to pass between tools.
|
|
142
142
|
|
|
143
|
+
**Do not recover the suffix from a canonical id by string surgery.** Taking the
|
|
144
|
+
last dot-separated segment gave the three-character suffix before 1.0.0 and
|
|
145
|
+
gives the whole durable id now — `01a0b9b4-a33e-7ab1-80a0-bb715504a0fb`, not
|
|
146
|
+
`0fb`. A reimplementation that does this builds qualified addresses that look
|
|
147
|
+
right and match nothing, and the failure surfaces as `unknown`, which names a
|
|
148
|
+
missing peer rather than a malformed address. Reported by muster, where it made
|
|
149
|
+
every `slug.suffix` address fail silently until a test was written for it.
|
|
150
|
+
|
|
151
|
+
Derive the suffix from the **uuid**, with `suffixOf` — the last three hex
|
|
152
|
+
characters of the id with non-hex removed. The canonical form is an address to
|
|
153
|
+
pass along whole, not a record to parse fields out of.
|
|
154
|
+
|
|
143
155
|
## Collision
|
|
144
156
|
|
|
145
157
|
A peer is suffixed in its **display** form when either:
|
package/CONTRACT_PROVENANCE.md
CHANGED
|
@@ -370,3 +370,114 @@ rule it documents — refuse a prefix that ends at a segment boundary — fails
|
|
|
370
370
|
new case *and* `resolve: unambiguous prefix resolves` together, in this copy.
|
|
371
371
|
That pair failing together is the argument for Tin Can's decision to document
|
|
372
372
|
the defect rather than change resolution, and it reproduces here.
|
|
373
|
+
|
|
374
|
+
## Re-sync to Tin Can 1.7.0 — 2026-09-24
|
|
375
|
+
|
|
376
|
+
The copies are now from tag `v1.7.0`, commit
|
|
377
|
+
`f2aaeb20ea278c229afe955db59f69301fc6626f`.
|
|
378
|
+
|
|
379
|
+
| File | SHA-256 |
|
|
380
|
+
| --- | --- |
|
|
381
|
+
| `CANONICAL_ID.md` | `8d5e93894e5c43cc854330f7b64ebbdcc450649cfa910c8b4015edf2559125e7` |
|
|
382
|
+
| `test/fixtures/canonical-id.json` | `1db118b22484271932e7cde33c1c80b469563f18f2961532d6910d79ce1e4c3b` |
|
|
383
|
+
|
|
384
|
+
`tincan_version: 1.7.0`, still 40 cases: 8 slugify, 7 suffix, 12 assignment, 13
|
|
385
|
+
resolution. **No expected value moved and no case was added.** Diffed
|
|
386
|
+
`v1.6.0..v1.7.0` upstream before copying: `src/naming.ts` does not appear in the
|
|
387
|
+
diff at all, the fixture's only changed line is its `tincan_version`, and
|
|
388
|
+
`CANONICAL_ID.md` gains fourteen lines of warning with no normative change. So
|
|
389
|
+
`naming.ts` is untouched here and the contract suite is expected to stay 4/4
|
|
390
|
+
without it — this is a re-label plus a doc, not an address-format change.
|
|
391
|
+
|
|
392
|
+
What the doc gains is the hazard this repo hit and reported: recovering the
|
|
393
|
+
three-hex suffix by taking a canonical id's last dot-separated segment returned
|
|
394
|
+
the suffix before 1.0.0 and returns the whole uuid now, so every qualified
|
|
395
|
+
`slug.suffix` address resolves as `unknown` — a missing peer, not a malformed
|
|
396
|
+
address, which is why it stayed quiet here until a test was written for it.
|
|
397
|
+
Tin Can names Muster as where it was found. The rule is to derive the suffix
|
|
398
|
+
from the uuid via `suffixOf` and otherwise pass a canonical id along whole
|
|
399
|
+
rather than parse fields out of it.
|
|
400
|
+
|
|
401
|
+
**A re-sync touches three sites, not two.** Both Tin Can pins —
|
|
402
|
+
`RELEASING.md` and `.github/workflows/publish.yml` — plus the SHA-256 drift
|
|
403
|
+
hashes in `test/naming.test.ts` ("contract copies remain frozen"), which must
|
|
404
|
+
move whenever a copied file changes. The two pins are the ones handed down in
|
|
405
|
+
conversation; the hashes were found by grepping for the old version and the old
|
|
406
|
+
digests rather than by working from that list, so grep the repo instead of
|
|
407
|
+
trusting an enumeration. That advice earned itself twice over: this very
|
|
408
|
+
enumeration missed `README.md`, which carried a literal baseline of its own —
|
|
409
|
+
recorded below.
|
|
410
|
+
|
|
411
|
+
Moving only the first pin is what made v0.9.0 an inert tag that published
|
|
412
|
+
nothing. `test/workflow-npm-pin.test.ts` now fails when the two pins disagree,
|
|
413
|
+
or when the `publish.yml` pin and the fixture's `tincan_version` disagree, and
|
|
414
|
+
that guard was re-confirmed by mutation here rather than assumed: reverting
|
|
415
|
+
`publish.yml` alone to 1.6.0 fails both assertions, and restoring it passes
|
|
416
|
+
them. A stale drift hash fails `npm run check` on its own.
|
|
417
|
+
|
|
418
|
+
### The pin sites became one derived value
|
|
419
|
+
|
|
420
|
+
Recording the fix rather than only the incident. The two Tin Can pins no longer
|
|
421
|
+
restate a version; both compute it from this fixture's `tincan_version`. That
|
|
422
|
+
field is the single place saying which Tin Can the vendored copies describe, so
|
|
423
|
+
a pin can no longer lag it — the v0.9.0 failure class is closed structurally
|
|
424
|
+
instead of guarded after the fact.
|
|
425
|
+
|
|
426
|
+
The guard that replaced the old agreement tests asserts the derivation
|
|
427
|
+
expression itself, not the word `tincan_version`. The first version of it
|
|
428
|
+
checked for the word and **passed against a `publish.yml` whose command had
|
|
429
|
+
been mutated to `ver="1.6.0"`**, because the prose explaining the derivation
|
|
430
|
+
contains that word too. It was caught by running the mutation rather than by
|
|
431
|
+
reading the test. A guard that cannot fail is the thing this document exists to
|
|
432
|
+
prevent, so the failure is written down next to the fix.
|
|
433
|
+
|
|
434
|
+
### README.md was a fourth site, and had already gone stale
|
|
435
|
+
|
|
436
|
+
The enumeration above missed it. `README.md`'s Verification section named its own
|
|
437
|
+
baseline — **Tin Can 0.6.4** in prose, and `@brutalsystems/tincan@0.6.4` in a
|
|
438
|
+
copy-paste command — and had drifted unnoticed while the vendored copies moved to
|
|
439
|
+
1.6.0 and then 1.9.2. Nothing failed, because it gates nothing: it is
|
|
440
|
+
instructions for a human, so the cost was silence rather than an inert tag.
|
|
441
|
+
|
|
442
|
+
That makes it worse than a failing pin, not better. Anyone following the README
|
|
443
|
+
installed a Tin Can four minors behind the one the fixture describes and watched
|
|
444
|
+
the contract suite pass 4/4 — which reads as confirmation that the contract holds
|
|
445
|
+
at a version nobody vendored.
|
|
446
|
+
|
|
447
|
+
Fixed the same way as the other two sites: the command derives `ver` from the
|
|
448
|
+
fixture, and the prose points at `tincan_version` rather than naming a release.
|
|
449
|
+
`test/workflow-npm-pin.test.ts` now includes `README.md` in the derivation loop,
|
|
450
|
+
and adds one assertion that its Verification section names no Tin Can version in
|
|
451
|
+
prose at all, because prose restates a pin as easily as a command does. Both were
|
|
452
|
+
watched failing against the stale README before anything was changed — the
|
|
453
|
+
literal-pin assertion on the command, and `expected 'Tin Can 0.6.4' to be
|
|
454
|
+
undefined` on the prose — and the derived command was then extracted from the
|
|
455
|
+
README and run end to end, installing 1.9.2 and passing the contract suite 4/4.
|
|
456
|
+
|
|
457
|
+
The prose assertion is scoped to `## Verification` on purpose. Elsewhere the
|
|
458
|
+
README records what was observed at a particular Tin Can — "Tin Can 0.6.0
|
|
459
|
+
delivers over v1, so nothing here depends on the v2 path" — which is a historical
|
|
460
|
+
claim and stays pinned to its version deliberately. A whole-file regex would fail
|
|
461
|
+
on those and teach the next person to delete the guard.
|
|
462
|
+
|
|
463
|
+
## Re-sync to Tin Can 1.9.2 — 2026-09-25
|
|
464
|
+
|
|
465
|
+
Copies are from tag `v1.9.2`.
|
|
466
|
+
|
|
467
|
+
| File | SHA-256 |
|
|
468
|
+
| --- | --- |
|
|
469
|
+
| `CANONICAL_ID.md` | `6e0dde03154956a480ae59f4d31b727ecc5a9e735c185fed6e4445f2574263a9` |
|
|
470
|
+
| `test/fixtures/canonical-id.json` | `b91406e068f6bec18629a4d2b9e91bc4d2e5a0487e4b6b4534fd5ba37c7f617a` |
|
|
471
|
+
|
|
472
|
+
`tincan_version: 1.9.2`, still 40 cases. Diffing `v1.7.0..v1.9.2` upstream, the
|
|
473
|
+
ONLY change across all three contract files is the version string in two lines —
|
|
474
|
+
`naming.ts` does not appear, and no fixture case or expected value moved. 1.8.0
|
|
475
|
+
(log chaining, arrival record), 1.9.0 (version reporting in `peers`), 1.9.1 and
|
|
476
|
+
1.9.2 (registration drift) do not touch the address format. Verified here rather
|
|
477
|
+
than taken from upstream's word: they explicitly said not to treat their summary
|
|
478
|
+
as a re-copy signal.
|
|
479
|
+
|
|
480
|
+
**This re-sync needed no pin edit.** The pins derive from `tincan_version`, so
|
|
481
|
+
updating the fixture moved CI on its own — the first cut where the failure class
|
|
482
|
+
that produced v0.9.0 had nothing to act on. The drift hashes still moved, which
|
|
483
|
+
is the third site behaving exactly as documented above.
|
package/README.md
CHANGED
|
@@ -1024,19 +1024,25 @@ The ordinary suite requires tmux, node-pty, POSIX `ps`/`lsof`, and Python 3 for
|
|
|
1024
1024
|
real file locks in the fake Codex executable. It uses isolated runtime homes and
|
|
1025
1025
|
no model APIs. It skips the four explicitly invoked compatibility cases.
|
|
1026
1026
|
|
|
1027
|
-
The verified contract baseline is
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1027
|
+
The verified contract baseline is the Tin Can named by `tincan_version` in the
|
|
1028
|
+
frozen fixture, `test/fixtures/canonical-id.json`. That field is the single place
|
|
1029
|
+
recording which release the vendored copies describe, and both `RELEASING.md` and
|
|
1030
|
+
`publish.yml` derive their pin from it. The suite spawns an installed binary as
|
|
1031
|
+
an MCP subprocess, compares durable IDs, and verifies delivery to fake runtimes
|
|
1032
|
+
through both terminal hosts. A missing binary or missing durable field fails the
|
|
1033
|
+
test. For reproducible verification, install that exact release outside Muster —
|
|
1034
|
+
derived here too, rather than typed, so this command cannot name a release the
|
|
1035
|
+
fixture has moved past:
|
|
1031
1036
|
|
|
1032
1037
|
```sh
|
|
1033
1038
|
contract_dir=$(mktemp -d)
|
|
1034
|
-
|
|
1039
|
+
ver=$(node -p "require('./test/fixtures/canonical-id.json').tincan_version")
|
|
1040
|
+
npm install --prefix "$contract_dir" --no-save "@brutalsystems/tincan@$ver"
|
|
1035
1041
|
MUSTER_TINCAN_BIN="$contract_dir/node_modules/.bin/tincan" npm run test:contract
|
|
1036
1042
|
```
|
|
1037
1043
|
|
|
1038
|
-
Verification uses
|
|
1039
|
-
|
|
1044
|
+
Verification uses that published release installed in an isolated temporary
|
|
1045
|
+
directory. No Tin Can source edits are made.
|
|
1040
1046
|
Fixture version metadata alone does not indicate address-format drift: compare
|
|
1041
1047
|
the case arrays. Those arrays cover naming only, not peer-list membership or
|
|
1042
1048
|
state semantics. Upgrades require separate compatibility verification; passing
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "FROZEN. Describes @brutalsystems/tincan address behaviour as shipped. Adding cases is fine; changing an expected value means the address format changed - see CANONICAL_ID.md, 'Changing this format'.",
|
|
3
|
-
"tincan_version": "1.
|
|
3
|
+
"tincan_version": "1.9.2",
|
|
4
4
|
"spec": "CANONICAL_ID.md",
|
|
5
5
|
"slugify": [
|
|
6
6
|
{
|