Skip to content

Releases: llopresto87/Cypress

v8.2.0

Choose a tag to compare

@github-actions github-actions released this 14 Oct 12:52

8.2.0 — a harvest folded back into the seed (2026-10-14)

This release comes from a harvest: what grown plants learned, made generic
and folded back into the seed. The seed now needs Python 3.14 and says so at
install time. Graft and grow commit the plant before they write. A team can
keep its own AGENTS.md. Generic skill pages reach a plant when its work
needs them, and every agent runs its own route. The corpora gain library,
tool, skill and legal pages. Project names that earlier records carried are
recast generically; the disclosure is below.

Python 3.14

  • The seed's minimum Python is 3.14, and SPEC-0005 §5 is the one home of
    that figure. Every script the installer places and every hook it wires
    runs on it.
  • install.sh runs on python3 when it is at 3.14 or newer, else on the
    first python3.<n> at or above it on PATH, and writes that name into
    every hook command, the Prime Agent extensions included. With none on
    PATH it refuses before writing anything, with the fix in one line. When
    python3 itself is older, a NEXT STEP says so, because agent sessions run
    the graph tools as python3 docs/graph/<tool>.py.
  • install.sh --check runs each wired hook on the interpreter the hook
    names. The CI gate runs on Python 3.14, and tests/test-tool-help.sh
    holds the installer's PYTHON_FLOOR, the spec line and the CI version
    equal.

The installer

  • A run that made backups ends with a BACKUPS block: every installer backup
    in the plant, one line per date with its count, and a reminder to stage
    by explicit path, never with git add -A or git add ..
  • When the plant is its own Git repository and ignores .cypress/seed.json,
    the installer prints the .gitignore lines that keep the stamp and the
    coverage record tracked. It never edits .gitignore.
  • A stamp key an earlier seed wrote and this one no longer reads is named
    and kept.
  • --kernel-mode compose keeps a team's own AGENTS.md canonical: the
    installer never writes it, and CLAUDE.md imports it on its first line
    and carries the kernel after it. The cost, stated on every run: a host
    that reads only AGENTS.md (opencode, Prime Agent, Codex, Copilot) never
    sees the kernel. The mode is recorded in the stamp as kernel_mode;
    --kernel-mode replace, the default, returns to one shared kernel body.
    The installer refuses compose before writing when AGENTS.md is missing,
    a symbolic link, or a body the seed wrote. graft-audit.py reads a
    compose-mode plant.
  • A crashed router is one line in the session, No route: graph-lint.py exit <status>: <its last stderr line>, and the prompt still goes through
    (SPEC-0003).
  • --expertise skill-corpus/<name> places a generic skill page as the
    routable node docs/graph/skills/<name>.md. Every skill-corpus page now
    carries node frontmatter, and the installer refuses a page without it by
    name.
  • A placed corpus page needs no row in the plant's index.md: the plant's
    graph-lint.py reads origin: corpus@<version> as an entry point
    (SPEC-0001 PLACED_CORPUS_PAGE_IS_REACHABLE).
  • The matcher proposes the Microsoft Graph platform page for the Graph SDK
    packages.

Graft, grow and harvest

  • Graft makes the baseline commit itself before its first write, per the
    plant's version-control shape: one commit of the tree as found in the
    plant's own repository, staged by explicit path, or a .gitignore and
    git init where the plant has no repository of its own. It commits a
    checkpoint after a ratified flag flip, after the apply, after each remedy
    that re-runs the installer and at the end, and records each commit.
    Nested repositories stay read-only. It never fetches, switches or pushes.
  • Graft lists the backups by date for the owner's decision on which to
    keep, offers compose mode to a plant that keeps its own hub, and records
    the owner's own words for a plant fact beside the value.
  • Graft and grow read what the plant needs (its recurring procedures, the
    tools and services it drives) as well as what its manifests name, and
    propose the corpus page that serves each need with the path that shows
    it.
  • graft.gate.routes records a plant's own adversarial routing baseline
    with agent-lint.py --eval --record-baseline at the graft that brings
    the routing corpus or changes the roster, and gates the plant on it. The
    seed's roster keeps its budget.
  • Grow commits a baseline before its first write and a checkpoint at the
    close of every phase that wrote, and grow.gate.write-scope reads each
    phase against the commit that opened it. A corrections record takes what
    authors find after the evidence ledgers freeze, and outranks them. An
    owner-stated fact no file witnesses is recorded once, labelled, with the
    owner's words.
  • Harvest's check that a plant was left untouched compares content hashes
    of dirty, untracked and read ignored files, so a write to a file that was
    already dirty is caught. A harvest that re-reads a plant it already read
    takes a fast path, and its agnosticism check takes --forbid-file.

Doctrine

  • Two new delegation leaves: delegation-wave-integrity.md (each worker's
    write set in a table, a wave baseline, output that survives an
    interrupted spawn) and delegation-continuation.md (when to resume an
    agent that already handed back, and when to brief a fresh one).
  • Every worker runs its own route. Architect, product, devil's advocate,
    UI/UX designer and legal gain Bash, which their charters limit to lookup
    and measurement; legal's shell never reaches the network. A worker brief
    no longer carries a closure the caller routed.
  • The graph-session bootstrap gains two steps: check the route against the
    files about to be touched, and leave shared git state alone.
  • In an operations or verification pass, the tester lists each bug it
    finds, root-caused, and the fix waits for the owner's go-ahead. Outside
    such a pass the default stands.
  • A project's own authorization levels and the seed's tiers are two axes;
    the stricter wins, and neither is translated into the other.
  • Decision points offer numbered options with a recommendation. A spec's
    failing tests are planned as one wave, with mutation testing batched at
    the end.
  • The release, secrets, contract, host-parity, version-control, design,
    incident and stewardship postures take the rollback, backup, credential,
    contract, reconcile and diagnosis rules plants had written for
    themselves.
  • skill.library-wiki now holds the rule for which dependencies get a
    full page when adopting a project, and files a staged research-scout
    draft at close-out. The templates gain setup sharing in a spec's §10,
    rollback per unit, and a record of declined tool candidates.

