Commit Graph
380 Commits
Author SHA1 Message Date
GodopuandClaude Opus 5 f5286a0e67 fix(issue-5): scope the persistent publisher's CONNACK result to its own connection
Found while self-reviewing phase 1. PersistentPublisher held the connect
handshake result on the instance, so a refused attempt left its reason code
behind for the next one. On retry the wait loop saw a non-None value straight
away and never waited for the new connection's CONNACK, which is wrong in both
directions:

  * a healthy second connection was rejected using the first attempt's rc, and
  * once a late callback had written a success rc, a subsequent connection that
    never acknowledged could be accepted on that stale value, letting a publish
    proceed on a socket that was not ready.

Both need an asynchronous CONNACK to reproduce, which is exactly how paho
delivers it; the earlier fake called the callback inline and hid it. The
handshake state is now a local the callback closes over, so it can only ever
describe the connection that produced it, and a client that fails the handshake
is torn down instead of leaked.

No production path is affected today: the CLI and shell helpers publish once
per process and use OneShotPublisher. The defect mattered because the phase 2a
engine is meant to build on this prototype, which is where a transient refusal
would have become a stuck publisher.

Also tightens PV-1 to check the bound tree against pytest's real basetemp
rather than sniffing for "pytest-" in the path.

Verified: the three new regressions fail against the previous implementation
(2 of 3, the third covers the healthy path) and pass against this one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
2026-09-06 16:15:40 +09:00
GodopuandClaude Opus 5 508ca99d71 docs(issue-5): phase 1 benchmark results, contract mapping, task checklist
Records the measured numbers and syncs every document that names the
delegation script paths, then bumps the framework to 4.3.0 in the three-way
lockstep (lib.sh, VERSIONS.md current + matrix, eight SKILL.md frontmatters).

phase1-benchmark.md carries both arms. The deterministic fake transport is what
CI asserts on: 50 publishes cost 50 connections one-shot and 1 persistent, p50
54.813ms -> 0.002ms. The real broker run is informational, since the PoC
default is a public broker: p50 1892.728ms -> 275.992ms, about 85% off.

It also corrects the plan's own estimate rather than repeating it. D8 predicted
the new shell path would drop from 3 forks to 2; the implementation is still 3,
because keeping the `_delegate_script publish_event.py` lookup is the only
thing that produces the "missing script tree does nothing" non-fatal contract
that C-02 pins. Saving that fork would change the contract, so it is deferred
to phase 4 rather than taken quietly.

SKILL.md gains the context table saying which tree wins where, so an operator
reading it knows a frozen loop runs frozen delegation code. The script paths in
every document remain correct and every quoted command still works verbatim.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
2026-09-06 15:48:38 +09:00
GodopuandClaude Opus 5 a4b7b45e13 feat(issue-5): persistent MQTT publisher prototype and benchmark harness
Splits publish_event.main into three pieces with no behaviour change:

  prepare_event   load the job, consume the seq, build the signed payload,
                  decide retain. The seq is burned here, before any transport
                  runs, so a failed publish can never leave a number a replayed
                  packet could reuse.
  record_outcome  audit record, registry event log and status sync -- all three
                  best effort, all three regardless of the publish result. That
                  is exactly the contract G-1/G-2/G-4 pin down, now in one place.
  main            parse, prepare, publish with retry, record.

publisher.py holds the two transports behind one interface. OneShotPublisher is
the current behaviour. PersistentPublisher keeps a single connection and lets
paho reconnect underneath, raising on an unacknowledged publish so the caller's
retry policy stays the only thing deciding attempt counts. It refuses an event
for a different broker rather than publishing to the wrong place.

Nothing in production uses the persistent path: the CLI and shell helpers exit
after one publish. The consumer is the phase 2a engine, which pays the CONNACK
cost on every event today -- this job's own started event took ~12.5s because
of one CONNACK timeout plus reconnect.

bench.py measures both arms. The fake transport is deterministic and is what
the tests assert on; the real-broker arm is informational, since the PoC
default is a public broker whose latency is not ours to control.

