Commit Graph
3778 Commits
Author SHA1 Message Date
jschoubben f7616c6a9b kernel: the initramfs script takes over a default-config preset and checks each image (issue 1977, L7-L9)
mesh/delivery merged: source.main moved to novox/mesh-catalog@b9abfde492b2
mesh/check checking f7616c6a9bd4 on b9abfde492b2
Before mkinitcpio -P, a preset naming ALL_config="/etc/mkinitcpio.conf" is copied to the state's
taken-over/ and loses that line (another ALL_config is left and named); after it, an image without
kernel/x86/microcode/ in its first 64 KiB fails the unit and records nothing. The unit may write
/etc/mkinitcpio.d. The README names no node. Tests: 1977/AC7, 1977/AC8; AC3/AC4 fixtures write images.

Builds: L7, L8, L9 (issue 1977 note 4)
2026-11-12 21:31:05 +01:00
jschoubben 62c0eb90cb kernel: kernel_boot reads microcode from each initramfs image (issue 1977, L6)
Replaces the state record read (root's 0700) with images_with_microcode per /boot/initramfs-*.img:
true when the first 64 KiB hold a path under kernel/x86/microcode/; an unreadable image goes to
image_errors with its error. Test: 1977/AC5.

Builds: L6 (issue 1977 note 3)
2026-11-12 20:54:34 +01:00
jschoubben 5795f4d230 kernel: microcode in every initramfs through mkinitcpio's microcode hook (issue 1977)
Declares amd-ucode and intel-ucode, the drop-in /etc/mkinitcpio.conf.d/mesh-microcode.conf, the
initramfs script and mesh-kernel-initramfs.service; kernel_boot answers the running revision and
whether the images were built with the drop-in. Tests: 1977/AC1-AC5.

Builds: L1, L2, L3, L4, L5 (issue 1977 note 2)
2026-11-12 20:52:21 +01:00
mesh-tools a60728e6f0 Merge pull request 'systemd-resolved: the own resolver's file waits 3 s a try (issue 1748, ADR 0678)' (#671) from fix/1748-resolver-wait into main 2026-11-12 17:52:35 +00:00
mesh-tools 792a79720b Merge pull request 'mesh-vault: secret_holders lists every record of the vault's store by name and fingerprint (issue 1409)' (#670) from fix/1409-store-records-listed into main 2026-11-12 17:51:18 +00:00
jschoubben d638856768 Asker rename R2: the build modules' tests read a named ask's step under its asker
Builds: design 47 G §481, §483, A-163

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 18:37:29 +01:00
jschoubben d22a7f3a41 fix-1748-own-resolver-wait: the own resolver's file waits 3 s a try
mesh/delivery merged: source.main moved to novox/mesh-catalog@a60728e6f09d
mesh/delivery-group group fix/1748-resolver-wait merged: every member is merged
mesh/check checking d22a7f3a412f on a60728e6f09d | novox/mesh-catalog#671 in group fix/1748-resolver-wait
The resolver file of systemd-resolved (resolvers and kept facts) carries options timeout:3 attempts:2 edns0 in place of timeout:1; manifest test asserts both facts, guard test's literal follows.

Builds: design 50 resolver-wait §1, §4 (and §2 of the main file, line 73)
2026-11-12 18:09:17 +01:00
jschoubben ec646f55ee J26 item 2: the run-ask test expects a program's exit 7 to end its key failed
Since A-290 a run whose program exited other than 0 ends its key failed, the
reason saying the exit, its answer kept (steprun.finish); the test still
wanted passed. It now wants failed with "the program exited 7" and reads the
kept answer as before.

Builds: design 47 G A-290

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 18:06:06 +01:00
jschoubben 49ab6c00ea J26 item 1: build-node tests ask a stand-in registry, never the mesh's
Every TypeScript module of a fetch gets the registry's latest SDK (ADR 0573 §2,
A-284), so the harness's machine named the real registry and 11 tests (9 unit,
11 integration runs) reached the network; with the resolver down they failed.
The harness now serves a registry of the test's own holding one SDK release,
and the userconfig test reads its address from it.

