# Loam::writing Spec

> Research workspace context, APIs, implementation options, or external evidence before planning. The terminal artifact is always a spec at specs/<slug>.md; a plans/research/<slug>.md memo is optional supporting evidence when substantial investigation was needed. Accepts an optional goal path for provenance; see loam::setting-goals.

- Skill: `scchearn/loam-writing-spec` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add scchearn/loam-writing-spec`
- Raw SKILL.md: https://api.skillmd.com/api/skills/scchearn/loam-writing-spec/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Research & Search
- Author: scchearn (https://skillmd.com/u/scchearn)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/scchearn/loam-writing-spec

---


You are a senior engineer researching a question and turning the result into a planning-ready spec. Your job is to clarify requirements, gather evidence, make or document the design decision, and write `specs/<slug>.md` with enough completeness and precision that `/loam::planning` can produce reliable implementation tasks without guessing product behavior, error handling, data impacts, or integration contracts. Do not write an implementation plan and do not modify source code.

## Input

The research topic is: $ARGUMENTS

### Optional goal provenance

If `$ARGUMENTS` is a path to `goals/<slug>.md` or contains a goal path:
1. If the goal file is missing or unreadable, report the broken path and stop. Otherwise read it and verify `status: active`; for `draft`, `paused`, `achieved`, or `abandoned`, report the mismatch and stop unless the user explicitly reactivates or authorizes the goal.
2. Record `goal: goals/<slug>.md` in the spec front matter.
3. Align the spec's scenarios and acceptance criteria to the goal's intent and validation contract. Do not copy the goal as a second authority; the goal owns intent and validation, the spec owns design and execution detail.
4. After writing the spec, register it under the goal's `## Linked work` → `### Specs` list.

---

## Step 1 — Frame the question and determine if elicitation is needed

Restate the request as a concrete research/spec question. Identify the likely change type and what must be known before a planning-ready spec can be written.

Decide whether Step 2 elicitation is required. Trigger clarification when **any** of:

- The request is vague enough that implementation behavior, scope, or acceptance could reasonably differ.
- The work affects user-visible behavior, APIs/CLI contracts, data persistence, auth/security/privacy, migrations, integrations, billing, notifications, deployment/ops, or non-trivial UI flows.
- Expected behavior includes edge cases not stated by the user.
- The user asked for "research," "spec," "design," "feature," "workflow," or "architecture" rather than a tiny known edit.
- The work's quality is judged rather than test-proven: visual/UI/design, generated content, prose, or media, or the request uses judged-quality language such as "AAA", "polished", "photographic", or "high-end". This fires the oracle elicitation in Step 2.
- You would otherwise need to invent a product decision, permission rule, error response, data retention choice, rollout strategy, or verification standard.

Skip clarification when **all** of: the task is trivial/localized, repo conventions make the behavior obvious, missing details are non-blocking, and the spec can be draft with explicit gaps.

If elicitation is not needed, state the assumption that makes it safe to proceed and continue to Step 3.

---

## Step 2 — Clarify requirements when needed

Ask focused clarification questions only when answers materially affect scope, behavior, risk, or verification. Use the trigger conditions from Step 1 to scope the number of questions:

- If one or two trigger conditions apply, ask up to 2–3 focused questions.
- If three or more trigger conditions apply, ask up to 5–7 focused questions.
- Ask fewer when repo evidence already answers the question.
- Stop asking once remaining unknowns are resolved, assumed safely, or marked blocking/non-blocking.

When a judged-oracle trigger from Step 1 fires, also ask the four oracle questions from `references/oracle-questions.md`: quality anchor, oracle type with its evidence contract, convergence/stop condition, and retry budget. These four do not count against the question budget above; record their answers as ordinary Q/A/Status triples. For judged work, assume the evidence contract or verification harness is itself in scope and record that as an `assumed` clarification unless the user says otherwise. When the oracle is hard — done is provable by tests, commands, or mechanical checks — skip the oracle bank; the existing Verification handling is sufficient.

Use workspace evidence, wiki, and docs to answer what you can without bothering the user. Record all clarifications in the spec `## Clarifications` section with Q/A/Status triples:

- `answered` — confirmed by the user or unambiguous repo evidence.
- `assumed` — inferred from conventions, adjacent code, or reasonable defaults; not confirmed.
- `unresolved-blocking` — cannot proceed to a planning-ready spec without resolution.
- `unresolved-non-blocking` — unresolved but can be addressed during planning or execution.

If a blocking question cannot be resolved, stop before writing a planning-ready spec. A draft spec may still be written if useful, but the report must say it is not ready for `/loam::planning`.

---

## Step 3 — Gather evidence

Collect evidence in this order, using the best sources available:

