Skip to content

chore: sync current Moltnet state - #10

Merged
apresmoi merged 78 commits into
mainfrom
agent/publish-current-state
Aug 13, 2026
Merged

chore: sync current Moltnet state#10
apresmoi merged 78 commits into
mainfrom
agent/publish-current-state

Conversation

@apresmoi

Copy link
Copy Markdown
Collaborator

What changed

  • Synchronizes the complete local Moltnet history onto a reviewable branch.
  • Advances rooms, messages, bridges, causal transcripts, machine coordination, authentication, transport, and website packaging.
  • Preserves Moltnet as an independently extractable transport service.

Why

The GitHub default branch is 77 commits behind the Moltnet build pinned by the current ecosystem integration.

Impact

  • Makes the current transport and Pi-bridge implementation available for coordinated Spawnfile, Simfile, and Daimon review.
  • Does not create a release or change published artifacts.

Validation

  • go test ./... — pass across all packages

Review notes

  • The historical diff contains several pre-existing blank-line-at-EOF warnings in website files.

apresmoi added 30 commits July 9, 2026 18:26
apresmoi added 27 commits August 2, 2026 19:07
…ntity

The control wake's `from` came from SenderName(), which returns Actor.Name in
preference to Actor.ID. Name is never validated by validateSenderIdentity, so
the server's own authenticated identity was discarded in favour of a string the
sender chose, and that string was rendered verbatim into another agent's prompt.

Measured against a real node configured like the tiny-football fixture (bearer
auth, public_read false, agent_registration disabled, per-agent bound tokens):

  red token, from.id=blue                     -> 403 agent "blue" is not allowed
  red token, from.id=operator                 -> 403 agent "operator" is not allowed
  red token, from.id=red, from.name=operator  -> 202 accepted

So the ownership check bites on from.id and was completely bypassed via
from.name. It survived the strictest configuration in the repo.

Control attribution is now Actor.ID, which the server credential-binds before
the stored event reaches the bridge. Protocol validation constrains it to
[A-Za-z0-9][A-Za-z0-9._:-]{0,127}, so the derived header value cannot contain a
newline, space, or bracket -- the envelope-forgery class dies structurally
rather than by escaping. SenderName still renders the display name in the
message body, which is untrusted by construction.

The sealed causal record already attributed the forgery correctly:
principal_id was operator:token:red-agent, not the claimed "operator", because
causalPrincipal() reads only authn.Claims.

internal/bridge/... 10/10 packages pass outside the sandbox.
…serting against it

web.Files is //go:embed all:dist, so the Vite bundle is compiled INTO the test
binary. TestConsoleBundleUsesRoomAccessForComposer asserts the bundle contains
"can_write", "registered agents write" and "members write" — but go test never runs
Vite, and an embedded stale bundle always exists and always looks valid. If web/src
changed those authorization strings and nobody rebuilt, the assertions pass against
last month's JavaScript with no signal anywhere. That is worse than a missing
existence check.

Compares the newest web source against the OLDEST file under web/dist and fails
loudly with both timestamps and the rebuild command. Fails as vacuous on a
zero-source or zero-output scan, with a test for the empty-output case so the
instrument is known to report a positive.

Proven both directions: touching web/src/App.tsx gives
`web bundle stale: source .../web/src/App.tsx mtime ... is newer than oldest output
.../web/dist/index.html mtime ...; run npm run build in ecosystem/moltnet/web`;
restoring the output mtimes returns the whole transport package to ok.
The sealed run record carried no message text and no sender: the causal log
records only message_id, target, content_sha256 and policy_decision. With a
network on store.kind memory the bodies died at container teardown, so a run
could not show who said what to whom -- the evidence the memetics programme is
built to study.

transcript.json is now written into the causal directory, which the compiler
already mounts unconditionally for exactly this reason. It reuses the existing
simfile.moltnet.transcript.v1 shape so existing readers and golden fixtures are
unaffected, plus a machine-readable attestation block.

The volume's contract changes from hashes to bodies and the file says so at the
site, including why it stays an attestation:

  - text is checkable -- sha256(json.Marshal(Parts)) equals the content_sha256
    already recorded for that message_id
  - attribution is stated, never assumed -- `from` is what the sender CLAIMED;
    principal_id is what the server AUTHENTICATED

Three attestation states, not two. A network on auth.mode: none stamps
system:moltnet.anonymous, so attribution is `unattested` and must never be read
as `passed`.

Verified on a real node outside the sandbox: seven messages written, every one
matching its causal content_sha256, and a message posted by red's token with
from.name "operator" recorded against principal operator:token:red-agent.

internal/{observability,rooms,app} pass outside the sandbox.
@apresmoi
apresmoi marked this pull request as ready for review August 13, 2026 20:24
@apresmoi
apresmoi merged commit 7baeb28 into main Aug 13, 2026
5 checks passed
@apresmoi
apresmoi deleted the agent/publish-current-state branch August 13, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant