Commit Graph
32 Commits
Author SHA1 Message Date
GodopuandClaude Opus 5.5 ec9586bb9b feat(issue-33): the job budget travels and the two clocks carry different labels
- wrapper: TIMEOUT falls back to MAM_JOB_TIMEOUT_S (--timeout > env > 3600);
  an invalid value warns and keeps 3600.
- loop: --job-timeout <sec> (run_loop.sh passes it on; refused in the legacy
  shell loop). The runner always hands the wrapper --timeout, so the budget
  the wrapper registers is the one its wait caps come from.
- runner: wait_for_job and the MAM_CHILD_WAIT_S default are budget + 300 s
  (MAM_WAIT_GRACE_S), today's 3900 with no option; an explicit
  MAM_CHILD_WAIT_S still wins.
- subscriber: the wall-clock budget returns 4 (RC_WALL_CLOCK), silence keeps
  2 (RC_NO_EVENT). The wrapper maps both to caller rc 2 and labels the close
  from the rc: wall_clock_timeout vs deadline_timeout; the disk-heartbeat
  grace that ends on the deadline is the wall clock too.
- registry close accepts wall_clock_timeout (engine: -> error); the remote
  runner's deadline and command-timeout details lead with wall_clock_timeout;
  the sub-job table files it CLOSED-UNCONFIRMED (first token, colon stripped).

Test expectations changed only where the contract changed: the loop's
contract_args now starts with --timeout, the subscriber's exit-code docstring
names rc 2/4, and the registry --help capture lists the new close kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 11:43:10 +00:00
GodopuandClaude Opus 5.5 30c8c7ebab fix(issue-34): the loop waits for the creator job's descendants, hands reviewers the sub-job table with closing reasons, and voids a round whose source changed during review in every mode
- wait_for_job_tree at the execution, correction and compliance waits;
  bounded by MAM_CHILD_WAIT_S (3900) and MAM_JOB_TREE_MAX (50)
- [하위 위임 잡] table: OPEN / CLOSED-UNCONFIRMED (deadline_timeout,
  agent_blocked, or error with no reason) / NOT-DISPATCHED / error /
  completed, plus unattributed open jobs; omitted when there are none so
  option-less prompts stay byte-identical
- --wait-open-jobs also waits for unattributed open jobs
- stale-review guard without --worktree/--base: head + tree (control
  plane excluded) before review, re-checked after verdicts and before
  promotion; off with a warning when the source cannot be fingerprinted
- tests/test_issue34_job_tree.py: real wrapper registrations, real
  publish_event / deadline close, real loop process

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 13:37:05 +00:00
GodopuandClaude Opus 5.5 59be1c8920 fix(issue-36): create_session hands the agent a brief path, not the task; a prompt file that cannot be written is removed
Review of f26952c (codex, job cc849cbf):

