Files
Skills/docs/design.md
T
Brummel 268ee705f4 feat(specify): record in-context fork resolutions as auditable issue comments
The `spec-skeptic` `scope-fork` juror reads only the seeding issue plus
the spec. On the legitimate `specify` direct-entry path — a fork settled
in a long in-context design discussion — that resolution lives only in
ephemeral chat the juror cannot replay. When the issue body lags the
discussion (still lists the fork open), the juror correctly blocks, and
a design BLOCK escalates without self-correction. The result: auto-sign
was structurally almost unreachable for the in-context entry path.

Close the blind spot by giving the juror an auditable source instead of
weakening the gate. When `specify` enters in-context and a tracker issue
still lists a now-resolved fork as open, the orchestrator posts a
reconciliation comment recording each fork's resolution WITH provenance
(a record of the user's decision, never a fresh orchestrator one) before
writing the spec. The comment is persistent and audit-able — unlike a
carrier digest — so it, not the orchestrator's confidence, is what the
juror checks.

Separation of powers keeps it honest: the orchestrator writes the
comment, the adversarial juror enforces the provenance requirement. A
bare `decision: X` with no provenance does not resolve the fork — the
re-dispatched juror blocks on it. The escalation rule and the
three-field carrier are untouched; only the juror's information changes.

Mechanics:
- specify Step 1.5: reconciliation-comment sub-step, provenance format,
  issue-less fallback (auto-sign -> human sign-off, no weak spec-note).
- spec-skeptic: replace the "quoted in the dispatch" drift; juror reads
  the issue WITH comments via `issue_tracker.show_cmd`; provenance check.
- new profile slot `issue_tracker.show_cmd` (must render comments);
  documented in schema + template.
- issue skill: `tea issues <idx>` is body-only; `--comments` required
  (verified against tea 0.14.1 and Aura #55 — 180 vs 144 lines).
- consistency: design.md out-of-scope, README, pipeline.md, boss skill.
2026-06-12 15:54:47 +02:00

5.2 KiB

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/, docs/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 protocolDONE / 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, issue_tracker.list_cmd, and issue_tracker.show_cmd and invoke the configured listing / single-issue commands, and specify may post a reconciliation comment via the tracker's comment command — 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.