Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,31 +75,31 @@ If a topic spans multiple packages or introduces new entities, it's system-level

## Spec frontmatter

Every spec begins with YAML frontmatter. The schema is locked so tooling and back-links can resolve specs by stable id rather than filename.
Every spec begins with YAML frontmatter. The `spec:` value is the spec file's repo-relative path so back-links and the index resolve via that path — the same string is also the navigable link target.

```yaml
---
spec: agent-executor # stable id, used by back-links and the index
spec: docs/specs/agent/executor.md # repo-relative path; used by back-links and the index
title: Agent Executor
status: current # see status enum below
status: current # see status enum below
version: 1.2
last_updated: 2026-04-14
level: system # application | system | cross-cutting | feature | plan
owners: # primary code paths this spec governs
level: system # application | system | cross-cutting | feature | plan
owners: # primary code paths this spec governs
- server/src/agent/executor.ts
- server/src/agent/usage.ts
adjacent: # related specs, by id
- agent-tools
- lifecycle-hooks
- scheduler
tests: # primary verification anchors
adjacent: # related specs, by repo-relative path
- docs/specs/agent/tools.md
- docs/specs/agent/lifecycle-hooks.md
- docs/specs/agent/scheduler.md
tests: # primary verification anchors
- server/src/agent/executor.test.ts
---
```

Rules:

- `spec` is the stable id. Back-links and the spec index resolve by id, not filename, so spec files can be renamed without breaking the graph.
- `spec` is the spec's repo-relative path. The same path is the back-link target in code and the link target in Markdown renderers. Renaming a spec file is therefore a graph-wide change — update `spec:`, all `adjacent:` entries elsewhere, and every code-side `// Spec:` backlink together (the maintenance audit will surface stragglers).
- `owners` lists *primary* implementing files. Most files appear under exactly one spec's `owners`. **Seam files** — plugin bootstrap, route registration, shared event normalization, schemas spanning multiple domains — may legitimately appear under several specs' `owners` lists. When they do, every owning spec must list the file, and the file's `// Spec:` comments must use the multi-link form with scope qualifiers so it is unambiguous which sections (or which symbols) belong to which spec.
- `adjacent` declares known coupling. Used to rank impact when one spec changes.
- `last_updated` must be bumped on any substantive change. The maintenance audit flags specs whose `last_updated` falls behind the most recent commit on any `owners` file.
Expand Down Expand Up @@ -149,31 +149,31 @@ The format is deliberate: name a *concrete* change, list the *concrete* files an

## Code-to-spec back-link format

Every owning code file references its governing spec via a `Spec:` comment using the spec id, optional section anchor, and optional scope/intent note.
Every owning code file references its governing spec via a `Spec:` comment whose value is the spec's repo-relative path, with an optional section anchor and optional scope/intent note. The path doubles as a navigable link target (IDE plugins, Markdown renderers, `$EDITOR $(grep -oE '^.+\.md' …)`).

**Format:** `// Spec: <spec-id>[#section] [— description]`
**Format:** `// Spec: <repo-relative-path>[#section] [— description]`

The `<spec-id>` is the `spec:` field from the target spec's frontmatter, **not** a filename. This survives spec renames.
The `<repo-relative-path>` is the spec file's path from the repo root (the same string as the spec's `spec:` frontmatter value).

**Simple** — file implements the full spec:
```
// Spec: agent-executor
// Spec: docs/specs/agent/executor.md
```

**Scoped** — file implements only part. **Section anchor is mandatory** when scope is partial:
```
// Spec: agent-executor#5-model-resolution — Provider/model resolution and custom model lookup
// Spec: docs/specs/agent/executor.md#5-model-resolution — Provider/model resolution and custom model lookup
```

**Intent** — captures a constraint not obvious from the code:
```
// Spec: agent-executor#6-subagent-spawning — Depth-limited to 3; do not raise without revising the spec
// Spec: docs/specs/agent/executor.md#6-subagent-spawning — Depth-limited to 3; do not raise without revising the spec
```

**Multiple specs (seam files only)** — file truly sits between systems. Each line carries a scope qualifier so it is unambiguous which lines or symbols belong to which spec:
```
// Spec: agent-executor#3-execution-flow — Run loop and bounds enforcement
// Spec: scheduler#4-trigger-resume — Cron resume path only (function: resumeFromCron)
// Spec: docs/specs/agent/executor.md#3-execution-flow — Run loop and bounds enforcement
// Spec: docs/specs/agent/scheduler.md#4-trigger-resume — Cron resume path only (function: resumeFromCron)
```