- P2: create_session registered the task by file but then pasted the whole
  task into the onboarding text, which send_keys_safe hands to `herdr agent
  prompt` as one argv string. A 130,500-byte --submit-job was registered
  intact and never reached the agent (execve E2BIG). The task now goes into
  <jobs>/<id>/brief.md, as the delegate-job wrapper does, and the injected
  text names that path. The publish command and its dispatch token (#23) are
  unchanged. The other send_keys_safe callers (the wrapper's short pointer,
  stop_session's exit key) carry no task text.
- P3: delegate_job_safe's write-failure branch left the partial prompt file
  behind and logged to stdout, which callers capture. It now removes the file
  and logs to stderr.

S8 (real create_session.sh, 100 and 130,500 bytes, strace when present) and
S9 (the real function, RLIMIT_FSIZE write failure) carry the reviewer's
reproductions over; all three fail on f26952c.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 07:02:20 +00:00
GodopuandClaude Opus 5.5 f26952ccc3 fix(issue-36): the legacy shell loop and lib.sh's submit helpers pass prompts by file
The two remaining exec points that carried a prompt as one argv string
(capped at 131,072 bytes):

- run_loop.sh (MAM_LOOP_PY=0): delegate_job_safe, which all eleven shell
  delegations go through, turns `--prompt <text>` into `--prompt-file` under
  the control root's .mam/ and removes the file once the wrapper returns. Its
  failure lines go to stderr: callers capture stdout, and under set -e a
  failed submit ends the loop at that line with the wrapper's code, so the
  cause was being swallowed.
- lib.sh delegate_submit_job and its legacy twin (create_session's onboarding
  and --submit-job): the prompt is written under .mam/ and handed on as
  --prompt-file; lib_py.delegation.cli submit accepts --prompt-file and
  forwards it to the registry. --prompt keeps working everywhere.

S6/S6b push a 140,000-byte prompt through the CLI and both helpers; S7 runs
the real run_loop.sh with a 140,000-byte plan and a 150,000-byte diff; S7b
fixes a nonzero exit when the implementation or compliance job cannot be
registered. All six fail on 14d11bf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 06:08:25 +00:00
GodopuandClaude Opus 5 a28711cccf fix(issue-25): reuse a promoted plan only with --plan-file; drop the implicit newest-plan load
Without --plan, Phase 1 resolved a planner session automatically and globbed
<workspace_root>/.agents/reports/<planner>/plan-*.md for the newest file by
mtime, handing it to the Creator as "the plan already agreed on". Both keys are
wrong: the report directory belongs to a session, not to this task, so other
issues' plans pile up in it, and right after a clone or checkout mtime is
checkout order. 47 such plans are committed in this repository, so an ordinary
run could silently implement against an unrelated design.

Reuse is explicit now. --plan-file <path> is the only way to load an existing
plan; it is resolved against the control root, checked before a single job
exists, and refused if the file is missing, not a regular file, unreadable or
empty (an empty file would quietly turn into a "no plan" prompt). It cannot be
combined with --plan, and --review-only warns and ignores it because no
implementation job is delegated there. The implementation prompt itself is
unchanged, so the Creator's contract does not move.

Phase 1 now says which plan it loaded and where from, or that it loaded none.
The legacy shell loop (MAM_LOOP_PY=0) loses the same auto-load and rejects
--plan-file rather than duplicating the check on a path that is on its way out.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 03:26:24 +00:00
GodopuandClaude Opus 5 e57663ac4c feat(issue-21): item 5 review identity - per-round snapshot and snapshot diff, detached review worktree (--review-isolation), stale-round re-review, identity records with evidence, pre-promotion re-check; remote reviewers refused or diff-only (--remote-review)
Active with --worktree/--base only; without them prompts, flow and promotion
are unchanged (a loop_id is recorded in the checkpoint either way).

- Every review round is pinned (B3): the source's HEAD and its working state
  as a tree built through a temporary index (the real index/status/refs are
  untouched); a dirty state becomes a ref-less snapshot commit on HEAD
  (committed as mam-loop, not as the user). An untracked nested repository
  cannot be pinned and is refused. identity = (loop_id, base, head, tree).
- Review isolation (B4): a detached review worktree of the snapshot under
  TMPDIR (default), or `--review-isolation env` (the source root with env and
  temp-dir instructions). Failing to open the tree refuses the round - the
  isolation is never lowered silently. Trees are removed after the round and
  on any exit (run() wraps the body; release_guard too).
- The reviewers' diff comes from the snapshot (B13):
  diff_collect.sh takes an optional head commit for a commit-to-commit diff;
  its two-argument form is byte-identical.
- Stale rounds (B7/B8): after the round the source is measured again; if it
  changed, the round's approvals are discarded and the next iteration
  re-reviews without a correction job (last iteration: rc 1). Only the last
  non-stale round's PASSes are promoted.
- Records (B9/B15): review_rounds in the checkpoint with per-reviewer
  transport/evidence, and report-<jid>.identity.json next to each promoted
  report: evidence review-tree | source-tree | diff-only.
- Pre-promotion re-check (B10): a source changed after approval is not
  promoted (rc 1).
- Remote reviewers (B14, Creator challenge 91c81095): they cannot reach this
  host's review tree. Checked before anything is delegated: refused by
  default; `--remote-review diff-only` admits them with the snapshot SHAs and
  diff as their only evidence (no local path in their prompt), and refuses a
  round whose diff is truncated or unavailable.
- run_loop.sh accepts both options (usage identical to the runner's); the
  legacy shell loop refuses them before the lock.

Tests tests/test_issue21_loop_b.py L1-L16 (22).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
2026-09-14 20:54:53 +00:00
GodopuandClaude Opus 5 d907359746 feat(issue-21): loop runner --worktree/--base/--review-only with a fail-closed empty change-set guard; control plane stays in the main checkout
- --worktree <path> (CLI over MAM_LOOP_WORKTREE): the source root. Only the
  diff, base, head and the empty-set check use it; the wrapper, registry,
  checkpoint, loop guard, promotion and cleanup stay on the control root. The
  collector is the control root's diff_collect.sh (never the worktree's
  unreviewed copy), its arguments shlex-quoted. Validation: an existing
  directory, the top of its working tree, the same git common dir as the
  control root (".git" is resolved against the directory it came from).
- --base <ref> (CLI only, no env - a stale sha would silently widen the next
  range): resolved to a full sha, must be an ancestor of the source HEAD.
- --review-only: requires --base, refuses --plan; Phase 2 is skipped and
  logged; correction and comply jobs still go to the creator.
- With --worktree or --base every delegated prompt starts with a context
  block (path, branch, base and its origin, head, base..head commit count,
  uncommitted changes); without them prompts are byte-identical. All call
  sites in run() go through one _dispatch helper.
- Fail-closed guard (only with --worktree/--base): before each review round,
  self-review included, an empty change set or one git cannot determine
  (exit codes, never output parsing) ends the loop with rc 1 instead of
  asking for reviews. This closes the fail-open where a loop started after
  an out-of-loop commit sent reviewers "(no changes since base commit)".
- The runner honours MAM_JOBS_DIR and passes --registry-dir to the wrapper.
- run_loop.sh accepts the three options; the legacy shell loop
  (MAM_LOOP_PY=0) refuses them before the freeze and the loop lock.

Tests T2-1..T2-14.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
2026-09-14 03:21:43 +00:00
Godopu f413f6ada6 feat(loop): complete Issue #5 Phase 4 immutable runtime and freeze removal
- Implement eager module loading (lib_py.loop.eager) to preload all framework
  dependencies into sys.modules and enforce PYTHONDONTWRITEBYTECODE=1.
- Synchronize runtime protocol version with MAM_VERSION constant (4.3.0).
- Bypass /tmp/mam-loop-freeze.XXXXXX copy overhead by default in Python mode
  while preserving legacy rollback fallback (MAM_LOOP_PY=0 / MAM_LOOP_FREEZE=1).
- Add tests/test_issue5_phase4_runtime.py verifying eager import completeness,
  mid-flight code modification immunity (B-13), and freeze bypass.
- Pass full test suite (749 tests, 0 failures).
2026-09-07 12:59:45 +09:00
Godopu 8cd256cc7a feat(loop): port run_loop.sh to Python lib_py.loop with thin wrapper and strict parser (Phase 3) 2026-09-07 09:04:49 +09:00
Godopu 94af7f6b8a feat(opencode): wire 29-point CLI lifecycle scripts, drift-C reconciler, and skill docs 2026-08-29 14:59:01 +09:00
Godopu f57cd5cdde feat(agent): deprecate and completely remove cline agent support
- Delete adapters/cline.py and unregister from registry.py
- Remove cline branches from lib.sh and all 8 skill scripts (create, resume, stop, status, reconcile, update_yaml_resumed, resolve_session_id, orc_onboard)
- Narrow own-key mapping dictionaries across lib_py core modules to 4 supported agents
- Delete cline-exclusive tests and retarget shared fixtures to grok/hermes/claude
- Update skills documentation and installation guides (439 passed, 0 failures)
- Archive cline deprecation consensus and review reports
2026-08-28 22:38:48 +09:00
Godopu 87b4501bbf feat(mux-loop): redesign role CLI flags with --creator and --planner, drop --target-agent
- Replace '--target-agent' with mandatory '--creator <session>' flag
- Add explicit rejection error for legacy '--target-agent'
- Add '--planner <session>' flag with fail-fast check when '--plan' is missing
- Implement 2-branch session validation ('is not registered' vs 'is not running')
- Update in-repo references in hooks, SKILL.md, INSTALL.md, and tests
- Add tests/test_loop_cli.py with 9 unit/contract tests
2026-08-26 14:03:20 +09:00
Godopu 8cee9374b1 fix(loop): resolve B-13 by implementing runtime freeze snapshot and dual-root isolation
- Add Stage 2 runtime freeze snapshot at run_loop.sh bootstrap to prevent in-flight tooling mutations
- Implement dual-root architecture separating code execution (frozen snapshot) and workspace state (real repo)
- Ensure original argv preservation and safe cleanup of freeze directories in exit traps
- Add 5 regression guards in tests/test_o3_scoped_guard.py (271/271 PASS)
- Update IMPROVEMENTS.md, VERSIONS.md, and include peer review report
2026-08-17 11:49:37 +09:00
Godopu b490713471 fix(loop): eliminate tmp script copy and trap leak in delegate_job_safe (P2-1/B-6) 2026-08-15 10:46:39 +09:00
Godopu c7df7ffd68 fix(loop): resolve O-2 atomic race-free lock and marker ownership release guard (22/22 PASS) 2026-08-11 12:30:16 +09:00
Godopu f8084cd927 fix(loop): resolve P0-1 (B-7) git diff CWD isolation and untracked file capture (20/20 PASS) 2026-08-11 09:39:57 +09:00
Godopu 1f8622e077 feat(o3): implement Invocation-Aware Scoped Guard for orchestrator role scoping (100% PASS) 2026-08-07 10:09:14 +09:00
Godopu cdeb9e2c8f feat(o1): implement reviewer feedback rebuttal and re-adjudication protocol (100% PASS) 2026-08-06 09:21:28 +09:00
Godopu ea36e81624 fix(skills): resolve session resolution, add cancelled event status, and scope mqtt topic 2026-08-05 09:11:35 +09:00
Godopu 36a087af58 refactor: update multi-agent rules to TMUX & refactor MAM skills scripts
- 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
2026-07-22 06:57:32 +09:00
Godopu ff7a2873f9 Implement full E2E, integration, component, and unit tests, and resolve all leftover tmux-to-herdr issues in UI and core scripts 2026-07-19 20:05:48 +09:00
Godopu 30e606b0fa Clean up all tmux occurrences from dev skills and integrate herdr wrapper translation shim with dynamic env and workspace ID parsing 2026-07-19 16:57:00 +09:00
Godopu b45649de76 feat(delegate-job): support role aliases mapping and run delegate job safely using isolated temp copy with signal cleanups 2026-07-17 17:07:30 +09:00
Godopu 5a6cb91fb0 feat(delegate-job): support --role parameter in submit and update commands to resolve role suitability mismatches 2026-07-17 15:59:14 +09:00
Godopu be46484108 fix(loop): fix wait_for_job hang bug and finalize Creator Self-Planning documentation 2026-07-17 15:51:37 +09:00
Godopu 6c903420d8 fix(skill): resolve hardcoded planner session name and plan file paths dynamically in run_loop.sh 2026-07-16 23:48:13 +09:00
Godopu 7d22774d76 feat(loop): allow run_loop.sh to automatically load existing plan if --plan is omitted 2026-07-16 20:54:38 +09:00
GodopuandClaude Sonnet 5 35fc44f269 fix(loop): repair review-diff/verdict-parsing bugs, deduplicate session lookups
Applies the P0-P3 fixes from the multi-agent-mux-loop audit
(.mam/jobs/ab686e47/claude-reports/report-final.md):

- P0-1: capture BASE_COMMIT before Phase 2 and diff against it, so reviewer
  diffs stay non-empty and cumulative even after the Creator commits per the
  documented DoD (bare `git diff` alone showed nothing once committed).
- P0-2: has_verdict now matches only the report's last non-blank line, so a
  stray [VERDICT: ...] token quoted mid-report as a formatting example can no
  longer flip the outcome.
- P1-1: replace the English-only refactor/complex/design/architect keyword
  sniff (dead code against Korean-language reviewer reports) with an explicit
  [ESCALATE: PLANNER] tag the reviewer prompt now asks for.
- P1-2: resolve_all_reviewers/resolve_agent_type/resolve_planner_session now
  read through lib.sh's load_state_json single source of truth instead of
  each hand-rolling its own SQLite+YAML lookup; resolve_agent_type's name
  fallback matches exact hyphen segments instead of a substring `in` check.
- P2-1: warn when --all-reviewer and --reviewer are both given, since the
  latter is silently discarded.
- P2-2: correct the SKILL.md CLI-mapping table row that overstated an
  automated lint gate and an unconditional Planner feedback loop.
- P3: fix lib.sh shellcheck SC2164 (unguarded cd in start_watchdog) and
  annotate the intentional SC2317 dual source/exec guard.

Verified: shellcheck clean on both scripts, bash -n syntax OK, and the
rewritten has_verdict/resolve_* functions were unit-tested against this
repo's live .mam/agent-sessions state.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 13:50:25 +09:00
Godopu 626f35adfc refactor: harden run_loop.sh verdict parser, add atomic promotion, and revise multi_agent_workflow.md guidelines 2026-07-16 12:57:56 +09:00
Godopu dfdbf69187 fix(loop): correct self-relative REPO_ROOT depth in run_loop.sh 2026-07-16 12:06:37 +09:00
Godopu 0f970b97fa fix(loop): address planner and reviewer architecture defects
- Fix B-1: Correct Mermaid sequence diagram syntax (fi -> end) in SKILL.md and PLAN_LOOP.md
- Fix B-2: Force target agent exclusion from active reviewers in run_loop.sh and correct creator session role in registry
- Fix B-3 & B-4: Integrate WAIT_TIMEOUT deadline inside wait_for_job
- Fix M-3: Update CHANGES_DIFF to use dynamic cumulative git diff
- Fix M-2: Resolve verdict string parsing and substring collisions
2026-07-16 08:28:57 +09:00
Godopu bacf139447 feat(skills): add multi-agent-mux-loop autonomous loop orchestrator
Implement a new autonomous planning-execution-review orchestration loop
supporting:
- Collaborative planning & creator-planner challenge discussions (--plan-talk)
- Self-planning and self-review fallbacks
- Custom reviewer target list and all-reviewer unanimous PASS verdicts
- API-cost runaway safety limits via --max-loop

Integrated inside deploy/install.sh checklist and deploy/gitea-ci.yml.
2026-07-16 08:12:24 +09:00