Skip to content

Merge dev → main (automated) - #2090

Merged
SorraTheOrc merged 54 commits into
mainfrom
release/dev-to-main-20260930093645
Sep 30, 2026
Merged

SorraTheOrc merged 54 commits into
mainfrom
release/dev-to-main-20260930093645

Conversation

@SorraTheOrc

Copy link
Copy Markdown
Member

Automated release created by ship skill.\n\nIncludes CHANGELOG.md with work-item summaries from this release.

pi and others added 30 commits September 27, 2026 01:41
…ripts imports

Add /home/rgardler/projects/SorraAgents to sys.path so that
skill.scripts.failure_notice resolves correctly. The existing
PI_SKILLS_ROOT entry only provides access to audit.scripts.*, not
the skill.scripts.* package needed by test_parses_with_wrapped_failure_notice.

Fixes WL-0MUJTF9SA0034BSP
…CV5005XAZX)

Test-first: 31 table-driven test cases covering all classification paths:
- Marker detection: end, mid-message, trailing whitespace, no marker
- Live agent below/above idle threshold
- Dead agent detection
- Never-close guards: implement, producer-review, invoking-pane, live-children
- Guard precedence verification
- Kind variant coverage for all non-implement kinds
- extractFinalAssistantText helper tests

Shared pure classifier module (pane-close.ts) provides:
- classifySession(): SessionSample → CloseDecision
- extractFinalAssistantText(): extracts final assistant message text
- DEFAULT_IDLE_THRESHOLD_MS constant (30 minutes)

All pure logic — no filesystem, herdr, or wl dependencies.
…(WL-0MUJW9DWO0070G9B)

Test-first: 13 fixture-based tests for the closure reaper with injected fakes:
- Idle pane with marker → exactly one close call
- Marker-less, dead agent → close
- Marker-less, live agent below threshold → no close
- Implement pane → never closes
- needsProducerReview → never closes
- Invoking pane → never closes
- Live children → never closes
- Already-closed pane → idempotent
- Close failure on one pane doesn't abort others
- --dry-run performs zero close calls
- Custom idle threshold support

Integration test for process-group teardown:
- Spawns real long-running child, terminates group, asserts child is gone
- Returns already-gone for non-existent PIDs

Implementation modules:
- pane-close-reaper.ts: runReaper(deps, opts) with injected I/O
- process-group.ts: terminateProcessGroup(pid, opts) with SIGTERM→SIGKILL

All pure testable logic — no real herdr/wl/ps calls in tests.
…009Q0V3)

Extends the reaper orchestration with the runnable CLI surface:
- runReaperCli(deps, argv) CLI entrypoint with partial-failure exit code
- parseReaperArgs: --dry-run, --threshold-minutes <n>, --ledger <path>
- JSONL ledger writer (writeLedgerRow) with fail-closed write semantics
- DEFAULT_LEDGER_PATH (.worklog/pane-close-ledger.jsonl)
- Reaper reuses extractFinalAssistantText for raw session entries (AC6)

Tests: 21 reaper tests (was 11) covering CLI parsing, ledger rows,
exit codes, and session-entry marker extraction. All pass; tsc clean.
…09008M)

Wires the out-of-process pane-closure reaper into the downtime worker tick
and adds operator configuration (parent WL-0MUJL1NAH0042GOS):

- settings.ts: paneCloseEnabled (default true) and
  paneCloseIdleThresholdMinutes (default 30, clamped [1,1440]) with load/merge
- pane-close-scheduler.ts: runScheduledPaneClose (enabled guard, threshold
  clamp, fail-closed exception handling, ledger), paneCloseReaperDue cadence
  predicate, PANE_CLOSE_REAPER_INTERVAL_MS (60s)
- pane-close-herdr.ts: production ReaperDeps over 'herdr pane list'
  (agent_session), session-log tail reader, label kind/item parsing
- downtime-worker.ts: optional paneClose config + runPaneCloseReaper dep,
  fire-and-forget cadence wiring with synchronous+async throw guards
- index.ts: settings→config wiring; production runPaneCloseReaper that also
  skips panes the dispatch monitor already closed (coexistence)
- reaper: alreadyClosedPaneIds skip for dispatch-monitor coexistence

Tests: 14 herdr-deps + 12 scheduler + 4 settings added; 123 pane-close/
settings/scheduler tests green; 644 downtime-worker tests green; tsc clean.
…WL-0MUJW9FY5008KBTQ)

- packages/herdr/README.md: new 'Pane-closure reaper' section — shared
  classifier interface, decision order, reaper CLI, scheduling, settings
  (paneCloseEnabled / paneCloseIdleThresholdMinutes), child-process teardown,
  pane-lifecycle.ts coexistence, and pane-triage reuse.
- docs/dev/downtime-dispatcher.md: reaper + dispatch-monitor cooperation
  section, timing defaults rows, and file/artifact table rows for the new
  pane-close modules and ledger.
- packages/tui/extensions/README.md: cross-reference to the closure reaper
  and its configuration.
- Appendix Q7 placement resolved in favour of ContextHub packages/herdr/ and
  recorded on the parent; interface + invocation guidance posted to the
  pane-triage work item (WL-0MUJMXVPO0016DZM).
…6000K5NV)

