Skip to content
permgpsPublic

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

318 Commits

Folders and files

Repository files navigation

Maestro

Maestro turns a dictated idea into a project and records what verification actually established, in one dialogue. You say what you need; it records your words as numbered requirements, asks only about the genuine forks, writes a specification, cuts it into tasks, builds them with parallel executors, reviews the result — and then checks the build against your original words with the specification withheld.

It is an Agent Skill. Installing it copies prompts, a dashboard and an autonomous TypeScript helper; nothing is compiled, and nothing runs at install time.

The package holds a second skill: scout. It is reconnaissance for the case Maestro deliberately does not handle — a ТЗ that is thin, or a domain you do not yet have the words for. Scout reads the domain across many sources, finds how existing products already solve it, asks only the forks that reading exposes, proposes edits to your ТЗ one at a time in your own words, and prints a бриф to paste after /maestro. It writes nothing a прогон reads and starts no run of its own.

Neither skill needs the other. Each runs without the other, and Scout ends at a block of text.

Status: 0.0.14-alpha. Four прогона have carried a бриф to a finished отчёт with all four gates passed on Claude Code. One of the four modes has never been run, Codex, Gemini CLI and DeepSeek Harness are unverified, and Scout has not yet run in front of a real прогон — see Limitations and CHANGELOG.md.

Contents

Quick Start

cd my-project
git init                              # before you start the agent session
npx skills add permgps/skills -y      # installs every skill the default branch carries

Then, in Claude Code, inside that project:

/maestro Сделай страницу заметок с локальным сохранением.

