Files
Brummel 08bc2aa027 refactor(pipeline): specs/plans are gitignored working files, never committed
Per-cycle specs and plans stop being git-tracked commit-then-git-rm
artefacts and become git-ignored working files: created on disk for the
active cycle, read across sessions from the working tree, and shell-rm'd
at cycle close by audit. Nothing is committed, so there is no
git-history copy — the durable record of a cycle's intent is the design
ledger only, and no durable artefact (code, test, doc, ledger) may cite
a spec/plan by number or path.

- conventions/pipeline/design/README: invert the git-tracked -> git-rm
  -> git-history-recovery model to gitignored -> shell-rm -> ledger-only.
- naming: drop the NNNN file counter; files are slug.md (fieldtest specs
  keep a fieldtest- prefix as the cycle-close discriminator).
- cycle number: separated from the (now-gone) file number, sourced from
  the feat(NNNN)/audit(NNNN) commit subjects, which cycle commits carry.
- specify/planner/fieldtest/fieldtester: no commit step; fieldtest splits
  fixtures (committed as code) from its spec (gitignored), with the
  cross-cycle rule that a fieldtest- spec belongs to the next cycle.
- boss: auto-sign auditability moves from the (boss-signed) commit
  subject to the run's reference issue; rollback reverts only code.
- audit: new Step 5 shell-rm's the cycle spec+plan after the architect
  reads them, sparing fieldtest- specs.

Companion machine config (outside this repo): the global git excludes
(~/.config/git/ignore) gains docs/specs/ and docs/plans/ so the ignore
applies to every project at once.
2026-07-02 11:35:06 +02:00

155 lines
7.3 KiB
Markdown

