Conversation
…f-scans readme_check did its own modules/ and tests/ globs that bypassed the central audit collector, so an in-place foo(disabled).py tripped a false 'missing module' violation and inflated README test counts. Wire is_disabled_file into both globs (check_module_list, _count_test_functions). +2 regression tests, 1086 green, self-audit 100%. Closes td-103. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
…ift) unused_function bypasses matched by file+line; the line was the function's def line, so any code shift above it staled the bypass and silently re-flagged the exempted function, dropping the branch below 100% (S216/S217). Mechanism: is_bypassed() gains a 'functions' field + name param; name-scoped match takes precedence, 'lines' kept for back-compat (no other standard changes). unused_function_check passes the function name. +7 tests (1093), seedgo self-audit 100%, bypass schema documented. Migration: converted 10 line-scoped entries to functions: across drone/memory/skills; removed 3 dead memory/vector_search entries already pointing past EOF (file is 152 lines). drone/memory/skills re-audit: Unused_Function 100% (names verified live). Closes td-009. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
The bulletin_created event handler propagated a 'bulletin_board' section into every branch dashboard, but it was fully dead: nothing fired the event, its BULLETINS.central.json store no longer exists, and prax already prunes 'bulletin_board' via DEPRECATED_SECTIONS. Archived the handler to events/.archive/, removed its import + trigger.on() registration, dropped the 5 covering tests (558 pass). seedgo audit 100%. prax pruning left intact. Closes td-102. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
…stem Streamlined prompts had drifted from reality. Full-context investigation (3 agents + @memory storyline) corrected: - .backup/ documented as a SHARED runtime namespace (3 writers: @backup snapshot stores, @memory rollover safety copies, @flow processed_plans), not @backup-exclusive. - @backup README: full 11-command coverage, .backup/ store layout, and a .backupignore (gitignore-for-backups: pathspec/gitwildmatch, BUILTIN_IGNORES, self-exclusion, ships as config) section. - @backup branch prompt: stale .backup_system/ -> .backup/ (3x), drive_test.py -> drive_check.py (was misleading the agent every turn). - Root README: @backup added to roster + uninstall covers .backup/.backupignore. navmap @backup line corrected (Drive planned + shared namespace). - Shipped root /.backupignore realigned to BUILTIN_IGNORES (dropped stale .backup_system/, removed over-broad *logs). - Removed dead backup/run/ test dir. @backup verified: 220 tests green, seedgo 100%. Closes td-218. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
…rax/.backupignore Completes the backup-docs sweep (td-218): - @memory README: note rollover writes rollover_backup_*.json to <branch>/.backup/ - @flow README: note closed plans archive to <repo-root>/.backup/processed_plans/ both cross-referencing @backup's canonical README. - Removed orphaned src/aipass/prax/.backupignore (prax is not a registered backup target; only the AIPass project root is). seedgo green across all three (@flow 100, @memory 100, @prax 99 = pre-existing Json_Handler, unrelated). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
The standard email footer told dispatched agents 'CLOSE FPLAN -> drone @flow close <plan_id>', which led them to close the orchestrator's master/parent plan referenced in their brief (bit us in FPLAN-0260). Reworded to 'CLOSE YOUR PLAN -> ... this task's plan only, never the master/parent': a worker still closes the sub-plan handed to it, the master stays the orchestrator's to close on completion. td-6. Footer string + test assertion; 737 ai_mail tests pass.
…step README: added the 3 missing agents (@daemon, @skills, @commons) to the tree and tables, normalized the agent count to 17 everywhere (was an inconsistent 13/14). @daemon -> Quality & operations; new 'Capabilities and community' group for @skills + @commons (td-28). /prep: both the Claude command and Codex skill mirror gained a 'Reconcile todos against reality' step — audit every open todo against the actual system and close what's verifiably done, catching past-session work that was never closed. CHANGELOG updated.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…/ default Confirmed (via @backup) the two-layer ignore model and wrote it down so it stops getting re-discovered: - BUILTIN_IGNORES (patterns.py) = the SEED that generates a new project's .backupignore at register; never consulted at backup time. - .backupignore (via load_spec) = the runtime source of truth. No static fallback exists, so the seed is safety-critical — an empty .backupignore backs up everything (.venv, node_modules, .git) and can crash the machine. Added a 'How Ignores Work' README section + code comments on BUILTIN_IGNORES and load_spec. Added logs/ to the seed so new projects exclude log dirs (prax .jsonl output) by default, not just *.log files, with a test. seedgo @backup 100%. td-27.
…a file Backup was the outlier — its default .backupignore content was hardcoded as the BUILTIN_IGNORES Python list + assembled in _build_backupignore(). Moved it to a template DATA FILE (backup/templates/backupignore.template), matching the AIPass convention (flow/spawn/memory all keep templates as files). - New: templates/backupignore.template (header + patterns, incl logs/). - _build_backupignore() reads the template via __file__-relative pathlib and RAISES FileNotFoundError if it's missing — never silently empty (an empty .backupignore = back up everything = crash). Behavior-preserving otherwise. - Retired BUILTIN_IGNORES (only setup.py consumed it). Runtime load_spec path untouched. - Tests expanded (30 pass): per-pattern template assertions + reads-template + raises-on-missing-template. Docs/comments repointed to the template. seedgo @backup 100%. td-30.
… --help in Rich seedgo's cli/help_text/introspection standards are static source scans — they confirm a print_help function, console.print, and --help wiring exist, but never execute --help. So a module could score 100% while rendering raw argparse. ai_mail did exactly that via console.print(parser.format_help()), laundering argparse plain text through the approved console API and dodging the existing parser.print_help() ban. - seedgo: cli_check now flags .format_help(); cli.md/cli_content.py name it alongside print_help(); +2 regression tests (1095 pass, self-audit 100%) - ai_mail: rewrote print_help() to hand-rolled Rich (737 tests pass); --help now renders Rich with no raw argparse, Cli back to 100% legitimately - behavioral --help check (run it, assert not raw argparse) noted as a follow-up DPLAN-0217. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
…ed CLI checker) The CLI help-checker fix (4d41065) immediately surfaced the same console.print(parser.format_help()) laundering in 4 @api modules on its first audit run — exactly the latent stragglers the static-scan loophole had been hiding. Rewrote each print_help() to hand-rolled Rich markup (content was already in the argparse epilogs); removed the help-only argparse parsers. - api_key.py, usage_tracker.py, google_client.py, openrouter_client.py - @api audit Cli + Overall back to 100% (38/38), 504 tests pass, no bypass DPLAN-0217 (follow-on). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
…rename catalog/, move telegram in, archive orphan fixtures, retire .aipass/skills/ Unifies all 6 first-party skills under lib/ (built-in tier). Fixes telegram not being cross-branch discoverable (was in cwd-relative .aipass/skills/). Built-in discovery path catalog->lib; telegram conftest parents[6]->[5]; .service ExecStart, seedgo bypass + test paths updated. Packaging/imports/gitignore unaffected (stays under src/aipass). 252/252 tests green, cross-branch discovery verified. DPLAN-0218.
…-0220) Surfaced by a full completeness audit of the telegram skill against TELEGRAM_PORT_MAP.md (366 tags, ~83% ported, 452/452 tests green). @api — in-process set_secret(provider, slug, value, *, as_json) writer mirroring get_secret (0o600 files / 0o700 dirs, no stdout echo). The store was read-only; this is the GAP1 enabler the telegram mother-bot needs to persist a created bot's config. 515 @api tests, seedgo 100%. @skills telegram wave-1 (fix-forward, no deletions): - GAP2: bot_factory + telegram-bot@.service launched a non-existent ~/.venv/bin/python3; now sys.executable -m ...base_bot (+ lib/__init__.py and lib/telegram/__init__.py for package resolution). - Reboot survival: enable_service now installs the unit to ~/.config/systemd/user/ + daemon-reload (was never installed). - GAP9: gitignore lib/telegram/.local/ so runtime state stops leaking to git. - prax-monitor: log_streamer now resolves repo-root system_logs (honoring AIPASS_TEST_LOG_DIR) instead of a hardcoded ~/system_logs. Verified: telegram 452/452 green (twice), base_bot imports via -m. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
…nted bots start (DPLAN-0220)
bot_factory.create_bot now calls set_secret('telegram', bot_id, config,
as_json=True) right after building the config (fail-loud on OSError), so a
newly-minted bot's token reaches the @api store that load_bot_config reads.
The disk write is downgraded to a non-fatal shadow; registry now records
bot_token_ref='@api:telegram/{id}' (TG-LIFE-069).
Proven: new TestCreateBotRoundTrip — create_bot -> @api -> load_bot_config
returns the persisted config; + a fail-loud test (set_secret OSError ->
create_bot returns None). Telegram 454/454, skills 252/252.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
…e, enriched (DPLAN-0220) Resolves the build_botfather_commands design call (Patrick: KEEP, not delete). POPULATE: base_bot sets its Telegram command menu on startup (setMyCommands) after verify_connection, so every bot — base or minted — gets a populated slash-menu, not just create_bot'd ones (the live @aipass was hand-launched and had none). SYNC: build_botfather_commands (telegram_standards) is now the single source feeding base_bot-startup AND create_bot; DEFAULT_BOT_COMMANDS retired. The Telegram menu and /help list the same commands incl. /create + /cancel. ENRICH: friendlier command descriptions + /help intro/footer. Wiring the builder (vs deleting it as 'dead') lifted Unused_Function 92->93%. 6 new tests (menu==help sync, enriched copy, startup-menu, custom cmds); telegram 460/460, skills 252/252. Running bots need a restart to pick up the startup menu. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QEQZXCtgnF3NQtcttTErpq
… log path The ported telegram-bot@.service logged to a non-existent ~/system_logs (would crash-loop the service); point StandardOutput/StandardError at <repo>/system_logs where the app already logs. Then installed the unit, enable --now + loginctl enable-linger so the @aipass mother-bot runs as a proper user service with reboot survival and a one-line restart. Startup log confirms: Telegram API OK, Command menu set (6 commands), poll loop, tmux session preserved, NRestarts=0. DPLAN-0220
…subscription Revives the old prax-monitor capability as a feature of the existing @aipass bot (no 2nd bot, no new credential). /monitor on|all|off|status on base_bot; subscribed chat persisted to @api (survives restart) and boot-started on startup. LogStreamer gains system_wide glob + level_filter (default WARNING/ERROR/CRITICAL, all=passthrough). 33 new tests, telegram 493/493, skills 252/252, seedgo 98%. Route B (true AS-WAS @prax event-feed relay) tracked separately. DPLAN-0221
…eedback loop Mirrors the live 'drone @prax monitor run' Mission-Control feed to a dedicated Telegram bot (DPLAN-0221). New monitoring/telegram_relay.py taps _render_event, batches every 5s (4000-split, 150 flood-cap, fail-silent-once), gated by --relay/env so local monitor stays console-only. Reboot-survivable prax-monitor.service. 937 prax tests green (31 new). Deploy fixes (devpulse): ExecStart -> 'monitor run' (module __main__ rejects 'run all --relay'); service log moved out of system_logs/ to ~/.aipass/ to break a monitor<->@trigger feedback loop.
…e-on-done discipline - .trinity sections carry config-sourced rollover/keep/char-cap tabs; @memory owns values (render_all_meta_tabs), @Spawn resolves placeholders at create via spawn_pusher - todos confirmed rollover-exempt; vestigial rollover-config entry removed - prep/memo/startup (Claude+Codex): delete finished todos, don't leave status:done - @memory README documents the system - FPLAN-0285, FPLAN-0286
…ction bot_registry did a bare 'import fcntl' (POSIX-only); on Windows the 8 telegram test modules importing it failed at collection (ModuleNotFoundError), reddening Windows Test on recent PRs. Guard the import and route flock calls through no-op-on-Windows _lock/_unlock helpers. 246 telegram tests green.
Guarding the fcntl import let Windows collection succeed, which surfaced 3 telegram tests that had never run on Windows — all test-portability bugs: - log_streamer byte-count broke on CRLF -> fixture writes newline='' - bot_registry write-failure used Unix-only /proc -> file-as-parent (all OS) - validate_bot_config rejected POSIX work_dir on Windows (Path.is_absolute is host-dependent) -> test absoluteness under PurePosixPath OR PureWindowsPath 493 telegram tests green on Linux; ruff clean.
core.py adopt-path read the passport via json.loads(read_text()) — a direct file op that fails the json_handler standard and the CI seedgo-audit gate. Switch to json_handler.read_json() (matches the pattern ~90 lines above), drop the now-unused 'import json as _json'. @Spawn 100%; 315 spawn tests green.
…document DPLAN-0218 pulled telegram into the seedgo gate, surfacing 16 unused_function flags across 8 handlers. They are ported-but-unwired (S249), not dead — pending DPLAN-0220 wiring. Added name-scoped unused_function bypasses citing DPLAN-0220, documented each in SKILL.md -> Ported-but-unwired (remove bypass as wired). @skills 100%.
…r fires hands-off (FPLAN-0287)
…DME scheduling section (FPLAN-0287)
…+ lifecycle telegram pings (TDPLAN-0008) - One queue: archive dormant task_registry + actions_registry (+5 tests) to .archive/, retire schedule/actions CLIs; .daemon/schedule.json is now the single source - Status capture: runstate gains last_status/last_error/last_success_at/last_failure_at; persisted on success AND failure paths (was success-only) - Unified view: drone @daemon queue + --json (frozen schema), aggregates .daemon/*.json joined to runstate - Lifecycle pings: un-archived telegram_notifier wired to @skills send_telegram_notification (fail-soft, per-job notify flag, zero calls on empty ticks) - 24 new tests (327 pass), seedgo 98%; verified live end-to-end (queue --json schema + real telegram delivery via daemon wrapper)
…igest (TDPLAN-0008) - SchedulerBot(BaseBot): rejects free-text (NO tmux/Claude spawn), /queue shells 'drone @daemon queue --json', hourly digest thread, chunked output - base_bot __main__: _BOT_CLASSES maps bot_id->SchedulerBot for systemd launch; passes config chat_id for digest target - bot registered (telegram-bot@scheduler), systemd unit installed (NOT started) - 26 new tests (519 telegram / 252 skills green), seedgo 99% fix(daemon): queue --json emits valid JSON at module level — flatten prompt_preview (collapse newlines) + soft_wrap/markup off. Verified valid via 'python -m'. NOTE: the drone router still re-wraps sub-command stdout at width 80, corrupting machine --json for ALL consumers routed through drone (separate @drone core bug; skills mitigates with strict=False JSON parse).
… super().run() (TDPLAN-0008) - run() called a non-existent self._poll_loop() AND duplicated the parent lifecycle incompletely (missing signal handlers, offset load/save) — bot exited 1 in <1s under systemd. Now wraps super().run() with digest start/stop only. - Fixed broken 'from .json import json_handler' (relative path did not exist) → absolute import; log queue_requested op so json_structure standard is met by use, not noqa - Added missing docstrings: handle_message / handle_file / get_custom_commands - ROOT CAUSE: 26 unit tests never executed run() (it blocks on polling) → green tests, failing ExecStart (key-learning #77: test the real ExecStart, not the drone/mocked form). Verified live: bot now active+polling via systemd, 26 tests + seedgo 30 still green.
…al, live-proven @api @skills: dup-spawn fix (run() lock-collision exit 0), attach_only + launch_mirror_session (--dangerously-skip-permissions), _config_chat_id init bug + /proc active-transcript baseline, systemctl start. @hooks: extract_mirror_turn cursor clamp + baseline reset on delivery, mirror-file unlink guards. +4 test files. 578 skills / 112 hooks green.
…ions; bare 'queue' renders Rich table (TDPLAN-0008, td-47) test_scheduler_bot.py: replaced test_data_files_archived + test_handler_files_archived (asserted gitignored .archive paths → failed in CI clean checkout) with test_task_registry_not_importable + test_actions_registry_not_importable (assert ImportError — env-independent). queue.py: bare 'drone @daemon queue' now renders the Rich table instead of print_introspection (matches --help). 24 scheduler_bot tests green. Fix by @daemon, verified by devpulse.
…tion bypass, exception-contract test, README count (TDPLAN-0008) Diagnostics 65%→100%: archived dead orphans scheduler_cron.py + modules/scheduler_ops.py (+ their test_scheduler_cron.py) — old cron scheduler superseded by queue/run_tick (S254), imported only by already-archived files; cleared 7 pyright unresolved-import errors. Introspection 98%→100%: bypass queue.py (td-47 — bare invocation renders operational Rich table). Test_quality 98%→100%: added test_invalid_mode_raises. README count fixed. Cleaned 6 stale bypass entries. Audit @daemon=100% (38 standards), 300 tests green. Fix by @daemon, verified by devpulse.
…ded .archive dead tests) CI's clean checkout counts 300 live tests (matches pytest); README claimed 486 because the count included 6 archived dead-test files under tests/.archive/ (186 tests). 300 is the true live/CI count. Root-cause framework fix (audit must always ignore .archive) dispatched to @seedgo separately.
…ctive) readme_check.py: _count_test_functions now skips any path with a SOURCE_SKIP_DIRS segment (.archive) — root cause of the local-vs-CI test-count mismatch (daemon counted 486 local incl archived dead tests vs 300 in CI clean checkout). test_quality_check.py: _find_test_files_broad replaced __pycache__-only skip with _should_skip_dir() on all path parts. Daemon 486→300, audit 100%, 17-branch audit zero regressions. CI-neutral (clean checkout has no .archive). Fix by @seedgo, verified by devpulse.
…tests drop platform tricks (TDPLAN-0009) base_bot.py _resolve_active_transcript: slug replaces both backslash and / (Windows work_dir paths left backslashes → wrong projects_dir; POSIX no-op). test_mirror_session.py: slug matches production + mkdir exist_ok=True (dir pre-created on Windows → WinError183). test_monitor.py: mock _save_monitor_subscription→False instead of /dev/null OSError trick. 578 TG + 252 skills green on Linux; Windows-safe by construction. Fix by @skills, verified by devpulse.
…289 P1) One live Claude runtime per branch. presence.py manages .ai_central/PRESENCE.central.json (claim/release/refresh, PID + /proc/cwd liveness, stale-reclaim, PID-guarded release so a non-holder can never release the holder). presence_gate.py: UserPromptSubmit blocks a duplicate (exit 2 + decision:block), Stop releases; skips sub-agents + dispatched/daemon. SessionStart can't block in Claude Code (inject-only) → gate is UserPromptSubmit, like the edit/git gates. NOT wired into hooks.json yet — dormant, zero behavior change until enabled. 705 tests pass, seedgo 100%. Live cross-process block + PID-guard verified (devpulse). Design: DPLAN-0225. Next: P2 telegram relay follows the pointer (@skills). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GFihce1oLtp6UDAPGryYSv
…fcntl (FPLAN-0289 P1) Windows CI was red on f460cd5: the patch_flock fixture patched presence.fcntl, which only exists on POSIX (msvcrt on win32), erroring all 16 presence-test setups. Now patches the platform-agnostic _presence_lock context manager (-> nullcontext per call) and skips the inherently-POSIX flock-acquire test on win32. Dormant prod code unchanged. 705 tests pass, seedgo 100%. Fix by @hooks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GFihce1oLtp6UDAPGryYSv
…n (FPLAN-0289 P2) The Telegram bot becomes a thin durable relay: it follows the live Claude session via .ai_central/PRESENCE.central.json and never starts its own brain. ensure_tmux_session resolves in 3 strategies (central pointer -> shared_session config -> already-running own tmux), re-binding to the live session on every message (handover-safe). The legacy AIPASS_SESSION_TYPE=telegram own-session spawn is retired: replaced with a clear "no live session to mirror" error; an absent/stale pointer falls back gracefully and never starts a session. on_session_create (which injected "hi" after self-start) removed as obsolete -- attaching to a live session injects nothing. New helpers: _find_presence_file, _read_presence_pointer (PID-liveness via os.kill), _find_tmux_for_presence (attach_handle preferred, tmux-CWD-scan fallback). 601 TG + 252 skills tests pass; seedgo Unused_Function 100% (overall 99%; residual is a pre-existing Json_Handler item in unrelated modules). Live mirror proof to follow. Design: DPLAN-0225 / FPLAN-0289 P2. Build by @skills. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GFihce1oLtp6UDAPGryYSv
…ropagates block exit code (FPLAN-0289 P1)
Activation fixes for the single-session presence gate. Two bugs blocked it,
both caught by live testing after all units were green:
1) Wrong branch key. presence_gate used Path.cwd().name, but under the Claude
Code bridge the hook process cwd is the project root, so every session keyed
to "AIPass": the gate never enforced one-live-session-per-branch and would
have rejected sessions project-globally (any 2nd interactive session in any
branch). Now _resolve_branch(hook_data) reads the event payload's cwd (the
real session dir) and walks up to the branch root (.trinity/ or apps/),
mirroring branch_loader. Applied in handle() and handle_stop().
2) Block never reached Claude Code. engine.dispatch() returned only stdout, so
the bridge could not surface a non-zero exit. dispatch() now returns
(stdout, exit_code) and the bridge exits with it on a block. Pre-existing gap
affecting every block hook on every event; now fixed engine-wide. An
intentional block (exit 2 + {"decision":"block"}) propagates; a crashing hook
(exit 2, non-JSON stdout) is logged and falls through, so the gate fails open.
Proven: 110 hooks unit tests pass (6 new for branch resolution); seedgo @hooks
100%, no type errors. Live bridge end-to-end (real live holder + real bridge):
duplicate into a held branch -> exit 2 + block reason naming the branch; a
different free branch -> exit 0 (per-branch isolation intact). Gate remains
dormant: not yet wired into provider settings.
Design: DPLAN-0225 / FPLAN-0289 P1 activation. Build by @hooks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CqoxFdbDMirzkQ5kjRVVos
…ephemeral hook PID (FPLAN-0289 P1)
Final activation fix. The gate recorded os.getpid(), but the hook runs as a
short-lived subprocess (python3 -> sh -> claude) that dies in milliseconds, so
every later session saw the prior holder's PID as dead, reclaimed it, and never
blocked. claim()/release() now resolve the owning session via _resolve_session_pid():
walk the /proc parent chain (PPid from /proc/<pid>/status) up to the comm=claude
ancestor and record THAT pid. Fails OPEN if no claude ancestor (non-Linux, or an
unexpected process tree). handle_stop() is now a no-op: Stop fires every assistant
turn, so releasing there would free the slot mid-session; stale-detection (the
claude pid going away) reclaims on real exit instead.
PROVEN LIVE — real two-session interactive test (the unit blind spot that a
long-lived-holder harness masks):
session 1 in branch X resolves chain 731814:python3 -> 731813:sh -> 730933:claude,
records pid 730933 (comm=claude, cwd=X); work_dir=X, cwd_match True.
session 2 in branch X resolves its own claude pid, sees X occupied by live
730933, and Claude Code blocks the prompt in the UI:
"UserPromptSubmit operation blocked by hook: ztest... already live at PID 730933
- attach, do not spawn."
session 2 did NOT clobber session 1; a different branch is unaffected.
Added 9 tests modelling the ephemeral-PID lifecycle (54 presence tests total);
seedgo @hooks 100%.
Activation is a machine-local provider-settings change (presence_gate wired first
in ~/.claude/settings.json UserPromptSubmit) — not tracked in the repo; the code
landing here is what makes it correct.
Design: DPLAN-0225 / FPLAN-0289 P1. Build by @hooks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CqoxFdbDMirzkQ5kjRVVos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.