Verified: N publishes cost N connections one-shot and 1 persistent; the two
transports leave field-for-field identical registry and audit records including
the HMAC signature and retain flag; an unacknowledged publish retries on the
same connection and records published=false; a second broker is refused. No
test opens a socket.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
2026-09-06 15:44:33 +09:00
GodopuandClaude Opus 5 78cb9ecfa9 feat(issue-5): DelegationService, cli router, ensure_subscriber_daemon; lib.sh helpers delegate to python
Adds the python side of the delegation helpers and switches lib.sh over to it.

  daemon.py   port of start_watchdog. Same monitor path, same pgrep pattern, so
              a daemon started by either implementation is found by the other;
              same stderr wording and exit 1 when reconcile.sh is missing; same
              "print the PID" contract, multiple pgrep matches included, since
              the shell echoed them all and trimming would be a silent change.
              start_new_session detaches it, and SIGHUP is ignored across the
              exec so it outlives its parent exactly as nohup did.
  cli.py      thin router. submit/publish forward to the existing main() of the
              module that already owned the behaviour, so exit codes, stdout
              shape and side effects cannot drift between the shell path and
              the script path. Only ensure-daemon carries logic of its own.
  service.py  DelegationService facade, with an optional persistent connection
              for the phase 2a engine. CLI and shell always use one-shot.

lib.sh keeps the three legacy bodies verbatim as _*_legacy behind
MAM_DELEGATION_PY=0, which is the instant rollback switch. PYTHONPATH is passed
explicitly so `-m` resolves lib_py from the tree this lib.sh belongs to, which
is what makes a frozen loop run frozen delegation code. start_watchdog survives
as an alias for ensure_subscriber_daemon.

The wrapper and run_loop.sh are untouched; reconcile.sh gains only the
ensure_env_loaded line from the previous commit.

Verified: C-01..C-09 pass against both the legacy and the python bodies, the
daemon dedups and survives its parent, the cli reproduces the legacy failure
line exactly, and publish failure semantics (status synced, seq consumed,
audit records published=false) are identical through the shim and the cli.
tier1+tier2 109 passed; bash -n clean on all six shell files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
2026-09-06 15:42:09 +09:00
GodopuandClaude Opus 5 fb3498e23b refactor(issue-5): move delegation scripts into lib_py.delegation with package-bound shims
The four delegation scripts become a real package. Their old paths stay as
shims because those paths are a wire contract: agent instructions, the bash
wrapper, SKILL.md, BOOTSTRAP.md, deploy/install.sh and three test modules all
call them literally.

The shim binds the lib_py.delegation *package* to the tree beside it, once per
process, and never touches sys.path. Two cheaper designs were rejected with
evidence (the context matrix now lives in the test suite):

  * inserting the sibling skills dir at sys.path[0] makes the first sandbox
    copy imported under pytest shadow lib_py.agents/layout/state for the whole
    session, and the identity assertion cannot see it -- `is` proves same
    object, not same tree.
  * loading only the named module by file path leaves a module that imports
    siblings pulling them from whichever tree is on the path, so a frozen
    publish_event ran against live dependencies and lost half of B-13.

Binding the package fixes both: one tree for all delegation modules, the parent
lib_py untouched, and a sys.path append only when no lib_py exists anywhere
(true standalone). Bind-once rather than nearest-wins, because rebinding would
split existing references and break monkeypatching.

Also moves the env-file load off import (_load_dotenv -> ensure_env_loaded,
called by each process entry point including reconcile.sh's embedded
subscriber), so importing the library no longer mutates os.environ.

Verified: PV-1 identity+provenance, PV-4's ten import scenarios plus K1/K3/K6
in fresh interpreters, PV-5 shim byte-identity, an AST check that the package
imports no sibling lib_py module, and --help output diffed against the
pre-move capture.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
2026-09-06 15:41:43 +09:00
GodopuandClaude Opus 5 265a1f6c3d test(issue-5): phase 1 delegation characterization suite
The three lib.sh delegation helpers (delegate_submit_job,
delegate_publish_event, start_watchdog) had zero direct test coverage, so a
"full suite green" gate would have been vacuous for the Phase 1 extraction.
Add the regression oracle before the move:

- C-01..C-09 golden tests for the shell helpers: the non-fatal contract (empty
  job id, missing script, non-zero interpreter exit), exact argv forwarding,
  stdout-is-the-job-id-alone, and the daemon's PID/dedup/log-path behaviour.
  All are parametrized over MAM_DELEGATION_PY so the legacy and python bodies
  must agree.
- CLI contract snapshots taken from the argparse parsers rather than --help
  text, so wording stays free to change but option names, choices and defaults
  do not.
- Auto-completion invariant guards for the three surfaces that decide job
  status: EVENT_TO_STATUS, the wrapper's exit-code mapping, and reconcile.sh's
  terminal mutation literals.
- conftest: PV-2/PV-3 session guards asserting that every non-delegation
  lib_py.* module resolves to the real skills tree and that no temp-tree
  sys.path entry contributes a lib_py package. MAM_ENV_FILE is pointed at an
  absent file inside the sandbox so delegation code can never inject the real
  .mam.env into a test process.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