Corpora

  • Library corpus: 27 new pages and 16 rewritten whole; seed claims the
    review found wrong were corrected against upstream sources. A page for a
    library in preview, or whose next major is a release candidate, says so.
  • Tool corpus: 11 new pages and 9 integrated. The seed-data page says a
    demo password lives on disk only, in a file no model reads.
  • Skill corpus: new generic and stack-keyed pages. discardme is now
    change-review-report: the report a reviewer accepts or rejects a
    substantial change from without reading the diff.
  • Legal corpus: one new EU regulation page, and four more GDPR provisions
    from the publisher's current text.

Tools and checks

  • source-index.py answers incomplete with a named record where it used
    to give an empty answer or refuse: language-not-read for an input in a
    language it does not read, reached-over-http for a test that reaches
    the code only through a URL, and repository-unnamed for a work tree
    nested in the plant, while the rest of the moved list is answered.
  • session-metrics.py --all names on stderr why it found no entry.
  • spec-lint.py reports a contract slug that only a comment carries as a
    WARN, never as coverage, under a ratchet that may only fall
    (--comment-only-budget).
  • graft-audit.py --record reads any heading that names a graft, in any
    case or position. An entry whose lists name no file fails; a graft that
    merged and kept nothing writes - none.
  • agnosticism-lint.py takes --forbid-file (with !allow lines),
    --optional-forbid-file, --tracked and --terms-only. A new gate step
    lints every tracked file against the steward's local, gitignored
    .cypress/forbid.txt, and prints SKIPPED where that file is absent.
  • The gate has 52 steps (python3 tools/gate-registry.py --summary).

Upgrade notes

  • Install Python 3.14 first. The installer finds python3.14 and writes
    it into every hook; with no Python at 3.14 or newer on PATH it refuses
    before writing. Put a python3 at 3.14 first on PATH for agent
    sessions as well.
  • Graft commits. The next graft makes a baseline commit of the plant's
    own repository before it writes, then checkpoint commits. It names each
    untracked path and stages none you have not admitted.
  • Keep the stamp tracked. If the installer prints .gitignore lines for
    .cypress/, put them in place of a rule that ignores the directory.
  • Decide on backups. The BACKUPS block and graft list them by date;
    which to keep is your call.
  • Plant agents gain Bash. A plant-authored agent without a shell is
    given one at the next graft, in a proposal you ratify.
  • Record the routing baseline. A plant with its own specialists records
    its adversarial baseline at the next graft.
  • Spec coverage may drop. A plant test that names a contract only in a
    comment no longer covers it; name the contract in the test's code.
  • Steward checkout. The gate reads the local .cypress/forbid.txt; a
    release waits for that step to read PASS in the checkout that holds it.
  • New rules in the protocols, method nodes, agents and templates reach an
    existing plant through graft.

Identifying toke...

Read more

v8.1.2

Choose a tag to compare

@github-actions github-actions released this 09 Oct 04:25

8.1.2 — a plant is ready to go from the get-go (2026-10-09)

After an install, a graft or a grow, the source index is already built, and
the owner reads in one short report what is set up and what still needs a
fix. Nothing is left to do by hand that the report does not name. A session
finds the tool through a seed skill, the kernel names it, and a question
about a file the plant owns loads that skill beside the node that owns the
file.

The build report

  • install.sh runs python3 docs/graph/source-index.py build as its last
    step, on every install that places files and so on every graft, and prints
    the report under source index build (advice, never a failure of the install; ...). The build runs in isolated mode (-I -B) with stdin
    closed and a 120-second bound. An install never fails on it: when the
    build does not finish, one line says so and gives the command to run by
    hand.
  • tools/growth-audit.py prints the same report after its verdicts, at
    every grow and graft. It is advice, never a verdict, and never sets the
    exit code; --json appends it as {"source_index_report": [...]}.
    graft-run.py keeps both copies, in install.log and coverage.txt.
  • The report holds the cache line, the counts and the build time, then one
    record per setup gap, each with a fix: line under it: a repo: value
    that names nothing on disk (repo-unresolved), a Git repository inside
    the plant that no node names (repository-unnamed, new), a missing or
    empty test declaration (no-test-declaration, no-test-files), and the
    rest. Hints name files that look like tests but sit outside TEST_GLOBS,
    files in the test class that do not look like tests, and patterns in
    docs/graph/source-index.json that match no file
    (config-pattern-unmatched, with its own fix line).
  • The cache bound, CACHE_MAX_BYTES, rises from 64 MiB to 196 MiB.

Finding the tool

  • A new seed skill, skill.source-index (skills/source-index/SKILL.md),
    is placed and projected like every seed skill. It sends the four
    questions (what depends on a file, which tests a change reaches, which
    pages cite a file, where a name is defined) to the tool, says how to act
    on the build report, and states the limit: an answer is a recommendation,
    and a file missing from it is never proof that the file is unaffected
    (ADR-0030).
    The seed now ships 16 skills; the Codex config example registers the new
    one, and the always-loaded surface on Claude Code grows to 25 800 bytes.
  • The kernel's "Where to look next" gains one line for code questions:
    python3 docs/graph/source-index.py --help and skill.source-index.
    The owner raised KERNEL_BUDGET from 8 000 to 8 200 bytes for it.
  • verify, canonize, grow and graft list the skill as a peer.

The router

  • When a task names a file that a plant node owns and also holds a trigger
    phrase of a seed skill, the router loads that skill beside the owning
    node, at most two skills (PATH_TIER_SKILL_CAP); a task that holds the
    phrases of more loads the node alone. Only skills the seed ships are
    added this way (SPEC-0002, ADR-0026 "Amendment, 8.1.2").
  • A file path or a code name inside a trigger phrase no longer breaks it.
    A path stands in for the phrase's word file and a code name
    (save_order, saveOrder) for name, so "what breaks if I change
    src/app.py" holds what breaks if I change this file. An ordinary word
    still breaks a phrase.

