From 253273b0071a04545359af98db0748afb650efee Mon Sep 17 00:00:00 2001 From: Brummel Date: Thu, 28 May 2026 14:20:13 +0200 Subject: [PATCH] skeleton: plugin layout + docs, skill/agent migration deferred to iter 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Establishes the repository structure for the skills plugin: - README + INSTALL describing the two-layer split (plugin mechanics vs per-project profile) - docs/design, profile-schema, pipeline, agent-template covering the universal discipline constants and the profile slot model - templates/project-profile.yml as a copy-and-fill starting point - templates/CLAUDE.md.fragment with the baseline orchestrator rules a project can import - install.sh / uninstall.sh wiring skills/ + agents/ into ~/.claude/ via idempotent symlinks - skills/ and agents/ directories empty except for migration READMEs; the actual SKILL bodies and agent files migrate from ~/dev/ailang/skills/ in the next iteration. No skill or agent runs yet — this commit only stands up the structure and documents the substitution model. --- .gitignore | 4 + INSTALL.md | 65 ++++++++++++ README.md | 75 ++++++++++++++ agents/README.md | 54 ++++++++++ docs/agent-template.md | 182 ++++++++++++++++++++++++++++++++++ docs/design.md | 120 ++++++++++++++++++++++ docs/pipeline.md | 129 ++++++++++++++++++++++++ docs/profile-schema.md | 150 ++++++++++++++++++++++++++++ install.sh | 59 +++++++++++ skills/README.md | 45 +++++++++ templates/CLAUDE.md.fragment | 69 +++++++++++++ templates/project-profile.yml | 55 ++++++++++ uninstall.sh | 32 ++++++ 13 files changed, 1039 insertions(+) create mode 100644 .gitignore create mode 100644 INSTALL.md create mode 100644 README.md create mode 100644 agents/README.md create mode 100644 docs/agent-template.md create mode 100644 docs/design.md create mode 100644 docs/pipeline.md create mode 100644 docs/profile-schema.md create mode 100755 install.sh create mode 100644 skills/README.md create mode 100644 templates/CLAUDE.md.fragment create mode 100644 templates/project-profile.yml create mode 100755 uninstall.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fc409a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +*.swp +*.bak +*~ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..07e2fc0 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,65 @@ +# Install + +## Prerequisites + +- Claude Code with `~/.claude/` writable +- bash or any POSIX shell to run `install.sh` + +## One-time global install + +```sh +git clone ~/dev/skills +cd ~/dev/skills +./install.sh +``` + +`install.sh` creates symlinks from `~/.claude/skills/` and +`~/.claude/agents/` into this repo. Claude Code discovers them +at session start under user-level skill and agent registries, +so they become available in every project without further setup. + +To uninstall: + +```sh +~/dev/skills/uninstall.sh +``` + +## Per-project activation + +A project opts in by dropping a profile file: + +```sh +cp ~/dev/skills/templates/project-profile.yml \ + /.claude/dev-cycle-profile.yml +$EDITOR /.claude/dev-cycle-profile.yml +``` + +Edit the profile to match the project's paths, commands, and +vocabulary. The skill bodies read the profile at the start of +each invocation; there is no template-render step. + +A project that has not dropped a profile file gets sensible +fallbacks (see `docs/profile-schema.md` for the defaults), but +the discipline shines when the profile is explicit. + +## Per-project CLAUDE.md fragment + +The plugin handles mechanics. Project-specific *sittenkodex* — +feature acceptance criteria, anti-patterns the project has +earned the hard way, domain-specific contracts — belongs in the +project's own `CLAUDE.md`. A starter fragment with the universal +discipline sentences (only-orchestrator-commits, main sacrosanct, +no nostalgia for removed features, etc.) lives in +`templates/CLAUDE.md.fragment` for projects that want to import +those baseline rules without rewriting them. + +## Update + +```sh +cd ~/dev/skills && git pull +``` + +Symlinks pick up the changes automatically. If new skills or +agents have been added, re-run `install.sh` to add the new +symlinks (it is idempotent and will not overwrite existing +ones). diff --git a/README.md b/README.md new file mode 100644 index 0000000..2f46ec7 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +# skills + +A self-contained set of development-cycle skills and agents for +Claude Code. Originally distilled from the AILang project's +in-tree `skills/` directory and generalised so it can carry the +same discipline across any project. + +The plugin is **mechanics**: pipeline shape, hard-gates, TDD, +RED-first bug fixing, agent-template, working-tree-as-quarantine, +status protocol. It does **not** know your project's paths, +build commands, vocabulary, or domain-specific contracts. Those +live in a small per-project profile file +(`.claude/dev-cycle-profile.yml`) plus the project's `CLAUDE.md`. + +## What's in the box + +Seven skills, each with the agents it primarily dispatches: + +| Skill | Trigger | Output | Mandatory? | +|-------|---------|--------|------------| +| `brainstorm` | New cycle starting | spec under the configured spec dir | Hard-gate before plan | +| `planner` | New iteration within an open cycle | plan under the configured plan dir | Hard-gate before implement | +| `implement` | Plan exists | code + tests, uncommitted in working tree | Standard iteration path | +| `audit` | Cycle closing OR baseline drift suspected | drift report + regression report | Mandatory at cycle close | +| `debug` | Bug observed | RED test in working tree + cause analysis | Mandatory RED-first for any bug | +| `fieldtest` | Orchestrator-dispatched post-audit, surface-touching cycle | example fixtures + friction spec | Optional | +| `docwriter` | API surface stable across N cycles | rustdoc / docstring sweep | Optional | + +Vocabulary is configurable. AILang calls a cycle a *milestone* +and a sub-cycle an *iteration*; your project may call them +*release* and *sprint*, or *epic* and *story*, or whatever fits. + +## The two-layer split + +This repo (the **plugin**) carries everything that is universal: + +- Pipeline form: `design → plan → execute → review → close` +- Hard-gates between phases +- TDD as an independent inner-loop discipline +- RED-first bug fixes +- Agent template (frontmatter / Iron Law / standing reading / + process / status / output / rationalisations / red flags) +- Status protocol: `DONE / DONE_WITH_CONCERNS / PARTIAL / BLOCKED + / NEEDS_CONTEXT` +- Working-tree-as-quarantine and only-orchestrator-commits +- main HEAD sacrosanct +- No nested subagent dispatch (Claude Code platform constraint) +- No orphan agents + +Your project carries a small **profile** that fills the slots: + +- Paths: spec dir, plan dir, design ledger, code roots, bench dir +- Commands: build, test, lint, regression scripts +- Vocabulary: cycle name, sub-cycle name, ledger-entry name +- Naming: counter prefix vs date prefix vs flat, slug shape +- Standing reading list: concrete files, per role +- Git: issue tracker kind, close marker, main-protection policy +- Pipeline customisations: which phases are mandatory, when + optional ones fire + +See `docs/profile-schema.md` for the full schema and +`templates/project-profile.yml` for a copy-and-fill starting point. + +## Install + +See `INSTALL.md`. In short: clone, run `install.sh`, then drop +a `dev-cycle-profile.yml` into each project that should use the +plugin. + +## Status + +This is the skeleton commit. The skill bodies and agent files +still need to be migrated from AILang's in-tree +`~/dev/ailang/skills/` and generalised against this plugin's +profile schema. That migration is iteration 1. diff --git a/agents/README.md b/agents/README.md new file mode 100644 index 0000000..c071dfc --- /dev/null +++ b/agents/README.md @@ -0,0 +1,54 @@ +# agents/ + +One subdirectory per skill, mirroring the `skills/` layout. +Each holds the agent files that the corresponding skill +dispatches. + +The skeleton commit ships this directory empty. Agent files +are migrated from AILang's in-tree +`~/dev/ailang/skills//agents/` and generalised against +the agent template (`../docs/agent-template.md`) and the +profile schema (`../docs/profile-schema.md`) in **iteration 1**. + +Expected layout after migration: + +``` +agents/ +├── brainstorm/ +│ └── grounding-check.md +├── planner/ +│ └── plan-recon.md +├── implement/ +│ ├── implement-orchestrator.md +│ ├── implementer.md +│ ├── spec-reviewer.md +│ ├── quality-reviewer.md +│ └── tester.md +├── audit/ +│ ├── architect.md +│ └── bencher.md +├── debug/ +│ └── debugger.md +├── fieldtest/ +│ └── fieldtester.md +└── docwriter/ + └── docwriter.md +``` + +Migration checklist per agent: + +1. Drop the `ailang-` prefix from the `name:` frontmatter + field. The agent path is the disambiguator. +2. Replace hardcoded standing-reading paths + (`design/INDEX.md`, etc.) with a reference to the profile's + `standing_reading` section. +3. Replace project-specific Iron Law clauses with the universal + discipline constants; project-specific clauses go to the + project's own `CLAUDE.md`. +4. Verify the body still reads coherently for a generic project + (see the skills/ migration checklist). +5. Confirm the `tools:` frontmatter list matches the agent + template's role-based conventions (read-only review vs + implementation vs orchestrator). +6. Confirm the agent does **not** have `Agent` in its tools list + (no nested subagent dispatch). diff --git a/docs/agent-template.md b/docs/agent-template.md new file mode 100644 index 0000000..9dda309 --- /dev/null +++ b/docs/agent-template.md @@ -0,0 +1,182 @@ +# Agent template + +Every agent file follows the same structure. Deviations need a +named reason in the agent's own body. The template was distilled +from the AILang in-tree agents and refined to remove project- +specific identifiers. + +## File layout + +``` +--- +name: +description: +tools: +--- + +> Violating the letter of these rules is violating the spirit. + +## What this role is for + + + +## Standing reading list + +`> + +## Carrier contract + + + +## Iron Law + + + +## The Process + + + +## Status protocol + + + +## Output format + + + +## Common Rationalisations + +| Excuse | Reality | +|--------|---------| +| … | … | + +(Calibrated to the past failure modes of this role.) + +## Red Flags — STOP + +- If you're about to do , stop. +- … +``` + +## Frontmatter conventions + +### `name` + +The agent slug, lowercase kebab-case. No project prefix (the +old `ailang-*` prefix was an AILang-only convention; the +plugin's agent path is enough disambiguator). + +Examples: `architect`, `bencher`, `debugger`, `implementer`, +`tester`, `fieldtester`, `docwriter`, `grounding-check`, +`plan-recon`, `spec-reviewer`, `quality-reviewer`, +`implement-orchestrator`. + +### `description` + +One sentence. Third-person. Either "Use when…" or a role +description. This is what the orchestrator (or a skill) reads +to decide whether to dispatch the agent — keep it sharp. + +### `tools` + +Comma-separated list of Claude Code tool names. No agent +receives `Agent` in its tools (no nested subagent dispatch). +The dispatching skill composes; agents do not call other +agents. + +Common tool sets: + +- Read-only review (architect, spec-reviewer, quality-reviewer, + grounding-check, plan-recon): `Read, Glob, Grep, Bash` +- Implementation (implementer, tester, debugger, docwriter, + fieldtester, bencher): `Read, Edit, Write, Bash, Glob, Grep` +- Orchestrator (implement-orchestrator): `Read, Edit, Write, + Bash, Glob, Grep` — same as implementer; the orchestration + happens via sequential role-switches within its own context + +## Sections in detail + +### Spirit-letter lead-in + +The single line `> Violating the letter of these rules is +violating the spirit.` is mandatory at the top. It exists to +forestall the "well, technically I didn't break the rule" class +of rationalisation. + +### What this role is for + +One short paragraph. Names the failure mode the agent exists to +prevent — not the success mode it enables. Failure-mode framing +is sharper for the model: "this role exists because past attempts +to do X without a dedicated reviewer led to Y" reads more +forcefully than "this role helps with X". + +### Standing reading list + +The plugin's skill body computes this from the project profile +(`standing_reading.always` + `standing_reading.by_role.`) +and passes the resolved list to the agent via the carrier. The +agent's body says, prosaically: "Read everything in the standing +reading list before doing anything else." + +The agent file itself does not hardcode file paths. + +### Carrier contract + +The carrier is the small payload the skill hands the agent. It +typically includes: + +- `task_text` — the spec excerpt or plan task verbatim +- `diff` — for reviewers, the diff to review +- `hypothesis` — for the bencher, what it should test +- `bug_symptom` — for the debugger, the observable misbehaviour +- `drift_focus` — for the architect, what part of the ledger to + check + +Agents do **not** open the project's plan or spec directories +directly to fish for context. Context curation lives at the +skill level so the orchestrator can see exactly what each agent +was told. + +### Iron Law + +Numbered list of the non-negotiable rules. These are the rules +the agent will violate if it rationalises. Calibrate to past +failure modes — abstract rules don't land; rules anchored to a +named past mistake do. + +### The Process + +Numbered steps. Each step is concrete — "Read X", "Run Y", +"Write to Z" — not abstract phases like "explore" or "synthesise". + +### Status protocol + +Specifies which terminal states the agent uses (see +`pipeline.md`) and what evidence each state requires. For +example: `DONE` requires "build green AND tests green AND no +new warnings". + +### Output format + +Word-budgeted. Structured — usually a small set of named +sections the orchestrator can quote in its commit body. The +budget prevents agent reports from drowning the orchestrator's +context. + +### Common Rationalisations + +A table of excuse → reality. Calibrated to the past failure modes +of this role. The point is to short-circuit the rationalisation +before it derails the agent's process. + +### Red Flags — STOP + +Bullet list of "if you're about to do this, stop" signals. +Concrete, not abstract. "If you're about to write a fix without +a failing test, stop" beats "be disciplined". diff --git a/docs/design.md b/docs/design.md new file mode 100644 index 0000000..829d53d --- /dev/null +++ b/docs/design.md @@ -0,0 +1,120 @@ +# 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. +- **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 + +- **Boss/autonomous-orchestrator mode**: AILang's `boss` skill + is gated to a user-invoked `/boss` for autonomous queue + execution. Whether that generalises across projects is + unclear (queue mechanics depend on issue-tracker semantics). + Not in the initial skeleton; possibly added later as + `skills/boss/` if a cross-project autonomous mode crystallises. +- **Issue-tracker integration**: the plugin can read the + profile's `issue_tracker.kind` and adjust commit-marker + suggestions, but does not directly call Gitea / GitHub / + Linear APIs. diff --git a/docs/pipeline.md b/docs/pipeline.md new file mode 100644 index 0000000..dcba43a --- /dev/null +++ b/docs/pipeline.md @@ -0,0 +1,129 @@ +# Pipeline + +``` +[new cycle] [bug observed] + | | + v v + brainstorm -> plan -> implement debug -> implement (mini) + (per iteration loop) + | + [cycle close] + | + v + audit --(drift)--> plan + implement (tidy iteration) + --(ratify)-> --update-baseline + ratify paragraph in audit commit body + --(clean)-+ + | + [orchestrator: cycle complete? if surface-touch:] + v + fieldtest --(bug)------> debug -> implement (mini) + --(friction)-> brainstorm OR plan (tidy) + --(spec_gap)-> ratify OR tighten ledger + --(clean)----+ + | + [orchestrator: surface stable across N cycles?] + v + docwriter + | + v + next cycle +``` + +## Phase descriptions + +### brainstorm + +Hard-gate before plan. Gathers requirements, explores 2-3 +approaches with trade-offs, presents a sectioned design with +user approval, writes the spec to the configured `spec_dir`. + +### planner + +Hard-gate before implement. Produces a placeholder-free, +bite-sized implementation plan in the configured `plan_dir` +that the implement skill can execute task-by-task. Dispatches +the plan-recon agent for read-only file-structure mapping. + +### implement + +Dispatches the implement-orchestrator agent, which runs the +entire per-task loop (implementer phase → spec-compliance check +→ quality check) as sequential role-switches inside its own +context. Writes code, tests, and stats files directly in the +working tree as unstaged changes. On `PARTIAL` or `BLOCKED`, +also writes `BLOCKED.md` at the repo root. + +### audit + +Runs at cycle close. Dispatches the architect agent (read-only +drift review against the design ledger) and the bencher agent +(regression diagnostics). Reports drift and regress. + +### debug + +Runs whenever a bug is observed. RED-first: produces a failing +test in the working tree before any fix is attempted. Hands off +the GREEN side to the implement skill in mini mode. + +### fieldtest + +Optional. Orchestrator-dispatched after the audit closes clean +on a cycle that touched user-visible surface. Picks 2-4 real- +world tasks within the cycle's scope, implements them using +only the design ledger and public examples (never the language's +own implementation), runs the results, and writes a friction- +and-bug spec. + +### docwriter + +Optional. Orchestrator-dispatched after API surface has +stabilised across multiple cycles. Brings docstrings up to a +level where a newcomer can navigate the public API without +reading the design ledger first. + +## Status protocol + +Agents return one of these terminal states: + +| State | Meaning | +|-------|---------| +| `DONE` | Task complete; no concerns. | +| `DONE_WITH_CONCERNS` | Task complete; flagged issues the orchestrator should weigh before committing. | +| `PARTIAL` | Task partially complete; the rest is blocked or out-of-scope. Writes `BLOCKED.md`. | +| `BLOCKED` | Task cannot proceed; explanation in report. Writes `BLOCKED.md`. | +| `NEEDS_CONTEXT` | Task cannot proceed without additional information from the orchestrator. | + +Reviewer agents have role-specific states: + +| Role | States | +|------|--------| +| spec-reviewer | `compliant` / `non_compliant` / `unclear` / `infra_blocked` | +| quality-reviewer | `approved` / `changes_requested` / `infra_blocked` | + +## Skip rules + +Skipping is codified per skill, not ad hoc. Each `SKILL.md` +documents what the skill skips and under what conditions: + +- `brainstorm` is never skipped at cycle start. +- `planner` is never skipped at iteration start, except for + the bug-driven `debug → implement (mini)` side path. +- `implement` is the iteration body; not skippable. +- `audit` is mandatory at cycle close. +- `debug` is mandatory RED-first for any observable bug. +- `fieldtest` and `docwriter` are optional and orchestrator- + dispatched. + +If a skill's body says it must run and the orchestrator wants +to skip it, the orchestrator records the reason in the relevant +commit body — never as undocumented practice. + +## Pipeline configuration + +The phase set, gating, and conditional dispatch are configured +in the project profile under `pipeline:`. A project that does +not want `fieldtest` simply omits the key. A project that wants +a different gate set (e.g. `planner` without a `brainstorm` +gate, for trivial bug-fix iterations) configures it there. + +See `profile-schema.md` for the syntax. diff --git a/docs/profile-schema.md b/docs/profile-schema.md new file mode 100644 index 0000000..ba31cf8 --- /dev/null +++ b/docs/profile-schema.md @@ -0,0 +1,150 @@ +# Profile schema + +Location: `/.claude/dev-cycle-profile.yml` + +Encoding: YAML. Each top-level key is a section. Keys are +lowercase snake_case. Lists are YAML sequences. + +## `paths` + +| Key | Type | Default | Description | +|---------------------|--------|------------------------|-------------| +| `spec_dir` | string | `docs/specs` | Where the brainstorm skill writes specs. | +| `plan_dir` | string | `docs/plans` | Where the planner skill writes plans. | +| `design_ledger` | string | `design/INDEX.md` | Canonical specification index (optional — projects without a design ledger can omit). | +| `design_contracts` | string | `design/contracts` | Directory of prose-authoritative contracts (optional). | +| `design_models` | string | `design/models` | Directory of onboarding whitepapers (optional). | +| `code_roots` | list | `[src]` | Code directories the architect / quality reviewer walk. | +| `bench_dir` | string | `bench` | Where regression harnesses live (optional). | + +Omitted optional keys signal that the feature is unused in this +project; skills that depend on them either short-circuit or +skip the corresponding step. + +## `naming` + +| Key | Type | Default | Description | +|--------------------|--------|----------------------------------|-------------| +| `counter_dirs` | list | `[]` | Directories that use the counter-prefix policy. | +| `policy` | enum | `flat` | One of `stable_per_directory_4digit`, `date_prefix`, `flat`. | +| `slug_separator` | string | `-` | Separator inside the slug. | + +`stable_per_directory_4digit` means each listed directory has a +per-directory counter, 4-digit zero-padded, assigned in +creation order, stable for the life of the file. New files +take the next-higher number; deleted files retire their number. + +`date_prefix` uses `YYYY-MM-DD-slug.md`. + +`flat` uses `slug.md`. + +## `commands` + +| Key | Type | Default | Description | +|----------------|--------|----------------|-------------| +| `build` | string | (required) | Build command — exit 0 means success. | +| `test` | string | (required) | Test command — exit 0 means success. | +| `lint` | string | (optional) | Lint command — exit 0 means success. | +| `regression` | list | `[]` | Regression scripts run by the audit skill. Each entry is a shell command; non-zero exit is a regress. | + +## `vocabulary` + +| Key | Type | Default | Description | +|----------------|--------|----------------|-------------| +| `cycle` | string | `cycle` | What a top-level work unit is called. Examples: `milestone`, `release`, `epic`. | +| `subcycle` | string | `iteration` | What a sub-unit is called. Examples: `iteration`, `sprint`, `story`. | +| `ledger_entry` | string | `contract` | What a single design-ledger entry is called. Examples: `contract`, `RFC`, `ADR`. | + +Skills use these names in their generated artefacts and prose. +Picking accurate vocabulary keeps prose readable; the underlying +mechanics are identical regardless of name. + +## `standing_reading` + +| Key | Type | Default | Description | +|----------------|--------|----------------|-------------| +| `always` | list | `[CLAUDE.md]` | Files every agent reads at start of every dispatch. | +| `by_role` | map | `{}` | Map from role name to list of additional files. | + +Role names match agent slugs: `architect`, `bencher`, `debugger`, +`implementer`, `tester`, `fieldtester`, `docwriter`, +`grounding-check`, `plan-recon`, `spec-reviewer`, `quality-reviewer`. + +Entries may be shell commands as well as file paths — they are +read as opaque strings the agent should fetch / execute, e.g. +`"git log -10 --format=full"`. + +## `git` + +| Key | Type | Default | Description | +|------------------------------|------|---------|-------------| +| `main_sacrosanct` | bool | `true` | If true, no actor may reset or revert main. | +| `only_orchestrator_commits` | bool | `true` | If true, no agent commits; the orchestrator commits. | +| `issue_tracker.kind` | enum | `none` | One of `gitea`, `github`, `linear`, `none`. | +| `issue_tracker.close_marker` | string | `"closes #N"` | Marker the orchestrator includes in commit bodies to auto-close issues. | +| `protected_branches` | list | `[main]` | Branches that are sacrosanct in the same sense as main. | + +## `pipeline` + +Per-phase configuration. Each phase has its own sub-map. + +```yaml +pipeline: + brainstorm: + gates: [planner] # planner cannot start until this has run + planner: + gates: [implement] + implement: {} # standard + audit: + mandatory_at: cycle_close # auto-fires at end of each cycle + fieldtest: + boss_only: true # only orchestrator dispatches + when: surface_touch # condition tag (orchestrator judgement) + docwriter: + boss_only: true + when: api_stable_across_n_cycles + debug: + trigger: bug # observable misbehaviour + red_first: true # RED test before any fix +``` + +Phases not listed are disabled for the project. A project that +does not want a `fieldtest` phase simply omits the key. + +## Example: minimal profile + +```yaml +paths: + spec_dir: docs/specs + plan_dir: docs/plans + code_roots: [src] + +commands: + build: cargo build + test: cargo test + +vocabulary: + cycle: milestone + subcycle: iteration + +standing_reading: + always: + - CLAUDE.md + - "git log -10 --format=full" + +git: + issue_tracker: + kind: github + close_marker: "closes #N" + +pipeline: + brainstorm: { gates: [planner] } + planner: { gates: [implement] } + implement: {} + audit: { mandatory_at: cycle_close } + debug: { trigger: bug, red_first: true } +``` + +This minimal profile enables five phases, no fieldtest, no +docwriter, no design-ledger. Good starting point for a small +project. diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..5cb65d5 --- /dev/null +++ b/install.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# Install the skills plugin globally into ~/.claude/. +# +# Creates symlinks from ~/.claude/skills/ and +# ~/.claude/agents/ into this repo's skills/ and agents/ +# subdirectories. Idempotent — existing symlinks pointing to +# this repo are left alone; existing entries that point elsewhere +# are reported and skipped. + +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +CLAUDE_SKILLS="$HOME/.claude/skills" +CLAUDE_AGENTS="$HOME/.claude/agents" + +mkdir -p "$CLAUDE_SKILLS" "$CLAUDE_AGENTS" + +link_one() { + local src="$1" + local dst="$2" + if [ -L "$dst" ]; then + local existing + existing="$(readlink "$dst")" + if [ "$existing" = "$src" ]; then + echo "ok $dst -> $src" + return 0 + fi + echo "skip $dst already symlinked to $existing" + return 0 + fi + if [ -e "$dst" ]; then + echo "skip $dst exists and is not a symlink" + return 0 + fi + ln -s "$src" "$dst" + echo "link $dst -> $src" +} + +if [ -d "$REPO_DIR/skills" ]; then + for s in "$REPO_DIR"/skills/*/; do + [ -d "$s" ] || continue + name="$(basename "$s")" + link_one "$s" "$CLAUDE_SKILLS/$name" + done +fi + +if [ -d "$REPO_DIR/agents" ]; then + for a in "$REPO_DIR"/agents/*/; do + [ -d "$a" ] || continue + name="$(basename "$a")" + link_one "$a" "$CLAUDE_AGENTS/$name" + done +fi + +echo +echo "Install complete." +echo "Next: drop a profile into each project that should use the plugin:" +echo " cp $REPO_DIR/templates/project-profile.yml /.claude/dev-cycle-profile.yml" diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..3c408b8 --- /dev/null +++ b/skills/README.md @@ -0,0 +1,45 @@ +# skills/ + +One subdirectory per skill, each containing a `SKILL.md` plus +any skill-local resources. + +The skeleton commit ships this directory empty. The actual +skill bodies are migrated from AILang's in-tree +`~/dev/ailang/skills/` and generalised against the profile +schema (`../docs/profile-schema.md`) in **iteration 1**. + +Expected layout after migration: + +``` +skills/ +├── brainstorm/ +│ └── SKILL.md +├── planner/ +│ └── SKILL.md +├── implement/ +│ └── SKILL.md +├── audit/ +│ └── SKILL.md +├── debug/ +│ └── SKILL.md +├── fieldtest/ +│ └── SKILL.md +└── docwriter/ + └── SKILL.md +``` + +Migration checklist per skill: + +1. Strip project-specific paths (`docs/specs`, `docs/plans`, + `design/INDEX.md`, `crates/`, `bench/`). +2. Strip project-specific commands (`cargo build`, + `bench/check.py`). +3. Replace literals with profile-slot references in prose. +4. Strip project vocabulary (`AILang`, `Form A`, `.ail.json`, + `Boss`); use the profile's vocabulary slots. +5. Strip project-specific contracts (honesty-rule, + feature-acceptance). These belong in the project's own + `CLAUDE.md`, not the plugin. +6. Verify the body still reads coherently for a generic + project — would it make sense in a Python web service? + A TypeScript library? diff --git a/templates/CLAUDE.md.fragment b/templates/CLAUDE.md.fragment new file mode 100644 index 0000000..786bcfd --- /dev/null +++ b/templates/CLAUDE.md.fragment @@ -0,0 +1,69 @@ +# Universal discipline fragment +# +# Copy these sections into your project's CLAUDE.md to import the +# baseline rules the skills plugin assumes. Edit freely afterwards — +# this is a starting point, not a binding template. + +## Roles + +I am the **orchestrator** of this project, not the implementer. +The agents under the skills plugin are my workers. I direct +them, review their output, and integrate it. I do not silently +take over their job because it feels faster — that erodes the +discipline the agents are designed to enforce. + +### What this means in practice + +- **Plan, design, decide** — myself. Architectural choices, + scope, invariants, commit bodies, and the contents of the + design ledger are my work product. +- **Implement, refactor, write tests, diagnose bugs** — by + default, delegated. Implementer for code changes that follow + a fixed design, tester for E2E coverage, debugger for + diagnostics, architect for read-only drift review. +- **Trivial mechanical edits** (one-line fixes, doc typos, + rename across N files) — fine to do directly. Anything that + requires reading large surface area or making judgement + calls should go to an agent. +- **Verify the work** — agent reports describe intent, not + outcome. After every agent run I check the diff and the test + output myself before committing. + +## Commit discipline and main-branch sanctity + +Two rules govern who touches git history and how: + +- **Only the orchestrator commits.** No skill agent runs + `git commit`. Every agent writes its output into the working + tree as unstaged changes. I inspect the result, decide commit + shape, and commit. Per-task or per-phase commits are not a + goal in themselves. +- **main HEAD is sacrosanct.** Nobody (including me) runs + `git reset` or `git revert` on main. main moves forward only + via my commits. If a dispatched agent's output is wrong, I + discard it via `git checkout -- ` or `git stash` on + the working tree — main HEAD does not move. If something + wrong does land on main, the remedy is a forward-fix commit, + never a rewind. + +## Design rationale ≠ implementation effort + +When picking between design options, the rationale must come +from the substance of the choice: semantics, structural fit, +what the design permits vs forbids, compositional clarity, +future-proofing. **Implementation effort is not a rationale.** +"Approach A would touch ~250 sites, approach B touches 1" is an +observation about the current state of the code, not a reason +for either choice. + +Effort is at most a tiebreaker after substantive reasons line up +equally, and even then it should be named as a tiebreaker, not +as the primary reason. + +## Bug fixes — TDD, always + +Bug fixes are RED-first, autonomous, no orchestrator gate. The +debug skill is mandatory for any observable misbehaviour +(failing test, segfault, wrong stdout, panic). See the debug +SKILL.md and debugger agent for the Iron Law and four-phase +process. diff --git a/templates/project-profile.yml b/templates/project-profile.yml new file mode 100644 index 0000000..b142632 --- /dev/null +++ b/templates/project-profile.yml @@ -0,0 +1,55 @@ +# Project profile for the skills plugin. +# +# Drop a copy of this file at /.claude/dev-cycle-profile.yml +# and edit. See ~/dev/skills/docs/profile-schema.md for the full schema +# and per-key documentation. + +paths: + spec_dir: docs/specs + plan_dir: docs/plans + # design_ledger: design/INDEX.md # optional + # design_contracts: design/contracts # optional + # design_models: design/models # optional + code_roots: [src] + # bench_dir: bench # optional + +naming: + counter_dirs: [] + policy: flat # stable_per_directory_4digit | date_prefix | flat + slug_separator: "-" + +commands: + build: "" # REQUIRED — e.g. "cargo build" or "npm run build" + test: "" # REQUIRED — e.g. "cargo test" or "npm test" + # lint: "" # optional + regression: [] # list of shell commands run by audit; non-zero exit = regress + +vocabulary: + cycle: cycle # what a top-level work unit is called + subcycle: iteration # what a sub-unit is called + ledger_entry: contract # what one design-ledger entry is called + +standing_reading: + always: + - CLAUDE.md + - "git log -10 --format=full" + by_role: + # architect: [design/contracts] + # debugger: ["git log -5 --format=full"] + +git: + main_sacrosanct: true + only_orchestrator_commits: true + protected_branches: [main] + issue_tracker: + kind: none # gitea | github | linear | none + close_marker: "closes #N" + +pipeline: + brainstorm: { gates: [planner] } + planner: { gates: [implement] } + implement: {} + audit: { mandatory_at: cycle_close } + debug: { trigger: bug, red_first: true } + # fieldtest: { boss_only: true, when: surface_touch } + # docwriter: { boss_only: true, when: api_stable_across_n_cycles } diff --git a/uninstall.sh b/uninstall.sh new file mode 100755 index 0000000..54030b3 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Uninstall the skills plugin from ~/.claude/. +# +# Removes only the symlinks that point into this repo. Other +# entries under ~/.claude/skills/ and ~/.claude/agents/ are left +# alone. + +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +unlink_pointing_here() { + local dir="$1" + [ -d "$dir" ] || return 0 + for entry in "$dir"/*; do + [ -L "$entry" ] || continue + target="$(readlink "$entry")" + case "$target" in + "$REPO_DIR"/*) + rm "$entry" + echo "removed $entry" + ;; + *) + ;; + esac + done +} + +unlink_pointing_here "$HOME/.claude/skills" +unlink_pointing_here "$HOME/.claude/agents" + +echo "Uninstall complete."