Extract canonical StarLang wire encoding into star-canonical-json #36

Merged
lost-rob0t merged 8 commits from extract/canonical-wire-encoding into main 2026-08-15 15:17:22 +00:00
lost-rob0t commented 2026-08-15 15:15:07 +00:00 (Migrated from github.com)

Scope

Continue reducing prototype authority after PR #35 by moving the remaining StarLang-specific byte-producing JSON composition out of prototype/ into final star-canonical-json.

After protocol validation became final-owned, the serializer layer can now own encoding without independently deciding payload validity.

Final serializer authority

star-canonical-json now owns:

  • portable manifest → canonical JSON composition
  • schema-aware wire value → JSON-node encoding after protocol validation
  • legacy wire-envelope canonical JSON
  • lifecycle common JSON fields
  • ACK/error/cancel control-payload JSON encoding
  • command/event/reply payload JSON encoding
  • complete canonical lifecycle-envelope JSON

The final serializer depends one-way on star-actor-protocol for data-contract validation and field/type interpretation. There is no compiler/runtime dependency and no cycle.

One-authority prototype reduction

prototype/canonical-json-prototype.lisp is reduced to compatibility delegates plus protocol helper aliases still used by binding/domain prototype code.

prototype/message-lifecycle-prototype.lisp no longer owns lifecycle JSON composition; canonical-lifecycle-envelope-json is a thin final-package delegate.

Extraction metrics

CI on final head 7fae4caa3a69a4d96f60b7c27683fce6b3dd2701 reports:

  • aggregate prototype/**/*.lisp: 19,327 → 19,077 LOC (-250)
  • prototype/canonical-json-prototype.lisp: net -172
  • prototype/message-lifecycle-prototype.lisp: net -78

Exact behavior preserved

This slice does not redesign canonicalization. It preserves the existing:

  • lexicographic object-key ordering
  • lower-camel manifest keys
  • symbol/keyword spelling rules
  • boolean/null sentinels
  • decimal string representation
  • structured string-alist object encoding
  • lifecycle optional-field omission
  • control payload shape

No float/RFC8785/Ryu work from issue #5 is included.

Validation

GitHub Actions and Nix are green:

  • independent target-system loading ✅
  • direct star-canonical-json generic tests ✅
  • exact-byte StarLang canonical wire tests ✅
  • final actor protocol / journal / lease / mailbox / Sento / runtime tests ✅
  • asdf:test-system :starlang-prototype ✅ — 34 standalone scripts
  • generated interchange artifact validation ✅
  • frozen canonical manifest/envelope fixture/hash verification ✅
  • Nix flake check ✅

Dispatcher note

A live-code audit corrected an earlier assumption: dispatcher-idempotency-identity-prototype.lisp currently computes semantic identity structurally by selecting stable command fields; it does not canonicalize identity through JSON. Therefore this serializer extraction is an independent one-authority cleanup, not an idempotency prerequisite.

Next slice

Deterministic wire dispatch is ready to move into starlang-runtime. Absorb the existing structural semantic-idempotency wrapper and deferred-completion behavior into one final implementation. Preserve the distinct dispatcher work queue; do not replace it with per-actor star-mailbox semantics.

## Scope Continue reducing prototype authority after PR #35 by moving the remaining StarLang-specific byte-producing JSON composition out of `prototype/` into final `star-canonical-json`. After protocol validation became final-owned, the serializer layer can now own encoding without independently deciding payload validity. ## Final serializer authority `star-canonical-json` now owns: - portable manifest → canonical JSON composition - schema-aware wire value → JSON-node encoding after protocol validation - legacy wire-envelope canonical JSON - lifecycle common JSON fields - ACK/error/cancel control-payload JSON encoding - command/event/reply payload JSON encoding - complete canonical lifecycle-envelope JSON The final serializer depends one-way on `star-actor-protocol` for data-contract validation and field/type interpretation. There is no compiler/runtime dependency and no cycle. ## One-authority prototype reduction `prototype/canonical-json-prototype.lisp` is reduced to compatibility delegates plus protocol helper aliases still used by binding/domain prototype code. `prototype/message-lifecycle-prototype.lisp` no longer owns lifecycle JSON composition; `canonical-lifecycle-envelope-json` is a thin final-package delegate. ## Extraction metrics CI on final head `7fae4caa3a69a4d96f60b7c27683fce6b3dd2701` reports: - aggregate `prototype/**/*.lisp`: **19,327 → 19,077 LOC (-250)** - `prototype/canonical-json-prototype.lisp`: net **-172** - `prototype/message-lifecycle-prototype.lisp`: net **-78** ## Exact behavior preserved This slice does not redesign canonicalization. It preserves the existing: - lexicographic object-key ordering - lower-camel manifest keys - symbol/keyword spelling rules - boolean/null sentinels - decimal string representation - structured string-alist object encoding - lifecycle optional-field omission - control payload shape No float/RFC8785/Ryu work from issue #5 is included. ## Validation GitHub Actions and Nix are green: - independent target-system loading ✅ - direct `star-canonical-json` generic tests ✅ - exact-byte StarLang canonical wire tests ✅ - final actor protocol / journal / lease / mailbox / Sento / runtime tests ✅ - `asdf:test-system :starlang-prototype` ✅ — **34 standalone scripts** - generated interchange artifact validation ✅ - frozen canonical manifest/envelope fixture/hash verification ✅ - Nix flake check ✅ ## Dispatcher note A live-code audit corrected an earlier assumption: `dispatcher-idempotency-identity-prototype.lisp` currently computes semantic identity structurally by selecting stable command fields; it does **not** canonicalize identity through JSON. Therefore this serializer extraction is an independent one-authority cleanup, not an idempotency prerequisite. ## Next slice Deterministic wire dispatch is ready to move into `starlang-runtime`. Absorb the existing structural semantic-idempotency wrapper and deferred-completion behavior into one final implementation. Preserve the distinct dispatcher work queue; do **not** replace it with per-actor `star-mailbox` semantics.
Sign in to join this conversation.
No description provided.