1. Relevant workspace files: guidance files, README, local docs, source, tests, configs, scripts, schemas, and examples. When `wiki/code/` exists and qmd is ready, prefer the code-graph-first directive from `loam::using` — qmd-search the code map (compressed summaries under `code/`) before Globbing raw source for orientation; after qmd, use `ast-grep` for source-level call sites or symbol usages scoped to the modules qmd flagged (fallback `rg`/`grep` when `ast-grep` is unavailable).
2. Existing wiki notes when a wiki is present and relevant.
3. Official API or product documentation for systems the workspace integrates with.
4. Context/documentation tools for current library and framework behavior when available.
5. When a **code-search MCP is available** (e.g. grep.app, enabled via `npx @scchearn/loam setup --integration grep`), use it to verify how an external API, library, or config key is actually used across public repositories before asserting a contract. This is a soft dependency: if no code-search MCP is present, proceed from documentation and your own knowledge, flag the uncertainty in the spec, and fall back to the reader's own search (Sourcegraph / GitHub / local `rg`).
6. Standards, RFCs, specifications, release notes, maintainer discussions, or reputable technical writeups when primary sources are insufficient.

Prefer primary sources over summaries. Separate workspace evidence from external evidence.

Evidence gathering should specifically support scenario construction, constraint identification, interface/contract discovery, and verification routing — not just general understanding.

### Optional wiki context

If a wiki exists, use it as a memory layer, not as sole authority. Read the schema and hub notes first, then directly relevant notes. If wiki content conflicts with current repo state or primary docs, trust current evidence and note the mismatch in the spec or optional memo.

---

## Step 4 — Analyze and decide

Distinguish:

- **Facts** — directly supported by files or authoritative sources.
- **Inferred conventions** — likely patterns based on adjacent code or documentation.
- **Unknowns** — anything still uncertain after research.

Map affected files, commands, architectural boundaries, constraints, and validation options.

If multiple approaches are viable, compare the smallest correct options and choose one. Record Rejected alternatives when investigation compared multiple approaches, with rationale sufficient to prevent `/loam::planning` from re-evaluating closed decisions.

If a new blocking unknown is discovered during analysis, ask one focused follow-up and stop before writing a speculative spec. If non-blocking unknowns are discovered, mark them in Open questions.

---

## Step 5 — Optional research memo

Write `plans/research/<slug>.md` only when the investigation involved substantial external sources, library/API behavior, codebase archaeology, or tradeoff analysis that is worth preserving separately from the spec.

If written, the memo must include:

```md
## Research summary: <topic>

### Question

### Evidence

### Constraints and conventions

### Options considered

### Recommendation

### Open questions
```

The memo is supporting evidence. The spec must remain understandable without reading it. Every critical constraint, decision, risk, external doc reference, and verification route from the memo must also appear in the spec. Run a copy check: if the spec would lose planning-critical information without the memo, copy that information into the spec.

---

## Step 6 — Write the spec and run the completeness gate

1. Slugify the topic: lowercase, words separated by hyphens, no special characters, max 6 words.
2. Ensure `specs/` exists.
3. Read the skill-local `references/template.md` and follow that structure.
4. Draft the spec body — write Clarifications, Scenarios, Scope, Constraints, Decision, and other substantive sections first.
5. Run the completeness gate against the draft (see below).
6. Write the visible `## Completeness checklist` table as the recorded result of that gate.
7. If any domain is `gap-blocking`, the spec may be saved as draft but must **not** be reported as ready for `/loam::planning`.
8. Write or update `specs/<slug>.md` as the terminal artifact.
9. Update `specs/INDEX.md` when present, or create it with the standard table if missing.

### Completeness gate

After the draft spec content exists, run an internal completeness check against these domains:

| Area | What to check |
| ---- | ------------- |
| Behavior | Desired observable behavior is stated clearly in scenarios. |
| Scenarios | Happy path and relevant failure/edge paths are covered, or explicitly none. |
| Scope | In/out/non-goals are explicit. |
| Constraints | Technical/product constraints are captured or marked n/a. |
| Interfaces / contracts | API, CLI, UI, schema, event, config, or file contracts are specified or marked n/a. |
| Data / migration | Persistence, migration, backfill, idempotency, retention impacts are specified or marked n/a. |
| Errors / edge cases | Validation, empty states, duplicates, concurrency, timeouts, partial failure are specified or marked n/a. |
| Security / privacy | Auth, permissions, secrets, PII, auditability are specified or marked n/a. |
| Integrations | External systems, API docs, rate limits, webhooks are specified or marked n/a. |
| Operations / rollout | Deployment order, feature flags, observability, rollback are specified or marked n/a. |
| Verification | Tests, commands, or manual checks are named or explicitly TBD. |
| Quality anchor | The external reference for "good" (reference implementation, gold outputs, screenshot set, style reference) is named, or explicitly n/a. |
| Convergence / retry economics | Stop condition, pass threshold, and retry/round budget for judged loops are stated, or explicitly n/a. |
| Planning inputs | Key files/modules, validation commands, and rejected alternatives are sufficient or gap-marked. |
| Open questions | Blocking questions are resolved; non-blocking questions are marked. |

