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.
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 pathdebug → 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_4digitordate_prefixorflat). - 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_dirin the project profile. Use the naming policy configured undernaming.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, andissue_tracker.show_cmdand invoke the configured listing / single-issue commands, andspecifymay 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.