Skip to content

Releases: Atri10/executor

2.1.1

Choose a tag to compare

@Atri10 Atri10 released this 05 Nov 15:02
b039c83

Patch release — packaging only, no engine behavior changes. The repo is now a Claude Code plugin marketplace.

Added

  • .claude-plugin/ manifests — install from inside Claude Code:
    /plugin marketplace add Atri10/executor
    /plugin install executor@executor
    
  • commands/ — seven slash commands for the verbs a human types:
    /executor:new, /executor:next, /executor:status, /executor:decide,
    /executor:check, /executor:doctor, /executor:change. Worker traffic
    (ingest, repair dispatches) stays inside the skills.
  • All 13 skills load unchanged; the engine stays bundled inside the
    executor skill, so Python 3.11+ remains the only requirement.

Verified

  • claude plugin validate . clean; sync_engine.py --check in sync;
    validate_skills.py clean.
  • 163 tests across test_cli / test_store / test_layout_v2 green
    (version-sensitive modules).
  • Engine logic unchanged from v2.1.0: full 828-test suite measured at
    100.00% branch coverage on that release.

2.1.0

Choose a tag to compare

@Atri10 Atri10 released this 22 Oct 12:22

An evidence-first audit of the engine against a live 325-event initiative,
and the three structural changes it demanded. Every defect in the register
carries the file and line, the observed behaviour, the command that
reproduces it, and the test that now covers it.

What was wrong

  • A worker could latch a halt while executor decide refused one.
  • A commit on an unrelated branch satisfied "the work advanced" — the
    ancestry check never required the dispatch base to be a descendant of the
    reported head.
  • The review phase was inert: the whole-plan final audit two documents
    promised never dispatched.
  • No projection was reproducible (wall-clock stamps), so a drift check
    and a byte-idempotent migration were both impossible.
  • state.json was 2.76 MB and rewritten whole on every event — 469.7 MB
    written over 320 projections, because the fold carried every artifact body.
  • A constraint could not change mid-run, and the fold had no task →
    requirement link at all, so a blast radius could only have been prose.
  • 37 prose/code divergences; the ones needing code are in the register, the
    rest are prose corrections in the same change set.

What shipped

Store layout v2 — a views tree with index.md at its root and one leaf
per plan and per task; plan.json is an index and each task contract is
tasks/<TASK-ID>/task.json in both stores; artifact instances are minted per
kind and an arch may declare components for per-component designs;
slot.json deleted; deterministic projections; the committed index is written
mid-run and verified against a re-render; check also reports a missing
canonical file. The fold cache keeps decisions, not bodies: state.json
2.4 MB → 1.10 MB, bytes written over the run 470 MB → 160 MB
(scripts/measure_store.py prints the curve).

Mid-run change protocol — a journaled, ID-bearing change_request
(executor change <file|->, --list); the engine mints CR-NNNN, computes
the blast radius from fold dependency data (depends_on, cites,
requirement/constraint/criterion ids) with a reported coarse fallback, and
drives a regression lane — revise, re-audit, re-dispatch, re-prove, apply —
that is a pure function of the fold, waits for in-flight dispatches and
pending gates, and is withdrawn by a ruling. change_not_applied verifies the
redraft really carries the change.

Git discipline, enforced — six rules with rejection codes and
clear-the-path hints (descent, base-branch purity, branch ownership, merge
ancestry, merge branch, commit subjects), enforced only for dispatches this
engine minted (rules: v2), so an upgrade never rejects work it inherited.

Command surface — executor change, executor migrate --dry-run|--apply,
a policy: and open-change: line in status, rulings in
views/progress.md, abandoned labelled honestly, sk- keys scanned.

Migration

A store written by 2.0.x is refused by the writer (store_outdated)
rather than half-converted:

executor migrate --dry-run     # every write and removal, touching nothing
executor migrate --apply       # convert, verify, stamp store_version v2

Deterministic and byte-idempotent: a second --apply rewrites identical bytes
and removes nothing. scripts/migrate_layout.py is the same implementation
from the command line.

Evidence

scripts/run_tests.py                     → 828 tests, TOTAL 100.00%
scripts/sync_engine.py --check           → bundled engine: in sync
scripts/validate_skills.py               → skill validation: all clean
scripts/lint-prompt-injection.py skills/ → prompt-injection lint: clean

