Logo FS-Skia-UI

Spec Kit placement

The governance subsystems documented in this section do not run at one moment; they are spread across the Spec Kit workflow this repository drives every feature through. This page is the section closer: it walks the Spec Kit phases in order — specify → clarify → plan → tasks → analyze → implement → merge — names which governance touchpoint applies in each, and says how a practitioner runs it and responds to it. The phase→touchpoint mapping is made explicit (a table) so that, for any touchpoint, you can state its phase and your response without guessing. It then closes the section with an honest, both-sided analysis of the governance design itself. For the mechanics behind each touchpoint, see routing and gates, evidence and audit, and single-source generation; the overview is the governance index, and the Spec Kit workflow itself is described in the process page.

This repository does not hard-fork Spec Kit. As recorded in ADR 0004, vanilla Spec Kit assets are vendored under .specify/ and all repository-specific governance behaviour is layered as extensions and presets plus a synchronized skill mirror — so the touchpoints below are overlays on the standard phases, not replacements for them.

The phases in order

Each Spec Kit phase is invoked as a skill (the speckit-* skills under .claude/skills/, mirrored from the canonical .agents/skills/). The seven phases, in the order a feature moves through them:

  1. specify — turn a feature description into spec.md: requirements, user scenarios, measurable success criteria.
  2. clarify — ask up to five targeted questions and encode the answers back into the spec, reducing downstream rework risk before planning.
  3. plan — produce the design artifacts (plan.md, research.md, data-model.md, contracts/, quickstart.md) and evaluate the Constitution Check.
  4. tasks — break the plan into tasks.md (the human checklist) and tasks.deps.yml (the dependency topology and skill metadata), in lockstep.
  5. analyze — a strictly read-only cross-artifact consistency pass over spec.md, plan.md, and tasks.md before any code is written.
  6. implement — execute the tasks against the plan, updating task statuses as real or synthetic evidence accrues.
  7. merge — squash-merge the feature branch onto the trunk, then bump and pack the packable projects.

A constitution phase sits logically before specify: it populates .specify/memory/constitution.md from the preset template. It is not run per feature — the constitution is established (or amended) once and then enforced in every later phase — but it is where the principles the other touchpoints depend on are authored, so it is included in the map below.

Phase → touchpoint map

This is the load-bearing table. For any governance touchpoint, read across to its phase and the practitioner response. A touchpoint can apply in more than one phase (for example Route is consulted at plan time to anticipate gates and again at implement time to select them).

Governance touchpoint

Spec Kit phase(s)

How to run

How to respond

Constitution / Constitution Check

constitution; plan

/speckit-constitution to author; the Constitution Check section is filled and re-evaluated during /speckit-plan

Fill every required Repository Governance Decisions area (N/A-with-rationale counts); a constitution conflict found later is automatically CRITICAL and is fixed in the spec/plan/tasks, never by diluting the principle

*Route tier/gate selection* (anticipate)

plan

./fake.sh build -t Route over the in-progress diff while planning

Read the printed tier and gates to anticipate the proof the change will need and shape the plan/tasks around it

*Route tier/gate selection* (validate)

implement

./fake.sh build -t Route, then run only the gates it prints, in order, sequentially

Run the gate list; if it escalated unexpectedly, compare matched-rules against what you actually changed

Surface baselines / PackageSurfaceCheck

plan; implement

At plan time, decide which *.fsi you will touch; at implement time Route selects PackageSurfaceCheck, FsiTranscripts, PerPackageSurfaceDiff for any src/**/*.fsi change

Regenerate/refresh the affected surface baseline and run the selected surface gates; a surface diff is a deliberate contract change to review, not noise

Evidence model [S] / [S*]

tasks; implement

Author [S]/[X]/[F]/[-] states in tasks.md (never write [S*] by hand); during implement, mark each task honestly as evidence accrues

Disclose every [S] in the Synthetic-Evidence Inventory (Principle V); fix the root-cause [S] to clear computed [S*] taint downstream

*EvidenceGraph*

implement (after every status change); analyze

./fake.sh build -t EvidenceGraph (set SPECKIT_FEATURE_DIR to your feature)

Run it right after /speckit-tasks to confirm the DAG is well-formed, and after each status change to refresh [S*] propagation cheaply; fix any structural error before proceeding

*EvidenceAudit*

merge (gate)

./fake.sh build -t EvidenceAudit before landing

Treat NEEDS-EVIDENCE as a hard block: upgrade [S] to [X] with real evidence, or fix blocking diff-scan hits; --accept-synthetic discloses but never clears the block

Single-source regeneration (RefreshSurfaceBaselines + currency gates)

implement (whenever Routing.fs or a .agents/canonical source changes)

./fake.sh build -t RefreshSurfaceBaselines, then commit source + regenerated views together

Edit the canonical source, regenerate, commit both; TargetMetadataDrift / SkillSyncCheck / DesignTokenDrift / ControlsCatalogGenerationCheck will block a stale committed view

Touchpoint-by-touchpoint

Constitution and the Constitution Check (constitution phase + plan gate)

The constitution (.specify/memory/constitution.md) is authored once via /speckit-constitution from the preset template. Its seven Core Principles and the governance/workflow sections are marked <!-- LOCKED --> — shared doctrine across every project on the fsharp-opinionated preset — so a per-feature edit to them must be escalated to an upstream preset change rather than made locally.

The Constitution Check then re-enters at plan time: /speckit-plan fills the Constitution Check section of plan.md and re-evaluates it after design. This is machine-enforcedGeneratedGuidanceCheck fails the build if any required Repository Governance Decisions area is empty, still boilerplate, or carries a NEEDS CLARIFICATION/TODO placeholder (N/A-with-rationale counts as filled). Respond by completing every area honestly; if a later phase surfaces a conflict with a principle, the fix goes into the spec/plan/tasks, never into reinterpreting the principle.