Graft and build output

  • A graft now names an outdated seed page left in a plant (a file under
    protocols/ or method/ that the seed no longer ships, such as
    protocols/toolcraft.md) as RETIRED, and ties the graph-lint errors it
    causes to that page. It deletes nothing: the steward removes the page by
    name (migration (d)). A test graft on a copy of wrt-migration found the
    case.
  • The build report's Incomplete: line stops at the row limit and ends
    with and N more; --all and --json show every row.
  • Memory was measured near the 196 MiB cache bound: about 100,000 files,
    where a query needs about 1.3 GB.

CI on macOS

  • tests/test-source-index.sh checks how repo: values with different
    letter case are read only on a file system where case matters. It probes
    first and, on the macOS runner's case-insensitive disk, skips those two
    checks with a printed reason instead of failing.

v8.1.1

Choose a tag to compare

@github-actions github-actions released this 07 Oct 21:26

8.1.1 — the gate checkout fetches full history (2026-10-07)

The CI gate cloned the seed without history or tags, so two tests that
read the v7.36.0 engine failed on GitHub since 7.37.0. The gate now
fetches the full history, and seed-lint requires it.

Gate checkout

  • .github/workflows/gate.yml fetches full history (fetch-depth: 0) on
    checkout, so gate tests can read git history and tags, such as
    git show v7.36.0:....
  • tests/seed-lint.py requires the full-history checkout, with
    tests/test-seed-lint.sh as its RED/GREEN test.

v8.1.0

Choose a tag to compare

@github-actions github-actions released this 07 Oct 21:08

8.1.0 — the source index: what a change reaches, read from the code (2026-10-07)

A plant can now ask which code depends on a set of files, which tests a
change reaches, which graph pages cite a file, and where a name is defined,
and get the answer from the code without a model. The tool is
docs/graph/source-index.py. Verify, canonize, grow and adopt-existing each
call it once, at the step that needs it. It recommends; verify and tiering
still decide what runs and how much process a change gets.

A node's repo: value now decides what it claims on disk, the same way
everywhere the graph reads it. A folder or a file, named with or without a
trailing slash, claims the paths under it; a repository or the plant root
claims nothing. A plant that holds a repo: value naming a folder or file
without a slash, such as src/ or a bare folder name, starts routing on
it after its next graft. A value that names nothing on disk is read as
before, and anchors now says so with a repo-unresolved note asking the
owner to correct it. The node template's comment states the rule: one
plant-relative path.

Source index

  • tools/source-index.py is placed at docs/graph/source-index.py. One
    reverse walk over file-to-file links answers three queries: impact, the
    code that depends on the inputs, nearest first; affected-tests, the same
    walk filtered to the plant's tests, plus an always-run set; and anchors,
    the graph pages that cite the inputs, with knowledge nodes kept apart from
    plans, specs and decisions. build forces a rebuild.
  • symbols <name> lists every definition of a name, with path, line and
    kind, and never picks one when several files define it. A Python
    definition, read with ast, is certain. A shell function, or a
    TypeScript/JavaScript declaration at the top level of its file or
    exported, is read line by line and is maybe. A file the tool could not
    read makes the answer incomplete, with the action "search by hand".
  • --history adds to impact and affected-tests the files that changed
    together with an input in past commits. Each is a maybe row in a
    history list of its own, with the number of commits the two files
    shared out of those that changed the input. History only adds rows. A
    shallow clone, or a repository with no history, makes the answer
    incomplete.
  • anchors --moved takes its inputs from the moved list of
    code-anchor.py, the files changed since the anchor was recorded, so no
    paths are copied by hand. With no anchor, the answer is incomplete.
  • Links come from Python imports, read with ast and never run; python3,
    bash, sh and source invocations; quoted path literals, whole or
    joined from segments; and TypeScript/JavaScript import, export from,
    require() and import(), resolved through tsconfig paths and
    baseUrl. A mention in Markdown is not a link.
  • Each row is certain or maybe, and a maybe row names the reason and
    line of its weakest link. A file whose references cannot be pinned, such
    as a whole-tree walk or a dynamic import, gives maybe rows that every
    input reaches alike. These are the floor, listed once after the input's
    own rows. What the tool cannot answer makes the answer incomplete, with
    a reason and one action: check by hand, run the full suite, or review by
    hand. affected-tests never presents its list as the only tests to run.
  • The tests are the plant's TEST_GLOBS in docs/graph/spec-lint.py. A
    plant can set exclude, always_run and global_inputs in
    docs/graph/source-index.json, which is its own file; the installer never
    places it.
  • The index is derived scratch in .cypress/source-index/, beside an inner
    .gitignore of *. Any query rebuilds it when its key changes (a commit,
    an uncommitted code edit, a config edit, a graft that changes the tool,
    another Python version), and deleting it is safe. A graft rebuilds it and
    never carries it over.
    ADR-0029
    records the decision; the owner accepted it on 2026-10-07.
    SPEC-0007 holds the contracts.
  • The tool needs the Python standard library and git, nothing else.

The protocols call it on demand

Each step below runs the tool once. No hook runs it, and nothing runs it
per prompt or per file access, the pattern ADR-0018 withdrew.

  • verify: after GREEN and before the gates are chosen, affected-tests
    is the recommended floor of the focused tests. The session may run more,
    and never reads a test's absence from the list as proof that the change
    cannot reach it. An incomplete answer puts the change in the "affected
    scope genuinely uncertain" row.
  • canonize: in flow step 1, before code-anchor.py --record, the session
    runs anchors --moved and hands the pages it names to the docs-librarian
    to re-check. Recording the anchor first would empty the list.
  • grow and adopt-existing: before the scouts are briefed, the
    inventory from build --json is their file list. On a refresh,
    impact over the moved paths gives the blast radius.