2026-09-06 15:33:37 +09:00
Godopu fc0bd96d8a test(issue-5): harden watcher evidence validation and add codex pass review report
- Enforce evidence-root confinement for capture_ref and 1:1 capture citation uniqueness
- Add pane identity and backend identity cross-validation
- Add bidirectional agreement checks between watcher/herdr manifests and scenario fixtures
- Expand contract test suite to 41 tests (100% pass)
- Document evidence confinement rules in herdr-runtime.md and update task.md
- Archive Codex 4th review report (Job 1bd561e6: [VERDICT: PASS])
2026-09-06 14:31:41 +09:00
Godopu 19d798bf8f test(issue-5): implement fail-closed evidence dispatch and fix VALID_STATUSES citation
- Fix Codex [P1]: add SUPPORTED_SOURCE_KINDS dispatch and enforce fail-closed rejection for non-herdr observed items without independent schema
- Add strict correspondence checks for native Herdr observed items (agent_status, native schema, session UUID)
- Add negative test reproducing Codex in-memory mutation of finalized_candidate
- Fix Claude Finding 2: update VALID_STATUSES citation in baseline.md to registry.py:38
- Update Phase 0 collected test counts to 499 in contract docs
2026-09-06 13:37:07 +09:00
Godopu dd774b1a9f test(issue-5): add phase 0 contract validation and negative test suite 2026-09-06 13:27:47 +09:00
Godopu f85fa5b6cf test(issue-5): add layer-1 herdr and layer-2 watcher test fixtures 2026-09-06 13:27:45 +09:00
Godopu 720774c1e7 docs(issue-5): add phase 0 contract specifications, state transitions, and implementation plan 2026-09-06 13:27:42 +09:00
Godopu fa59741a9b docs(reports): archive issue #5 consolidated cross-review report (Rev.2) 2026-09-06 13:27:40 +09:00
Godopu 47640e2fd7 fix(codex): resolve peer-review findings R1-R6 and T1-T2
- R1: use herdr send-keys C-c for graceful stop
- R2: preserve JSONL fallback discovery when database is empty
- R3: apply workspace-scoped SQLite query before bounding results
- R4: tighten artifact validation to fail closed on missing/invalid metadata
- R5: verify actual rollout presence before reporting resumable in status
- R6: remove unconditional drift-B backend command fallback
- T1: parameterize artifact metadata regression with verified finder fixture
- T2: seed unmanaged and managed sessions in mock herdr for drift-B testing
- Add final loop review reports (100% PASS)
2026-09-06 00:18:19 +09:00
Godopu 76f10b2096 feat(agent): add full codex agent support (v4.2.0)
- 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
2026-09-05 23:02:29 +09:00
Godopu de0a9c2e81 fix(herdr): guard idle-pane env wrapping on explicit env_flags in new-session
- Prevent injecting 'env HERDR_WORKSPACE_ID=...' into final_cmd when caller passed no environment variables
- Avoid argument parse errors in real agent binaries (e.g. grok, agy) when reusing an idle pane in new-session
2026-09-05 21:01:18 +09:00
Godopu 4d11308497 docs(reports): archive markdown audit & cleanup plan and unanimous peer review reports 2026-09-02 09:01:06 +09:00
Godopu cfa15eadee docs(cleanup): remove redundant root-level bug report and synchronize project documentation to v4.1.3 2026-09-02 09:01:04 +09:00
Godopu 8154d9a12b docs(reports): archive v4.1.3 post-commit peer review reports (100% unanimous PASS) 2026-08-31 11:50:06 +09:00
Godopu 4b2f703a73 docs(reports): archive v4.1.3 version update assessment and unanimous peer review reports 2026-08-31 11:25:09 +09:00
Godopu 85a46ef98b chore(release): bump framework and 8 skills to v4.1.3 (PATCH — herdr daemon isolation & Class A 0-turn resume reliability fixes) 2026-08-31 11:25:07 +09:00
Godopu 94f2e213d2 docs(reports): archive Issue #3 analysis, implementation plan, and multi-agent peer review reports
- Add Rev. 3 technical analysis report from creator-agy-01
- Add implementation plan from planner-reviewer-claude-01
- Add peer review reports across analysis and implementation review loops (Claude, Grok, OpenCode)
2026-08-31 10:30:46 +09:00
Godopu 7e15081d87 fix(resume): allow fresh spawn fallback and refresh epoch on 0-turn Class A resume
- Branch on Class A agents (agy, hermes, opencode) in resume_session.sh to fall back to clean spawn (CMD_FULL) when stopped before first turn (empty UUID)
- Update update_yaml_resumed.sh to support empty UUID with --cmd-full and refresh herdr_session_epoch on fresh spawn resume to prevent stale transcript capture
- Strictly preserve Class B (claude, grok) assigned UUID escape hatch and test_t8 contract
- Add regression tests test_t14, test_t15, test_t16 (Closes #3 Item 2)
2026-08-31 10:30:44 +09:00
Godopu c49ee3bdd8 fix(herdr): detach daemon bootstrap into own process group via python spawner
- Replace 'nohup ... server & disown' with portable Python 'Popen(..., start_new_session=True)' in lib.sh shim generator
- Isolate headless herdr server in its own SID/PGID to protect against parent process-group signal broadcast (SIGTERM/SIGINT)
- Add regression test test_h26_daemon_spawn_uses_process_group_detachment to verify child PGID detachment (Closes #3 Item 1)
2026-08-31 10:30:42 +09:00
Godopu 50a9f32773 docs(reports): archive v4.1.2 implementation plan and unanimous peer review reports
- Add plan-c107763c (Rev 1 & Rev 2 with creator critique and refinements)
- Add report-b11cf3b2 (planner-reviewer-claude-01 PASS)
- Add report-c9796d8c (reviewer-creator-grok-01 PASS)
- Add report-8e6b346e (reviewer-opencode-01 PASS)
2026-08-30 11:02:56 +09:00
Godopu 0644e7736a chore(release): bump framework and 8 skills to v4.1.2 (PATCH — pane resolution & reuse reliability fixes) 2026-08-30 11:02:54 +09:00
Godopu 526f7a59b7 test(herdr): add regression tests for pane misattribution and idle-pane reuse
- Add test_r2 and test_r3 for bare-kind fallback restriction and R-1 exact-match enforcement
- Add test_h24 and test_h25 for idle-pane reuse and env_flags preservation
2026-08-30 11:02:51 +09:00
Godopu b327bc7132 fix(herdr): prevent pane misattribution and prioritize idle-pane reuse in new-session
- Restrict generic agent_kind fallback in _resolve_herdr_pane_id to bare-kind searches
- Exclude 'agent' key from exact-match loop to enforce R-1 fail-closed contract
- Prioritize reusing existing idle pane on new-session to prevent unbounded pane proliferation
- Wrap final_cmd with env prefix to preserve env_flags when reusing idle pane
2026-08-30 11:02:50 +09:00
Godopu ccdde63bac docs(bug-report): add upstream bug fix report artifact 2026-08-30 11:02:47 +09:00
Godopu a18f9f825b docs(reports): archive final unanimous PASS reports from grok and opencode 2026-08-30 08:36:22 +09:00
Godopu 285e6bae81 docs(reports): archive creator-agy-01 final consolidated v4.1.1 report 2026-08-30 08:31:37 +09:00
Godopu c316c43e21 docs(reports): archive reviewer-opencode-01 review reports for v4.1.1 2026-08-30 06:59:30 +09:00
Godopu a93c32cb49 docs(versions): refine SemVer section reference for v4.1.1 2026-08-30 06:14:25 +09:00
Godopu eb8057b031 chore(release): bump framework and 8 skills to v4.1.1 (PATCH — agent creation & runtime reliability fixes) 2026-08-30 06:08:15 +09:00
Godopu 6de15350c0 chore(release): bump framework and 8 skills to v4.1.0 (MINOR — OpenCode AI agent integration) 2026-08-29 23:20:53 +09:00
Godopu de2c0e6824 test(opencode): add adapter contract, TUI readiness, and lifecycle integration tests 2026-08-29 14:59:04 +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 7341186ef9 feat(opencode): implement OpenCodeAgentAdapter and core identity bindings 2026-08-29 14:58:57 +09:00
Godopu d1f4f9eb9e docs(opencode): add implementation plan, integration guide updates, and peer review consensus reports 2026-08-29 14:58:55 +09:00
Godopu 6c0b8b0084 chore(release): bump framework and 8 skills to v4.0.0 (MAJOR — cline removal & hermes modernization)
- Bump MAM_VERSION to 4.0.0 in lib.sh
- Bump all 8 skill frontmatter versions to 4.0.0 in 3-way lockstep
- Update VERSIONS.md with v4.0.0 changelog, migration guide (B-1..B-5), and skill matrix
- Archive multi-agent version upgrade consensus and peer review reports (439 passed, 0 failures)
2026-08-28 23:31:31 +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 e0c0c107f5 merge: support-hermes branch (Hermes agent support modernization) 2026-08-28 20:18:40 +09:00
Godopu 6208a7fda3 feat(hermes): modernize hermes agent adapter and skills support
- Add --yolo and --accept-hooks headless auto-approval flags to spawn_spec and resume_spec
- Define Hermes TUI input delimiters (input_prompt='❯', input_rule_pattern='─{10,}')
- Refactor verify_artifact and discover in hermes.py using session started_at timestamps
- Fix HERDR_EPOCH capture timing before spawn in create_session.sh to prevent epoch race
- Update reconcile.sh for hermes drift-C multi-candidate and sibling claimed exclusion
- Add Hermes contract, epoch filtering, and C-ambiguous unit tests (140 passed)
- Add agent evaluation report and final review reports for Hermes support
2026-08-28 20:17:04 +09:00
Godopu 4a3328d0b7 chore(release): bump framework and 8 skills to v3.1.0 (MINOR)
- Define immutable MAM_VERSION="3.1.0" runtime constant in lib.sh
- Bump YAML frontmatter version to 3.1.0 across all 8 skill packages
- Document v3.1.0 changelog, 2-tier TUI readiness architecture, and migration guide in VERSIONS.md
- Document new tuning knobs (MAM_KILL_ON_READY_TIMEOUT, MAM_DIALOG_TAIL_LINES, MAM_READY_EMPTY_GIVEUP) in .mam.env.example
- Add 3-way lockstep and immutability test suite in tests/test_version_consistency.py
2026-08-28 18:25:14 +09:00
Godopu 17edf90676 fix(tui): establish 2-tier readiness model, modal/hint token separation, and adapter modal contracts
- Separate TUI dialog detection into blocking gate layer (_MAM_MODAL_TOKENS) and recovery layer (_MAM_HINT_TOKENS) to eliminate idle dialog starvation
- Add modal_tokens contract across agent adapters (claude, cline) with dynamic scope facts resolution in send_keys_safe
- Implement fail-closed resolution for ambiguous same-kind panes (R-1) and enforce WORKSPACE_ROOT export (R-2)
- Preserve session on TUI readiness timeout when PID is alive for diagnostics
- Add comprehensive test suite in tests/test_c1_tui_readiness.py and adapter contract assertions in test_a4
2026-08-28 15:21:10 +09:00
Godopu 4a5a093986 chore(docs): clean up temporary FIX.md and bug_report.md 2026-08-27 21:43:26 +09:00
Godopu c3631e2aa1 fix(herdr): resolve shim routing defects, add workspace scoping, and bump to v3.0.1
- Resolve Herdr shim 5 routing & paste defects (ISSUE-1 ~ ISSUE-5):
  * paste-buffer: use pane send-text without auto-enter, propagate rc=3 to send_keys_safe
  * exact-match pane resolution: remove substring matching ('in tn') across all branches
  * workspace scoping: introduce HERDR_WORKSPACE_ID and .mam/herdr_workspace_id persistence
  * unified resolver: single _resolve_herdr_pane_id helper across shim commands
- Resolve dialog token false-positive on 'Yes, try it' tip and isolate fullscreen modal rejection
- Sync mock Herdr CLI contracts in tests/conftest.py
- Add contract tests H-15~H-23 and regression tests D-4~D-7 (412 tests, 100% PASS)
- Add multi-agent loop plans, review reports, and bug report
- Update framework and skill packages to v3.0.1
2026-08-27 21:42:37 +09:00
Godopu 4bbd03bf2d fix(lib): handle agent_not_ready startup state and reject claude fullscreen upsell modal
- Accept agent_not_ready from herdr agent start to allow startup dialog handling without premature rollback, while preserving fail-closed behavior on dead process timeouts.
- Match Claude fullscreen renderer upsell modal via 'Yes, try it' and dismiss with Escape to avoid dropping permission flags or deadlocking on idle /tui tips.
- Add behavioral test suite in test_b19_headless_reconcile_fixes.py and cross-agent review reports.
2026-08-27 10:17:53 +09:00
Godopu d875584ef4 chore(submodule): update nats-docker submodule to 26fd65a 2026-08-26 18:38:52 +09:00
Godopu b18e0ae0bc docs: add verification report for v3.0.0 deployment and installation 2026-08-26 15:53:22 +09:00
Godopu 050baed640 fix(lib): enhance target agent resolution and import fallback in herdr shim 2026-08-26 15:41:50 +09:00