The reference corpus (a copy; the live store belongs to a sibling project) was
migrated with 139 writes and 13 removals, verified, then re-applied
byte-identically across 658 files; executor check reports chain: ok and
zero store problems.

Breaking changes

  • Store layout: 2.0.x stores must be migrated before the writer accepts
    them (store_outdated names the command).
  • halt is human-only; executor ingest refuses it.
  • merge now requires branch (plan/<PLAN-ID> or initiative/<INIT-ID>)
    and must contain every task head of the plan.
  • slot.json is gone from the grammar; the flat per-round verdict views are
    gone (a task's rounds live in its one view leaf).
  • Payload additions are optional only (task.requirements/constraints,
    report.branch, arch.components, design.component, change_request).

2.0.3

Choose a tag to compare

@Atri10 Atri10 released this 19 Oct 11:31
03d3c97

Patch release: the Windows suite goes green. The v2.0.2 install path was correct on POSIX, but the matrix — and the main-branch run that followed — exposed three failures: --help crashed under the cp1252 pipe encoding, a test tried to execute the launcher as a native program, which Windows cannot do, and the bundle check trusted a whole-second timestamp cache instead of the bytes.

If you are on v2.0.2 with Windows, upgrade: executor --help and executor new with a non-Latin title can crash or the suite can flake there.

Fixed

  • CLI output is UTF-8 even when Windows redirects it. A pipe inherits the locale code page, and print(__doc__) raised UnicodeEncodeError on the help arrow before it could print a line. main now reconfigures stdout and stderr where the stream supports it, so help text, JSON with ensure_ascii=False, and error messages survive a redirect on a non-UTF-8 Windows console.
  • The bundle check compares bytes, not cached metadata. filecmp.cmp keys its verdict on int(st_mtime), so a drift check that followed a same-second rewrite could report a file stale that had just been synced. scripts/sync_engine.py now compares contents directly, and a regression test pins the same-second case with a forced mtime.
  • The bare-launcher test is POSIX-only. Windows has no exec bit and CreateProcess cannot run a .py file without a registered association. The portable spelling — python3 <skill-base-dir>/scripts/executor — remains the tested, documented form on every platform.

Install

npx skills add Atri10/executor
python3 ~/.agents/skills/executor/scripts/executor --version   # 2.0.3

~/.agents/skills/ is the global install location; use ./.agents/skills/ for a project-local install.

v2.0.2 — An Install Is a Complete Install

Choose a tag to compare

@Atri10 Atri10 released this 19 Oct 10:22
64bf2fe

Patch release: the engine ships with the skill. Installing the skills used to leave executor undefined — the skills call a bare command that only existed for someone who had cloned the repository and exported PYTHONPATH. Now the engine travels inside the router skill and a launcher beside it resolves the copy relative to itself, so an install needs no path setup at all.

Fixed — an install is now a complete install

  • The engine ships inside skills/executor/. npx skills add copies a skill directory and nothing outside it, so engine/executor/ — a sibling of skills/ — never reached a user. The package now also lives at skills/executor/scripts/lib/executor/, which the installer copies, and skills/executor/scripts/executor is the launcher the skills name.
  • No PYTHONPATH, no pip, no PATH edit. The launcher resolves scripts/lib/ from __file__, so it works from any project directory. Python 3.11+ is the only requirement; the engine remains standard library only.
  • scripts/sync_engine.py is the one writer of the shipped copy, and --check is a CI gate. engine/executor/ stays the source the suite tests; the bundle is generated, so a hand edit to either side fails test_engine_ships_with_skill.py rather than shipping an engine the repository never tested.
  • A real install is exercised in CI, not just the repository layout: the skill is copied out of the tree, PYTHONPATH is dropped, and the launcher runs from an unrelated directory.

Changed — the documents name the command a reader can run

  • Every skill states the spelling. executor <verb> is defined once in the router and restated at the top of each phase skill, so loading executor-execution directly no longer leaves an agent to guess at an executable that is not on PATH.
  • Engine source citations point inside the skill. The references cited engine/executor/paths.py and schemas.py — paths an installed user does not have. They now cite scripts/lib/executor/, which exists wherever the skill was copied. A test walks the skills tree to keep it that way.
  • The README install section is the install path. The PYTHONPATH step, the one-paste prompt's profile edit, and the python3 -m executor examples are replaced by the launcher; working from a clone is documented separately, where PYTHONPATH is still the honest spelling.
  • CONTRIBUTING.md describes this repository. It documented exec-scan-secrets, validate-skills.sh, test-executor.sh, and a ShellCheck gate — all deleted in the v2 shell-to-Python cutover. The file now names the Python entry points, the 100% branch floor, the bundle rule, and the CI jobs that actually exist.

Install

npx skills add Atri10/executor
python3 ~/.agents/skills/executor/scripts/executor --version   # 2.0.2

~/.agents/skills/ is the global install location; use ./.agents/skills/ for a project-local install.

v2.0.1 — Concordance

Choose a tag to compare

@Atri10 Atri10 released this 16 Oct 11:00
00507b9

Patch release on top of v2.0.0: the documents say what the engine enforces.

Changed

  • The README's merge contract is the slot-free payload ingest actually verifies. MERGE is emitted once every task in the plan is complete; the action names the plan and each task's head commit; ingest checks the plan is known and unmerged, every task complete, and the merge_sha resolves. The old text claimed a minted slot, a respond_to path, a dispatch binding, and a descent check the engine does not perform.
  • The exit-code contract names refusals. A payload refusal exits 2, like usage and engine errors; 1 is a check that found problems — corrected in the README and in cli.py's own docstring.
  • references/branches.md stops claiming a descent check. The merge bullet lists what ingest verifies; "descends from the plan's head" moves to the procedural list, where it is the skill's job.
  • Counts catch up with the code. 48 documented refusal codes (was 37) and 722 tests (was 717), in the README and the 2.0.0 changelog entry; a duplicated changelog heading is gone; the shipped v2 entries are folded under 2.0.0 instead of sitting under Unreleased; the README's CI and store-map rows describe the three-OS matrix and this repo's ignored docs/.

Verified

  • scripts/run_tests.py: 722 passed, 0 failed — 100.00% branch coverage.
  • CI on main: all five checks green — ubuntu, macOS, Windows; skill contract + prompt lint; secret scan (both stores).

Full Changelog: v2.0.0...v2.0.1

New Dawn

Choose a tag to compare

@Atri10 Atri10 released this 16 Oct 08:07

New Dawn

The executor v2 engine becomes the product. A payload is data and the engine renders every document; the shell scripts are gone; the skills speak the v2 protocol; a payload that means nonsense is refused before it lands.

What changed

  • Payloads are data. Sections carry prose, bullets, tables (columns + rows), and code. No string in a payload may carry markdown syntax — a pipe table, a fence, or a heading is notMatch; a row wider than its columns is row_width; a blank value is nonBlank; a section with no shape is empty_section; sections[].id is unique because a reviewer cites it. engine._render_doc is the only writer of document markdown, so the store has exactly one renderer.
  • Contracts are enforced, not hoped for. schemas.py is a closed mini-validator with anchored patterns, back-references tying a task to its plan, numeric bounds pinned by a literal table, named object invariants, and 37 documented refusal codes that test_docs_agreement.py keeps in step with the code in both directions. A new references/rejections.md lists every code with its field and the action that clears it.
  • The store has one writer. The journal is the state — hash-chained, and recomputed by check, which refuses a store edited by hand. Views are projections. A dispatch is answered exactly once. executor decide exists so gate_decision, ruling, and resume carry actor: human; a worker cannot approve its own work.
  • Autonomy is fail-closed. Every phase defaults to deny; every ambiguity — a missing file, an unlisted phase, a typo'd mode — resolves to deny. The pick-class phases and handoff never clear automatically. An auto-cleared gate is journaled as by: "auto", visibly distinct from a human passed.
  • Plans are audited as a set between planning and execution — coverage, seam closure, ordering, constraint propagation, file ownership. Execution cannot start until every plan is clean or a human waives a finding by ruling.
  • Evidence is capability-aware. The verifier records the strongest feasible evidence per criterion, or an explicit unavailable with a named blocker — never a claim. executor status counts every criterion proven / failed / unavailable / unanswered, because a criterion nobody ran is unproven however obviously it must work.
  • Cross-platform for real, not by assertion. CI runs the suite on Ubuntu, macOS and Windows. That matrix earned its place immediately: it found a validator that disagreed with itself about path separators, a store lock whose contended acquire held a descriptor for the OS's own retry window, and a linter whose CRLF handling changed line numbers. All three are fixed, and the tree now carries tests that pin each so they cannot return.

Measured, not claimed

Gate Result
Tests 722 tests, OK
Branch coverage 100.00% — 2200 statements, 926 branches, 0 missed, 0 partial
Mutation schemas.py 260 mutants, 254 caught, 6 equivalent survivors allow-listed with reasons
OS matrix ubuntu, macos, windows — all green
Validators validate_skills.py exit 0 · lint-prompt-injection.py exit 0

Install

npx skills add Atri10/executor
export PYTHONPATH=<clone>/engine
python3 -m executor --version      # 2.0.0

The engine has no runtime dependencies beyond the standard library. The README is the single design document: the protocol, the reasoning behind each invariant, and the flows that drive it.

v0.7.1 — The Store Helpers Stop Inventing Roots

Choose a tag to compare

@Atri10 Atri10 released this 05 Oct 16:30
a1f6b7f

Patch release on top of v0.7.0.

Fixed

  • exec_docs_store / exec_run_store invented a filesystem root outside a repository. Written as echo "$(exec_root)/docs/executor", the command substitution swallowed exec_root's death — the subshell exited, $( ) yielded empty, and echo still succeeded — so the helpers printed /docs/executor and /.executor. Callers then globbed the filesystem root via "$store"/*/INDEX.md. Both helpers now propagate the failure; exec-status refuses with "not inside a git repository" instead of printing a digest that reads like an empty project; exec-step and exec-graph guard their store globs. Found by running the README's own install-verification command in a bare directory — where a fresh install actually runs it.
  • exec-graph did not parse under bash 3.2. A case statement directly inside $( … ) is a syntax error on the stock macOS shell (/bin/bash 3.2), which is what the macos-latest CI runner uses. The case is hoisted into a function; the suite now runs /bin/bash -n over every shipped script as a parse gate, separate from the existing bash-4-construct grep.

Changed

  • Docs describe the scripted write path. The README script table gains exec, exec-dispatch, exec-ladder, exec-seen, exec-heartbeat, exec-prompt, exec-adjudicate, exec-present, exec-status, exec-graph; the task-loop and shape-of-run diagrams use the current verbs; the execution skill's dispatch table is the real nine-column schema with the write path named; the report-status table routes DONE/DONE_WITH_CONCERNS mechanically and hands BLOCKED to the SUPERVISOR instead of the controller.

Verified

  • scripts/test-executor.sh: 145 passed, 0 failed — under bash 5.3 and under /bin/bash 3.2. Four new tests cover the store-root defect class.
  • CI on main: all six jobs green (macOS + Ubuntu).

v0.7.0 — The Scripted Write Path

Choose a tag to compare

@Atri10 Atri10 released this 05 Oct 16:20
7784af7

Every state mutation the controller used to perform by hand is now a script call behind one exec front door. The engine's core claim — the controller holds no state and makes no judgment — now holds on the write path, not just the read path.

The front door

exec            # resume digest: every in-flight run, its next verb, open rows, store drift
exec verbs      # the decision table, generated from the machine-readable registry
exec step       # any exec-* script by name

Added

  • exec-dispatch — one locked act: mints the agent ID, builds the role's input file, marks the ledger, appends the dispatches.md row, renders a bracket-clean prompt.
  • exec-ladder — revive/redispatch rewrites revived-rvN cells and enforces EXEC_MAX_REVIVE itself.
  • exec-seen, exec-heartbeat — the two liveness witnesses that exec-supervise actually consumes.
  • exec-prompt — renders any role template; refuses while a [UPPER_SNAKE] bracket remains unfilled.
  • exec-adjudicate — assembles the adjudication evidence pack mechanically, then dispatches SUPERVISOR. The adjudicated party no longer selects the adjudicator's evidence.
  • exec-present — the fixed-shape gate card for PHASE-GATE; artifact bytes never enter the pump's context.
  • exec-status — one-file resume digest; --write stamps .executor/RESUME.md so a cold agent reorients in one read.
  • exec-graph check — every verb has exactly one actuator row, every ledger file has a script writer, every role template resolves, every ID grammar carries placeholders, every reference resolves. A dangling reference is a FAIL, not a NOTE.
  • exec-step verbs — RUN-START, REVIEW, FIX, CRITIQUE; REPORT narrows to verdict-clean; every emit carries a (wake on …) condition.
  • exec-initiative phase … check — dry-run gate validation that writes nothing.

Fixed

  • REPORT livelock — a report with a reviewer in flight emits WAIT indefinitely instead of three identical REPORTs and an ADJUDICATE loop on a healthy run.
  • Worker status routing — report result: frontmatter routes blocked → ADJUDICATE, needs-context → ASK. A finished worker can no longer silently burn revive rungs.
  • exec_product_exists — crashed BSD/bash-3.2 runs on glob specs; supervisor zombies now report instead of dying.
  • exec-report — refreshes the registry's Tasks cell inside its own store lock (the header had always claimed it did; it never did).
  • exec-gate check mode — no longer mutates the phase log it claims to inspect.
  • bash 3.2 parse — exec-graph's case inside $( ) was a syntax error on the stock macOS shell; hoisted out, with a permanent parse gate in the suite.

Verified

  • scripts/test-executor.sh: 142 passed, 0 failed — under bash 5.3 and under /bin/bash 3.2 (the macOS floor).
  • exec-graph check: 50 checks green.
  • End-to-end on a scratch initiative: dispatch → heartbeat → suspect → revive → redispatch → report → review → verdict → commit → gate → DONE, with the REPORT livelock proven dead (five consecutive folds during a live review emit WAIT).

0.6.0 Governor

Choose a tag to compare

@Atri10 Atri10 released this 29 Sep 09:36
v0.6.0
7f82c0b

The controller no longer carries the work. The pipeline is two axes of script-driven state with a dispatched subagent at every step that needs judgment, a critique gate on every authoring phase, and a fail-closed path for unattended runs.

Five new scripts, one new skill, 17 prompt templates. 9,633 lines across 52 files.

⚠️ If you installed an earlier v0.6.0

The first three v0.6.0 tags shipped exec-store-check using an associative array (declare -A), which is bash 4.0+ only. The scripts use #!/usr/bin/env bash, so on a stock macOS — and on any machine where bash resolves to the system 3.2 — the script died on that line and every check after it silently never ran. Re-install from this tag if you are on macOS.

Three structural defects this closes

Only 2 of 11 phases could reject a bad deliverable. plan-regression and review dispatched independent critics; design and verification had no artifact gate at all, and architecture and spec ran adversarial self-critiques whose own skills refused the word critic — correctly, since one agent grading its own work is not review.

Upstream drift was structurally undetectable. No reviewer prompt in executor-review ever opened the architecture store, so an implementation satisfying every R-nn and every C-nn while violating the ARCH passed every gate in the system. Adapters importing each other, an ORM row crossing into policy, a seam renamed from its IFCE — there was no seat at which anything could see it. Two seats catch it now: the code component's catalog makes the architecture, IFCE and design stores required inputs, and the final reviewer takes them the same way.

The pump's "never authors" rule had no mechanism behind it. AUTHOR-<phase> was a registered role that nothing ever dispatched. The decision table now says to dispatch it, and the phase-axis loop is written out.

The critique gate

executor-critique generalises the plan-regression contract to all nine authoring components. Each phase's artifacts are audited as a set — the defects worth finding live between documents — and the phase cannot be marked passed until that audit is clean or the human has waived it in writing.

The gate is a script, and it is harder than the stage it generalises from:

  • verdict: PASS beside a non-zero high/medium is refused, not believed
  • the three-round cap is enforced by the script — audit 04 exits 2
  • a waiver needs both a note in the row and an initiative ruling naming the artifact
  • an empty clearance is not a cleared one

Adding a component is a registry row and a catalog section, not a script. plans proves it: it resolves to the pre-existing plan-regression/ home and reads the same summary.md — one gate, two front doors, not two gates that can disagree.

Unattended runs

exec-gate INIT PHASE --auto clears a gate only when the initiative's autonomous.md permits it, and every ambiguity resolves to deny — no policy file, enabled: false, an unlisted phase, a mode spelled wrong. A typo in a table cell must not become an unattended phase gate. Pick-class phases still require a scored verdict on disk, because a script can count files but cannot choose between designs.

An auto-pass records as **auto-passed**, visibly distinct from a human passed, and a human who disagrees overturns it with one command.

Cross-platform correctness

Four defects that behaved differently across environments while failing silently — each found by running on the environment it actually breaks on, never by reasoning about it:

  • bash 3.2 — declare -A in exec-store-check is bash 4.0+, and #!/usr/bin/env bash resolves to the stock macOS 3.2. Under set -e the script died there, so every check after it never ran. The only bash 4+ construct in the codebase; replaced with a newline-delimited set.
  • Worker liveness — BSD's date -j -f ignores the date it was handed and returns roughly now; GNU's -d parses it. The same dispatch row read alive on macOS and dead hours later on Ubuntu. A false DEAD verdict burns a revive rung and replaces an agent still holding its context.
  • validate-skills — the box-drawing check used a multibyte bracket expression. mawk is byte-oriented, so an em-dash in prose matched. The validator passed on macOS and failed on every Linux runner.
  • exec-store-check timestamps — BSD's date -j -f needs -u; the offset cancelled in its current call sites, so nothing was broken today, but it was a trap for the next caller.

script-smoke now runs on an [ubuntu-latest, macos-latest] matrix, and the suite prints a toolchain banner so a CI log carries the environment it ran against. A Linux-only job catches these only when the author is on Linux; a macOS-only one never would have.

Every dispatch prompt now covers its edge cases

A prompt is the only definition of what a subagent does, so an undefined state is an unreviewed behaviour. Measured before: one prompt in seventeen had preconditions, none had a refusal channel, none handled a file left behind by an aborted prior run. All seventeen now define their preconditions, edge cases, refusal path, and output-file collisions.

Two bugs worth calling out. component-reauditor-prompt.md hardcoded R01/R02 while claiming R02+, so an R03 dispatch would have written R03's findings into R02's file — the loop would have reported progress it never made. And design-critic-prompt.md required a ranking while stating "you do not pick the winner", pre-empting the human's choice with an unreviewable judgment.

Upgrade notes

This release rewrote main's history to sign every commit. If you cloned before, run git fetch && git reset --hard origin/main — the old commits are gone from every branch.

All commits on main carry verified signatures, as does the v0.6.0 tag.

Verification

123 regression tests, validate-skills, prompt-injection lint, and shellcheck -S warning — all clean on bash 3.2, bash 5, macOS and ubuntu 24.04.

0.5.1 Burnish

Choose a tag to compare

@Atri10 Atri10 released this 26 Sep 16:55
b1ed490

Hygiene release — headers, rename, self-contained comments

No behavior changes. Every code file now carries its license, the regression suite has a name that says what it tests, and comments describe the failures they guard against instead of citing closed issue numbers.

Changed

  • SPDX headers on all 20 code files — 16 executor scripts, 3 repo scripts, the CI workflow: # SPDX-License-Identifier: MIT + # Copyright (c) 2026 Atri10, matching LICENSE. Markdown is deliberately left alone: the root LICENSE covers it, and an HTML comment at the top of files agents read is context noise for zero protection.
  • scripts/test-issue9-fixes.sh → scripts/test-executor.sh — the old name referenced a closed issue; the suite covers the executor scripts' contracts. CI, CONTRIBUTING, and the CHANGELOG updated with it.

Fixed

  • Stale comments made self-contained — three issue #N references (in exec-plan-lint, exec-run, and the planning skill's lint description) now describe the failure they guard against: a guessed store path breaks the moment the workspace moves; a completion line without a verdict is an unjudged claim.
  • Stale documentation — CONTRIBUTING's layout table no longer lists a docs/ directory (the repo keeps none; normative content lives in skills/executor/references/), its references list gained branches.md and test-quality.md, and its contract-update rule names the branch model. The README's exec-branch and exec-run check rows now describe the task/side/spike subcommands and the topology audit.

Verification

Suite 40/40 · validate-skills.sh clean · prompt-injection lint clean · ShellCheck --severity=warning clean · secret scan clean · CI green on every push.

Full diff: v0.5.0...v0.5.1