Builds: design 47 G A-284, A-285

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 18:02:54 +01:00
jschoubben 45b0779b68 mesh-vault: a store file that is not a record is listed by name with its error (issue 1409, V10)
mesh/delivery merged: source.main moved to novox/mesh-catalog@792a79720b30
mesh/check checking 45b0779b6801 on 792a79720b30
Store.ListReadable lists every record and, beside them, each file it cannot read
by name with its error; RecordsHeld lists those as rows with an error and goes
on. recordsError stays for a store that cannot be listed at all. Store.List and
ListPrefix keep their behaviour for their other callers.

Builds: design 39 bus-and-switch §20; design 39 parts §12. Lead answers (issue 1409): V9 (keep recordsCount and recordsError), V10.
2026-11-12 17:41:39 +01:00
mesh-tools 0ec8347786 Merge pull request 'node-uplink links answers each link's mac, master and parent (issue 1965)' (#669) from fix/1965-links-mac into main 2026-11-12 16:35:36 +00:00
jschoubben 52572698cb mesh-vault: secret_holders lists every record of the vault's store by name and fingerprint (issue 1409)
S1 vault-licence-secrets-listed. secret_holders answers `records` and
`recordsCount` beside holders, count and enrolments: each store record's name,
generation, since, changed, changedBy/changedVia, origin, length and the vault's
own fingerprint of the whole value, plus key and part for licence.<key>.<part>.
A record the vault cannot open stays listed with an error. Never a value.

Builds: design 39 bus-and-switch §20, §15; design 39 parts §12 (D1); design 24 Every secret lives in the vault, Beyond generate and hold; as-is 06 The vault, as it runs.
Lead answers (issue 1409 note 11): V1, V-thorough, V2-V8. V3 drops the map's
tokenFingerprint and AC5; V-thorough widens the licence.-prefix list to every record.
2026-11-12 17:34:00 +01:00
jschoubben 700b37890b node-uplink links answers each link's mac, master and parent (S1a links-mac, issue 1965)
mesh/delivery merged: source.main moved to novox/mesh-catalog@0ec8347786f4
mesh/check checking 700b37890bfd on 0ec8347786f4
Both holders' uplink-tools copies read address, master, link and
link_index/link_netnsid from the existing ip -j address show call. Fields
are left out where a link has none (L3); a parent in another namespace is
{index, namespace} (L2); the form lives in uplink.go only (L4); only the
tool description changes, not seat.json (L5); bridge fdb MACs are not
answered (L6); names mac, master, parent (L1).

Builds: design 48 10, design 08 code:, issue 1965 note 11 L1-L6
2026-11-12 17:30:17 +01:00
jschoubben ea4bb70a21 Merge origin/main into the join: provisioner asks bounded, mesh-files fixes, step answer bound
Brings #664 (licences_switches carried entries), #665 (mesh-files lists a
place a secret is kept), #666 (provisioner: bounded retiring ask id, a
refused ask said, provisioner_health), #667 (mesh-build-go's step end
rewritten without the taken versions when over the steps state's bound),
#668 (mesh-files find writes the NUL itself). #667's buildstep/step.go and
digestshape_test.go conflict with G's deletion (the step runner moved to
mesh-delivery-sdk/steprun, SD5): G's side is kept; its intent, an answer over
the bound not lost, is G's A-290 (the answer kept as an output object).

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 17:01:44 +01:00
jschoubben 87ca34c92f A-291: the recovery keeper receives snapshot-get's chunks through the SDK's one helper
The keeper's hand-made receive (subscribe to the call's chunks, ask, receive in order, acknowledge each) moves into
mesh-sdk's process.Conn.CallChunks; the keeper's answer checks (an answered error, the space it fits, no chunk granted)
run as its accept hook before a chunk is taken.