One home for the path rules

  • tools/source_paths.py, placed at docs/graph/source_paths.py, holds the
    rules for what counts as code, which repositories a plant governs, where
    Git ends, the content hash, the atomic write under .cypress/, and how a
    page cites a path. code-anchor.py and growth-audit.py now use it; their
    behaviour is unchanged, and their existing tests prove it.
  • tools/plant_walk.py, the walk over one plant's files that graft-audit.py
    already used, is now also placed, at docs/graph/plant_walk.py, because
    source-index.py loads it.

Measured

The figures come from copies of each tree, at seed commit 17d4539, before
the tool read paths joined from segments; nothing was written into a real
plant.

  • On a temporary plant over a clone of the seed, affected-tests answered
    for 48 past commits that changed at most three source files, scored
    against the tests each commit edited, out of a set of 40. The full answer
    (tests, always-run and floor) found 0.989 of them, but named 38.0 of the
    40 tests on average: on the seed it suggests nearly the whole suite. The
    input rows alone (tests and always-run, no floor) found 0.880 at 21.7
    tests, and they are the useful part on the seed. The certain rows alone
    found 0.120, because most of the seed's links are path literals, which are
    maybe.
  • A full build of the seed plant takes 0.67 to 0.76 s, and a cached query
    0.10 s. A TypeScript plant of 397 files builds in 0.66 s, and a llama.cpp
    clone of 4,320 files in 3.19 s.

Checks

  • The gate has 51 steps (python3 tools/gate-registry.py --summary).
  • tests/test-source-index.sh holds the source index, on synthetic Git
    plants.

Upgrade notes

  • New placed tools. Every install now places
    docs/graph/source-index.py, docs/graph/source_paths.py and
    docs/graph/plant_walk.py, fast-forwarded like the other seed tools. The
    installer writes no index; the first query builds it.
  • Set exclude before reading an answer as a gate set. A plant's
    TEST_GLOBS often match fixtures, helpers and a suite runner. List them
    under exclude in docs/graph/source-index.json.

Known limits

  • symbols says where a name is defined, not who uses it. A TS/JS class
    member, an indented declaration that is not exported, and a definition in
    a shell here-document are not read.
  • History does not follow renames, and a CI checkout that holds one commit
    gives no history rows, so every --history answer there is
    incomplete.
  • Hook commands written in host settings files, such as
    .claude/settings.json, are not read, so a hook script has no dependent
    in any answer.

v8.0.0

Choose a tag to compare

@github-actions github-actions released this 06 Oct 01:50

8.0.0 — corpus pages placed on request, a deeper corpus, and sharper doctrine across the lifecycle (2026-10-05)

A plant can now ask the seed for the corpus pages that match its own stack,
one by one, and get version-aware library, skill and tool pages it can work
from without a research pass. The corpora are much larger. Planning,
delegation, the postures and the lifecycle protocols carry new rules. A
placed tool reads the session-metrics block of every full delivery. This
release is a major version because it adds a placed tool, a stamp key and
stricter checks that an existing plant meets on upgrade (see Upgrade notes).

Install and selective placement

  • install.sh <host> --expertise propose prints the library, tool and
    stack-keyed skill pages that the project's manifests match, one line per
    page with the manifest entry that matched, and writes nothing.
    tools/corpus-match.py does the matching; it runs from the seed and is
    never placed.
  • install.sh <host> --expertise <id>[,<id>...] places exactly the pages
    named: library pages at docs/graph/libraries/<name>.md and tool pages at
    docs/graph/tools/<name>.md under a provenance line, and a stack-keyed
    skill page as the node docs/graph/skills/<name>.md with
    origin: corpus@<seed version>. The list is recorded in .cypress/seed.json
    under expertise, with the SHA-256 of each page written.
  • Each later install refreshes the recorded pages nobody edited and names
    each edited page for graft. --check names a recorded page that is
    missing or stale.
  • grow proposes the list, graft refreshes it, and ingest-library skips
    the scout for a placed page and pins only the version delta
    (ingest-library.corpus-first).

Seed defects fixed

  • The graft ledger takes an honest lineage base and accepts --base-dir.
    graft-run infers the adapters of an old stamp. graft re-checks at the end
    every file its record says it merged or kept.
  • status-migrate keeps multi-line statuses and invents no dates.
    growth-audit declares grounding it could not check.
  • graph-lint's artifact escape check is lexical, so a symlink install no
    longer reports false escapes. spec-lint and grill-lint refuse a misnamed
    spec instead of passing over it.
  • A missing hook script prints one cypress: hook script missing line
    instead of nothing, and install.sh --check runs each wired context hook
    once. A harness agent or skill with no graph home is named RETIRED or
    ORPHAN; nothing is deleted.
  • The hooks detect deeply nested input on any Python version. The installer
    resolves the legal jurisdiction once per run.
  • Router triggers are sharper, and the adversarial ratchet is 2.

Corpora

  • The library corpus grows from 91 to 131 pages, with new galaxy and pub
    ecosystems. Pages state the version facts the library's own docs document
    (a minimum version, a version where behaviour changed) next to their
    subject, and a section per major line where the surface differs.
  • The skill corpus grows from 12 to 33 pages. Stack-keyed pages live at
    skill-corpus/<key>/<name>.md, carry node frontmatter and a stack: field,
    and can be placed as routable skill nodes.
  • The tool corpus grows from 24 to 40 pages, each with a self-test where the
    page claims portability. A tool page may carry the same stack: field.
  • The agent corpus grows from 6 to 8 roles, including discipline roles on a
    stack-shaped surface.
  • The legal corpus grows from 13 to 16 instrument pages: PSD2, the SCA
    technical standards and EDPB Guidelines 2/2023, plus two more provisions of
    the national data-protection code.
  • Every corpus admits a page only at the withdraw-ready bar: a new plant
    could adopt it instead of running a research scout. Pitfalls, steps and
    rules from problems met in practice are written into the pages that own
    their subject.