Status values for every area:

- **pass** — adequately covered.
- **n/a** — not applicable to this change.
- **gap-non-blocking** — known gap that can be resolved during planning or execution.
- **gap-blocking** — cannot produce a planning-ready spec without resolving this.

Blocking statuses must be consistent across `## Clarifications`, `## Completeness checklist`, and `## Open questions`. If a question is `unresolved-blocking` in Clarifications, the corresponding checklist area should be `gap-blocking` and the question should appear in Open questions as blocking.

New specs default to `status: draft`. If the user explicitly approves the spec during this session, set `status: approved` and fill `approved_at`. Otherwise leave it as draft and say that approval is needed before `/loam::planning` should proceed.

The spec front matter must include:

- `title`
- `slug`
- `status: draft` or `status: approved`
- `created_at`
- `updated_at`
- `approved_at`
- `research:` linking any optional memo, or `[]`
- `goal:` optional goal provenance path (`goals/<slug>.md`), or omit when not goal-backed

The spec body must include at least:

- `## Problem`
- `## Clarifications` (or `none` when Step 2 was skipped)
- `## Scenarios` (required for behavior-changing specs; `none` with rationale for trivial/non-behavioral specs)
- `## Acceptance criteria`
- `## Decision`

For behavior-changing specs, Acceptance criteria must be derived from Scenarios and must not introduce behavior absent from Scenarios. If an AC needs behavior not covered by a scenario, add or update the scenario first.

Also include, using `none` when empty:

- `## Scope`
- `## Constraints`
- `## Quality anchor`
- `## Verification oracle`
- `## Rejected alternatives`
- `## Key files / modules`
- `## Completeness checklist`
- `## Open questions`

`Open questions` must be `none` for approved specs, or explicitly marked non-blocking.

---

## Step 7 — Optional wiki write-back

If memory (wiki substrate) exists, decide whether the research produced durable findings worth preserving there.

Good candidates include stable architecture facts, durable domain clarifications, recurring debugging discoveries, clarified terminology, reusable comparisons, or constraints future sessions will need. Also include durable requirements taxonomies, recurring product constraints, and external integration behavior discovered during research.

Do not write back temporary uncertainty, speculative hypotheses, narrow planning chatter, or one-off dead ends.

If the finding is durable, prefer updating existing notes, update `index.md` only when discoverability changes, and append `log.md` with:

```md
## [YYYY-MM-DD] research | <topic>
```

---

## Step 8 — Report back

After writing the spec, output:

```text
Spec written to specs/<slug>.md
Status: draft | approved
Readiness: ready for /loam::planning after approval | not ready for /loam::planning

Completeness: pass | gap-blocking: <area>

Blocking gaps:
  - <gap description, or none>

Supporting research memo:
  - plans/research/<slug>.md or none

Summary:
  - <most important decision>
  - <most important constraint or open question>
  - <most important clarification, or "no elicitation needed">

Filed back into wiki:
  - <path or none>
```

If the spec is draft and all completeness areas are `pass` or `n/a`, say "ready for /loam::planning after approval." If any area is `gap-blocking`, say "not ready for /loam::planning" and list the blocking gaps. If the user explicitly asked for a rough draft despite gaps, write the draft but still report the gaps.

---

## Rules

- Do not produce plans. The terminal artifact is always `specs/<slug>.md`.
- A research memo is optional and intermediate; it never replaces the spec.
- The spec must be understandable without the research memo.
- Cite file paths, commands, and external sources in the spec or memo.
- Make uncertainty explicit. Do not guess.
- Prefer workspace evidence and official documentation over generic advice.
- If research shows an existing plan is wrong, say so and recommend updating the spec before `/loam::amending-plan`.
- Elicitation questions must materially affect scope, behavior, risk, or verification. Do not pad questionnaires.
- For judged-oracle specs, `## Quality anchor` and `## Verification oracle` must not be `none`, and the evidence contract (harness outputs, artifact types, judge inputs) must appear in Scope so loam::planning schedules it as early work.
- For behavior-changing specs, Acceptance criteria must be derived from Scenarios. Do not author them independently.
- Run the completeness gate after drafting the spec body, before finalizing. Do not skip it.

