Working state — a note taken while the work happens, not a specification. The system as it is meant to be is in Architecture.

Tonight (2026-08-07): interrogation → tight cleanup → playdate on hardware

John heavily in the loop for all of it. The culmination: the playdate build working for real — running on real hardware — and remote-debugging it when the program on it hits a disrupt we plant. That exercise pulls together the whole arc: the product press, the cross lane, the debugger, the symbol sidecar, and the cockpit.

Phase 1 — interrogation (now)

The question on the table: what do the docs say, what does the system do, and what are these tests doing? Every CI job is still red after the second push.

  1. Docs self-consistency audit — where the docs contradict themselves. First step, because a doc that disagrees with itself cannot be an oracle for the system.
  2. Docs-vs-system audit (John launches this himself) — every divergence, classified: ruled-but-unbuilt (expected — docs are target-final by design), system-contradicts-docs (defect in one or the other), docs-overreach (the docs describe machinery the system should not have — John suspects “it may be doing too many things in certain areas”).
  3. Test interrogation — what each red CI job actually tests, and whether that is a thing worth gating.

Phase 2 — tight cleanup

Driven by phase 1’s findings, item by item, with John ruling as we go. Not an autonomous batch.

Phase 3 — playdate, for real

  • The playdate build working — the wota32/nan32 Linux build break is already fixed (shoplib/wota.c limits.h); the coverage gate produces a verdict again (533/553 vs a 3.1.1 SDK; CI pins 3.0.6 — pin decision is John’s).
  • Running on real hardware (device lane has always been local-only).
  • Remote debug: plant a disrupt in the shipped program, hit it on device, attach from the host — freeze, frames, locals, symbols fetched by pool content hash. The debugger mechanism all exists; this is its first end-to-end demonstration, on the least forgiving target we have.

Tabled

  • The memory arc (plans/memory-arc.md) — design is ruled and captured; execution deferred. R7/static-lane deletion rides it when it resumes.

Still queued (unchanged)

  • Compiler quality arc, with the shootout’s target list: record ops and closures ~1.5–2.5× behind lua/quickjs; loops/GC ahead. bind_getup item.
  • Debugger demo beyond playdate (general remote attach).

Decisions parked with evidence, awaiting John

  • Cart target identity (;system= axis + un-trusting the root mount — invalidates committed seeds, overturns the trusted-root ruling).
  • Does a red Mac block the nightly (publish-nightly needs)?
  • Playdate SDK pin: 3.0.6 vs 3.1.1 (20 APIs differ).
  • The mac 32-bit-arm reds (real, pre-existing, newly visible — gc_policy asserts absolute byte sizes with no value-width gate).

Open defects

  • mach cache write failed — intermittent store publish race (shop_build.cm:968), the one real product-code suspect from CI.
  • shop_resolve intermittent — always step 5, load-correlated, smoke sometimes insufficient.
  • bench emits a truncated JSON line (BENCHRUN … Unterminated string).
  • stages baseline capture — needs a quiet machine.

Scheduled from John’s docs read-through (2026-08-07 evening)

The FLIP — policy becomes an explicit-answer actor (RULED, design in John’s words): policy.ce receives a message shaped like "<locator> started from <locator> wants to use <endowment>" and answers yes or no. An always-allow policy is simply a policy that doesn’t check and answers yes; a tighter one checks however it likes. Policies are actors precisely so this is expressed as code — no standard policy-JSON config format. “allowed: all” must be EXPLICIT, not the silent default (today policy.ce is default-allow twice over; the source itself calls the narrowing “the FLIP”).

Rides with it (one landing, the swappable-policy work):

  • Policy actor selected by LOCATOR, not the string literal "pit-shop/policy" (clerk.ce:1881, :1689) — the builders already show the shape (policy names their locator, clerk starts what is named; apply that to policy itself).
  • “Landing 2” (named in shoplib/recipe.cm:94): the shop reads its lists (fallback / bin / c_native / endowments) FROM the selected recipe instead of the hardcoded DEFAULT record — this is what makes a forged engine’s recipe lists real, and converts the accept/deny gaps found 2026-08-07.
  • The message carries BOTH program and starter; the policy decides their weight. (Reconciles clerk.ce:583’s program-keying rationale — “a rule for the program could be dodged by who asks” — with John’s shape: the clerk supplies the facts, the policy owns the judgment.)

Crypto locator cleanup (dispatched): delete std/crypto.cm wrapper, repoint bare use('crypto') importers at true locators. Docs already ruled and rewritten on arc/docs-corrections (held until the audit finishes).

Source: plans/tonight.md