Busy-state transparency: queue semantics, optimistic echo, Hidden section (round J) #34

Merged
ClaudiuSchuster merged 1 commit from oss-oo/observatory-j-package-nkyj20260925 into main 2026-09-25 00:11:53 +00:00
Owner

Round J of the pinky series — the busy verdict becomes transparent, the send button keeps the queue promise, the owner never loses his words.

Core (busy-state transparency): activityMs/busyAgeMs in the APIs; pulsing bg active · Ns row hints (never on running rows — background active ≠ user-visible turn); a queued steer explains WHY it waits and WHEN it lands (background turn, activity age, ~≤45 s after idle: 30 s grace + sweeper cadence); state-aware busy line (idle / bg active) instead of an always-on will-queue hint.

Send-button queue semantics (addendum 1): button stays ENABLED while earlier steers are queued or in flight — every send queues as the next sequential turn (dispatcher self-queue, never interleaving); live depth (1 in flight · 2 queued) in the dialog and queued · waiting for idle on the row; soft cap of 3 waiting steers (friendly inline note, drafted text kept, never a dead button); ⤢ expand moved onto the target line above the input row.

Optimistic echo (addendum 2): instant pending entry on Enter, seamless confirmation swap against the DB row (content+timestamp, no duplicate), failure flips to ⚠ not delivered with Retry + copy — preserved text, never a silent loss. Page-session buffer survives panel close/reopen.

Poll resilience (addendum 4): busy_timeout + single retry-on-busy on every shared-DB read (with a _TRACK rollback so retries cannot swallow completion webhooks); failed polls keep the last good content under a reconnecting… hint (hard error + Retry only after 3 consecutive failures); automatic recovery; section transitions never invalidate an open panel; dock items toggle.

Hidden section (addendum 6): deliberate view-state hiding (observatory-state.json) distinct from the native archive — order Running → History → Hidden → Archived, collapsed by default, full toolkit + Unhide + Archive.

Bell ledger (addendum 8): family edges also from stream-bells.json spawn records (lineage survives bells stuck in flight — the chain-break lesson), 🔔 pending/🔔 stuck row hints, tolerant time parser, graceful degradation on older dispatchers.

Expandable tool parts (addendum 5): ▸ ⚙ name unfolds pretty-printed input/output, capped height, … N more lines + copy-full; state survives re-polls.

Polish (addenda 3+7): row-leading title removed (the spanning line is THE title), section-header helper texts stripped (moved to README).

Validation: 57-check API+CDP gate against a fixture DB + stub dispatcher (real steer round-trips incl. queue/fail paths, live DB-lock resilience with content preservation and recovery) — all green; super-linter pylint 10.00/10. Evidence: /tmp/pinky-busy-transparency-evidence/.