Route tier/gate selection (plan to anticipate; implement to validate)

Route is the compiled selector that maps the working-tree diff to a tier and a minimal gate list. It is consulted twice in the workflow. At plan time, running ./fake.sh build -t Route over the in-progress change tells you which contract surfaces you are about to touch and therefore what proof the feature will need — useful input to the plan and the task breakdown. At implement time it is the operating rule: run Route first, then run only the gates it prints, in the order shown, sequentially (FAKE-backed targets share .fake state and are not concurrency-safe).

Respond to the output by reading tier, gates, and matched-rules. A routine src/**/*.fs edit routes to inner-loop (Dev only); a consumer-contract change escalates. If the route looks heavier than your edit warrants, check matched-rulesRoute reasons over the whole dirty worktree, so unrelated in-progress work can pull in gates. See routing and gates for the full tier table, default-deny, --enforce, and dogfood behaviour.

Surface baselines and PackageSurfaceCheck (plan + implement, for .fsi changes)

A public package surface is a consumer contract, so changes to src/**/*.fsi carry their own proof. At plan time, decide which .fsi surfaces the feature will change and record that in the plan's contract-impact decisions. At implement time, Route selects the package-surface rule — PackageSurfaceCheck, FsiTranscripts, and the per-package DiffPlex PerPackageSurfaceDiff — for any .fsi edit (and the controls-public-surface rule adds the same surface checks for src/Controls/**).

Respond by refreshing the affected surface baseline and running the selected gates. A surface diff is meaningful: it is a deliberate change to what consumers see, to be reviewed as a contract decision rather than waved through. The stable baselines are among the artifacts RefreshSurfaceBaselines regenerates (see below).

The evidence model [S] / [S*] (tasks + implement)

Every task in tasks.md carries a status. The five written states are [ ] pending, [X] done with real evidence, [S] done with synthetic evidence only, [F] failed, and [-] skipped. You author these during tasks and update them honestly during implement. The crucial discipline: never mark [X] when any synthetic condition applies (a mock, a placeholder, a hardcoded literal standing in for a real source, a test that exercises only synthetic fixtures), and never write [S*] by hand — [S*] is computed by the evidence gates as propagated taint when an otherwise-[X] task depends on an [S]/[S*] task.

Respond by disclosing every [S] in the Synthetic-Evidence Inventory at the bottom of tasks.md, as Principle V requires. To clear a computed [S*], you do not edit it — you upgrade its root-cause [S] upstream to [X] and re-run the gate. The narrow [SEH] exception (design-approved synthetic error-handling) may only be classified during specify/clarify/plan/tasks, never at implement time. The full model is in evidence and audit.

EvidenceGraph (after every status change during implement; and at analyze)

EvidenceGraph validates the task DAG and refreshes the computed views (readiness/task-graph.json, readiness/task-graph.md). It is validation and rendering only — it does not by itself block a merge. Run it ./fake.sh build -t EvidenceGraph early and often: right after /speckit-tasks to confirm the initial DAG is well-formed, conceptually alongside the analyze pass (which is itself a read-only consistency check over the artifacts), and after each status change during implement to refresh [S*] propagation cheaply before the expensive audit.

Respond to a failure by fixing the named structural problem — a dangling ref, an orphaned key, a cycle, a duplicate id, a missing/invalid skillist, or an unresolved skill — and not proceeding until the graph is clean. One operational gotcha worth knowing: the gate resolves the feature from SPECKIT_FEATURE_DIR (or the branch), and a missing setting can silently validate a bundled sample feature and report a false green — set the feature directory explicitly.

EvidenceAudit (merge gate)

EvidenceAudit is the merge-gate verdict. It re-runs the graph compute, counts any remaining [S]/[S*] against merge-readiness, and scans the feature diff against the blocking/advisory pattern library — and it hard-blocks on either signal. Run it ./fake.sh build -t EvidenceAudit before merge; a feature should reach /speckit-merge only after the audit passes (or after an explicitly disclosed --accept-synthetic override).

Respond to a NEEDS-EVIDENCE verdict by walking the report top to bottom: upgrade declared [S] tasks to [X] with real evidence where you can, leave auto-[S*] tasks alone (they clear when their root-cause [S] clears), and fix blocking diff-scan hits in the code. --accept-synthetic records a written justification but does not change the exit code — it is disclosure, not a bypass.

Single-source regeneration (RefreshSurfaceBaselines + currency gates) — whenever Routing.fs or .agents change, during implement

Several committed files are generated views of a canonical source, not policy: validation.contract.yml is rendered from Routing.fs, the .claude/skills/** tree from .agents/skills/**, plus design tokens, the controls catalog, generated docs, and the constitution fragments. Whenever you edit one of those canonical sources during implement, regenerate every view with one command — ./fake.sh build -t RefreshSurfaceBaselines — and commit the source together with the regenerated views.

Respond to the currency gates as a forcing function, not an obstacle: if you skip regeneration, TargetMetadataDrift (for the contract and metadata views), SkillSyncCheck (for the .claude mirror), DesignTokenDrift, or ControlsCatalogGenerationCheck will fail with a diagnostic naming the stale file and the exact command to fix it. There is one source to edit and one command to run. The pattern is detailed in single-source generation.

Analysis

This closes the governance section. The bullets below assess the governance design itself — both what it gets right and where it costs the practitioner — grounded in the routing rules, the evidence engine, and the two governance analyses under docs/reports/.

Implementation strengths

Implementation weaknesses

Design pros

Design cons


See also: governance index · routing and gates · evidence and audit · single-source generation · Spec Kit process · API reference.

Type something to start searching.