Replace the fixed `await sleep(100)` before reading the mock herdr socket's
first client with a poll-based `waitForClient()` helper (5s timeout, 10ms
poll). The fixed sleep was flaky under heavy concurrent load — the WebSocket
client had not connected within 100ms, so `getFirstClient()` returned
undefined. Deterministic now.

Verified: 3 consecutive isolated runs pass; full herdr suite 2679/2679 green.
…re-dispatched (WL-0MUBVH8QG0020H9L)

- icons.ts: derived coverage via shared isAuditFresh (isCoveredByParent), [COVERED] noIcons fallback, getIconPrefixParts stage-range for dimming
- worklist.ts: enrich nested rows with parent audit state; dim the covered indicator; metadata 'Covered by <parent-id>' row
- downtime-worker.ts: belt-and-suspenders parentId exclusion in selectAuditCandidate (dispatch stays root-only)
- fix stale 'r' chord assertion (WL-0MUKDBVFP008ARY6)
…04X0U9)

- context-aware shell escaping in substituteIdentifiers: single-quoted,
  double-quoted and unquoted placeholder contexts handled separately
- shell-route (!/!!) templates escaped; agent-prompt templates stay raw
- regression tests incl. bash round-trip for apostrophes/metacharacters
…omplete (WL-0MUIB7D30009KG00)

STAGE_STATUS now maps plan_complete and intake_complete to 'open,in-progress'
so actively-worked items (status=in-progress) remain visible in their
corresponding stage-filtered worklists.

Before WL-0MTOHS5B4001Y9FX removed the in_progress stage, worked items
retained their pipeline stage. After that change, they keep plan_complete
or intake_complete but flip status to in-progress. The old 'open'-only
filter hid them.

- fetcher.ts: add plan_complete and intake_complete to STAGE_STATUS
- fetcher.ts: update JSDoc documenting per-stage status semantics
- stage-status.test.ts: 7 tests covering all stage status mappings

AC7 (TUI tools.ts) not applicable — TUI browse UI removed
(packages/tui/extensions/Worklog/index.ts).
…r gate

Supersede the symmetric fallback gate (|auditedAt - updatedAt| < 60s) — which
wrongly marked a clearly-newer audit as stale — with the long-standing
one-sided ContextHub currency predicate:

    auditedAt > updatedAt - AUDIT_FRESHNESS_AT_NEAR_TOLERANCE_MS

An audit at or after the item's content timestamp is fresh (it covers the
content); an audit that precedes a later content edit is stale once the gap
exceeds the tolerance. This matches the SA reuse gate on the audit-later
region (auditedAt > updatedAt + 60s is fresh there too) while keeping the
ContextHub tolerance semantics.

Keeps the unification: isAuditNotReadyFresh delegates to the shared
isAuditFresh, so the ordering tier, icon path and dispatcher share one
comparison. Adds an audit-later-than-updatedAt regression test.

SA origin (documented in icons.ts): SA-0MRJBEJGY0095XAY introduced the
stricter auditedAt > updatedAt + 60s gate as a conservative pipeline-reuse
decision; SA-0MSI3XH34001LLU4 + SA-0MTHC710X003ORZM added the 30s reverse
persistence tolerance because atomic persistence makes the +60s form
unreachable. That reuse gate is not a currency predicate.
…titution (WL-0MUKH3DVA00488U0)

Commit 992ec91 (WL-0MU7KEX65004X0U9) made substituteIdentifiers shell-quote
substituted values for !/!! shell-route templates. The legacy test file
tests/herdr/form-dialog.test.ts had stale expectations for raw (unescaped)
substitution — update the 6 failing tests to expect the new shell-escaped forms.
pi added 24 commits September 28, 2026 14:04
The recovery extension crashed pi when its captured ctx became stale
after session replacement/reload. _notifyFn now goes through _safeNotify,
a try/catch wrapper that silently skips notifications when the ctx is
stale. _notifyFn is also cleared on session_start to avoid retaining
stale references.

Changes:
- Add _safeNotify() helper that wraps _notifyFn in try/catch
- Update all _notifyFn call sites to use _safeNotify:
  _notifyRetryAttempt, triggerCompactionContinue,
  triggerCompactionGateRecovery (3 call sites)
- Reset _notifyFn to null on session_start
- Add module header documenting notify/ctx lifecycle
- Add regression test (notify-safety.test.ts) asserting stale ctx
  does not throw from the retry notification path
- Update README Architecture section with stale-ctx protection note
… auto-close

AC1 - Dead agent no longer closes panes (operator may need final output).
AC2 - Idle threshold <= 0 means never close on idle.
AC3 - Default idle threshold is 0 (disabled by default).
AC4 - DEFAULT_PANE_CLOSE_ENABLED = true (auto-close re-enabled).
AC5 - Table-driven tests cover dead-agent no-close and idle<=0 paths.
AC6 - README, doc comments, and settings comments updated.
AC7 - Full suite passes (7069 tests).

WL-0MUMEJHT9004EQPI
@SorraTheOrc
SorraTheOrc merged commit c938d87 into main Sep 30, 2026
@SorraTheOrc
SorraTheOrc deleted the release/dev-to-main-20260930093645 branch September 30, 2026 09:40
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