Use multi-link sparingly. Most files belong to exactly one spec.
Expand Down Expand Up @@ -299,7 +299,7 @@ Run before finalizing any spec:
- [ ] Edit-impact section names concrete files and sections (not "related docs")
- [ ] Code map links every spec section to implementing files, with symbols where helpful
- [ ] Test map links every section to primary tests
- [ ] Owning files have `// Spec:` comments using the spec id (code → spec)
- [ ] Owning files have `// Spec:` comments using the spec's repo-relative path (code → spec)
- [ ] Section anchors used in back-links whenever scope is partial
- [ ] Multi-link only on true seam files, with scope qualifiers
- [ ] Known deltas populated if status is `drifted`; empty otherwise
Expand Down Expand Up @@ -331,7 +331,7 @@ If any gate fails, fix it or surface it explicitly. Do not silently ship a half-
| Generic edit-impact | "Be careful when editing this" | Name the concrete files and sections to inspect |
| Back-link spam | Every utility file has back-links, often to multiple specs | Restrict to core/route/stateful/schema/UI-state files; prefer single-link |
| Pseudocode entities | A spec with implementing code defines a stylized type that does not match source | For specs with code on disk, paste the real type. For `draft` specs the canonical declaration is allowed; replace it with the pasted form once code lands |
| Filename back-links | `// Spec: specs/agent-executor.md` | Use the spec id: `// Spec: agent-executor` |
| Slug-style back-links | `// Spec: agent-executor` | Use the spec's repo-relative path: `// Spec: docs/specs/agent/executor.md` |
| Why-as-summary | Why section restates what the code does | Replace with the constraint, incident, or product reason that motivated the system |

## Guardrails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Map and record:

Group related code into logical systems by domain, not by directory. Each system with its own data model, API surface, or lifecycle is a candidate for a spec. Reserve cross-cutting specs for the concerns surfaced in step 1; do not invent them.

Present the proposed breakdown to the developer for validation. Include the proposed spec id for each system (the value that will go into `spec:` frontmatter) since back-links will use that id, not the filename.
Present the proposed breakdown to the developer for validation. Include the proposed spec file path for each system (the value that will go into `spec:` frontmatter and into every code-side `// Spec:` back-link).

### 3. For each system: extract then interview

Expand Down Expand Up @@ -113,7 +113,7 @@ This step is not optional. Both directions must be created in the same pass.
Add the Code map and Test map sections. Link spec sections to implementing files. Use symbol names (`AgentExecutor.run`) for stable anchors; line numbers may augment but should not stand alone.

**Code → spec (`Spec:` comments in code files):**
Add a `Spec:` comment to every owning file using the **spec id** from the target spec's frontmatter (not the filename). Section anchors are mandatory when scope is partial. Multi-link only on true seam files identified during the survey, with scope qualifiers on each line. See SKILL.md for the locked format.
Add a `Spec:` comment to every owning file using the spec's **repo-relative path** (the value of `spec:` in the target's frontmatter). Section anchors are mandatory when scope is partial. Multi-link only on true seam files identified during the survey, with scope qualifiers on each line. See SKILL.md for the locked format.

### 6. Build the spec index and conventions file

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ Report findings before making changes. Let the developer decide whether spec or

**Back-link convention:**
```
// Spec: <spec-id>[#section] [— description]
// Spec: <repo-relative-path>[#section] [— description]
```
Use the spec **id** from frontmatter, not the filename. See SKILL.md for the full format and rules on multi-link seam files.
Use the spec's repo-relative path (the same string as the `spec:` field in frontmatter). The path is both the identifier and the navigable link target. See SKILL.md for the full format and rules on multi-link seam files.

### 4. Prune

Expand Down Expand Up @@ -141,6 +141,6 @@ When drift is ambiguous, ask:
After any maintenance operation, run the gates from SKILL.md. Specifically:

- All touched specs have valid frontmatter and a status from the enum
- Every owning file has a back-link using the spec id
- Every owning file has a back-link using the spec's repo-relative path
- `SPEC_INDEX.md` is regenerated if frontmatter changed
- The drift report is included in the run summary, even if all checks passed (so the user knows what was checked)
Loading