Doctrine

  • Planning: a scoped standing grant for repeated non-production acts, asked
    for once at plan approval (vcs-posture.publish-authorization); a walking
    skeleton first for a new pipeline or deploy path, with a spec that grows one
    signed slice ahead of each RED; an environment-parity read for a plan that
    changes a deploy chain; an operational act that closes on evidence of the
    act, not of the tool that performs it.
  • Delegation: an error signature is not a failure class; a provisional
    reading inside a contract keeps a worker going until the ruling pass; the
    run that gates the goal goes first; work split by area is routed area by
    area; a worker that hits a limit is resumed, not respawned.
  • Postures: a control sits where the party it must stop cannot edit it; leak
    triage settles liveness by digest and verifies a rotation at the consumer;
    records a system already holds start unmanaged; a green dry run is
    structural evidence only, and a target selector is resolved to hosts before
    a mutating run; staging-only machinery refuses a production profile; a
    changed producer field updates its consumers in the same change.
  • Lifecycle: grow treats an agent-operations system in the source as
    evidence; canonize keeps a harvest-candidate record from
    docs/graph/plans/_harvest-candidates.template.md and asks for missing tool
    and library pages at close-out; deliver requires the Session metrics block
    on the full form and records a production fault in the incident runbook; a
    ratified ADR takes an appended, dated Correction.
  • The harvest protocol now takes knowledge whole. It generalizes a
    candidate instead of rejecting it, admits a stack-bound procedure as a
    stack-keyed page, and admits the version facts a library documents. It
    never states a plant's own version, and it leaves security warnings and
    CVE ids to scanners. Each fact carries a provenance class, candidates read
    from more than one project are consolidated first, a lesson goes into the surface that
    already owns its subject, and an independent reviewer reads each lane.
    ADR-0028
    records the decision.

Session metrics

  • tools/session-metrics.py is placed at docs/graph/session-metrics.py.
    deliver runs its lint role on the full-form entry it appends to
    changelog.md, and harvest reads its query role. It takes the block's
    labels from the plant's deliver node at run time.
    SPEC-0006 holds its contracts.

Checks

  • The gate has 50 steps (python3 tools/gate-registry.py --summary).
  • tests/test_corpus_match.py holds the matcher, and
    tests/test-session-metrics.sh the session-metrics reader.
  • tests/test-tool-corpus.sh runs the self-test of every portable tool page
    and a mutated copy.
  • The two knowledge-graph templates are held by prose-lint.
  • SPEC-0001 carries the selective-placement, hook-check and
    harvest-candidate form contracts, and SPEC-0003 the missing-script
    warning.

Upgrade notes

  • New placed tool. Every install now places
    docs/graph/session-metrics.py, fast-forwarded like the other seed tools.
    A full-form delivery whose Session metrics block is missing or malformed
    is reported by it.
  • Nothing is placed from the corpora by default. A plant gets library,
    tool or skill pages only through --expertise. Once it has used the flag,
    .cypress/seed.json carries an expertise key, and later installs refresh
    the recorded pages it has not edited.
  • New blank form in plans/. The docs scaffold adds
    docs/graph/plans/_harvest-candidates.template.md where it is missing;
    graft treats it as expected.
  • Stricter spec discovery. After graft reconciles the graph engines, a
    Markdown file in docs/graph/specs/ that is not named SPEC-*.md (index
    and readme aside) fails spec-lint and grill-lint as a misnamed spec. Rename
    it, or it is never checked.
  • Louder hooks. A context hook whose script is missing now prints one
    line naming it. install.sh --check runs each wired hook once, names each
    recorded expertise page that is missing or stale, and names harness agents
    and skills with no graph home.
  • New rules in the protocols and method nodes, as listed above, reach an
    existing plant through graft. A new plant gets them from install.sh.

Known limits

  • The cli/ library pages keep their documented minimum-version markers.
  • The portability gate breaks one property per page with a single mutation;
    a self-test that misses other properties still passes it.
  • skills/adopt-existing/SKILL.md sits at the 170-line leaf ceiling. Whether
    it moves to the lifecycle class or the ceiling is raised is the owner's
    decision.
  • ADR-0028 is proposed and waits for the owner.

v7.37.1

Choose a tag to compare

@github-actions github-actions released this 01 Oct 20:24

7.37.1 — two decisions of 7.37.0 ratified by the owner (2026-10-01)

