---
name: v0392-published
description: "v0.39.2 counter 70 PUBLISHED 2026-07-21; shell frame contract + {perch_dir}; version-bump rule written into CHANGELOG header"
metadata: 
  node_type: memory
  type: project
  originSessionId: 0cc427d2-c078-40d7-86d1-52aeb724e14c
  modified: 2026-07-21T14:22:58.450Z
---

v0.39.2 PATCH PUBLISHED — counter **70** @aeec392 (PR #47), 2026-07-21. Off main @88d040e (PR #46 shell-contract mini-wave, doyle whole-branch gate PASS). Range `v0.39.1..HEAD` = 5 commits; ADR-0046 (notif) + REQ triage excluded as design records.

**Notes:** Added — optional `{perch_dir}` spawn-template placeholder, filled at launch with the shell instance's own data directory; join a file notification's relative path against it to find the landed file (existing templates unaffected). Documentation — "Shells: the frame contract" published (every message type, attributes, body formats, per-message auth stamp, where sent files land).

**⭐ FIRST `### Documentation` SECTION — my call, doyle ruled it in.** Reasoning that became the ruling: the frames page is a CONTRACT a shell author codes against (flynn conformance-diffs a decoder against it on landing), so for that reader the publication IS the change; filing it under Added would overstate a docs drop as a code feature. Section set that cut: Added + Documentation. Pairs with the Known precedent in [[v0391-published]] — add a section type honestly rather than misfile.

**⭐ VERSION-BUMP RULE NOW LIVES IN THE CHANGELOG HEADER (was the actual defect).** Old text ruled only on breakage ("pre-1.0: breaking changes bump the minor"), so every additive cut had to re-derive or ask — it produced a patch-vs-minor question this cut, with the v0.38.0 precedent ("MINOR: new behavior") pointing the other way. doyle RULED patch, and asked for the rule to be written where the next release author reads it. Header now says: pre-1.0, **minor** when a release breaks something or changes observable behavior of existing surfaces broadly; **patch** for fixes and for additive opt-in capability (new key/flag/page no existing user can encounter without opting in). Also grounds: the OPERATOR had already named this cut 0.39.2 and reserved v0.40.0 for NOTIF-TRUTH. Instance of [[rule-failed-its-author-needs-a-mechanism]].

**⭐ ESCAPE THE DOTS IN RESIDUAL GREPS.** My post-bump residual check used an UNESCAPED version pattern; `.` matched checksum hex (`0439c1`, `043951`) and reported 3 phantom `0.39.1` residuals. `grep -c '0\.39\.1'` shows 0. Cost a verification round. Always escape.

**⚠ MY CI MISDIAGNOSIS — corrected to doyle, keep the corrected form.** PR #47 sat ~25min queued. I reported, in order: contention → kitsubito WEDGED (on "no `Runner.Worker` on the box") → main's run is a ZOMBIE (in_progress with all 8 jobs completed) → moved to force-cancel it. The force-cancel returned **409, already completed** — it had finalized on its own; nothing was cancelled, no harm, but I acted one observation short of confirmation on SHARED infra. Ground truth: ordinary contention plus run-finalization lag throughout. Durable lesson, narrower than the "read `busy` not `status`" version I sent earlier and which is recorded in [[v0391-published]]: **a single process sample cannot distinguish an idle runner from one between jobs, and a run in_progress with all jobs complete is finalization lag before it is a zombie** — both need a second sample or a job-assignment query before they support a claim. Same sibling-probe discipline as [[absence-needs-sibling-probe]], which I had and failed to apply to myself.

**Ceremony:** counter 70 verified from published metadata (v0.39.1=69). Relayed GO again — verified with doyle DIRECT before merging, and that round is where both rulings above happened (see [[v0391-published]]). Own branch off main. Cargo.toml + 11 first-party lock lines, zero third-party. `xtask gen` no drift. Ladder contiguous, 0.39.1 intact. doyle pre-merge PASS. 7/7 green, release build green, no reruns. Latest verified: counter 70, product 0.39.2, isDraft:false, isPrerelease:false.

**⚠ OPEN DEFECT AGAINST THIS RELEASE'S DOCUMENTATION ENTRY (flynn, 2026-07-21, accepted).** The published frames page documents **no body/attribute encoding**. It says the envelope is "one line of XML-shaped text" and shell_text's "body is the raw text"; actual frames HTML-escape attribute values AND bodies, encode newlines as `<br>`, and require **amp-last decode order**. Evidence: (1) multi-line `spt shell send` arrives on the drain as ONE line with literal `<br>` — self-proving against a one-line envelope; (2) `shell_command` JSON observed as `{&quot;ref&quot;:&quot;#5&quot;,...}`; (3) clean-room binary written strictly from the page renders literal `<br>`, breaks on first `&`, cannot round-trip `&lt;`; (4) negative probe — grep page for escap/entit/newline hits only the stdin sentence. Fix = short "Body and attribute encoding" section; **no behavior change wanted — the frames are the truth, the page is the bug.**

**MY NOTE OVERSTATED.** This release's Documentation line claims the page publishes every message type "with its attributes, **body format**, and per-message authentication stamp" — body format is exactly what is absent. Same failure class as the v0.39.0 false purge clause ([[v0390-published]]): a shipped claim asserting more than the artifact delivers. Lesson compounding: **I published a page as a CONTRACT without verifying it was sufficient to build against** — the argument I used to win the Documentation section ("for that reader the publication IS the change") is precisely the argument that obligated me to check it. A consumer's clean-room read is the test for a contract page; ship it before that read and the note is a guess. Routed to doyle (triage/vehicle ruling: ride v0.40.0 vs docs-only v0.39.3 counter 71) and todlando (author). Not mine to write — docs content is core's call.

**Post-publish:** flynn conformance-diffs their decoder against the published frames page (told to FILE any page-vs-frame gap as a core defect with evidence, not paper over it in the decoder) and is unblocked for alchemy W4; doyle opens NOTIF-TRUTH triage (v0.40.0 reserved). Still outstanding: hertz both-seam field-verify, and v0.39.0's three TEARDOWN-AUTHORITY claims remain unverified ([[v0390-published]]).
