Skip to content

feat: autonomous orchestrators p3c — one Mind writer (ledger ops, temp-worktree commits, worker hook) - #560

Merged
Jammy2211 merged 2 commits into
mainfrom
feature/autonomous-orchestrators-p3c
Nov 4, 2026
Merged

Jammy2211 merged 2 commits into
mainfrom
feature/autonomous-orchestrators-p3c

Conversation

@Jammy2211

Copy link
Copy Markdown
Contributor

Closes #559. Phase 3c of the autonomous-orchestrators epic — AUTONOMY.md "One Mind writer per shift — 2026-11-03", implemented and enforced. Read with PyAutoLabs/PyAutoMind#526 (merge that one first).

What changes

  • _mind_writer.py (new) — workers' Mind changes arrive as op files in <slot>/ledger/ (append | write | move | remove | drop-section); every path must be ledger by PyAutoMind's own scripts/ledger_merge.py (loaded from the checkout being written; default deny — scripts/, .github/ refused). commit_ledger applies all pending ops in a temporary detached worktree on origin/main, commits once, pushes; if main moved, the ops are replayed on the new origin/main (a rebase of operations), at most 3 tries. No reset, no force flag anywhere in the module (a test pins it); the canonical checkout's working tree is never read or written; committed ops move to ledger/committed/; an op that cannot apply stays pending.
  • bin/shift_ledger.py (new) — the worker-side CLI that queues one op (validated against Mind at write time).
  • bin/worker_git_hooks/pre-commit (new) — refuses a commit in a PyAutoMind repo when PYAUTO_SHIFT_WORKER=1, naming shift_ledger.py; otherwise chains to the repo's own hook (read from --git-common-dir, since --git-path would resolve to the override and loop).
  • _orchestrator.py — worker_env(): real workers run with PYAUTO_SHIFT_WORKER=1, PYAUTO_SHIFT_LEDGER_DIR, and core.hooksPath via GIT_CONFIG_COUNT/KEY/VALUE (appended to any existing GIT_CONFIG_*), so the refusal covers prompt_sync_push, lifecycle close and a raw git commit alike. Each tick commits pending ledger ops after the reap (result gains ledger). The 3b sandbox fence is removed (human decision 2026-11-03).
  • worker_template.md — tells the worker to queue its claim, its draft/ → active/ move and its close-out with shift_ledger.py.
  • Conductor AGENTS.md "The watcher" — one Mind writer, the ops, the hook.
  • Tests — tests/test_orchestrator_mind_writer.py (9, real git); the two 3b fence tests flipped (a non-sandbox brief now dispatches; with the fake flag unset the default spawner is real — no tick is run there, since it would start a session).

Note on wording: AUTONOMY.md's sub-rule says workers write ledger lines "into the lease directory"; the implementation uses <slot>/ledger/, the lease directory's sibling, so ops outlive the lease that queued them. Same rule, one directory over.

Tier: judge — merge mode: human /prm. Heart YELLOW reason set acknowledged by the human at ship.

Witness

$ pytest tests/test_orchestrator_mind_writer.py -v   (real git: bare PyAutoMind.git remote + canonical clone + a racing clone)
test_two_workers_land_in_one_orchestrator_commit  PASSED
test_a_concurrent_commit_is_replayed_over_never_forced  PASSED
test_a_non_ledger_path_is_refused_before_anything_moves  PASSED
test_an_op_that_cannot_apply_stays_pending  PASSED
test_the_worker_hook_refuses_a_direct_mind_commit  PASSED
test_the_worker_hook_allows_other_repos_and_chains_their_own_hook  PASSED
test_worker_env_marks_points_and_hooks  PASSED
test_the_module_never_resets_or_forces  PASSED
test_a_tick_commits_what_the_workers_queued  PASSED

$ pytest tests/test_orchestrator_dispatch.py tests/test_orchestrator_watcher.py   → 33 passed, 1 skipped in 2.83s
$ repos_sync.py --check --only 'tenant firewall (organ code)' --root <task worktree>   → OK
full suites (PYAUTO_* unset): PyAutoBrain 1482 passed, 1 skipped in 217.29s (0:03:37)  ·  PyAutoMind 712 passed in 80.80s (0:01:20)
lifecycle.py check: DRIFT only the pre-existing active/chapter2-explanations.md

🤖 Generated with Claude Code

…ith replay, worker pre-commit hook; lift the sandbox fence

Autonomous orchestrators phase 3c (#559). Fence lift: human decision 2026-11-03.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kout gains no __pycache__

CI (bytecode on) caught commit_ledger leaving scripts/__pycache__/ in the
canonical Mind checkout; the test now forces bytecode writing on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Jammy2211

Copy link
Copy Markdown
Contributor Author

First CI run (41688956065) was red on both legs at Run tests, one test: test_two_workers_land_in_one_orchestrator_commit — the canonical checkout gained scripts/__pycache__/. Real defect, not CI noise: _ledger_merge() imported Mind's scripts/ledger_merge.py with exec_module, which writes bytecode into the canonical checkout, breaking the module's "canonical working tree never written" promise. My shell sets PYTHONDONTWRITEBYTECODE=1, so local runs hid it.

Fixed in 726090b: the module is compiled from source and exec'd (no cache written); the test now forces sys.dont_write_bytecode = False so the environment cannot mask it again. Full Brain suite with bytecode on: 1482 passed, 1 skipped; tenant firewall OK.

@Jammy2211
Jammy2211 merged commit 06c964c into main Nov 4, 2026
2 checks passed
@Jammy2211
Jammy2211 deleted the feature/autonomous-orchestrators-p3c branch November 4, 2026 08:16
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.

feat: autonomous orchestrators p3c — one Mind writer (ledger ops, temp-worktree commits, worker hook)

1 participant