Changed

  • ADR-0026 (the node router's tier ladder and its gated corpus) and ADR-0027 (the first move runs the router) gain a Ratification section. The owner ratified both after the 7.37.0 release. No code, check or node changed.

v7.37.0

Choose a tag to compare

@github-actions github-actions released this 01 Oct 20:21

7.37.0 — the first move runs the router, and a session pays for a route once (2026-10-01)

The owner asked for fewer model-facing tokens, not for speed. One --plan
run already takes about 70 ms, so latency was never the cost. The cost was
text: Prime Agent injected the full route on every prompt, a route printed
the same facts several ways, and every session opened docs/graph/index.md
before it knew what the task needed. This release cuts that text where a
program can derive it, and keeps every pointer a model follows.

What a plant gets

  • The FIRST MOVE routes the task line. A session takes the router
    suggestion the host injected, or runs
    python3 docs/graph/graph-lint.py --plan "<task>", reads the LOAD nodes
    through graph-lint.py --show <id>..., and acts on any ! notice.
    docs/graph/index.md becomes the fallback map: a session opens it when the
    router fails, when a notice leaves the plan empty or wrong, or when the task
    explores the graph itself. The orchestrator's Turn 0, the
    knowledge-graph tier table, _schema.md and the docs map say the same.
  • Prime Agent keeps one route per session. install.sh prime-agent now
    places the same route-hook.py and status-hook.py that Claude Code runs,
    byte for byte, under .prime/agent/hooks/. The two extensions pass the
    prompt, the session id and the session depth to that core and compose no
    text of their own. A node this session was already shown is named by id on
    one seen: line instead of being injected again. The status register and
    the code-anchor line arrive once after each session start, compaction,
    tree switch or refine. The overlay's ## Surfaced nodes section, a set the
    model kept by hand, is gone.
  • Children and non-human turns are not routed. A spawned child session
    (depth above 0) and a turn a person did not type (an agent message, a
    task notification, a harness digest) get no route and no status text, on
    every host that runs the core.
  • Route lines are compact and keep every path. --plan prints one line
    per node with its file beside its id, a skip block, and the owner's
    plant: facts when all four are filled. Programs read --plan-json, one
    cypress.plan/1 document bound to the prompt by its SHA-256. The hooks
    read only that document and render the same lines from it.
  • --show reads a node without its router keys. It prints a header with
    every edge and leaf pointer resolved (requires, peers, composes,
    delegates_to, artifacts, libraries, plant_knowledge), then the body
    verbatim. It drops only router input, spawn settings and copies of the body.
  • The node router abstains instead of guessing. It takes the first tier
    that hits: an exact node id in the task, a path the task names, a trigger
    phrase of two or more content words, then the word score with a floor of
    two confident terms. A strong tier that hits more than three nodes falls
    through. A task with no signal, or one too long to be a task line, loads
    nothing and gets a short notice that names the next step. Root is no longer
    forced into every plan.

Measured

Model-facing tokens are cl100k counts from the round's records; each run
replays real sessions from the steward plant against the uncommitted tree.

  • Follow-up prompts: 47 follow-ups across 22 real sessions fell from 36,402
    to 11,131 injected tokens (-69%).
  • Five real prompts in one session: 5,885 to 2,306 tokens (-61%).
  • First-move window of short sessions: Prime Agent 25,359 to 14,739 tokens
    (-42%, 15 sessions), Claude Code 56,189 to 32,418 (-42%, 9 sessions). This
    assumes a session no longer reads index.md first. On Prime Agent the
    saving holds while fewer than about 14% of short sessions still read it;
    before the change, 5 of 15 did.
  • --show over the plant's 116 nodes saves about 216 tokens per opened node
    and keeps 651 of 651 pointers.
  • Routing quality on a 74-row plant corpus: adversarial rows hit a forbidden
    node 2 times, down from 19, and 8 of 9 unknown-domain tasks now abstain,
    up from 1.

Known limits

  • A plain re-install keeps a plant's older graph-lint.py
    (ADR-0014). The
    new hook then injects one line saying the engine lacks --plan-json, until
    graft brings the engine up.
  • The FIRST MOVE now needs python3. A shell-less GitHub Copilot mode can
    only take the index.md fallback; Copilot is a frozen host and gets no
    adapter work.
  • The hook waits up to 15 s for the router before it gives up and injects
    the pointer line alone.

Decisions and checks

  • ADR-0024:
    one Python hook core and per-session residency on Prime Agent; children and
    non-human turns are not routed. It supersedes ADR-0010 in part.
  • ADR-0025:
    compact route lines with every path, --plan-json between programs,
    --show for reading nodes.
  • ADR-0026:
    the tier ladder, the abstentions, and graph-lint.py --eval over
    tests/graph-routes.golden.tsv, gated per class on the GRAPH_* ratchets
    by tests/graph-route-eval.sh in tests/run.sh.
  • ADR-0027: the
    FIRST MOVE runs the router and index.md is the fallback map. It amends a
    consequence of ADR-0017 in part.
  • SPEC-0001, SPEC-0002, SPEC-0003 and SPEC-0005 carry the new contracts.
    tests/test_graph_lint.py, tests/test-prompt-hooks.sh,
    tests/test-full-install.sh and tests/test-install-placement.sh hold
    them. tools/code-anchor.py no longer counts __pycache__/, *.pyc or
    installer backup files as code.

How plants pick this up

  • A new plant gets all of it from install.sh.
  • An existing plant needs graft: it brings the engine, the kernel's
    FIRST MOVE and, on Prime Agent, the hook core under .prime/agent/hooks/.
    A plant that re-installs an adapter without graft gets the one-line
    engine notice above in place of a route.

v7.36.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 23:11

7.36.0 — a declarative edit is proved by a run, not a new test (2026-09-30)

An owner reported that a plant, asked to add a selector to a pipeline, set
out to write a RED test first. That test could only read back the line it was
testing: red while the line is missing, green once it is there. It proves
nothing the diff does not already show, and it breaks on the next rename.
The rules led the worker there because they said, with no qualifier, that
every production change starts from a failing test. This release adds the
missing qualifier and puts the question where increments are planned.

What a plant gets

  • A change with nothing to get wrong earns no new test. Before RED, the
    worker names what a test could catch that the edit being present does not
    already guarantee. For a declarative edit (a selector, a pipeline stage, a
    route, a flag, a config key, a mapping entry, a label) the answer is
    usually nothing. The proof is then the run that shows the edit working: an
    existing test or gate over that surface, or the cheapest real run (a
    dry-run, a validate command, one pipeline run), named with its result in
    the handback. A declaration that holds logic still earns a test: a pattern
    (regex, glob, wildcard), a condition, an order that changes the output, or
    a computed value. The rule lives in test-first.proportionate-checks.
  • The planner asks first. grill.increment-shape asks of every
    increment whether it needs a test. A no reads
    Tests to write (RED): none — <why>; proved by <run>, and that increment
    gets no RED spawn: the implementer makes the change and runs the named
    proof, and review and commit stand. When the planner cannot tell, the row
    keeps its test and the tester decides at RED, handing back unwritten if
    the answer is no. The grill template shows the form.
  • Spec coverage counts the run. spec-lint.py treats the live contracts
    that such a row names as covered by its run, and says so in its PASS line
    and in --list. A row that reads none — consolidation covers nothing.
  • The tier does not move. A config or selector edit still changes
    behavior, so it is T2 or above and keeps its reviewer audit. On the
    contained lane the recorded run takes the place of the pinning test, and
    the why-record names "test or run".

What changed and why

  • The kernel's §3.4 anchor gains one line pointing at the exception, and
    method.tiers' contained lane, the test-first rule statement and the
    canonize why-record point at test-first.proportionate-checks instead of
    contradicting it.
  • The test-first exceptions list replaces "Pure configuration changes" with
    "Declarative edits with nothing to get wrong". The old entry applied only
    where there was no unit-testable behavior, and almost any edit is
    unit-testable in the weak sense, so it never stopped the read-back test.
  • The implementer's contained-lane handback and the tester's step 3 name the
    run as the proof for such an edit.

Decisions and checks

  • ADR-0023,
    proposed, amends ADR-0006 in part: the contained lane still trades the
    spec for proof plus a why-record, and the proof is now the one the change
    earns. Its named risk is a worker calling logic "declarative" to skip a
    test; the logic list above is the check, and the reviewer audits the
    claim.
  • tests/test-spec-lint.sh case P1 holds the run-proved coverage and the
    consolidation case.

How plants pick this up

  • A new plant gets the rule from install.sh.
  • An existing plant gets it by graft. Plans written before it keep
    their test rows and stay valid; the none — <why>; proved by <run> form is
    available to new increments. A plant that already recorded a declarative
    edit under the old "Pure configuration" exception needs no change.

v7.35.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 20:13

7.35.0 — positive voice: rules say what to do, plants name their models once (2026-09-30)

The owner asked for a seed-wide re-reading of every prompt, to turn "don't do
this" into "do it this way, because", to clear accumulated cruft, and to fix
whatever had gone stale on the way. This release is that pass, plus the tools
that four of the owner's rulings needed.

What a plant gets

  • Rules in positive voice. Every protocol, skill, agent charter, method
    node and template, and the agent- and skill-corpus pages, state the
    behavior they want and the reason for it. A bounded role says what it ONLY
    does. A prohibition stays only on a hard boundary (an irreversible act, a
    security, privacy or legal line, a user-sovereign trigger, loop control)
    and names the right move beside it.
    The rule's home is method.engineering-posture §8. Meaning is unchanged
    except where a statement was false against the code; the main corrections
    are listed under "Corrected facts" below.
  • A model map. A plant names its models once, in docs/graph/models.md:
    the providers, and the model each host runs for each class and effort.
    Nodes, protocols and briefs name only the class (authoring or
    investigation) and the effort. On Prime Agent the overlay reads the map,
    resolves the selector with rlm.find_models, and spawns with
    rlm.spawn(..., model=..., thinking=<effort>); a selector that does not
    resolve stops the spawn, and an unfilled row inherits the parent's model
    and says so in the routing evidence. On opencode, install.sh opencode
    writes each agent's model: line from the map, and
    install.sh opencode --check reports drift. Claude Code reads the class
    alias itself, so the map has no Claude Code column. The Prime Agent
    overlay's version table and its "nearest higher model" fallback are gone.
    agent-lint.py --lint rule 6 holds an agent's model: to the four aliases
    Claude Code reads: opus, sonnet, haiku and inherit
    (ADR-0022, which
    supersedes ADR-0019 in part).
  • One companion block in every brief. The spawn id, the routing evidence
    and the handback requirement now travel as a second canonical block,
    COMPANION, beside GRAPH DISCIPLINE in
    templates/prompts/graph-session-bootstrap.md. Seed-lint holds every copy
    of both blocks byte-identical.
  • Known bugs. A bug a test uncovered is marked for a fix and the owner is
    told. The test that found it stays unchanged as the bug's only acceptance
    check; the implementer fixes the bug and the same test is re-run, and until
    then the red is declared in the delivery (test-first.known-bug).
  • Retractions. A recorded claim found false is struck through, with a
    dated Correction beside it. skill.holistic-editing is the one home of
    that rule, and graft uses it for a plant fact it corrects.
  • The humanizer scope. The humanizer pass applies to prose a person reads
    (documentation, extensive comments, handoffs and briefs for people,
    ADR and spec bodies). Graph nodes and session records get none, because
    the graph is written for models; prose-lint.py stays the floor.
  • Corrected facts, among others: the orchestrator's cold-repo route goes
    through protocol.initialize; the legal referrers name the base-roster
    agents/14-legal.md, and agent-corpus/legal.md, a duplicate of its
    mandate, is removed at the owner's go-ahead; SSH
    hardening allows root login by public key and refuses it by password
    (PermitRootLogin prohibit-password); the
    deploy-fleet-on-remote-docker-host skill-corpus page uses
    StrictHostKeyChecking=accept-new with a committed known_hosts; the
    skill-corpus release page defines its "release branch".

What was removed

  • The closing prohibition lists ("What you do not do", "Anti-patterns",
    "Common ways to fail", "Forbidden moves", "What stays out of scope"), after
    each rule they carried moved into the section that owns it. The fact key
    holistic-editing.forbidden-moves stays; its section is now "Integration
    moves". skill-corpus/discardme.md is unchanged this round, and the
    Anti-patterns catalogs of templates/knowledge-graph/_schema.md and
    multi-agent-architect stay, because they are catalogs, not closing
    lists.
  • The KNOWN_BUG_<id> assertion marker in protocol.verify-disagreement and
    every copy of it.
  • History narration in doctrine ("until 7.x", "added in", "was split"). A
    sentence that carried a rule's reason now states the reason in the present
    tense; the history stays here, in the changelog.

The owner's rulings

The round asked the owner ten questions. The answers: the reference pages
keep their walkthroughs and stay current (D1); lint holds the brief
companion aligned (D2); the humanizer's LICENSE.upstream names the
doctrine's holder (D3); SSH host keys and root login as above (D4, D5); the
skill-corpus "unsecured lane" is defined as a release branch (D6); known bugs
as above (D7); retractions as above (D8); one model policy for Prime Agent,
Claude Code and opencode, where Prime Agent and opencode may run any
provider (D9); and templates/knowledge-graph/_schema.md keeps its
frontmatter house style with two named exceptions (D10).

New checks

  • check_seed_only_stays_home: docs/skills/seed-release.md and
    tools/prepare-release.py are never named by manifest.json or
    install.sh, and the manifest's tools map equals what install.sh
    places.
  • check_decision_index: docs/decisions/index.md lists every ADR file, and
    every link resolves.
  • check_reference_tables compares each protocol's load_when strings in the
    protocols reference with its frontmatter, and check_published_counts
    checks "N protocols" as it checks agents and skills.
  • agent-lint.py --lint rule 6, above.
  • tools/prepare-release.py refuses a CHANGELOG entry holding a ##
    heading that is not a version heading, because the entry would end there.
  • graft-audit.py --unfilled and growth-audit.py report an unfilled model
    map as a disclosed line, not a failure.

Decisions and specs

  • ADR-0021: a
    procedure that runs only on the seed's own tree lives under docs/skills/,
    and seed-lint proves it never reaches a plant. Its first procedure is
    docs/skills/seed-release.md, the end-of-round release: one documentation
    pass, the gate, the staged notes, the commit, the steward plant's canonize,
    and the tag push on the owner's go-ahead. CLAUDE.md's Release section is
    now a pointer to it.
  • ADR-0022: the model map,
    above. Both ADRs are proposed.
  • SPEC-0001 gains the model-map contracts: the template is placed once and
    then left to the plant, the opencode projection takes its model: line from
    the map or drops it, an unreadable map fails closed, --check detects
    opencode drift, and the seed-only files are never placed.
  • SPEC-0003's brief-template contract covers the COMPANION block.
  • SPEC-0005 (version 0.15) adds AGENT_DECLARES_MODEL_CLASS.
  • The round's plan of record is docs/plans/grill-7.35.0-positive-voice.md.

How plants pick this up

  • A new plant gets everything from install.sh and the install prompt.
    The model map arrives as a template; growth asks the owner to fill it with
    the other plant facts.
  • An existing plant gets it by graft. The machinery fast-forwards, and
    the model map is placed because it is missing. Until the owner fills it,
    graft reports it as a disclosed line, not a blocker, and every agent runs
    on its caller's model. On opencode, re-run install.sh opencode after
    filling the map. A plant agent whose model: holds a full model id fails
    rule 6 after the graft; the id belongs in the map, and haiku or
    inherit keep passing.
  • Skill-corpus copies stay the plant's. A plant that instantiated
    deploy-fleet-on-remote-docker-host or harden-docker-host from the skill
    corpus keeps its own copy, and graft does not refresh it. Compare its SSH
    line and its PermitRootLogin setting with the corpus page and bring them
    in line.
  • Routing text moved in a few places, as stale-fact fixes: the
    verify-disagreement description and one of its load_when lines, the
    grow description (its scouts and authors are now named by class,
    investigation and authoring), and the spec-author description, which
    now cites rule.spec. In several agent, protocol and skill descriptions,
    an all-caps word is now in plain case. A plant that keeps its own route
    golden set may see rows move after the graft.
  • Existing KNOWN_BUG_<id> assertions in a plant's suites are the
    plant's own tests, and graft leaves them in place. When one of those bugs is
    next worked on, follow test-first.known-bug.

v7.34.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 06:35

7.34.0 — a harvest: tests sized by contract, and grill-lint reads a spec's status from its frontmatter (2026-09-30)

A grown plant was harvested back into the seed. What ships here is the
general part: no plant identity, no stack, and no counts from any project.

Signs that a check costs more than it is worth. test-first.proportionate-checks
names four more. A test that passes on either of two implementations asserts
nothing, so it asserts the one mechanism, and a contract that allows two shapes
goes back as a spec ambiguity. Where a behavioral assertion is possible, no
test checks that code calls a function, imports a module or takes a path: a
mock that only counts calls fails on a rename and passes on wrong behavior.
A long setup, a helper of its own, or a comment that points at the one line
that matters marks a test as over budget, and the answer is a smaller test or none. A
property of a factory, a table or a loop is one case over the collection,
never one per element. The Mocking-everything anti-pattern in test-first now
links to the mock and either-or rules instead of repeating them.

A plan names contracts, not test cases. In grill.increment-shape, the
Tests to write (RED): field names the contract slugs and a case cap no
larger than the number of contracts. The tester names the cases. A plan that
lists test names writes the suite twice, once in prose that nobody runs. The
grill template follows the new shape.

grill-lint reads a spec's status from its frontmatter first, as spec-lint
already did. The spec template's body line says "see frontmatter", so
grill-lint read every spec as live and asked the plan to cover the contracts
of a retired spec. It no longer does. A regression case holds the fix.

The owner ruled that the doctrine changes carry no tests of their own ("don't
write tests about when to not write tests"). The lints are their proof.

Rejected: a second home for anti-patterns the skill already owns, and the
plant's own measured evidence.

Harvest log

# Harvest — from a grown plant — 2026-09-30
Harvested:   four rules on an over-budget test in the test-first skill;
             a contract-and-cap shape for a plan's RED field, with the
             template; a grill-lint fix with its regression case.
             No plant identity.
Generalized: plant names, paths, stack and counts stripped.
Rejected:    a second home for anti-patterns the skill already owns; the
             plant's own measured evidence.
Decided:     the owner ruled that the doctrine changes carry no tests of
             their own; the lints are their proof.

Seed integrity gate (verdicts only)

  • G1 agnosticism-floor: PASS
  • G2 agnosticism-judgment: PASS
  • G3 faithful-import: PASS after correction (two thinned passages restored; one skipped rule added by owner ruling)
  • G4 availability: PASS
  • G5 plant-untouched: PASS
  • G6 self-consistency: PASS
  • G7 clean-install: PASS
  • G8 prose: PASS, genre exception recorded (the heading dash and the version arrow are the entry format)
  • G9 minimum-sufficient: PASS
  • G10 provenance: PASS
  • G11 no-loosened-limit: PASS
  • Version bump: 7.33.0 → 7.34.0