What happens next:

  1. The first run in a project asks how to work — how it should explain things (по-простому or обычный), then which mode to start in, then which models build what — and writes the answers to .maestro/config.json. It never asks them again; only a new host, or a pinned model no longer offered, brings the models question back.
  2. The dashboard opens in your browser (or in your host's pane) and stays current for the whole run.
  3. Your words come back numbered as R01, R02… Correct anything that was misread; this is the last moment the list is open to the run.
  4. A block of questions arrives about the genuine forks, each with options and one marked as recommended. Pick, say «как советуешь», or answer in your own words.
  5. From there it specifies, plans, builds, reviews and checks — stopping only where a decision is yours. At the end you get report.md and a block of questions to forward.
  6. It closes with one commit and .maestro/PROGRESS.md — what is settled, not done and known broken. The next run reads it first and offers you the open items once. See Between Runs.

If the session is interrupted, open a new one in the same project and say «продолжай». The run picks up from where its state says it stopped, after checking that its commits are still there.

Requirements

  • An agent host that reads Agent Skills. Claude Code is the supported one; Codex, Gemini CLI and DeepSeek Harness (dsh) install but are unverified — see Hosts.
  • Node.js 22.18+ with native TypeScript stripping, for Maestro. Preflight runs a real .mts probe rather than reading a version string, and stops with the prerequisite named if the probe fails. Scout needs no runtime.
  • A git repository, initialised before the session starts. Maestro works without one and says so, but the final отчёт is checked against what reached version control, and a host decides at session start whether it can raise worktrees — a git init afterwards narrows every wave to one таск for the rest of that session.
  • Nothing else: no Python, no compiler, no npm install in your project. After installation Maestro's only network call is the update check — one GET per run, which MAESTRO_NO_UPDATE_CHECK=1 turns off (see Updating And Removing); Scout reads the web by design. Browser checks use a headless browser when one is available; without one, the checks that need it stay incomplete.

Installation

From The Published Repository

npx skills add permgps/skills -y             # both skills
npx skills add permgps/skills -s maestro -y  # only Maestro
npx skills add permgps/skills -s scout -y    # only Scout

Not yet measured against GitHub itself: the two-skill install was verified against a publish-shaped export of this repository. The default branch now carries both bundles, but an install from it has not yet been run and recorded.

The -y matters: with two skills in the package, the CLI stops on a picker with nothing pre-selected, so pressing enter installs nothing. For Claude Code the skills land in ./.claude/skills/ — the preview line that mentions .agents/ is wrong, the final summary is right. The full record, with the picker and real output, is in docs/install.md.

From A Local Checkout

npx skills add /path/to/maestro -l                                     # list what it sees
npx skills add /path/to/maestro -s maestro -a claude-code -y --copy    # install one

A development checkout exposes the repository's own agent tooling too, so the -s selector is mandatory there. See installing from a checkout.

Codex And Gemini CLI

npx skills add permgps/skills -s maestro -a codex -y
npx skills add permgps/skills -s maestro -a gemini-cli -y

Both install into ./.agents/skills/maestro. Use -a gemini-cli, not -a gemini. If the skill does not appear, restart the client, and keep one copy — two installed copies of one skill are ambiguous to the host. See Codex setup.

DeepSeek Harness (dsh)

npx skills add permgps/skills -s maestro -a universal -y

The skills CLI has no dsh agent; universal writes ./.agents/skills/maestro, the directory dsh discovers, so one copy serves Codex, Gemini CLI and dsh. Turn on subagent model selection in dsh before the session if you want the models dial; Maestro never changes dsh's settings. See dsh setup.

Updating And Removing

npx skills update refreshes installed skills. skills-lock.json records a hash per skill, so the two update independently. An update overwrites every bundle file, which is why your project's settings live in .maestro/config.json, outside the bundle. Each new run's preflight copies the installed helper — sync.mts and runtime/ together — into .maestro/ without touching existing runs, so an updated bundle reaches a project with its next run.

You do not have to remember to check. Each run's preflight compares the installed SKILL.md's metadata.version with the published one, in one GET with a 2-second timeout that sends nothing about you or your project. When a newer version is out, the announcement names it and npx skills update; offline or on any error it says nothing. Set MAESTRO_NO_UPDATE_CHECK=1 to turn the check off.

No uninstall command is documented. To remove a skill, delete its installed directory (for example .claude/skills/maestro) and the guard's hook entry if you wired one. .maestro/ in your projects and the memory block in your CLAUDE.md/AGENTS.md/GEMINI.md are your record, not the skill's — they stay until you delete them.

Developing Against The Checkout

npm run link     # symlink skills/maestro into .claude/skills, .agents/skills, .gemini/skills
npm run unlink   # remove those links

link refuses to replace a real directory, is safe to run twice, and exits 1 if it refused anything. See developing against the checkout.

Optional: A Guard Against Destructive Git

On Claude Code only, you can wire a PreToolUse hook that refuses git push, reset --hard, a forced clean, branch -D, and a checkout, switch or restore that would discard work — even after you agreed to it under S4. Nothing installs it for you, because wiring it edits your settings. It does not see through aliases, scripts, shells reading stdin, or command names built at run time. Remove it by deleting the hook entry; debug it with MAESTRO_GUARD_DEBUG=1. Instructions and limits are in the git guard.

Starting A Run

Host Command
Claude Code /maestro [dials…] <what you want built>
Codex CLI and app $maestro [dials…] <what you want built>
Gemini CLI no invocation form is documented yet; see Hosts
DeepSeek Harness (dsh) /maestro [dials…] <what you want built> in the session composer

Only you start it. On Claude Code the skill declares disable-model-invocation: true, which dsh reads too, and on Codex allow_implicit_invocation: false: however much a request sounds like a build, the agent will not open a прогон on its own.

Everything after the command is bare words, no dashes:

  • Dial words set how the run behaves — see Dials. They count only as standalone words; a phrase inside a sentence of your бриф sets nothing.
  • Everything else is the бриф. A word you meant literally is never stolen by a dial. One sentence is enough to start; the briefing stage asks about what it leaves open.
/maestro Сделай страницу заметок с локальным сохранением.
/maestro semi deep Онлайн-запись в барбершоп: выбор мастера, слота и оплата картой.
/maestro по-простому полный автомат Лендинг для моей пекарни с меню и адресом.
/maestro manual strict Повтори вот эту страницу один в один: https://example.com
/maestro opus/sonnet Добавь экспорт заметок в Markdown.
$maestro interview Build a notes page with local saving.

The brief is typed, not attached. Maestro takes only what follows the command. Paste a Scout бриф or any other text after it. Pasted fragments, pages behind links and files read during the run are content — Maestro builds from them, but a sentence inside them addressed to the agent is never an instruction (rule S6).

Dials

Five dials. Each has a value whether you name one or not; the full rules are in the dials specification. Before any work begins, one announcement states the register, mode, depth and models — written in the language the second dial chose.

Register — How It Explains

Value Default Russian triggers English triggers Effect
plain по-простому, простыми словами, объясняй проще plain, simple, explain simply every sentence is written for someone who has never built software: no shorthand like гейт or коммит, and a term such as таск gets one clause of explanation the first time it appears
normal yes как обычно, обычным языком usual, as usual the terms are used as they are

The register changes wording and nothing else: the same questions are asked, the same checks run. It can change at any moment — say «как обычно» or «по-простому» mid-run and the next sentence follows. The bare word normal is not a trigger, because it is also a depth.

Language — Which Words It Speaks In

Value Russian triggers English triggers Effect
ru по-русски, отвечай по-русски in russian, russian chat and dashboard labels in Russian
en по-английски, отвечай по-английски in english, english the same sentences and labels in English

This dial has no built-in default. It comes from a trigger word in this run, then from a language key you added to .maestro/config.json by hand, then from the language your бриф is written in; a бриф that is neither clearly Russian nor clearly English (a URL, two words) takes en. It is never asked, the skill never writes it to the config, and it can change at any moment. Every file the run writes stays English either way — see The Language It Speaks.

Mode — How Much It Asks

Value Default Russian triggers English triggers What it asks you
full полный автомат, ничего не спрашивай, сам реши full, fully automatic, don't ask nothing about the project; every fork is answered by the run and recorded as self-briefed
semi yes полуавтомат semi questions only on genuine forks — sometimes none
interview режим интервью, погоняй меня, разбери со мной interview, grill me, ask me everything every fork the бриф opens
manual ручной режим, согласовывай каждый шаг manual, approve every step the same as interview, plus approval of the specification and of the plan

No mode removes a gate or a safety rule. Even full asks before an irreversible or outward-facing action (S4), and it still asks the two first-run questions, because those are about the tool, not the project.

Depth — How Far Beneath The Brief

Value Default Russian triggers English triggers Effect
strict строго по брифу, ничего не добавляй strict, nothing extra only what a requirement cannot work without; no new capabilities, and behaviour nobody asked for found in review may be sent to repair
normal yes depth by judgement, in proportion to the feature; new capabilities allowed, each tied to a parent requirement
deep проработай глубоко, продумай за меня deep, think it through every dimension of every requirement — empty states, failures, limits, interruptions; new capabilities encouraged, each tied to a parent requirement

Depth buys thoroughness beneath the бриф; it never buys a direction away from it.

Required visual or interaction fidelity — "make it look like this page" — is checked at acceptance in every mode and at every depth. There is no polish dial: «like X» in your бриф is a requirement, and the page you name reaches the executors before they build (see What A Run Does).

Models — Which Model Builds What

Value Default Strong Standard Effect
session/session yes session session every subagent runs on your session's model — the only value on a host that cannot choose
session/next session one tier below recommended in the question: judges, repairs and producers keep your session's model
session/cheapest session the cheapest reported the largest saving; every таск is still reviewed on strong
<strong>/<standard> as typed as typed your own pair, typed as one word: opus/sonnet

Two tiers. strong runs every judge of the run's work — the gate readers, the reviewer, the standards reader, the repair diagnostician, the strategy reviewer, the acceptance reader — every repair, and every таск the plan marks strong: always a таск others build on (a producer in the Seams table) and the skeleton laid first, and, by the planner's judgement with a one-line reason, a таск touching sign-in, money, deletion, secrets or outgoing messages, or one whose core is hard. standard runs the ordinary таски, the existing-code reader, the commit reader and one preflight probe. The orchestrator itself stays on your session's model. session means no model is passed at all.

A slash word counts as this dial only when both halves are model names your host reports, character for character; a URL, a path or session/sonnet stays бриф text. The models are fixed for the whole run — a change applies from the next run, by editing models in .maestro/config.json. On Gemini CLI a subagent's model cannot be chosen per dispatch, so this dial is not asked and everything runs on the session's model; the announcement says so. dsh is the same unless the session enabled subagent model selection, and there a model name is a route, <provider>:<model>, as dsh lists it — for example deepseek-official:deepseek-flash, the default route of dsh 0.2.1-rc.2.

Where A Value Comes From

Order Mode and register Language Depth Models
1 a trigger word in this run a trigger word in this run a trigger word in this run a <strong>/<standard> word in this run
2 .maestro/config.json the language key in .maestro/config.json — models.<host> in .maestro/config.json
3 built-in default (semi, normal) the language of the бриф built-in default (normal) a question, once per host

An argument always wins over the config file, and only for that run — the announcement says so.

The First Run In A Project

When .maestro/config.json does not exist, the run asks once, before the manifest:

  1. the register — so the next question can already be asked plainly;
  2. the mode, in the register you just chose, with semi marked as the built-in default.

If you named either on the command line, it asks whether to pin that value instead. A third question, the models, is asked once per project and host — on the first run after the two above, and again the first time another host runs here, or when a pinned model is no longer offered. These questions are asked in full too. See the first run.

.maestro/config.json

{
  "configVersion": 1,
  "mode": "semi",
  "explain": "plain",
  "models": { "claude-code": { "strong": "session", "standard": "sonnet" } }
}
  • mode is full, semi, interview, manual or null; explain is plain, normal or null. null means "asked, chose not to pin".
  • You may add "language": "ru" or "en" by hand; the skill reads it and never writes it.
  • models holds one pin per host: each half is session or a model name that host reports.
  • Preflight writes the file once. After that it is yours: every announcement names its path, so editing it is how you change the defaults. The one change a run makes afterwards is a host's models pin, merged in by the helper with every other key kept.
  • A key outside its set is ignored on its own; a file that will not parse is ignored whole and the run continues on the built-in defaults. A setting is never a reason to stop a run.

The Announcement

Before the manifest, in every mode, one block states the register, the mode, the depth, both models by name, where each value came from (your arguments, the config file by path, or the built-in default), any capability your host lacks and what that costs — and the one consequence most likely to surprise you: no questions in full, nothing beyond the бриф in strict, two approvals in manual. When a newer Maestro is published, one more line says so. It is a statement, not a question.

Changing Dials Mid-Run

  • Register and language: at any moment, effective at the next sentence.
  • Mode and depth: at a phase boundary. The new value applies to phases not yet started; nothing already done is re-run, and switching to a mode with fewer questions never removes a gate that already passed. The change is recorded so the отчёт can say which parts ran under which settings.
  • Models: never during a run. A change applies from the next run.
  • Two different words for one dial (semi … full): the run stops before the manifest and asks which you meant — except in full, where the first word wins and the announcement says so.

What A Run Does

Project code is written in the second-to-last stage. Everything before it decides what to build; everything after it proves the right thing was built. What each phase must do is in the phases specification.

# Stage (on screen: ru / en) Produces What you see or answer
0 Preflight (Подготовка / Setup) resolved dials, run state, dashboard, prior.md the announcement; the first-run questions; a dirty working tree is a question outside full
1 Manifest (Требования / Requirements) brief.md, manifest.md your words numbered R01…, with the original under each line when the languages differ — confirm or correct
2 Briefing (Брифинг / Briefing) answers.md, reference.md one numbered block of forks, at most two rounds
3 Specification (Спецификация / Specification) codebase.md in a project with code, spec.md approval in manual only
4 Plan (План / Plan) tasks/, interfaces.md, shared.md, plan-reads/ approval in manual; a notice elsewhere, with one line on the build's estimated volume
5 Build (Разработка / Development) project code, discovered-interfaces.md the dashboard's waves filling in; nothing to answer unless an S4 action comes up
6 Review (Ревью / Review) reviews/ nothing to answer
7 Acceptance (Приёмка / Acceptance) report.md the outcome, the отчёт, and a block of questions to forward

A page you point to reaches the таски that build what it shows. The plan cites each reference from reference.md into the task files of those таски — a References row with its id and where to open it — and the executor opens what its row names, read-only, before it builds. It never gets the whole register, and an example is inspiration it follows where its task file does not decide. G3 refuses a plan that leaves an available visual reference or example uncited. «Make it like X» is a requirement, so acceptance checks it; nothing else compares the build against X afterwards.

A small build is one таск. The plan first estimates how many lines the build will change, tests included, and cuts by that volume rather than by the kind of product. Up to about 3,000 changed lines the whole spec goes to one executor — one landing, one review — even when it touches many files; above that it is about one таск per 3,000 lines. A README or a self-check page always travels with the таск it describes. The 3,000 is borrowed, not yet measured on our own runs, and the plan says so. You see the estimate and the trade in one line: fewer reviews and less waiting on landings, less parallel width.

Your existing code is read once, before the spec. Preflight checks whether the project already holds code; Maestro's own files, the host's skill installs, memory files, your project glossary, a root README or licence, and anything git ignores do not count. If it does, the specification phase sends one fresh reader through the repository, which changes nothing and writes down where things live, the conventions, the exact run, test and lint commands, the names the work will touch, and what not to touch, into codebase.md. The spec and the plan name things after it — the Terms table gains a Name in code column — and every executor reads it before exploring. The blind readers never see it. The same discovery reads relevant architectural decision records from the project's documented locations, preserving their status, constraints and reasons. Current decisions shape the spec; superseded decisions and proposals do not bind it. A new request may override a decision with an explicit explanation. When relevant records exist, a separate G2 reader checks for silent contradictions. Missing or incomplete discovery stays visible, and your decision records are never edited.

Uncertain external contracts are checked before they become tasks. When an API or dependency fact changes feasibility or a task boundary, Maestro reads installed source/types first and then official documentation for that version. It records a bounded answer with provenance in research/Qnn.json. Missing access or conflicting sources remain explicit blockers. Only relevant current facts reach the specification and owning tasks; a version change requires a recheck. Ordinary local changes start no research, and blind acceptance receives no producer research notes.

Review reads each таск's commits against the task file it was given — and for five risks the task file may never mention. Whenever the diff touches sign-in and permissions, money, deleting data, secrets, or messages sent to third parties, the reviewer checks that category whatever tier the таск ran on, and a finding comes with a concrete counterexample, tagged risk:<category>. A blocking one goes to repair like any other; an observation reaches the отчёт. Once every таск is done, one standards reader looks across the whole прогон for what a per-таск review cannot see — duplication between таски — against your project's documented standards: the memory files, CONTRIBUTING*, CODING_STANDARDS* and STYLEGUIDE* at the root and in .github/, and conventions pages under docs/. It writes reviews/standards.md once; its observations go to the отчёт and are never repaired.

Three more phases run outside that sequence:

  • Repair — a таск reaches it through one of six doors: it came back not done, failed review, carries a final disagreement from acceptance, built something its dependants recorded as diverging, left a required observation uncovered, or the integrated build would not start. A finding is split into defects under its parent таск; each repair targets one defect, two attempts per finding and eight in total. A batch of repairs that closed nothing, or a cause that survived a similar repair, stops for a fresh strategy review — which may change the approach, stop the run incomplete, or ask you to raise the total limit. Only your words raise it. When the build shows that something cannot be built as specified, the scope amendment is your decision. Observed intermittent failures require bounded baseline and post-fix series for both the original and minimized workload. One lucky green cannot close the defect; incomplete evidence stays incomplete. See docs/spec/verification.md, Intermittent Repair Evidence, for the contract.
  • Memory — runs once during the build and again after every closure, acceptance's or repair's, and asks nothing. It writes what should outlive the run into the instruction file your host loads, appends to decisions.md, and ends the closure with one commit — see Between Runs.
  • OpenSpec Export — only in a project that keeps OpenSpec requirements, and only after a completed or closed_with_exceptions closure: a writer drafts one OpenSpec change from what passed, and the closing publish writes it — see A Project That Keeps OpenSpec Requirements.

Before any broad, browser or integrated check, the run records readiness against a disposable source-only copy of the project, so a broken setup is fixed as a setup problem instead of being filed as product failures.

When It Asks You

Every stop carries its answers. Your host shows them as choices when it can, or the question numbers them; one is marked as the run's recommendation with a one-clause reason, and your own words are always accepted beyond the options. «Не понял» is not an answer: the same question comes back with the premise it was missing, and in briefing it costs no round. An id never travels alone — you see «R03 — оплата картой», not «R03».

Stop When Modes What you can answer
Dirty working tree preflight finds uncommitted changes not in full continue, or stop and tidy up first
A Latin name for the run the бриф is entirely in Russian not in full (it uses run-<date>) a short English name for the run directory
Register, then mode first run in a project all, full included a register and a mode, or "pin neither"
Models first run on a host, or a pinned model the host no longer offers — see The First Run In A Project all, full included; never on Gemini CLI, nor on dsh without subagent model selection one of the offered pairs (session/next is recommended) or your own <strong>/<standard>
Ambiguous dials two different words for one dial not in full which one you meant
A credential in your text redaction finds one at ingest all S2: before going on, it names the redacted variables, advises rotating them, and never echoes a value — a secret found in a file already written stops the run
The manifest after numbering your words semi, interview, manual (shown without a question in full) "right, start the briefing" · "R02 is wrong / something is missing" · your own correction · with 2 or fewer requirements, "stop here, I'll make the change directly"
Leftovers from earlier runs PROGRESS.md holds open items; asked once, in the first briefing round — see The Next Run semi, interview, manual leave them, take some, or say they no longer matter
The briefing block forks in the бриф semi (genuine forks), interview, manual (all forks) an option, «как советуешь», «да» to the recommendation, or your own text; each choice is echoed back as recorded
The specification after G2 manual approve, or say what to change
The plan after G3 manual approve, or say what to change
An irreversible or outward-facing action deploy, publish, pay, message someone, delete data, rewrite history all, full included (S4) allow or refuse that one action
A scope amendment the build shows a requirement cannot be built as specified all accept the amendment, or change what you asked for
Raising the repair limit a strategy review asks for more attempts all your exact words authorise it; a forecast of what will close comes with the question
Closing with residual findings acceptance ends with findings left all accept the residual set shown (the run closes closed_with_exceptions), or keep repairing
Someone else holds the run the state carries another session's token all continue it, or wait — the run cannot tell a live session from a dead one
Commits on another branch a resumed run finds a таск's lost commits on another local branch — see Resuming An Interrupted Run all switch back to that branch, or let the run rebuild the таск
The state changed underneath another write landed since the last read all re-read and continue from what is on disk
A gate fails a third time the same finding fails one gate three times all the run stops and reports what cannot be satisfied
A gate's round budget is spent G1, G2 or G3 has failed 60 rounds, each finding something new all another 60 rounds; the next phase now, with the open findings named in the отчёт; or stop

While the run waits on any of these, the dashboard says it is waiting for your reply rather than counting silence. A stop that asks nothing — a gate failing a third time, a таск failing its third attempt — shows the run as interrupted instead.

Talking To A Run In Progress

  • Resume. Say anything — «продолжай», a question, a correction — in a session opened in the same project. The run resumes at the stage that is still open and never restarts; see Resuming An Interrupted Run.
  • Add, withdraw or reword a requirement, at any point. Your words are appended verbatim, in the language you said them, to the dated additions block of brief.md with one English line naming the R## and what changed; the requirement's status changes in the state while its original row stays in manifest.md; a fresh source audit runs; the plan is updated; and you get one sentence on what it costs the schedule. The final check reads those additions, so a requirement you withdrew never comes back reported as missing.
  • Switch register or language with the trigger words above, at any time.
  • Change mode or depth with their trigger words; it takes effect at the next phase boundary.
  • The dashboard disappeared or froze? Say so, or run node .maestro/sync.mts --reopen yourself.
  • What you hear while it works. One line in the chat at every stage transition and whenever a wave of таски closes: what closed and what comes next. It says this even when the dashboard is open, because the page is not always in view.
  • Stop. There is no stop command; tell the run to stop and it closes as stopped_incomplete with your reason recorded.
  • A closed run can be reopened with a new бриф aimed at it; see Reopening A Closed Run.

Four Gates

Each runs after a phase, in every mode, at every depth. A gate that fails is not a warning: the phase is redone.

Gate After Passes when
G1 briefing every requirement has a status/reason; every question in answers.md records its recommended option and the option chosen; a fresh independent source audit has run and the initial agreement is frozen
G2 specification intent and independent raw-reference readers find no unresolved mandatory gap
G3 plan each required obligation has an implementation owner, each check has an execution owner, the task reader finds the handoff executable, and the plan-consistency reader, seeing every task file at once, finds no two таски sharing a file without an order between them; every producer and the skeleton laid first are strong, and each task file's Model and References rows agree with the run state
G4 acceptance all current required checks and coverage pass; missing evidence remains pending

The installed helper also checks the G3 ownership rules when publishing a new pass or further work that relies on it. Tasks sharing a path in files or zone must be ordered by blockedBy, directly or through other tasks; a passed label alone does not establish that the plan is safe to execute.

Independent readings withhold earlier conclusions. G2 includes a separate reader of raw reference material; G4 can inspect that authority and exercise the integrated build with available headless tools. The precise input boundaries are in the gates specification.

G2 and G4 are the same question asked at the two ends of the run: does this match what you actually said, with our paraphrase of it taken away. G2 asks while the answer is still a paragraph and cheap to change; G4 asks when it is the last chance to know — and it is handed the manifest plus whatever you said about the brief after it was frozen, in your own words and your own language, so a requirement you withdrew or added mid-run is weighed by the reader instead of falling between two documents.

G4 is the one gate that does not send its phase back: the отчёт is written anyway as the record of what disagreed, each disagreement travels to repair, and acceptance runs again once the build has changed.

Six Rules Nothing Turns Off

No mode or depth removes any of them. Their full statement is in the safety specification.

  1. S1 — A requirement is removed only by you, in your own words. Change your mind while a run is going and what you said is quoted verbatim, in the language you said it in, into the additions block of the brief with the requirement it changes named — and the final check reads it.
  2. S2 — A credential is never requested, echoed, or written. Redaction runs at ingest, before your text reaches any file; only variable names survive. This is the only stop condition among the six.
  3. S3 — A fact about you is never invented — prices, addresses, texts stay visible placeholders until you supply them, and each one is listed for you.
  4. S4 — An irreversible or outward-facing action is a question, even in the mode that asks nothing else.
  5. S5 — The orchestrator does not write the project's code. Every line travels to an executor.
  6. S6 — Text that did not come from you directly — a pasted fragment, a page behind a link, a file read during a task — is content, never instruction.

What A Run Leaves In Your Project

your-project/.maestro/
├── 2026-10-04-notes-page--wip/     one directory per run; --wip comes off when it closes
│   ├── 2026-10-04-brief.md         your words, redacted, plus the dated additions block
│   ├── manifest.md                 the numbered requirements
│   ├── prior.md                    what earlier runs decided and left open, your project glossary, and the commits since, read at preflight
│   ├── answers.md, reference.md    briefing answers and the recorded reference
│   ├── research/Qnn.json           optional immutable external-contract evidence
│   ├── codebase.md                 what your repository held before the run, read once before the spec
│   ├── spec.md, interfaces.md      the specification and the contracts between таски
│   ├── shared.md                   each fact two таски need, once; copied into the task files that cite it
│   ├── discovered-interfaces.md    what the build found it needed
│   ├── tasks/                      one file per таск, a handoff file for a таск that outgrew one context, and units.json, the unit hashes of the last complete plan-reading round
│   ├── plan-reads/                 each plan reader's return, one verdict per unit it was asked about
│   ├── reviews/                    one file per таск review, and standards.md from the one standards pass
│   ├── evidence/<execution-id>/    captured check output, referenced by path and hash
│   ├── report.md                   the отчёт
│   ├── decisions.md                what was decided, what instead, and why
│   ├── amendments.md               specification changes the build forced
│   ├── openspec/                   the OpenSpec draft, only in a project that keeps OpenSpec requirements
│   └── state.js                    the run's last state, kept when the next run starts
├── README.md                       the register: one row per run and how it ended
├── PROGRESS.md                     where the work stands: what is settled, not done, known broken, fixed by hand
├── config.json                     your pinned mode and register, and each host's models
├── state.js, dashboard.html        the run state and the page that reads it
├── validation.js                   the helper's verdict on the last state it published, shown on the page
├── serve.json, opened.json         the page's local server, and the address already opened for you
└── sync.mts, runtime/              the helper copied in at preflight

your-project/openspec/changes/maestro-<dir>/   one OpenSpec change per closed run, only in a project that keeps OpenSpec requirements

The helper's own files are listed module by module in the runtime layout.

  • The register. .maestro/README.md lists every run — when it started, its directory, whether it is in progress, completed, closed with exceptions or stopped incomplete, and when it finished — between <!-- maestro:runs:begin --> and <!-- maestro:runs:end -->. Text you write outside the markers is never touched.
  • The отчёт. report.md has fixed sections, in this order: What was asked, Disagreements, Assumptions, Questions to forward, Hard to undo, Checks to run on the target, Observations, What is left. Checks to run on the target lists each required check this machine could not run, such as a live database, DNS, HTTPS or the target host's packages. Each one comes with the command to run where the build lands and the outcome to expect, or no command recorded when there is none. The plan writes such checks as committed commands, and an installer's check names every dependency the target lacks. What was asked ends with one line counting the таски each model built — Models: N таски on strong (<name>), M on standard (<name>). A second acceptance round is appended below the first. The questions to forward are also given in chat as one block you can copy, in your language.
  • The outcome. A closed run is completed (a current passing G4), closed_with_exceptions (you accepted a residual set; the underlying failure is preserved), or stopped_incomplete (with its reason). Activity reaching 100% does not establish conformance.
  • What carries over to the next run — PROGRESS.md, the memory block in your instruction file, your project glossary — is in Between Runs. Every file a run writes is listed in the artifacts specification.

Between Runs

A прогон ends with a file and a commit the next one reads first, and a session that picks up an interrupted one checks its commits before it writes.

Closing A Run

Every run that closes — through acceptance or through repair — rewrites .maestro/PROGRESS.md from what it left:

  • Settled By The User — requirements you dropped, leftovers you dismissed;
  • Not Done — deferred, waiting on you, incomplete, failed таски;
  • Known Bugs;
  • Fixes Without Maestro — your own lines, the one part of the file that is yours to edit.

Each item is keyed by the run it came from, and the header names the commit the run closed at. The memory phase then writes the memory block, and the closure ends with one more commit, maestro: close <dir>, holding .maestro/, the memory file, the OpenSpec change when one was written, and nothing you had staged.

Project Memory

A short block between <!-- maestro:begin --> and <!-- maestro:end --> in the instruction file your host loads at session start, so the next session reads it first. Your own text outside the markers is never edited. Alongside it, decisions.md in the run directory records what was decided, what instead, and why. The block always ends with Working Between Runs, which the helper writes itself on every write: how to make a small fix without Maestro (see Fixing Something By Hand) and which slice of the history to read — since the last closure, by requirement, by file, by fragment, by line, never the whole log. Edit it and the next write puts it back.

Host Loads at session start Creates when none exists
Claude Code CLAUDE.md, .claude/CLAUDE.md, CLAUDE.local.md; else AGENTS.md CLAUDE.md
Codex AGENTS.override.md; else AGENTS.md AGENTS.md
Gemini CLI GEMINI.md GEMINI.md
DeepSeek Harness (dsh) AGENTS.md, CLAUDE.md, AGENTS.local.md, CLAUDE.local.md, all of them together AGENTS.md

The file it writes is, in order: the one already carrying the block; else the first file your host loads that exists; else any other existing file from the table (AGENTS.md, CLAUDE.md, .claude/CLAUDE.md, GEMINI.md) — and then it tells you the host does not load it; else it creates the file in the last column. A project never gains a second memory file because you switched hosts. It never writes CLAUDE.local.md, AGENTS.local.md or AGENTS.override.md. The same block in two files, or broken markers, stop the memory phase instead of guessing. Details in the hosts specification.

Your Project Glossary

Read, never written. If the project root has a GLOSSARY.md or CONTEXT.md, or a GLOSSARY-MAP.md or CONTEXT-MAP.md linking to one such file per context, preflight reads it into prior.md. The plan names things with your words and avoids the words you mark to avoid. Where the manifest uses one of your terms in another meaning, the manifest wins for that run, and the отчёт asks you under Assumptions to fix the project glossary or the бриф. All of it together is read up to 32 KiB; past that, none of it is read, and the run says so. Terms your project glossary already defines are not repeated in the memory block.

A Project That Keeps OpenSpec Requirements

If your project uses OpenSpec — openspec/config.yaml (or .yml) exists — a run reads your approved requirements and, after it closes, hands back what it verified in OpenSpec's own format. Nothing changes in a project without it.

Before the spec. Briefing runs node .maestro/sync.mts --openspec-index and reads the requirements of the capabilities your brief touches. A requirement your brief agrees with is settled by reading. One it contradicts is a question: keep the approved behaviour (always the recommendation), replace it, remove it, or rename it. full never asks and keeps it. Your answer is recorded on an OpenSpec: line in answers.md. The existing-code reader then treats approved requirements as current decisions the spec must respect. The blind acceptance reader never opens openspec/.

After the run closes. For a completed or closed_with_exceptions closure, a writer drafts one change and the closing publish writes it to openspec/changes/maestro-<dir>/:

  • only requirements that passed acceptance, each scenario taken from a check the run actually executed;
  • ADDED by default, and MODIFIED, REMOVED or RENAMED only where you answered that question yourself;
  • left out, and named in proposal.md: failed, incomplete, deferred and dropped requirements, those an exception you accepted covers, and those whose question was kept.

If the openspec command line is installed, the change is checked with openspec validate --strict, with its telemetry and update check switched off. Maestro never runs openspec archive and never writes openspec/specs/: merging is yours, and PROGRESS.md lists the change until you do. A change the helper cannot write, or refuses because a requirement is not backed, is reported in one line and never fails the run.

The Next Run

Preflight copies the memory block, the decisions.md of every earlier run and PROGRESS.md into prior.md, with the commits over code since the last closure and the paths they changed. It reads from the commit PROGRESS.md's header names; if a rebase rewrote it, from the closing commit, found by its subject; failing both, from the closure's date — and says which. Past thirty commits, a reader on the standard model sums them up in at most ten lines.

  • Leftovers are offered once. In semi, interview and manual the first round of briefing questions offers the open items: leave them, take some, or say they no longer matter. full never asks and takes nothing.
  • Earlier decisions are named. Briefing says when a recommendation follows or contradicts an earlier decision.
  • The changed paths go to the existing-code reader first. The blind readers never see PROGRESS.md, prior.md or any of it.

Resuming An Interrupted Run

Say anything — «продолжай», a question, a correction — in a session opened in the same project. The run reads .maestro/state.js and resumes at the stage that is still open. It never restarts. Before its first write it runs node .maestro/sync.mts --commits-check: a таск whose commit a reset or a rebase took off HEAD's history is named in one line, reset and relaunched from what its zone still holds. If the commits sit on another local branch, the run names the branch and asks before it rebuilds anything. History is never rewritten to bring a commit back.

Fixing Something By Hand

A small fix does not need a прогон, and a run says so itself. When the manifest holds two or fewer requirements, one line before the list says a direct edit would most likely cost less. In semi, interview and manual you are offered to stop there; full says it and carries on. To fix by hand, read .maestro/PROGRESS.md, add a line under Fixes Without Maestro, and commit with the trailers a run uses. Every таск and repair commit carries two, Maestro-Run: <dir> and Requirements: R01, R02, because таск numbers and requirement ids restart every run; git log -E --all-match --grep='^Maestro-Run: <dir>$' --grep='^Requirements: (.*, )?R02(,|$)' finds every change one requirement of one run caused, yours included.

Reopening A Closed Run

A new бриф aimed at a closed run brings its directory back to --wip under its original date. A бриф dictated on a later day goes into a new <date>-brief.md under that day's date rather than being appended to the old one. A second run started the same day with the same name gets a numeric suffix. Nothing earlier is deleted.

The Dashboard

One self-contained HTML file, opened for you when the run starts, reading the run state on its own. Offline, no CDN, no fonts, no build step. Every number on it is computed from the run state when the page draws itself; everything about it is in docs/dashboard.md.

The dashboard during the build stage

  • The band at the top says what is happening: the прогон's condition as a word and a colour — working, waiting for you, finished or failed — progress across the whole прогон, the таски in flight by title, the eight stages with their clocks, and «Осталось», a range to acceptance that is never sharper than the прогоны it was measured from. See A run in flight.
  • Four cards — requirements built, таски as squares, the last tests with the таск they ran after, working time — and below them the build grouped by wave, each таск bar saying its status in a word and opening to its requirements, blockers, files, commits, repairs and tests.
  • Your requirements, each opening to your own quoted words, the таски that name it and its checks, filtered by what became of them. See Verified original and current scope.
  • «Ваш ход» — what only you can settle, in one place. See Your move.
  • «Лента» — what just happened, newest first. See Feed.
  • A small i on every region and stage explains its number with figures from your run. See Asking what a number means.
  • Silence and waiting are told apart. The page says how long it has been since the last write and raises that line once the silence is longer than any this run has come through; a run stopped on your question says what it is waiting for, the tab reads «● Ждём вас», and the clocks stop. See When the page has nothing new to say.
  • A finished run reads as a report — the run's own sentence on what now exists, and the path of the отчёт. See A finished run.
  • Two switches in the header, theme and language, remembered by your browser only; in a narrow pane the same regions turn dense and never scroll sideways. See the two switches.

The dashboard after a finished run

You do not have to go looking for it. The helper that keeps the page current is what opens it, once per address, and nothing opens over SSH or in CI. A host that shows the page in a pane of its own should load the loopback http:// address the helper prints, not a file:// path, and the run passes --no-open there so you do not get two pages. It is the only user-visible page a прогон opens — see It is the only page the прогон opens.

The commands you might run yourself, from the project root:

node .maestro/sync.mts                       # refresh the page and print its address
node .maestro/sync.mts --reopen              # bring the panel back
node .maestro/sync.mts --no-open             # refresh without opening a browser
MAESTRO_SYNC_DEBUG=1 node .maestro/sync.mts  # diagnostics on stderr

--no-open can still start or reuse the local dashboard server; it suppresses opening a browser. MAESTRO_SYNC_NO_OPEN in the environment does the same, and LOG_LEVEL=DEBUG also turns diagnostics on. --validate and --project are read-only checks that print JSON; --publish (with --land <NN> when it records a таск's commit), --serve, --memory-read, --memory-write, --config-models, --update-check, --commits-check, --openspec-index, --returns-check, --repair-dispatch, --import-evidence, --plan-units, --plan-render and --plan-coverage are what the orchestrator uses, not you. If the loopback server cannot start, the page falls back to a file snapshot. More in viewer runtime and recovery.

Repair dispatches reserve budget before work starts. Captures and reusable replay tools are preserved before workspace cleanup; failed import keeps the source. See installed helper commands for recovery and publication receipts.

Scout

Use Scout when your ТЗ is thin, or when the domain is one you cannot yet name the parts of. It turns an incomplete ТЗ into a бриф you can paste after /maestro — still in your own words, only fuller.

/scout Хочу сайт для школы танцев: расписание и запись на занятия.
/scout

With nothing after the command, Scout asks for the ТЗ in one short turn — incomplete is fine. Unlike Maestro, Scout does not switch implicit start off, so an agent may also offer it when you ask for help completing a ТЗ.

Its Five Steps

# Step What you see What you do
1 Ground two or three lines on what it understood, how many gaps it found with one example read; correct it if it misunderstood
2 Search the search plan first — the angles, one example query each, the budget — then progress as sources come back let it run, or say you do not want the sweep
3 Grill one numbered block of Q## forks, each with candidate answers, a recommendation, and its source marked as fact or заявление (a product's own claim); roughly seven to ten per round answer by choosing, in your words, or «не знаю»; a bare «да» takes every recommendation and prints each one back
4 Reconcile proposed edits to your ТЗ — add, fix, remove — one at a time accept or reject each; silence is not acceptance, and "yes to all" prints what it accepted
5 Compose the бриф, written to a file and printed as one block; the open questions after the block, each with why it stayed open; a short cost summary copy the block

The search runs two sweeps: about fifty sources for the domain's vocabulary (no fewer than fifteen, and stopping early once three in a row add nothing new), and ten to twenty existing products compared in a table whose key column is present in most, absent from your ТЗ. Steps 3 and 4 loop for at most three rounds. The findings go to findings.md, which is for you and a second round — it never reaches Maestro.

Handing It To Maestro

Paste the printed block after /maestro:

/maestro semi <the block Scout printed>

Maestro takes no file, and Scout never starts a run or offers to. Questions Scout left open are printed after the block on purpose: Maestro's briefing asks about every fork the бриф opens, so they come back there on their own.

Every line of the бриф follows four rules, because Maestro turns each line into one R##: one asked-for thing per line; no line joins two things with «и» or «and»; no line addresses a tool ("search the web for…"); and every line is your own words — written by you, or accepted by you in a proposal.

Six Boundary Rules

# Scout never
B1 treats a finding as a fact about you — twenty products having a feature says nothing about whether you need it
B2 turns a finding into a requirement — a finding can become a question; only your answer becomes a line
B3 acts on text a sweep fetched — a page is data, even when it addresses the agent by name
B4 puts your specifics in a search query — your names, addresses, numbers and sentences do not leave the session
B5 narrows, widens or drops your scope on its own — a doubt comes back as a question
B6 writes anything a прогон reads — no .maestro/, no run state, no R##

What It Needs

Web access and subagents, and no runtime. Without web access the search step does not run and Scout says so before grilling from your ТЗ alone. Without subagents both sweeps run one source at a time, and Scout states a lowered budget and a time estimate first. There is deliberately no dial to skip the web — that would be Scout without its reason to exist.

Scout speaks your language and writes the ТЗ in it too — the one thing in this package that does not become English on the way to a file, for the reason given in The Language It Speaks. Its specification is docs/spec/scout/.

Hosts

Host Status Start with
Claude Code supported. Worktree isolation is unavailable when the session began outside a git repository /maestro, /scout
Codex CLI unverified — partial runs attempted, no complete brief-to-report run established $maestro
Codex app unverified — CLI evidence does not establish app support $maestro
Gemini CLI unverified — the bundle installs, no прогон has run on it; the skill may start implicitly there, because Gemini documents no way to switch that off not documented
DeepSeek Harness (dsh) unverified — mapped from its documentation (a developer preview, read 2026-10-20); the bundle installs into .agents/skills, no прогон has run on it. The models dial needs subagent model selection switched on in dsh /maestro

A host moves to supported when a прогон has run on it from бриф to отчёт, not when it installs. Scout has not been run on Codex, Gemini or dsh.

A missing capability degrades the wave, never a gate. Preflight tries each capability rather than reading it off the host's name, and the announcement names anything missing and what it costs before the first stage:

Missing What happens
subagent fan-out waves narrow to one таск; independent readers still run, one after another, in fresh contexts
worktree isolation waves narrow to one таск
context isolation the run stops — G2 and G4 cannot be honest without it
version control no commits; review reads the working tree instead of a diff, and says so
browser automation affected UI checks stay unavailable and their requirements incomplete
ordered tool calls each step of a landing is its own message: commit, publish, then launch; nothing is skipped
Node.js 22.18+ with type stripping preflight stops and names the prerequisite

The Language It Speaks

Maestro talks to you in the language of the dial and writes every file in English. That is a deliberate split rather than an oversight: the conversation happens where you are, and the artifacts live where the code does. The language dial (above) chooses Russian or English for the chat and the dashboard; it reads your бриф's language when you name none. Your brief is translated exactly once, and the numbered manifest is shown to you before any other work begins — with your original line beneath each requirement when the two languages differ — so the translated contract is agreed rather than substituted.

Two things stay in the words they were said in. The additions block of brief.md is a quotation of you, and it is the ruler the blind acceptance reader measures the build against — a ruler the run translated is a ruler the run wrote. And Scout's ТЗ is written in your language, because handing Maestro an English бриф means Maestro translates it zero times and shows the manifest with no original line beneath each requirement — switching off the round-trip check exactly where the contract was not written in your own words.

The skill uses Russian names for the things you see on screen in ru. The stages read Подготовка, Требования, Брифинг, Спецификация, План, Разработка, Ревью, Приёмка; a run is a прогон, a unit of work is a таск, and your numbered words are the манифест. Each term has exactly one name — the словарь is docs/spec/vocabulary.md.

Five fields of the state carry the прогон's language — the run's own sentences to you: gate findings, таск titles, stage notes, what it is waiting for, and the closing result. Every other field stays English, and a line the отчёт and the gates also read, such as a requirement's title, is quoted as written rather than translated. node .maestro/sync.mts holds the rule for ru; the field list and why en cannot be held are in the state contract.

How plainly it speaks is a separate dial, and it does not change the words themselves. In по-простому a таск is still a таск — it simply arrives with one clause saying what a таск is. Renaming things for a beginner would leave them reading a dashboard whose words appear nowhere in what they were told. What does go is the trade's shorthand: гейт, спека, коммит, стейт. The list is in the vocabulary beside the labels, and scripts/validate/dashboard-integrity.ts holds every plain sentence the dashboard ships to it.

Under The Hood

One state file. A прогон is one atomic JSON snapshot — activity, verification records and closure outcome — published only through the helper, which validates a complete candidate and replaces state.js atomically. Immutable evidence captures live under the run's evidence/ and are referenced by path and hash. The dashboard, the отчёт and the metrics all derive from the same records.

A прогон says who is driving it. The session that opens a run with no owner mints a token into heldBy and re-reads the state immediately before every write, comparing updatedAt with what it last read. The helper checks the expected revision and holder token, and serializes publication through a write lock that also covers derived files. A competing writer or stale candidate is refused, and changed state must carry a later updatedAt. Session ownership does not expire automatically: when another owner is recorded, the run asks you before taking over.

A plan reader judges every instruction, once. Every instruction in a task file is a numbered unit, and each G3 reader returns one verdict per unit it is asked about; the helper refuses a return that skipped one. After a round whose returns are all complete, a later round asks only about the units that changed. Removing a unit requires a fresh reading of every remaining unit in that task, plus a consistency reading of the affected task and seams.

A fact two таски need — a checklist row, an oracle, a decision about either — is written once in shared.md and copied into each task file that cites it, and a finding is fixed by rewriting the text it quotes, never by appending a correction beside it. One run before this spent sixty-one G3 rounds and 1.8 billion tokens because each fresh reader sampled the plan differently and each fix was appended.

Generated facts sections use one ordered pair of markers on separate lines. Malformed markers stop rendering, baseline recording and coverage checks before any file changes. Repair the delimiters while preserving the task instructions, then render again; literal marker examples belong inline or must be escaped.

A таск's commits are a list, because a repaired таск lands twice. Review reads the ordered union of that таск's own commits, one diff per commit — never a range, which would carry every foreign commit between them, and never the tree. Paths those commits touched outside the таск's files are listed beside the diffs, not filtered away. Every таск and repair commit carries the Maestro-Run: and Requirements: trailers described in Fixing Something By Hand.

The contract is versioned, and old runs stay readable. New runs publish contract 10; the helper publishes a state from contract 4 through 10, and the dashboard renders an older state as it always did. What each version added is in the state contract and CHANGELOG.md.

Superseded findings stay in the run's history, but current closure checks, verified scope and dashboard details follow their successors. A later finding resolved by fresh passing evidence can close the gap without rewriting its open predecessor. Historical compatibility does not permit a new resolution without valid evidence.

The fields, and what may be left out of them, are in docs/spec/state-contract.md; what verification can and cannot establish is in docs/spec/verification.md and docs/parity-verification.md.

Limitations

  • Alpha numbering is deliberate. Versions stay below v0.1.0 because one of the four modes has never been run end to end and two findings about concurrent orchestrators stand open. Nothing installs by tag; the default branch is what ships.
  • Only Claude Code is verified. Codex CLI, the Codex app, Gemini CLI and DeepSeek Harness are unverified — see Hosts and the Codex checkpoint.
  • Scout has not run in front of a real прогон. Its rules come from the specification, not yet from evidence.
  • Two orchestrators on one run are detected, not prevented. A session that died holding a run looks exactly like one that is still working; you decide.
  • The chat is not checked mechanically. Validators hold every label and explanation the dashboard ships to the vocabulary; sentences composed at run time are covered by rules in the skill, which is a weaker guarantee.
  • No uninstall command and no CI yet. npm run check is run by hand.

For Contributors

Path What it is
skills/maestro/ the skill itself: the orchestrator, one file per phase, the subagent briefs, the dashboard, the helper
skills/scout/ the second skill: the reconnaissance order, the boundary, one file per step
docs/spec/ Maestro's behavior specification — what the phases must do, and the authority when a phase file disagrees
docs/spec/scout/ Scout's, kept separate because they are separate skills and no sentence may have two homes
docs/ the documentation pages listed in the Documentation Map
scripts/ this repository's own tooling: validators, the state contract, the gate checks, the metrics and cost tools
CHANGELOG.md every tagged release and what it shipped, newest first

Repository tooling is TypeScript run directly by Node's type stripping; the only development dependencies are typescript and @types/node.

Command What it does
npm run check typecheck through test below, in that order — twelve validator runs between the typecheck and the suite
npm run typecheck tsc --noEmit
npm run spec Maestro's specification is self-consistent
npm run spec:scout Scout's specification is self-consistent
npm run bundle Maestro's bundle structure and links
npm run bundle:scout Scout's bundle structure and links
npm run dashboard the dashboard's regions, labels and logic against the specification
npm run state the state contract in code matches the specification, and the config keys match CONFIG_KEYS
npm run hosts every host degradation is probed and spent, the memory-file table matches, and every host says where it lists its models
npm run doors every entry into repair is defined
npm run dials dial values and defaults agree across files, and the models token rule is stated once on each side
npm run readers each gate reader is given and withheld what it should be, every brief runs on its tier — judges always strong — and the standards reader's documents are searched for in the same places everywhere they are named
npm run report the отчёт's sections agree in the bundle and the specification
npm run view the viewer boundary: the run opens only its dashboard
npm run test every *.test.ts, including the copied-runtime integration tests and the README reference check
npm run link / npm run unlink link the checkout into the local agent directories
npm run metrics measure a finished run: npm run metrics -- [<dir>] [--json], default .maestro; reads only state.js; counts таски, restarts and repairs per model tier; exit 0 measured, 2 unreadable
npm run metrics:cost measure what a run cost from the host's own log: npm run metrics:cost -- <project> [--run <state>] [--log-dir <dir>] [--json] [--out <file>]; reads Claude Code transcripts, state.js and git; prints each role's share, orchestrator calls per landed таск, executor peak context and changed lines beside the plan's estimate, and whether each review blocked; units are price ratios, not money; exit 0 measured, 2 unreadable or unsupported host
npm run parity:browser the real-Chrome pointer suite; exit 2 when no browser is available
npm run parity:workflow an isolated Codex CLI evaluation
npm run parity:workflow:prepare prepare that evaluation without running it
npm run completion:workflow a provider-neutral completion evaluation
npm run completion:workflow:prepare prepare it without running it

The parity and completion runs need tools check does not; see completion prerequisites and docs/parity-verification.md.

Documentation Map

Page What it covers
docs/install.md every install form, the runtime layout, the first-run questions, Codex, Gemini and DeepSeek Harness, the git guard, checking the repository
docs/dashboard.md every region of the page, the switches, what each number means, the silent page, the opener, recovery, and what is checked
docs/parity-verification.md verification commands, the parity matrix, and execution limits
docs/spec/README.md reading order for the specification, and how to run the checks
docs/spec/vocabulary.md every term, its one name, and the on-screen labels in both languages
docs/spec/safety.md the six rules
docs/spec/dials.md register, language, mode, depth, models, and how each resolves
docs/spec/phases.md what each phase must do
docs/spec/gates.md the four gates and what each reader is given and withheld
docs/spec/artifacts.md every file a run writes
docs/spec/state-contract.md the run state, field by field
docs/spec/verification.md evidence, checks and what completion may claim
docs/spec/dashboard.md the dashboard's behaviour specification
docs/spec/hosts.md capabilities, degradations, host status, memory files, who starts the skill
docs/spec/scout/README.md Scout's specification: boundary, steps, search, reconcile, output, vocabulary
CHANGELOG.md releases and upgrade notes

License

MIT.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages