ce797b7556
The nested-subagent-dispatch constraint is unchanged in Opus 4.8. Workflows added a top-level fan-out mechanism alongside it, but a workflow's spawned agents still cannot spawn further agents. Record this in both the design rationale and the README capability list so a future reader does not read the plugin as unaware of Workflows.
121 lines
5.0 KiB
Markdown
121 lines
5.0 KiB
Markdown
# Design
|
|
|
|
## Why split plugin from profile
|
|
|
|
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 a per-project profile).
|
|
|
|
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/`, `design/INDEX.md`, `Form A`, or any project-specific
|
|
identifier, it goes to the profile (as a slot) or to the
|
|
project's `CLAUDE.md` (as sittenkodex).
|
|
|
|
## Plugin layer (universal)
|
|
|
|
The plugin owns:
|
|
|
|
- **Pipeline form** — the directed graph of phases:
|
|
`design → plan → execute → review → close`, with the
|
|
bug-driven side path `debug → execute (mini)`.
|
|
- **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** — no reset, no revert, by any actor.
|
|
main moves forward only via orchestrator commits.
|
|
- **No nested subagent dispatch** — a hard Claude Code
|
|
platform constraint; the implement-orchestrator runs phases
|
|
as sequential role-switches inside its own context. Opus 4.8
|
|
added Workflows as an orthogonal top-level fan-out mechanism
|
|
but did not lift this constraint — a workflow script
|
|
orchestrates from the top level, yet the agents it spawns
|
|
still cannot spawn further agents.
|
|
- **No orphan agents** — every agent lives under the skill
|
|
that dispatches it.
|
|
- **Output budget discipline** — agents have word budgets on
|
|
their reports.
|
|
|
|
## Profile layer (project-specific)
|
|
|
|
The profile fills slots that the plugin's prose references
|
|
generically. Concretely:
|
|
|
|
- **Paths**: `spec_dir`, `plan_dir`, `design_ledger`,
|
|
`design_contracts`, `design_models`, `code_roots`, `bench_dir`.
|
|
- **Commands**: `build`, `test`, `lint`, `regression` (list).
|
|
- **Vocabulary**: `cycle`, `subcycle`, `ledger_entry`.
|
|
- **Naming**: `counter_dirs`, `policy` (`stable_per_directory_4digit`
|
|
or `date_prefix` or `flat`).
|
|
- **Standing reading**: `always` (a list), `by_role` (a map
|
|
from role to list).
|
|
- **Git**: `main_sacrosanct` (bool, default true),
|
|
`only_orchestrator_commits` (bool, default true),
|
|
`issue_tracker.kind` (`gitea` / `github` / `linear` / `none`),
|
|
`issue_tracker.close_marker` (e.g. `"closes #N"`).
|
|
- **Pipeline customisations**: per-phase `mandatory_before`,
|
|
`mandatory_at`, `boss_only`, `when` (a condition tag).
|
|
|
|
The full schema lives in `profile-schema.md`. The functional
|
|
starting template is `../templates/project-profile.yml`.
|
|
|
|
## Resolution model
|
|
|
|
The plugin uses **profile-driven prompts**, not template
|
|
rendering. Each SKILL.md and agent file is generic prose that
|
|
references the profile prosaically:
|
|
|
|
> Write the spec to the directory configured under `paths.spec_dir`
|
|
> in the project profile. Use the naming policy configured under
|
|
> `naming.policy`.
|
|
|
|
When Claude Code loads the skill, the project profile is in
|
|
context (the skill body explicitly instructs the model to read
|
|
it first). The model performs the substitution 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
|
|
- **Profile** (per project): slots — paths, commands,
|
|
vocabulary, naming, git conventions, pipeline customisations
|
|
- **Project CLAUDE.md**: sittenkodex — domain-specific anti-
|
|
patterns and acceptance criteria
|
|
|
|
## What's out of scope for this plugin
|
|
|
|
- **Issue-tracker integration**: the plugin can read the
|
|
profile's `issue_tracker.kind` and `issue_tracker.list_cmd`
|
|
and invoke the configured listing command, but does not
|
|
directly call Gitea / GitHub / Linear APIs. The `boss` skill
|
|
uses the configured shell command for queue reads, so the
|
|
plugin remains transport-agnostic.
|