Skip to content

feat: improve semantic monitoring and Pi handoffs - #76

Merged
nicobailon merged 7 commits into
mainfrom
feat/semantic-monitoring-handoffs
Sep 22, 2026
Merged

nicobailon merged 7 commits into
mainfrom
feat/semantic-monitoring-handoffs

Conversation

@nicobailon

Copy link
Copy Markdown
Owner

Summary

Implements Stage 1 of #75:

  • add one bounded quiet semantic reassessment per inactivity episode, including no-output launches
  • keep unchanged quiet evaluations strictly observe-only so they cannot replay or authorize terminal actions
  • attach bounded, redacted, source-grounded terminal context and content-sensitive identity to existing semantic handoffs
  • add a state-bound semanticReply action for ordinary input-required handoffs, with exact session/event/decision/state revalidation and trusted global permission

This is the monitoring and Pi-handoff foundation only. Inline confirmations and multi-select remain later #75 stages, so this PR intentionally does not close the issue.

Behavior

output change / quiet deadline
          ↓
semantic assessment
  ├─ continue watching
  ├─ existing authorized local action
  └─ contextual Pi handoff
          ↓
Pi may submit semanticReply
          ↓
live session + ownership + hash/generation + secret + permission checks
          ↓
one bounded reply, then wait for visible change
  • monitor.semantic.quietIntervalMs is bounded to 250–60,000ms and defaults to 2,000ms.
  • The same unresolved handoff deduplicates; a meaningfully different question with the same event type wakes Pi.
  • Reply text is single-line, bounded, and rejects secrets, token shapes, shell metacharacters, and destructive/process-lifecycle intent.
  • Replies are limited to ordinary input handoffs; approval/result/watch/intervention events cannot use this path.
  • Ordinary manual session input remains unchanged.

Safety

  • quiet checks never send terminal bytes or renew action/approval budgets
  • final reply execution rechecks the delivered event, decision history, current observation hash and generation, live ownership/activity/epoch, secret state, and global semantic-reply permission
  • deny wins; unmatched defaults to ask; unavailable/rejected UI fails closed
  • changed state, replay, stale history, takeover, reload, exit, and secret prompts send zero bytes
  • event excerpts are derived only from already bounded/redacted terminal data; private diagnostics remain content-free

Validation

  • full Vitest suite passed
  • npm run typecheck
  • npm pack --dry-run — 53 packaged files including semantic-reply.ts
  • git diff --check
  • independent review found and blocked a delayed-reply freshness bug; retained-writer fix at 9c7700b received targeted fresh review with no P0/P1/P2 findings

Live Jev acceptance

Using the real Jev provider and production supervisor/event/reply paths:

  • initial free-form question emitted input-required with source excerpt
  • unchanged quiet reassessment preserved the same trusted hash/generation and handoff identity
  • the original delivered handoff remained replyable after that quiet reassessment
  • exactly one reply was written and immediate replay was blocked
  • a new question produced a different handoff identity and accepted a separately bound reply
  • final completion emitted result-ready

Two earlier harness runs timed out only because the synthetic scenario presented completion while leaving its second detected question unanswered. Jev correctly continued to report waiting_input; answering that handoff made the end-to-end scenario pass.

Provider cache

Low impact: quiet reassessment reuses the existing Jev request schema, contextual excerpts are event data, and semanticReply is local. The public tool schema gains stable fields, so provider tool-schema caches must refresh once; there is no per-turn tool-definition or system-prompt mutation.

Part of #75.

@nicobailon
nicobailon merged commit 2337526 into main Sep 22, 2026
2 checks passed
@nicobailon
nicobailon deleted the feat/semantic-monitoring-handoffs branch September 22, 2026 03:17
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