Round J of the pinky series — the busy verdict becomes transparent, the send button keeps the queue promise, the owner never loses his words. **Core (busy-state transparency):** `activityMs`/`busyAgeMs` in the APIs; pulsing `bg active · Ns` row hints (never on running rows — background active ≠ user-visible turn); a queued steer explains WHY it waits and WHEN it lands (background turn, activity age, ~≤45 s after idle: 30 s grace + sweeper cadence); state-aware busy line (idle / bg active) instead of an always-on will-queue hint. **Send-button queue semantics (addendum 1):** button stays ENABLED while earlier steers are queued or in flight — every send queues as the next sequential turn (dispatcher self-queue, never interleaving); live depth (`1 in flight · 2 queued`) in the dialog and `queued · waiting for idle` on the row; soft cap of 3 waiting steers (friendly inline note, drafted text kept, never a dead button); ⤢ expand moved onto the target line above the input row. **Optimistic echo (addendum 2):** instant pending entry on Enter, seamless confirmation swap against the DB row (content+timestamp, no duplicate), failure flips to `⚠ not delivered` with Retry + copy — preserved text, never a silent loss. Page-session buffer survives panel close/reopen. **Poll resilience (addendum 4):** busy_timeout + single retry-on-busy on every shared-DB read (with a _TRACK rollback so retries cannot swallow completion webhooks); failed polls keep the last good content under a `reconnecting…` hint (hard error + Retry only after 3 consecutive failures); automatic recovery; section transitions never invalidate an open panel; dock items toggle. **Hidden section (addendum 6):** deliberate view-state hiding (observatory-state.json) distinct from the native archive — order Running → History → Hidden → Archived, collapsed by default, full toolkit + Unhide + Archive. **Bell ledger (addendum 8):** family edges also from stream-bells.json spawn records (lineage survives bells stuck in flight — the chain-break lesson), `🔔 pending`/`🔔 stuck` row hints, tolerant time parser, graceful degradation on older dispatchers. **Expandable tool parts (addendum 5):** `▸ ⚙ name` unfolds pretty-printed input/output, capped height, `… N more lines` + copy-full; state survives re-polls. **Polish (addenda 3+7):** row-leading title removed (the spanning line is THE title), section-header helper texts stripped (moved to README). **Validation:** 57-check API+CDP gate against a fixture DB + stub dispatcher (real steer round-trips incl. queue/fail paths, live DB-lock resilience with content preservation and recovery) — all green; super-linter pylint 10.00/10. Evidence: /tmp/pinky-busy-transparency-evidence/.
Busy-state transparency: queue semantics, optimistic echo, Hidden section (round J)
All checks were successful
Checks / Functional checks (pull_request) Successful in 13s
f4d2445fd2
Core (owner report: a session that LOOKED idle answered 'busy' with no
explanation — background turns are invisible in the desktop chat):
- busy reason + age surface everywhere: activityMs/busyAgeMs in the APIs,
  'bg active · Ns' row hints (breathing dot, never on running rows), and
  a queued steer's status line explains WHY it waits and WHEN it lands
  ('background turn active — last transcript activity Ns ago · delivers
  ~≤45 s after it goes idle (30 s grace + sweeper cadence)').
- the busy hint is state-aware (idle once the grace has actually passed;
  the will-queue phrasing only appears for sends that genuinely queue)
  and the grace threshold rides the server's configured value.

Send-button queue semantics: stays ENABLED while earlier steers are
queued or in flight — each send becomes the next sequential turn
(dispatcher self-queue, never interleaving); live queue depth ('1 in
flight · 2 queued') in the dialog and 'queued · waiting for idle' on the
row; soft cap of 3 waiting steers per session (friendly inline note, the
drafted text kept, button never dead over queue state); the prompt
expand control moved onto the target line above the input row.

Optimistic echo — never lose the owner's words: sends appear instantly
as pending entries (dashed accent, ⏳ chip), reconcile seamlessly with
the DB row by content+timestamp (one render pass, no duplicate), and
flip to a preserved-text error state ('⚠ not delivered' + Retry + copy)
on dispatcher failure, drop/dead-letter, or a POST that never got out;
a stale pending echo (10 min, no trace) also flips honestly. Buffer
survives panel close/reopen for the page session.

Poll resilience: every shared-DB read runs behind a 5 s busy timeout
with one retry-on-busy (fetch_sessions rolls its _TRACK mutations back
so the retry cannot swallow completion webhooks); a failed poll never
blanks an open panel — content stays under a 'reconnecting…' hint that
turns into a retry button only after three consecutive failures, with
automatic recovery and section transitions never invalidating a panel.

Deliberate Hidden section (view state, observatory-state.json —
distinct from the native archive): Hide on Running/History rows,
Hidden between History and Archived, collapsed by default, full row
toolkit plus Unhide and Archive; dock excludes hidden sessions.

Bell ledger (dispatcher v0.3.1+ stream-bells.json, tolerant parser,
graceful degradation): parent/family edges also derive from spawn
records, so lineage survives bells stuck in flight; parents show
'🔔 pending · Nm' / '🔔 stuck — watchdog notified' row hints.

Expandable tool parts: '▸ ⚙ <name>' affordances unfold pretty-printed
input/output (monospace, capped height, '… N more lines' + copy full);
expansion state survives re-polls.

Owner polish: row-leading title removed (the spanning line's title is
THE title), section-header helper texts stripped (moved to README),
dock items toggle (expanded favorite minimizes on click), README gains
the three-states section and hide-vs-archive distinction.

Validated: 57-check API+CDP gate (fixture DB + stub dispatcher, real
steer round-trips, live DB-lock resilience) — all green; super-linter
pylint 10.00/10.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OSS-Singularity/zcode-dispatch-observatory!34
No description provided.