# Design
## Why split plugin from project
The skills system originally evolved inside the AILang project,
where it grew organically against AILang's specific paths,
build commands, vocabulary, and contracts. Lifting it into a
plugin requires a clean separation between what is universal
(belongs in the plugin) and what is project-specific (belongs
in the project's `CLAUDE.md`).
The litmus test: would a sentence in a SKILL or agent body
still make sense in a Python web project, a Rust CLI, and a
TypeScript library? If yes, plugin. If it mentions `cargo`,
`crates/`, `docs/design/INDEX.md`, `Form A`, or any project-specific
identifier, it goes to the project's `CLAUDE.md` — either as a
project fact (the few mechanical facts the skills consume) or as
sittenkodex (domain contracts, anti-patterns).
There is no separate profile file. An earlier design had a
per-project `dev-cycle-profile.yml`, but it was never parsed — it
was prose the skill bodies told the model to read, and almost every
slot was constant across projects, dead, or derivable. So the
constant parts became fixed conventions (`conventions.md`) and the
genuinely-varying parts moved into each project's `CLAUDE.md`.
## Plugin layer (universal)
The plugin owns:
- **Pipeline form** — the directed graph of phases:
`design → plan → execute → review → close`, entered through a
**selector cascade** of entry paths walked on a verification /
enumeration axis (observed bug → `debug`; design fork →
`brainstorm`; behaviour-preserving type/signature edit →
`compiler-driven`; test-specifiable → `tdd`; else → spec-driven).
The taxonomy of paths and their oracles lives in
`pipeline.md` § The methodology taxonomy.
- **Hard-gates** — spec before plan, plan before implement,
audit before cycle-close. Skipping rules are codified per
skill.
- **Agent template** — every agent file follows the same
structure: frontmatter (name, description, tools), Iron Law,
standing reading list, numbered process, status protocol,
output format, common rationalisations, red flags.
- **TDD as an independent inner-loop discipline** — the
implementer agent carries TDD even when the plan task forgot
to script a RED-first step.
- **RED-first bug fixes** — non-negotiable for any observable
misbehaviour; the debug skill is the gate.
- **Status protocol** — `DONE / DONE_WITH_CONCERNS / PARTIAL /
BLOCKED / NEEDS_CONTEXT`, plus reviewer-specific terminal
states.
- **Working-tree-as-quarantine** — agents write artefacts to
the working tree, never commit. Only the orchestrator commits.
- **main HEAD sacrosanct below the session anchor** — no reset, no
revert of user-ratified history, by any actor; main moves forward only
via orchestrator commits. The one narrow exception is the `/boss`
rollback sandbox: the orchestrator may wind back its *own* unpushed
autonomous commits above the run's start anchor (`boss/SKILL.md`
§ Direction freedom).
- **No nested subagent dispatch** — a hard Claude Code platform
constraint: an agent cannot spawn further agents. Workflows do not
lift it; a workflow script orchestrates from the **top level**, and
the agents it spawns still cannot spawn further agents. This is
exactly why the autonomous execution loops moved onto the Workflow
substrate: the `implement-loop` and `compiler-driven-edit` scripts
(`implement/workflows/`) run the per-phase agents as their own
top-level `agent()` calls, so a single phase is independently
invokable — which retired the former `implement-orchestrator`
agent's inline-role-switch workaround (it had to absorb the three
phases into one context precisely because it could not nest). The
four phase agents survive as the agent-types the scripts dispatch;
what was retired is the dispatch/aggregation prose. The interactive
paths (`specify`, `brainstorm`) stay prose skills — their oracle is
human intent and needs a human in the loop, which a
run-to-completion workflow cannot host.
- **No orphan agents** — every agent lives under the skill
that dispatches it.
- **Output budget discipline** — agents have word budgets on
their reports.
## Fixed conventions (universal)
The constants that used to be configurable but were the same in
every project are now plugin conventions, named directly in skill
and agent bodies and documented once in `conventions.md`:
spec dir `docs/specs`, plan dir `docs/plans`, slug-only `slug.md`
naming, the vocabulary cycle / iteration / milestone / contract,
standing reading (`CLAUDE.md` + `git log -10`), git discipline
(only-orchestrator commits, main sacrosanct), Gitea + `closes #N`,
and the whole pipeline graph (see `pipeline.md`).
Specs and plans are ephemeral active-cycle working files — the two
directories are git-ignored and hold only what is in flight; at cycle
close each is shell-`rm`'d (never committed, so nothing to `git rm` and
no git-history copy). The durable record of a past cycle is the design
ledger only, and no durable artefact cites a spec/plan (see
`conventions.md` § Lifecycle).
## Project facts (project-specific)
The handful of facts that genuinely vary per project live in the
project's `CLAUDE.md` under `## Skills plugin: project facts`:
code roots, build / test / lint / doc-build commands, regression
scripts, architect sweeps, design-ledger / glossary / contracts /
models / bench / public-interface / fieldtest-examples paths,
by-role standing reading, and the issue-tracker repo slug and commands.
The template is in
`../templates/CLAUDE.md.fragment`; the per-fact reference is the
table in `conventions.md`.
## Resolution model
The plugin uses **convention-and-fact prompts**, not template
rendering and not a config parser. Each SKILL.md and agent file is
generic prose that either names a fixed convention directly or
points at a project fact:
> Write the spec to `docs/specs`. Use the project's build command
> (its CLAUDE.md project facts).
The project's `CLAUDE.md` is always in context (it is standing
reading #1), so the model resolves the facts at read-time. This
avoids a build step and keeps a single source of truth in the repo.
## Sittenkodex split
The plugin does **not** carry project-specific anti-patterns,
feature-acceptance gates, or domain contracts. Those belong in
the project's own `CLAUDE.md`. The plugin only carries the
*universal* discipline constants (only-orchestrator commits,
main sacrosanct, no orphan agents, agents-don't-call-agents)
which are conditions for the plugin's own correctness.
The relationship:
- **Plugin** (this repo): mechanics, universal discipline, fixed
conventions
- **Project CLAUDE.md**: project facts — the few mechanical facts
the skills consume (code roots, build/test, tracker slug, …) —
plus sittenkodex (domain-specific anti-patterns and acceptance
criteria)
## What's out of scope for this plugin
- **Issue-tracker integration**: the plugin reads the project's
issue-tracker commands (the repo slug, list command, and
single-issue-with-comments command, all in its CLAUDE.md project
facts) and invokes them, and `specify` may post a reconciliation
comment or create a seeding issue via the tracker's comment / create
commands — but the plugin does not directly call Gitea / GitHub /
Linear APIs. Every read and write goes through the configured shell
command, so the plugin remains transport-agnostic.