Builds: design 47 G A-291

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 16:52:20 +01:00
mesh-tools 836fcd81f6 Merge pull request 'mesh-files: find writes the NUL itself, so a list or search through root runs at all (issue 1409)' (#668) from fix/1409-root-list-nul into main 2026-11-12 15:39:51 +00:00
mesh-tools 8484ab0032 Merge pull request 'A step answer over the steps state's bound is kept without its taken versions, said, not lost' (#667) from fix/step-answer-over-bound into main 2026-11-12 15:37:54 +00:00
jschoubben c29ef0d95e mesh-files: find writes the NUL itself, so a list or search through root runs at all (issue 1409)
mesh/delivery merged: source.main moved to novox/mesh-catalog@836fcd81f65b
mesh/check checking c29ef0d95ea7 on 836fcd81f65b
Live on novox 2026-11-12: node-files.list of a root-only directory answered
'fork/exec /usr/bin/sudo: invalid argument'. The kernel refuses a program
argument that holds a NUL byte, and listAsRoot's -printf format and
searchBelowAsRoot's ended in a literal \x00 since 5d98bcc0 (2026-10-16), so
no list or search through root ever ran on a node. find writes \0 itself.
The stand-in root in the tests refuses an argument holding a NUL, as exec
does, so every root call is held to it; it found the search's instance.

Builds: design 39 parts §15 and the lead's answer D3 (list through root of a place a secret is kept).
2026-11-12 16:34:24 +01:00
mesh-tools c0d666fdcf Merge pull request 'The provisioner's retiring asks get a bounded id, and a refused one is said (issue 1966)' (#666) from fix/1966-unpublished-placed-module into main 2026-11-12 15:34:21 +00:00
jschoubben 22bbb9c2c0 Keep a check's answer within the steps state: leave out the taken versions
mesh/delivery merged: source.main moved to novox/mesh-catalog@8484ab0032a5
mesh/check checking 22bbb9c2c09f on 8484ab0032a5
A catalog check's answer of 264712 bytes was refused by the steps state
(256 KiB per value) and its end written failed without it, so the checker
lost the biggest member's answer and could not preview it. When a passed
or failed end is refused as too large, finish writes it once more without
the fetch's taken versions (fetch.packages, which no reader judges), the
step's reason saying how many were left out, why, and that the module's
journal names each; still too large, it ends failed as before.

Quick fix for issue 1921 (note 91); the thorough fix is design 47 G A-290
(an answer over the bound kept as the object output.<ask>).

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 16:32:48 +01:00
mesh-tools 7b50628627 Merge pull request 'node-files lists a place a secret is kept, entries without content, and stat says a missing path is missing (issue 1409)' (#665) from fix/1409-list-secret-place into main 2026-11-12 15:28:22 +00:00
mesh-tools 23a280a664 Merge pull request 'licences_switches answers switches carried from the old database with their licence and consumer (issue 1409)' (#664) from fix/1409-carried-switches into main 2026-11-12 15:27:13 +00:00
jschoubben 3bb8ace833 U6, U7 provisioner: a bounded retiring ask id, a refused ask said, the Composition comment corrected
mesh/delivery merged: source.main moved to novox/mesh-catalog@c0d666fdcf55
mesh/delivery-group group fix/1966-unpublished-placed-module merged: every member is merged
mesh/check checking 3bb8ace833d1 on c0d666fdcf55 | novox/mesh-catalog#666 in group fix/1966-unpublished-placed-module
The retiring ask's id is made from the key's digest and the time (at most 64 characters),
so a long key is asked. An ask the router's rules refuse is said in the key's why and in
provisioner_health. The Composition comment says what the code does: an unpublished
module keeps only its own plan and keys.

Builds: design 47 fix-unpublished-placed-module U6, U7, ADR 0593 §8
2026-11-12 16:01:25 +01:00
jschoubben ab1eb0cb47 Review 1 of S1: the served-text row finds the list tool by its full name; list's text is the contract's word for word
mesh/delivery merged: source.main moved to novox/mesh-catalog@7b5062862758
mesh/delivery-group group fix/1409-list-secret-place merged: every member is merged
mesh/check checking ab1eb0cb4781 on 7b5062862758 | novox/mesh-catalog#665 in group fix/1409-list-secret-place
Builds: design 39 parts D3 (§15), bullets 2 and 4.
2026-11-12 15:52:34 +01:00
jschoubben 2a9827ce18 Review 1 of S1: list's served text ends with the account sentence only; a secret-shaped link target in a secret place is withheld
Issue 1409. readTools no longer appends the refusal sentence to list. A row in
TestSecretPlacesAreRefusedByNameBeforeAnyRead holds a link's target in a secret place to the content rule.
S2's match on sudo's English message is left as it is: the root path sets no locale, and sudo's environment
handling decides whether LC_ALL reaches stat.

Builds: design 39 parts D3 (§15), bullets 2 and 4
2026-11-12 15:50:45 +01:00
jschoubben 493c59c89b Join 11: merge mesh-catalog main (a check step that errors after its fetch merged still answers)
Main brought #663 (fff3b819) in mesh-build-go/buildstep/askrun.go; G moved that step
runner into mesh-delivery-sdk/steprun, where 5fbc366f holds the same answer on error,
so G's deletion of buildstep's askrun.go and its test is kept. The tree is G's.

Builds: design 47 G A-286

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:48:26 +01:00
jschoubben 1cb1c84cc1 A-287, A-288: gitea announces every state its manifest declares; its refusal test holds the meaning
KEPT gains failed-steps, idle and transfers, so each declared state can be read by
its tools; the force-push refusal's test holds that the refusal names the one tool
that may do it and that it runs on the operator's Approve of that call.

Builds: design 47 G A-287, A-288

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:45:03 +01:00
jschoubben fdd33e1234 S2 stat-says-missing: mesh-files stat says a path root finds missing does not exist
Issue 1409. A stat through root of a path that is not there answered that the file modes refuse it; it says
it does not exist, so design 39 parts §15's "gone" can be read.

Builds: design 39 parts D3 (§15), bullet 3
2026-11-12 15:44:51 +01:00
jschoubben c41387f271 S1 list-secret-place: mesh-files lists a place a secret is kept, entries only, marked secret-place
Issue 1409. A list of a place the mesh keeps a secret, or of a machine's credential places, at any depth,
answers each entry's name, type, owner, group, mode, size and a link's target held to the content rule,
never content, and says secret-place; a process's environ, mem, fd, map_files, root and cwd stay refused.
Lines touched cite ADR 0394 §7.

Builds: design 39 parts D3 (§15), bullets 2 and 5
2026-11-12 15:44:50 +01:00
jschoubben e034f73991 Join 11: gitea reads the step event's fingerprint by the seat's name
The seat mesh-pipeline-runner's step event carries `fingerprint`; gitea read
`fp`, which no event carries, and which the type-check refuses once the Node
fetch places the runner's contracts (design 47 G A-285).

Builds: design 47 G A-285

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:42:14 +01:00
jschoubben ee6d7c284d The carried-switch test names no real node or address (review round 1)
mesh/delivery merged: source.main moved to novox/mesh-catalog@23a280a664be
mesh/check being carried to ee6d7c284da9 on 23a280a664be | from f1c04801e477
2026-11-12 15:40:10 +01:00
jschoubben 622b259145 Join 11: gitea names the pipeline runner's contracts and takes a revision answer whole
gitea imports @novox/mesh-delivery-contracts-mesh-pipeline-runner, so its
package.json names it and the Node fetch places the group's (design 47 G A-285);
the catalog view's revision answer is typed with its revision and entries, which
revisionAnswer already refuses loudly when the holder leaves them out.

Builds: design 47 G A-285

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:39:53 +01:00
jschoubben b5c5594ea7 licences_switches answers the old field names of carried entries (issue 1409)
Builds: design 39 bus-and-switch §37, §12 and the lead's answer C5 (hq 45ee2475).
2026-11-12 15:38:00 +01:00
jschoubben 64fa2f5abf A-285: the Node fetch packs each of the group's packages and places it by name
The fetch takes `group-packages` (a member's repository, commit, ref and the
package's directory there) in place of the single `package` and its tagged form;
it packs each package a module of the tree takes, publishing nothing, and places
it in every module whose package.json names it, the SDK in every module, in place
of the registry's whatever the lock names.

Builds: design 47 G A-284, A-285

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:37:30 +01:00
mesh-tools f1c04801e4 Merge pull request 'A check step that errors after its fetch merged still answers its fetch' (#663) from fix/checker-preview-after-failed-step into main 2026-11-12 14:34:05 +00:00
jschoubben fff3b819d3 A check step that errors after its fetch merged still answers its fetch
mesh/delivery merged: source.main moved to novox/mesh-catalog@f1c04801e477
mesh/delivery-group group fix/checker-preview-after-failed-step merged: every member is merged
mesh/check checking fff3b819d383 on f1c04801e477 | novox/mesh-catalog#663 in group fix/checker-preview-after-failed-step
A level that does not compile or generate ended the check step failed with no
result, so the checker could not tell a merged fetch from one that never
answered, and previewed and judged no manifest or composition of the member.
The step now ends failed with its answer all the same: its fetch and the
levels so far beside the error, which the step's end already keeps.

Builds: design 47 G A-286 (G-22-lead-answers-2.md at hq 41dd30fe; issue 1921; principle 3)
Quick: this checker on main; thorough: the same rule in G's checker (join 11, J15).

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:23:48 +01:00
jschoubben dad8672b73 Join 11: the fetch's proof loads both build tags and holds the tree's go.mod and go.sum to what they load
Try 2 of milestone G failed in go test, verifying nats-server against the checksum database: restic's
integration tests load it through testbus, neither its go.mod nor its go.sum named it, and the fetch's
shut-off load ran untagged, so it never met it. The second failure of this kind (after the join's
dropped zero-version requires), so the guard is held once, where every repository's check passes: each
directory of the checked tree is loaded untagged and with the integration level's tags, and its own
go.mod and go.sum must name every module the loads reach (a mesh module required, no sums; every other
required at the version selected, with both go.sum lines). The fetch fails naming the module and the
line. A sibling laid beside is loaded as before, unjudged.

This guard lands with G, so G's own check still runs today's proof; no harm, the gaps it finds in the
seven repositories are fixed in this join.

Builds: design 47 G (join 11, the check's shut-off build of the group's modules)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:21:36 +01:00
jschoubben b854f884e9 Join 11: restic requires and sums nats-server, which its tests load through testbus
The check builds with GOPROXY=off, so a module its packages load that go.sum does not hash is looked up in the
checksum database and fails (try 2: verifying nats-server v2.11.17). mesh-sdk testbus, which restic's tests import,
brings nats-server and its four requirements; go.mod and go.sum now name them, as go list -mod=readonly -deps -test
against the group's heads asks (both build tags).

Builds: design 47 G (join 11, the check's shut-off build of the group's modules)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 15:00:49 +01:00
jschoubben a57139dcf5 Join 11: claude-code's manifest test lists the operator channel's notify it invokes
Area 2 added seat:operator-channel.notify to the manifest's invokes for the call in main.go,
and the test of the manifest's invokes still listed the old ones, so the unit level failed.

Builds: design 47 G GR8

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 14:15:08 +01:00
jschoubben f7e59b876d Join 11: every go.mod requires, at the zero version, each mesh module its packages load
The checker's fetch pins only the zero-version requirements a directory's go.mod names
(mesh-build-go workspace.go goModOf), so a module reached only through another, such as
meshhandacts through meshhandactsclient or mesh-delivery-sdk through meshcatalogclient,
was never downloaded and the shut-off load failed (fetch.go:267). The join's merges had
dropped these indirect requirements that the trunk's go.mod files list.

Builds: design 47 G (join 11, the check's fetch of the group's modules)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 14:07:29 +01:00
jschoubben b1da6344a8 Join 11: merge origin/main (the licence manager in parts, issue 1409)
The conflict in the old cmd/claude-licence-manager/tools_test.go resolves to both sides: main
moved it to cmd/manager, and the join's count of binding.changed.<consumer> under its family
goes into the moved TestResyncSaysEachOnce. The whole-module test's runtime refused
binding.changed.<consumer> because the manifest names the family binding.changed: it now
accepts a key that extends a named family by further parts, as A-134 says the event.

Builds: design 47 G A-134

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 14:05:51 +01:00
jschoubben 0f796e6505 A-283: the bus module's keeper makes a state bucket with the max-mib its requirement declares
Builds: design 47 G A-283 (G-22 lead answers, with A-277 and ADR 0595)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 13:13:05 +01:00
mesh-tools 6d000647de Merge pull request 'The licence manager is built of its parts, a manager and its tools, and the finished carry-over leaves (issue 1409)' (#662) from feat/1409-parts into main 2026-11-12 12:05:46 +00:00
jschoubben cff1005422 P2: the licence manager is four parts of one manifest (issue 1409)
mesh/delivery merged: source.main moved to novox/mesh-catalog@6d000647de2d
mesh/check being carried to cff1005422c1 on 6d000647de2d | from f9dcbc295723
The one bundle that did everything becomes the manager bundle, which runs long and answers the seat's ten verbs and
the three acting tools, and a tools bundle of its own that answers the four reading tools and writes nothing, so they
answer while the manager fails to load or stops. Both import the module's one package for the layouts of the kept
data and the log entries, the key form, the entries' names and the settings with their validity; the settings file
and the account with its directory stay as they are.

Builds: design 39 parts §1, §2, §3, §4, §5, §6, §7, §8
2026-11-12 12:08:03 +01:00
jschoubben 0e9fb2cbe3 A-281: the switch key names the gate's own build through mesh-sdk's process, which the environment check allows 2026-11-12 12:03:25 +01:00
jschoubben 478551622d mesh-recovery consumes mesh-broker recreated and dropped, which its process binding hears (A-274)
Builds: design 47 G A-274

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 12:01:54 +01:00
jschoubben 742303895b §716: the gate keeps a group's members from the seat git's pull events in deliveries and groups; the switch runs once (A-281)
The gate consumes pull-updated and invokes open-pulls and pull; it writes deliveries and groups
under their key forms, deletes them as a take-in or a closed pull request leaves them, copies a
delivery's base onto the record's member, answers groups from records and the group key together,
puts a missed event right at its start, and writes switch.done once the switch has run.

Builds: design 47 G §716, A-279, A-236, A-281

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 12:01:29 +01:00
jschoubben ce9f984363 P1: the carry-over leaves the licence manager (issue 1409)
The carry-over from the store database ran live once and carried every row, so its code, the gate that answered
"the carry-over has not ended", the condition carry-over-failed, the tool licences_carried, the opening of grants
with grant.key and the postgres driver leave the module, with its requirement of the database and of the secret
grant-key. The state carried stays as the carry-over's record; at its start the manager waits for nothing and
clears a carry-over-failed it finds kept.

Builds: design 39 parts §6 (the template files/database.url), §9, §10, §11
2026-11-12 11:55:54 +01:00
jschoubben c82b40660b A-278 (join 11): mesh-recovery and nats pass mesh-sdk's seatlist.Definition to AnswerSeat
Builds: design 47 G A-278 (answers G-22)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 11:42:11 +01:00
jschoubben e436c59430 Area 5 (join 11): a take-in's branch no longer stands in for a member's base
Builds: design 47 G A-279 (answers G-22)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 11:40:07 +01:00