itsalt/pepper-orchestrator
Preview: one orchestrator session runs work across several repositories or parallel streams of one repository - plan, work packages, dispatch with worktrees and locks, PR review with a read-only reviewer agent, owner queue, closing a program when its goal is reached, state in files. Start with /pepper-orchestrator:init <program>, then /pepper-orchestrator:plan <task>.
Changelog
0.11.0 — 2026-10-01, public preview
- Dedicated Codex CLI skill, native scout/reviewer/verifier roles, prepared ordinary Git worktrees and documented queue/App Server session transport. Keep Claude methodology and per-client models; switch clients only after stopping writers.
- Local SQLite ID reservations with idempotent retries, explicit legacy import, short process locks and recoverable multi-file state changes.
- Paired CLAUDE.md / AGENTS.md shared blocks preserve existing instructions and check expected versions. Numbering locks narrow only after producer migration.
- Windows UTF-8, interpreter selection, CRLF point edits and PowerShell quoting. CI exercises concurrency/recovery on three platforms and installs the built plugin with native Windows Codex. Interactive account permissions/MCP/PR lifecycle remains a separate owner acceptance check. See Windows guide.
0.10.0 — preview, unreleased
Stage 3d: production by the orchestrator, only when the owner handed prod over by a decision D-n
(DELIVERY.md sections 5-7).
orch.py release --planwritesrelease/release-sheet-<date>.md(EN/RU): theVERIFIED_TESTpackages by repository with the SHA each passed the stand at (the evidence of itsverify --env test, else the ledger), migrations from the package's Migrations row, the promote SHA per repository (the stand SHA that contains the others), open defects and self-contained steps with expectations (the owner can release by the sheet too).release_policy: per_packagewrites a sheet of one package right after itsVERIFIED_TEST(never a second sheet for the same package).orch.py release --check [<sheet>]: gates P1-P7 by facts, not status fields. P1: the promote SHA is the tip oforigin/<integration_branch>(forff: on it), contains every stand SHA, and prod has no commit the stand never saw (git rev-list --no-merges; merge commits of earlier promotes aside;ffneeds prod to be an ancestor and a cleanrelease_cloneof the same origin); it also refuses a sheet planned for other branches or another promote method thanorch.yamlhas now, and a promote SHA that would ship another unreleased package not in the sheet. P2: every packageVERIFIED_TEST. P3: no open defect of severity blocker, critical or high inbugs/. P4: migrations (the sheet or the package file now): withprod_migrations: owneran owner itemR-n(once) and stop; withorchestratorthe review report saysmigrations: safe, reversibleandbackup_prodis set. P5:release_window("Mon-Fri 10:00-18:00 Europe/Berlin"; IANA zone,UTCor an offset;Пн-Птtoo; past midnight allowed) andmax_prod_releases_per_daycounted from the ledger. P6:prod: orchestrator, no hold, configuration valid after re-readingorch.yaml. P7: after the release.orch.py release --apply [<sheet>]: every gate first, nothing written before; then per repositorybackup_prodwhen the batch has migrations (output in the ledger; a failure stops before the promote), the promote (a PRintegration_branch->prod_branchtitled[TAG] release <date>with the sheet as body, pending checks waited for, merged with--mergeand never--delete-branch, so prod contains the stand SHA; orgit push origin <sha>:refs/heads/<prod>from the clean clone, never forced), the prod deploy run,verify --env prod --sha <prod SHA>per package ->PROD, ledger rows and an FYI item in the owner queue. GitHub refusing the promote or red promote checks become an owner item, closed by a later successful promote of the sheet.- Failure on prod: defect,
delivery.holdfor every delivery,rollback_prod(with{previous_sha}= the prod tip before the release) only for a batch without migrations; otherwise, or when the rollback fails, an owner item with the ready command (a revert PR of the promote when norollback_prodis set). The orchestrator never rolls back a database. - Ledger (backlog B1 of the 3c review):
release/deliveries.mdis written inowner_language(headings and fixed notes), package rows gain Prod run, Prod verification and Rollback columns (the stand rollback moved there from the note), and a Releases table records backup, promote, prod SHA, run, verification and rollback. A ledger written by 0.9.x is upgraded in place on the first write (its rows keep their values; a journal line records it). - Backlog B3 of the 3c review: an owner item opened because GitHub refused a merge is closed when
a later
deliverof the same package merges. - Code, not only history (review rev.2). P1 compares trees: the prod tip must carry the code of the
stand SHA of the last promote (a hand-resolved promote merge, a revert or a hotfix on prod is red,
with the recovery step; a reverted sheet is never offered for
verify --env prod).--applyreads the prod tip again right before the merge and refuses when it moved since the gates, and after the promote compares the promoted commit's tree with the stand SHA's tree before anyPROD. Any error after the promote (other code, an unknown merge commit, a failing command) ends in a hold, a defect and an owner item. P7 is red before the release when a package has nothing to verify on prod. The P1 fact names the promote merge method (merge_methodother than merge is not used for a promote). The P4 migrations item is closed after the release of its batch and not opened again once the owner closed it. Pushes tointegration_branchandprod_branchare denied like pushes to the base in the module and orchestrator settings whenorch.yamlhas adeliveryblock. lint:release_policy,release_window,max_prod_releases_per_day,promote(andffneedsrelease_clone),prod_migrations: orchestratorneedsprod: orchestrator.orch.py settings orchestratorwithprod: orchestratorallowsverify_prodandbackup_prodverbatim androllback_prod(askwhenrollbackis incheckpoints); the promote PR, its merge and the promote push happen only insiderelease --apply, so no allow rule forgh pr create,gh pr mergeor a push to prod (gh pr mergeand pushes to the base stay denied).close: the closeout has a Deliveries section from the ledger and the package Version column from the ledger when the orchestrator delivered the package.- Documentation:
releasemode,/pepper-orchestrator:release, concept section 15 (EN/RU), README scenario "Trusted release", the review brief's migrations verdict line.
0.9.1 — preview, unreleased
Hotfix for three field reports (Issues #20, #21, #24).
- #20, output through a pipe.
orch.pyandsafe_edit.pyreconfigure stdout and stderr to UTF-8 (errors='replace') at start: an agent session reads them through a pipe, where Windows uses the ANSI code page (cp1252) andqueuefailed withUnicodeEncodeErroron Russian text.PYTHONUTF8is no longer needed. - #20, process output. All 16
subprocess.run(..., text=True)calls read withencoding='utf-8', errors='replace'(git, gh,claude --version, check, verify and delivery commands). - #20, the
Noneinparse_push_trigger- cause established. On Windowssubprocesscommunicate()reads pipes in reader threads (Popen._readerthread:buffer.append(fh.read())). AUnicodeDecodeErrorthere (UTF-8 Cyrillic in a workflow decoded as cp1252, whose bytes 0x81, 0x8D, 0x8F, 0x90, 0x9D are undefined) kills only that thread;communicate()then returnsstdout = stdout[0] if stdout else None. On POSIX the same decoding happens in the main thread and raises instead, which is why it did not reproduce there. Fixed by the UTF-8 reading above; besides,parse_push_triggerrefuses a non-string text (DeployFormError: "could not be read") anddeploy_safe_dirsoffers no directory at all when a workflow could not be read, or contains bytes that are not UTF-8 (a replaced character never reaches a candidate name). The fix is guarded by the pipe tests (cp1252 output encoding, C locale); a separate selftest block only illustrates the CPython thread behaviour and would pass on 0.11.0 too. - #21, escalation.
review-start --round 3+prints and writes a conditional line ("if the same REVISE items are still open after this review, restart ..."); the owner item opens only when the package is set toREVISEagain from round 3 (the round comes from the newest review report), once per open item. - #24, PR cell.
set <WP> prtakes a pull request URL (a tail such as/files,?w=1or#issuecomment-…is cut) or a number (#87,87), expanded tohttps://<host>/<owner>/<repo>/pull/<n>fromorigin_name()of the module repository, only when the host is a forge (never loopback or a private address such as the cloud git proxy); anything else is refused with an example.pr_url()expands a cell that is exactly such a number, so cells written before 0.9.1 work as they are.review-start --pr,merge add --prandacceptvalidate and normalize the value before anything is written (no partial state);acceptextracts the URL from an older cell by search and never refuses because of it;merge add --pralso fills an empty PR cell;close --checkreads numbered cells too. - The self-test reads child output as UTF-8 itself, so it runs under a non-UTF-8 locale too.
0.11.0 — preview, unreleased
Preview of stage 3c: trusted delivery of merges and the stand, only by an explicit owner decision.
deliveryblock inorch.yaml:merge,stand,prod,prod_migrations(owner | orchestrator, default owner; workspaces before 0.11.0 = all owner),enabled_by,hold.orch.py delivery showanddelivery set <level> owner|orchestrator --decision D-n(orchestrator only with a recorded decision).lint: orchestrator withoutenabled_byor with an unrecorded one,prod: orchestratorwithoutmerge: orchestrator,merge_methodandrun_timeoutvalues. Repository keys:merge_method(merge | squash | rebase),delete_branch,deploy_test,rollback_test({previous_sha}),run_timeout,integration_branch.orch.py accept <WP> <sha> --report <path>:ACCEPTEDat the reviewed revision, journaled.orch.py deliver --check <WP>: gates G1-G10 with facts (accepted revision and report, PR head = accepted SHA,gh pr checks, open/mergeable/base/title, merge queue head and previous mergeVERIFIED_TESTor--after-failure D-n, locks, repository checks, owner items marked "blocks delivery" and referenced decisions, "graph: checked" when the package has a Specification, and the delivery level re-read fromorch.yamlwith no hold).--apply:gh pr merge <n> --repo <origin> --<merge_method> [--delete-branch](never--admin; a GitHub refusal becomes an owner item),MERGED, merge queue, ledgerrelease/deliveries.md, journal; withstand: orchestratorthe deploy run of the merge SHA (gh run list+gh run watch,run_timeout) ordeploy_test(stdin closed: no TTY confirmations), thenverify --env testandVERIFIED_TEST. A failure:delivery.hold, defect,rollback_testwhen configured, REVISE text;orch.py hold/unhold; the firstlintwarning andresumename the hold. Withoutdelivery.merge: orchestrator,deliverrefuses with "delivery is done by the owner" and the owner's command.settings orchestratorfollows the levels:gh run watch/list,gh pr view/checks,deploy_test,verify_testandrollback_testverbatim (rollbackcheckpoint = ask).gh pr mergestays denied in every session: the merge happens only insideorch.py deliver --apply.deliverrefuses on an invalid delivery configuration (and G10 re-checks it);merge_methodother than merge, squash or rebase never reachesgh;--after-failuretakes a recorded D-n, journaled and in the ledger; a deploy run still in progress at verification exits 2 (MERGED, no hold); a merge commit GitHub has not reported yet stops before the stand;acceptnotes the revision in the package's PR cell; the review and owner modes hand merges todeliverwhenmerge: orchestrator.- Work package row "Graph"; the review brief checks the graph and writes "graph: checked".
delivermode and command; hard rules 1 and 13 name the only exception; README (EN/RU) "Trusted delivery"; concept 1.8, sections 1, 2 and 12.
0.8.0 — preview, unreleased
Preview of stage 3e: a channel for defects of the plugin itself.
orch.py report --check [--command] [--log] [--title] [--expected-actual] [--workaround]: facts of the installed copy and the environment (plugin and version, Claude Code, OS and architecture, Python, shell), the command and the first 30 lines of its output (or the top of the journal), the workspace shape without names. Names fromorch.yaml(program, tag, title, coordinator, modules, sessions, repositories, their paths and origin URLs, web hosts, cloud environments, workspace path and branch) become placeholders; home paths, e-mail addresses, secret-looking strings and the terms of a gitignored.private-terms.localare removed; the result is scanned again and nothing is written if anything private remains. Writesbugs/PLUGIN-BUG-<n>.md(owner language) andbugs/PLUGIN-BUG-<n>.issue.md(English), prints the Issue text and a fingerprint: plugin, version and the error line (the exception line of a traceback, else the first line with an error word, else the title) without placeholders, timestamps, SHAs, package ids and numbers. Also covered: owners and non-public hosts of every origin (the home repository too), URL-encoded forms, andNAME_PASSWORD=/NAME_KEY:secrets.--logrefuses environment, settings and key files,orch.yamland mostlyKEY=valuefiles.orch.py report --apply [--id] [--confirmed]: without--confirmedand withoutbug_reports: auto(which needsbug_reports_decision: D-nrecorded in decisions.md;lintchecks it) it refuses with the question for the owner. The title and the text are scanned again. Searches Issues ofITSalt/PepperSkillsby the fingerprint as a quoted phrase (open and closed, open ones preferred, the state journaled); a match gets a comment with this environment's facts, otherwisegh issue create --title "[<plugin> <version>] <title>" --label bug,from-agent,needs-triage(retried withbugonly when the labels are missing, with a command for the maintainer). The URL goes to the record, the journal and an FYI owner item. Withoutgh: steps for the GitHub MCP tools, or the text for manual posting.--securitypoints to SECURITY.md and writes nothing.orch.py report --status(used byresume): recorded defects with their Issues and, withgh, one line when a newer version is on the marketplace'smain.reportmode and command; hard rule 11 "a defect of the plugin is reported, not patched"; the package section "If a permission is denied" points to it. README (EN/RU) scenario "The plugin broke - report it"; concept 1.7, section 16.- Repository: issue form
agent-bug-report.yml(labelsbug,from-agent,needs-triage), links to SECURITY.md and CONTRIBUTING inconfig.yml, the indentation ofbug.ymlfixed (it did not parse),.github/CODEOWNERS(* @ITSalt), PR template withFixes #Nand a private-traces check, CONTRIBUTING sections "Report a defect from an agent", "Fix from an agent" and the merge rule;scripts/test-github-templates.pyincheck.sh.
0.7.1 — preview, unreleased
Hotfix for Windows: generated settings were rejected by their own validator, so no settings files
were written and dispatch refused.
- One function builds the absolute path of a rule (
session_settings.abs_rule_path)://<path>on macOS and Linux (unchanged output, compared byte for byte with 0.7.0 on a fixture); on Windows the documented POSIX form//<drive letter>/<path with forward slashes>; network (UNC) and relative paths are refused with a clear error. Used for the repository, module paths, workspace and both templates. - Bash rules with paths use forward slashes; on Windows the orchestrator's settings also allow the
python ...andpy -3 ...forms of its scripts.--settingspaths in start commands use forward slashes on Windows. shell: bash|powershellinorch.yaml(default bash;init --shell, asked explicitly on Windows): with PowerShell,initanddispatchprintcd "<dir>"; claude ....- Texts: on Windows a worktree does not read
.claude/settings.local.jsonof the main checkout (the 0.6.0 statement held for macOS and Linux only); the plugin passes the rules with--settingson every system. README (EN/RU) section "Windows". - Backlog: a Windows runner in CI; PowerShell-specific forms of Bash rules.
0.7.0 — preview, unreleased
Preview of stage 3b: verification of the stand and production by facts, whoever merged and deployed.
orch.py verify <WP> --env test|prod [--sha <sha>] [--expect-version <v>]: the expected SHA is the merge commit of the package PR (throughgh) or--sha; checks in order: the run of eachdeploy_workflowsentry (a list or{test, prod}) for that SHA on the environment's branch (integration_branch/prod_branch, default the base) finished withsuccess;version_url(with{base_url}/{env}, or per environment) serves the SHA (version_patternwith one group) or--expect-version;verify_test/verify_prodcommands run through the shell in the main checkout withORCH_ENV,ORCH_SHA,ORCH_WP,ORCH_BASE_URL, timeoutverify_timeout(default 300 s). Reportreports/verify-<WP>-<env>-<date>.mdwith a table (check, command or target, exit, first output lines with secret-looking fragments redacted, verdict) and a "Live scenario" section. PASS: statusVERIFIED_TESTorPROD(a later status is kept). FAIL: status kept, journal,bugs/BUG-<n>-verify-<wp>-<env>.md; an owner item only when the deploy run is missing or failed. WAIT (exit code 2): the deploy run is still queued or running - a journal line, no report, no defect, no owner item. Test needsMERGEDor later; anACCEPTEDpackage is set toMERGEDaftergh pr viewconfirms the merge. On prod with a separateprod_branchthe expected SHA is the tip oforigin/<prod_branch>that contains the merge commit, else a refusal asking for--sha.lintchecksversion_pattern(compiles) andverify_timeout(positive integer); an invalid pattern at run time is a FAIL. Reports and defects follow the owner language.--dry-runprints the plan and neither runs, callsghnor writes; withoutghit refuses with a hint when a run or a merge commit is needed.verify --listshows packages waiting for test or prod verification.- Status vocabulary:
VERIFIED_TEST(satisfies dependencies likeMERGED). verifymode (references/modes/verify.md, command/pepper-orchestrator:verify), briefreferences/verify-brief.md, agentorchestrator-verifier(Read, Grep, Glob, Bash; read-only; nomodel, runs on the orchestrator's model);resumelists what waits for verification.- README (EN/RU): "Checking the stand and production by facts"; concept 1.6, section 9.
0.6.0 — preview, unreleased
Preview of stage 3a: session permissions, worktree preparation, message delivery, on-demand locks.
orch.py settings <module|all|orchestrator>writesorchestration/settings/<name>.jsonfromorch.yamlandtemplates/settings/*.json:Readof the repository, module paths and workspace; narrow Bash rules (cat,grep,rg,sed -n,ls,find,head,tail,wc, git status/diff/log/show/branch/fetch/add/commit/switch/restore --staged,gh pr view/list/checks/diff);gh pr create; every command oftests,checksandworktree_setupverbatim, one exact rule per simple command. Deny:gh pr merge, force pushes, pushes to the base in every usual form (origin <base>,HEAD:<base>,*:<base>,refs/heads/<base>, with any tail), force pushes after any argument (--force,-f,--force-with-lease,+<ref>),gh workflow run,gh release,Editof the workspace, production MCP servers fromenvironments.prod, a module'sdeploy_prodcommand,ssh/psql/mysqlwhenguardsare set,Skill(<name>)formethodology.forbidden. No allow rule forgit push(a*tail would also match refspecs to the base and force flags): pushes of the package branch go to the classifier, or ask with thepushcheckpoint (Bash(git push *)). Ask:checkpoints(push,pr,deploy_test; defaultdeploy_test).autoMode.environment=$defaults+ trusted repository and source control;crossSessionInbound: accept. Idempotent; rules are syntax-checked before writing;<name>.local.jsonis never touched (and gitignored in new workspaces).dispatchadds--permission-mode <permission_mode> --settings <absolute path>to local start commands, refuses without the file (hintorch.py settings <module>), warns when the file is older thanorch.yaml;--no-settingskeeps the pre-0.6.0 command. Cloud modules are unchanged.initrequires--permission-mode(auto recommended, asked explicitly), writespermission_mode, generates all settings files, prints the orchestrator start command (--name <coordinator_session> --permission-mode <mode> --settings orchestration/settings/orchestrator.json) and the/configalternative, and opens a P-n item with a ready.worktreeincludefor local repositories with streams that have none.lint:permission_modeandcheckpointsvalues are checked; warnings for a workspace withoutpermission_mode, missing or stale settings files,cp/rsync/lnof.env*, secret, key or certificate directories or.claude/inworktree_setup, backticked names in Shared paths or Resources rows that are not locks, on-demand locks older thanlock_stale_hours(default 4).- On-demand locks:
resourcesentries{name, mode: on-demand}are not taken atdispatch; the session sendsLOCK/UNLOCK(protocol),lock acquire/releaseas before; statusREVIEW(READY),DONEorCANCELLEDreleases them;overlap --plannedreports package resources declared by two packages;lock listmarks on-demand locks. - Work package template: section 6 "If a permission is denied" (never work around a refusal,
QUESTIONwith the exact text, retry when the classifier is unavailable, LOCK/UNLOCK); the Start command note describes the dispatch flags. Protocol:LOCK,UNLOCK, message delivery. Bootstrap prompt and thedispatch/resumemodes check the session name againstcoordinator_session. - Field fixes:
init --in-repoaccepts a positivepathsfilter when the branch filter already excludesorch/<program>;--deploy-override D-nwithout--dirtakes the first directory the readable workflows ignore and asks for--dironly when there is none, naming both reasons and both options; backticked text that is not a lock no longer refusesdispatch. - README (EN/RU): "Session permissions and permission mode" and the scenario "A stream got a refusal"; concept 1.5, sections 4 and 12.
0.5.0 — preview, unreleased
Preview of stage 2e: implementer model per package, session kind chosen by the owner, cloud environment.
initrequires--sessions local|cloud(the owner's explicit choice; the mode recommends local, asks and waits for the answer; the choice is journaled);--sessions cloudrequires--cloud-environment <name>; in a cloud session (CLAUDE_CODE_REMOTE=true)init --sessions localanddispatchof a local module are refused (a cloud orchestrator works only with cloud sessions). The choice is the program'ssessions; repositories and modules inherit it.orch.yaml:models(implement,implement_effort,escalate,escalate_effort), modulemodel/effort,cloud_environment(program, repository or module);lintrejects unknown aliases and efforts and warns about cloud modules without an environment. Withoutmodelsstart commands carry no model flags, as in 0.4.0.- Work package template: Model, Effort, Model reason;
new-wpfills them;orch.py modelchanges them together with the start command and journals;dispatchtakes the flags from the header. dispatchof a cloud module prints a block (environment, repository and branch, model and effort, claude.ai/code prefill link without the prompt above 2000 characters) and refuses a cloud module without an environment;orch.py cloud-envrecords the name.review-startfrom round 3 prints and queues an escalation restart (cd <repo> && claude --resume <session> --model <escalate>locally; model list or/modelin the cloud).- Agents:
orchestrator-scouthasmodel: opus;orchestrator-reviewerhas nomodelon purpose. dispatch --dry-runprints a model note (model <m>, effort <e>ormodel owner default) next to the locks, and the journal line ofDISPATCHINGgets the same suffix, also in workspaces created before 0.5.0.- Model and effort in package headers are validated: invalid values are
linterrors and refusedispatch; an Effort without a Model is alintwarning. From review round 3 the escalation hint is printed every round, but only one open owner item per package.init --sessions local --cloud-environmentis refused. - Concept 1.4 (EN and RU): session kind and implementer model, and the
/model <name>trap; README "Models and environment".
0.4.0 — preview, unreleased
Preview of stage 2d: program completion. One program, one goal: reached, closed; the next goal is a new program.
PLAN.mdtemplate: "Goal and completion condition";planfills it and does not run on a closed program.- Mode
closeandorch.py close --check | --apply: blockers by fact (non-terminal packages, open PRs of package branches viagh, or branches still on origin until--prs-verified, locks, queued merges, open owner items), module sessions to close;--applywritesreports/closeout-<date>.mdfrom the template (EN/RU), setsstate: closed, puts a banner onstatus.md, journals and commits; a separate home repository archives the workspace tofeatures/_archive/<program>withgit mv; an in-repo workspace gets an owner item with the tag and branch-deletion commands (never run by the plugin) and an optional question about keeping the workspace indocs/of the base branch. orch.py owner carry <id> "<reason>"moves an open owner item tobacklog.md.- After closing:
dispatch,new-wp,lockandmergechanges are refused with a hint;lintreads only; among several workspaces a closed one is never picked automatically;resumeon a closed program reports the result, and on a finished one proposesclose. - Mode
reopenandorch.py reopen "<reason>". - Concept 1.3 (EN and RU), section 21 "Program completion"; README scenario 10.
- Closing is strict:
--prs-verifiedneeds concrete evidence (a PR URL with its state, orlist_pull_requests/gh pr listoutput) and is written to the journal and the closeout; recorded PR URLs are checked withgh pr view; a failingls-remote, a missing module repository or an uncheckable PR URL blocks until verified; an unwritten completion condition needs--goal-confirmed.close --applychecks the commit conditions before changing anything and a second--applyfinishes an unfinished close; the archive move is pushed; a workspace at the root of its repository is not moved. In-repo archive commands run from any clone and are tied to the closeout commit (git push origin <sha>:refs/tags/<tag> && git push origin --delete orch/<p>), and a closed in-repo program whose branch is gone is never pushed again. The closeout has a version column to fill in and a "checks without full evidence" section. After closingset,decide,owner addandreview-startare refused too, andlintreports a closed program with a non-terminal package.ORCH_NO_GH=1hidesgh.
0.3.0 — preview, unreleased
Preview of stage 2b: review of module deliveries.
- Mode
reviewand command/pepper-orchestrator:review: automatic findings, theorchestrator-revieweragent on the first submission, the revision diff on resubmissions, verdict REVISE/ACCEPTED, report from thereview-reporttemplate (EN/RU), REVISE message and ACCEPTED hand-over (merge queue, owner merge item). Never merges, approves or comments. orch.py review-start <WP>: automatic findings reusing the stream rules (files outside the allowed paths, shared paths undeclared or without the lock, repositorychecks) plus a stale merge-base with the branch files the base changed since; report skeleton; statusREVIEW; the disposable clone command;--since/--roundfor resubmissions (git range-diffafter a rebase).scripts/review_clone.sh: clone at a SHA into a marked temporary directory, setup, tests, removal (--keepfor mutations,--cleanuponly for marked directories); never pushes.- Agents (Claude Code adapter):
orchestrator-reviewer(read-only, disposable clone, mutations, claims as claims, base comparison) andorchestrator-scout(read-only facts, SELECT only). references/review-brief.md: brief template and risk checklists (state machines, migrations, registries and shared types, UI, permissions, integrations).- README: "Typical workflows" (EN/RU) with exact calls for local and cloud sessions.
review-startreviewsorigin/<branch>or the given--ref(never a local branch), warns when the local branch differs, stops on a failing fetch (--no-fetchto skip), printsgit range-diff <base>..<old> <base>..<new>after a rebase, and putsmain @ <sha>in the report header. Review clones use the repository's ownreview_setupwithORCH_MAIN_CHECKOUT, neverworktree_setup.review_clone.shchecks flag values andmktemp.- Agents state honestly that MCP tools are not available to them (the orchestrator collects
database and GitHub-tool facts) and forbid database clients and
sshthrough Bash; the cloud review brief allows only reading GitHub tools. The report template has an "Owner questions" section, and small fixes that need the owner's consent become conditional REVISE items.
0.2.1 — preview, unreleased
Preview of stage 2c: cloud sessions over one repository.
- In-repo workspace:
init --in-repo <repo-id>switches toorch/<program>(created without tracking the base), finds a directory every push workflow ignores (on.pushpaths-ignore,branches,branches-ignorein.github/workflows/*) and refuses when there is none; neworch.yamlkeysworkspace_mode,workspace_branch,workspace_dir; repository paths may be relative to the workspace's repository (path: .).commitgoes only toworkspace_branchand always pushes to the same-named remote branch. sessions: cloudon a repository or module: work packages carry a cloud-session prompt (read the package fromorch/<program>or inline, branch from the base, PR with the package id, no message back, never merge tools such asmcp__github__merge_pull_request);dispatchprints it (--inlineappends the package text).orch.py ready: dispatched packages whose branch is on origin (git ls-remote), with the PR viaghwhen available;resumedescribes the no-ghpath through the session's GitHub tools.- Workspace discovery also finds nested in-repo workspaces (up to four levels below the current
directory);
lintchecks the in-repo keys and warns when the workspace directory is not ignored by every push workflow. scripts/install-skill.sh(repository root): idempotent copy of a canonical skill into~/.claude/skillsfor cloud environment setup scripts; README section "Cloud sessions".- Skill: hard rule "no merge tools", cloud section,
/pepper-orchestrator <mode>calls without plugin commands. Concept 1.2 (EN and RU), section 20 "Cloud sessions". - Deploy check is strict: workflows are read from the pushed ref (
git ls-tree/git show), a missing ref or any workflow form outside the documented list is a refusal, hidden directories are never candidates anddocs/comes first; an unsafe--diris refused; the only override is an owner decision (--deploy-override D-n, stored asdeploy_check_override).commitof an in-repo workspace refuses while the check fails. dispatch --dry-runwrites nothing for any module; a cloud package must be onorigin/orch/<program>(same content) before its prompt is printed; withpush_deploysa cloud package holds thestaginglock and its prompt says to push once.init --in-repofetches first and reuses an existingorigin/orch/<program>(refusing a second workspace);commitrefuses a detached HEAD before committing, pushes to the branch's own remote and keeps an existing upstream; repository names are read from GitHub and cloud proxy URLs;readyreports only open PRs with the package id in their body.- README setup fragment never fails the environment's setup script;
install-skill.shremoves its temporary directory on failure.
0.2.0 — preview, unreleased
Preview of stage 2a: streams in one repository and dispatch. A 0.1.0 workspace works unchanged
(orch.py upgrade only adds the two new tables when locks or the merge queue are needed). 0.1.0
modules that share one repository path now get a lint warning (not an error) and are dispatched
one at a time; each keeps its own base. To run them in parallel, add a repos entry and turn
them into kind: area|domain modules with paths.
orch.yaml:reposblock (base, branch prefix, worktree root and setup, merge policy, shared paths, resources, checks, deploy workflows) and modules of kindarea,domainorrepowithpaths,session,test_db,ports,tests,methodology; the 0.1.0 module form iskind: repo,paths: ["**"].- New
orch.pycommands:dispatch,overlap,lock acquire|release|list,merge add|done|drop|list,worktrees,upgrade.lintchecks module path overlaps, whole-repository modules sharing a repository, lock and merge queue tables. - New mode
dispatchand command/pepper-orchestrator:dispatch;inithandles several modules per repository, reads the repository's branch prefix, asks the owner's language explicitly and refuses a workspace in a module's base checkout (also oncommit);resumereads worktrees, finds PRs by branch and package id, foreign writers and stand deploys;ownerprints the merge queue in order with waits and recommends batches when merges deploy production. - Work package template: stream, worktree, allowed and shared paths, migrations, resources, test
database and ports, line, merge slot, methodology limits; generated worktree preparation,
delivery (with or without a remote) and start command (
claude -wfor streams). safe_edit.py --stdin: one or more OLD/NEW blocks, applied all or nothing, no temporary files;lintrejects leftover marker lines; backup fallback when.orch-backup/cannot be written.- P4 identifies a module repository by git common directory and origin URL (linked worktrees and
clones included; git older than 2.31 supported);
orch/<program>is the only allowed branch. - Globs support
{a,b}(expanded for matching and overlaps;initkeeps commas inside braces);[/]are literal. Dependencies accept module ids with hyphens (WP-ADMIN-UI-01). - Locks: shared-path locks collide by glob; unknown resources and paths outside
shared_pathsare refused; a released lock with a queue stays as a free row, the queue is respected, and a package leaves every queue once it gets its lock;merge donenames the waiting packages. push_deploys: trueon a repository: delivery sections tell sessions to commit locally and push only with the stand slot.git statusin session worktrees uses--no-optional-locks.plannever writes an open P-n's recommendation as decided; the manifest description says where to start.- Concept 1.1 (EN and RU): rules P1-P5 in sections 4, 7 and 12, new section 19 on repositories where a push deploys a stand.
0.1.0 — preview, unreleased
Preview of the stage 1 core; formats and commands may change before 1.0.0.
- Stage 1 core: canonical skill with a mode router and modes
init,plan,resume,owner,decide. - Workspace CLI
orch.py(init, new-wp, set, journal, owner, queue, decide, lint, commit) andsafe_edit.py(exactly one match, backup, size check), standard library only, with a self-test. - Workspace, work package and bug templates in English and Russian; optional
Specificationfield in work packages andspec_graph: noneinorch.yamlas the docking point for a specification graph. - Concept: English translation (
references/concept.md) and Russian original (references/concept.ru.md). - Claude Code short commands in
commands/.