stop called purge_artifacts only. It now prints `WARN residual: <path>` for
each leftover or `residual: none (agent: <agent>)`, the strings orc_onboard
prints. The row is still removed and the exit stays 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review 9a1adb46 (planner-reviewer-codex-01):
- R1 [P1] lib.sh new-session: a forwarded binding reached the agent as
arguments. With env flags the idle-pane branch prefixed `env K=V ...` to
the command that `herdr agent start ... --kind <agent> -- <args>` passes to
the agent executable. An idle pane is now reused only when no environment
has to be set; otherwise the pane is created by pane split / workspace
create, which take --env. The dead `env` prefix code is removed (its
send-text fallback would have typed the same line).
- R2 [P2] runner: a relative MAM_JOBS_DIR is resolved once against the
control root, the way the wrapper (cwd=workspace_root) reads it, and that
absolute dir is used for delegation, wait, report lookup and cleanup.
- R3 [P2] stop: the row's control_plane.delegate_job_logs_dir is restored
(exported unless the caller set DELEGATE_JOB_LOGS_DIR), so the
cancellation history lands in the row's audit-log root.
Tests: T3-1 and T3-3 now assert that the binding arrives as --env on the
pane-creation calls and that no env/K=V token follows `--` in agent start
(fresh and reused pane); T3-4c (audit root on stop) and T2-15 (relative
MAM_JOBS_DIR) are new. The design doc's compatibility table and a create
comment no longer describe the removed idle-pane env path.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
A session row now records the control plane it belongs to, and the pane
gets it explicitly instead of relying on env inheritance.
- lib_py/control_plane.py (+ thin lib.sh wrappers mam_control_plane_json /
mam_control_plane_prefix): the binding is WORKSPACE_ROOT,
AGENT_SESSIONS_YAML, MAM_JOBS_DIR, DELEGATE_JOB_LOGS_DIR as absolute paths.
- create: the binding is always persisted on the row (`control_plane`) and
forwarded to the pane only when it differs from what --workspace alone
implies, as leading K=V tokens that lib.sh's new-session already turns into
--env (fresh pane) or `env K=V` (reused idle pane). pane.cmd_full and
start_command stay unprefixed. A binding with whitespace that would have to
be forwarded is refused with exit 2 (lib.sh splits the flags unquoted); the
~/.local/bin wrapper path records the binding but warns it is not forwarded.
- resume: the row's binding wins over the caller's env (a difference is
reported on stderr) and is forwarded again; a legacy row without one uses
the caller's binding and update_yaml_resumed.sh records it.
- stop: registry order MAM_JOBS_DIR > the row's mam_jobs_dir >
$WORKSPACE_ROOT/.mam/jobs > .mam/jobs, exported for delegate_publish_event.
- status: both get_job_status copies look in MAM_JOBS_DIR, the row's
registry and the matching audit logs before the old candidates.
- reconcile: MAM_JOBS_DIR wins in the subscribe heredoc and is passed in.
Tests T3-0..T3-8 (mock herdr: forwarding is verified at the herdr-call level
only; real pane env propagation is left to item 7). T3-7 is a static guard.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
Issue #10 - agy purge_artifacts left resumable pieces behind: it now also
removes the SQLite sidecars (-wal/-shm/-journal), the title annotation and
the presence lock (the lock only once no live process references the
conversation), and residual_artifacts() reports anything under
~/.gemini/antigravity-cli still carrying the uuid.
Issue #13 - the orchestrator has no herdr_sessions row, so its conversation
could not be purged by any skill. `lib_py.agents purge <agent|auto> <uuid>`
resolves the adapter from what is on disk (orchestrator_uuids stores bare
uuids), refuses while a live process names the uuid (conversation_in_use:
process list minus the caller's own lineage, plus lsof), and prints what it
purged. `orc_onboard.sh --remove <uuid> --purge-conversation --yes [--agent]`
runs it before the registry update so a refusal changes nothing (exit 4
without --yes, 5 while in use).
Issue #11 - "Successfully removeed": conjugate add/remove explicitly.
Issue #15 - the job registry and audit log followed the caller's cwd, so the
pytest suite (create_session.sh with its default onboarding job, run from the
repo root) had left 593 test records in the real .mam/jobs. Defaults now
resolve MAM_JOBS_DIR / DELEGATE_JOB_LOGS_DIR, then $WORKSPACE_ROOT/.mam/...,
then the cwd (mqtt_common.default_registry_dir / get_logs_dir; registry.py,
publish_event.py, service.py, create_session.sh, stop_session.sh); the
sandbox fixture pins both. The tier suites that used to leak now leave the
real registry untouched (881 records before and after).
Tests: test_issue10_13_purge.py (13), test_issue15_registry_isolation.py (7);
T-O13 pins the corrected message; the R1 helper test and B-9 logs-dir test
now assert the workspace-anchored contract; publish_event snapshot updated.
Refs #10#11#13#15
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
- Implement CodexAdapter in lib_py/agents/adapters/codex.py with safe flags and TUI readiness
- Extend create_session, resume_session, stop_session, and reconcile for codex CLI
- Support codex agent delegation and loop integration across all multi-agent skills
- Add unit, component, and contract test suites for codex integration
- Verify all 462 tests passing cleanly
- Standardize --herdr-session as primary flag with --herdr-server alias across create_session.sh, resume_session.sh, update_yaml_resumed.sh, and stop_session.sh
- Guard HERDR_SESSION_NAME in create_session.sh from being overwritten by workspace slug defaults when explicitly provided
- Forward explicit --herdr-session from resume_session.sh to update_yaml_resumed.sh and force-update row metadata
- Add 5 new Tier 2 component tests covering CLI dry-run parsing, usage matching, default preservation, YAML serialization, and resume propagation
- Update multi-agent-mux-create/SKILL.md documentation
- Verified by autonomous multi-agent loop with unanimous PASS verdicts from Claude and Cline
- In stop_session.sh and update_yaml_resumed.sh: standardize explicit --agent option and use resolve_agent_type_from_registry to read agent type from YAML/DB state rather than brittle suffix-only regex inference.
- Update multi-agent-mux-stop/SKILL.md, multi-agent-mux-resume/SKILL.md, multi-agent-mux-create/SKILL.md, and deploy/INSTALL.md to standardize passing --agent explicitly.
- Fix J-1 in layout.py: refactor _env_int(*names, default=None) to take an explicit default parameter, eliminating the falsy-zero trap so MAM_MIN_PANE_COLS=0 is respected.
- Add regression and contract tests: test_j1_env_zero_min_cols_matches_flag_zero, test_j1_env_zero_min_rows_matches_flag_zero, test_comp_stop_agent_fallback_*, test_comp_docs_stop_examples_pass_agent.
- Verified 100% UNANIMOUS PASS from Planner claude and Reviewers claude and cline.
- Remove dead agent_identities read path and PyYAML import from workspace_uuid.py
- Defer eager PyYAML import in verify_session.py to lazy YAML fallback branch
- Simplify UUID resolution to 2-tier model (tier-1 own row ID -> tier-2 adapter scan)
- Clean up unused Drift D and ghost cache clearing in reconcile.sh and stop_session.sh
- Add 3 regression guards in tests/test_tier1_unit.py (266/266 PASS)
- Update IMPROVEMENTS.md, VERSIONS.md, and SKILL.md files
- Option B / C-3b: Deprecate isolation.root and remove its 4 legacy consumers in lib.sh, workspace_uuid.py, verify_session.py, and stop_session.sh.
- M2~M7 Migration: Implement artifact_path, verify_artifact, purge_artifacts, spawn_spec, resume_spec, auth_ok, discover, ready_tokens, exit_key, and delegate_agent_key across BaseAgentAdapter and all 4 adapters (Claude, Agy, Hermes, Cline).
- Migrate shell duplications in lib.sh, create_session.sh, resume_session.sh, stop_session.sh, and reconcile.sh to python -m lib_py.agents facts.
- Hardening & Corrections: Fix Cline resume_spec flag to '-i --id', apply shlex.quote across all facts variables with MAM_ prefix, add safe fallback in wait_for_tui_ready.
- Add comprehensive contract tests in tests/test_a4_adapter_contract.py and sync IMPROVEMENTS.md / LOG.md.
- Verified: 100% PASS across unit, component, contract, and integration tests.
- Update .agents/MULTI_AGENT_RULES.md & .ko.md to align with TMUX concepts
- Add .agents/INSTALL.md guide for MAM setup and workflows
- Clean up legacy markdown reports under .agents/reports/
- Refactor MAM scripts in .agents/skills/ (rename resolve_herdr_session to resolve_herdr_workspace)
- Improve workspace pane splitting/re-use logic in lib.sh
- Reduce paste safety sleep in send_keys_safe and support linking ~/.claude.json
- Extract load_state_json centralized helper inside lib.sh to unify state querying
- Refactor status, resume, stop, and monitor scripts to fetch state via MAM_STATE_JSON env var to avoid stdin pipeline collisions
- Restructure delegate-job to provision .mam/jobs/<job_id>/brief.md and direct agents to it, minimizing token size and preventing TUI paste freezes
- Harden send_keys_safe submission loop with was_popup state capture and edge case guards, preventing timing spin false-positives
- Passed cross-verification approved PASS from Planner Claude session
- OP-1: Implement reactive _wait_session_gone in lib.sh and stop_session.sh with set -e || true guard
- OP-2: Event-driven MQTT subscribe handshake with sub_pid liveness in delegate-job
- OP-3: Replace CPU time.sleep(0.5) spin with threading.Event wait in reconcile.sh
- OP-4: Define mam_tmux dispatcher targeting resolved _REAL_TMUX_PATH to prevent recursion
- OP-6 & OP-7: Add token variables and bash version source check in lib.sh
- Integrate approved optimization plan and PASS review reports from all agents
- Add send_keys_safe + quiescence/dialog-detection helpers to lib.sh:
keys are sent on pane evidence, never fixed timers; distinct exit
codes 1-4; dialogs are never blindly Enter-ed
- inject_instructions delegates to send_keys_safe; create --submit-job
publishes a terminal error event on delivery failure (no zombie jobs)
- wait_for_tui_ready: drop dialog-ambiguous tokens, treat open dialogs
as not-ready, return 1 on timeout instead of proceeding
- delegate-job wrapper: replace copy-pasted raw paste/C-m block with
lib.sh send_keys_safe (restores single source of truth)
- resume: conditional signature-gated dialog handling replaces blind
Enter/Down/Enter; stop --graceful delivers exitkey safely, fallback
chain unchanged
- create SKILL: passive capture-pane probe instead of stray Enter
- Mark FW-W2 resolved; add 3-agent analysis/plan reports
- lib.sh: update atomic_dump_yaml to sync with YAML on any active session status change; set reader timeouts to 60.0s
- create_session.sh: add exit trap cleanup_tmux_on_error to rollback spawned tmux sessions on initialization failures
- reconcile.sh, update_yaml_resumed.sh, status.sh, stop_session.sh: align SQLite connection timeout values to 60.0s