Przejdź do treści
Biblioteka skilli
Programowanie · Planowanie

tech-spec

/tech-spec

Zamienia PRD w specyfikację techniczną: dekompozycję modułów, kolejność według wycinków i bramkę pytań przed zakończeniem.

Repozytorium
skills ↗
Licencja
MIT
Ostatnia zmiana repozytorium
06.06.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 06.06.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Zamienia PRD w specyfikację techniczną: dekompozycję modułów, kolejność według wycinków i bramkę pytań przed zakończeniem.

Wyzwalacze z opisu

what and whyhowtech-specwrite a technical specturn this PRD into a planhow do we actually build this?
Oryginalny opis (EN)

Turn a PRD into a technical implementation spec. Bridges the "what and why" of a PRD and the "how" an agent needs to execute. Module decomposition with deep-module emphasis, sequencing by tracer-bullet principles, and a grill gate before exit. Use when the user says "tech-spec", "write a technical spec", "turn this PRD into a plan", or after /write-prd when the next question is "how do we actually build this?".

Jak działa

  1. Contract
  2. Phases
  3. Output format
  4. Concrete example of what "good" looks like
  5. Anti-patterns
Sekcje z nagłówków SKILL.md, w oryginale · 329 linii, 2 250 słów
Podgląd SKILL.md
---
name: tech-spec
description: Turn a PRD into a technical implementation spec. Bridges the "what and why" of a PRD and the "how" an agent needs to execute. Module decomposition with deep-module emphasis, sequencing by tracer-bullet principles, and a grill gate before exit. Use when the user says "tech-spec", "write a technical spec", "turn this PRD into a plan", or after /write-prd when the next question is "how do we actually build this?".
---

# Tech Spec

Turn a PRD (the "what and why") into a technical implementation spec (the "how"). A tech-spec answers: which modules do we build, in what order, with what interfaces, and what can go wrong along the way.

Inspired by Ouroboros's Double Diamond execution decomposition (Discover → Define → Design → Deliver), John Ousterhout's *A Philosophy of Software Design* (deep modules), and the classic "design doc" form used at big engineering orgs.

---

## Contract

**Input:** a PRD (as a file path, conversation content, or caller-injected context) + the codebase.

**Output:** a technical spec as markdown. Default destination: `docs/tech-specs/<slug>.md`. Callers can override.

**What this skill does NOT do:** re-litigate the PRD. If the PRD is unclear, invoke `max:grill-me` on it, or push the user back to `max:write-prd`. Tech specs build on PRDs; they don't replace them.

**Composition chain:** `caller` → `write-prd` (outputs PRD) → `tech-spec` (outputs implementation plan) → `grill-me` (stress-tests the plan) → return to caller.

---

## Phases

### Phase 1: Load the PRD

Read the PRD from wherever the caller points at — file path, conversation, or pre-loaded context. Verify every PRD section has content (Goals / Requirements / Non-Goals / Constraints / Approach / Open Questions).

**Hard-stop if these are missing:**
- **Requirements** — no concrete behaviors to decompose into modules
- **Non-Goals** — risk of silent scope creep during design

If either is missing, STOP and tell the user: "This PRD needs sharpening before I can tech-spec it. Want me to invoke `max:grill-me` on the PRD first, or do you want to revise it yourself?"

**Warn but proceed if these are weak:**
- **Approach** — direction is helpful but tech-spec can propose one
- **Open Questions** — unresolved items become explicit inputs to the tech spec phase

### Phase 2: Discover (explore the problem space)

Before designing the solution, understand the constraints the PRD's Approach section gestured at.

**What to look for:**
- **Files the Approach mentions** — read each one fully, don't skim
- **Sibling code** — the directory the Approach points at, the module it lives in
- **Shared abstractions** — utilities, helpers, types that would be reused or extended
- **Existing patterns** — how similar features are implemented in this codebase (not how they'd be implemented in general)
- **Recent history** — git log on the affected files for the last 30-60 days. Prior attempts, in-flight work, reverted commits all matter.
- **Test infrastructure** — what test patterns exist? Unit? Integration? Snapshot? This shapes the Design phase.
- **Cross-cutting concerns** — auth, logging, error handling, observability. Is there a convention?

**Output of this phase:** a mental model rich enough to decompose the work. You should be able to answer: "Given this codebase, what shape does the solution naturally want to take?"

**Time budget:** 10-20 minutes. If you find yourself reading beyond that, the PRD scope is too big — push back and ask for a slice.

### Phase 3: Define (commit to a decomposition)

Break the work into modules with clear interfaces. This is where deep-module thinking applies.

**Deep module test** (Ousterhout):
A module is *deep* if its public interface is much smaller than the implementation it encapsulates. A class that exposes 3 methods but internally handles 500 lines of complexity is deep. A class that exposes 20 methods that are each 2-line wrappers around something else is *shallow*.

**Good deep modules:**
- `TranscriptParser` — public: `parse(text) -> Transcript`. Internal: tokenization, speaker detection, timestamp normalization, punctuation recovery.
- `CacheEvictionPolicy` — public: `shouldEvict(entry, now) -> Bool`. Internal: LRU tracking, priority weighting, size accounting.
- `ExportManager` — public: `export(document, format) -> URL`. Internal: format-specific renderers, asset collection, zip packaging.

**Bad shallow modules:**
- `TextUtils` with 15 static methods each wrapping one line of string manipulation
- `DatabaseHelper` whose methods all take a SQL string and pass it to the underlying client
- `EventMiddleware` that exists only to re-emit events on a different name

**Decomposition steps:**

1. **List the behaviors from the PRD Requirements.** Each behavior is a candidate for a module or a method on a module.
2. **Cluster behaviors that share state or invariants.** Behaviors that touch the same data belong in the same module.
3. **Identify seams.** A seam is where test boundaries live. Each module should have exactly one public seam where tests can reach it. Multiple seams = shallow module.
4. **Name each module** with a noun that describes its responsibility, not its implementation. `TranscriptParser` good, `StringProcessor` bad.
5. **Sketch the public interface** for each module. 1-5 methods is the sweet spot. 10+ methods is a smell — the module is probably two modules pretending to be one.
6. **Call out reused abstractions.** If the decomposition is inventing a new pattern when the codebase already has one, merge them.

Present the decomposition to the user in chunks (2-3 modules at a time). Get approval on each module before proceeding to the next.

### Phase 4: Design (per-module specifics)

For each module in the decomposition, spec:

```markdown
### <Module Name>

**Responsibility:** <what this module does in one sentence. If it takes more than one sentence, it's two modules.>

**Public interface:**
```swift
struct TranscriptParser {
  func parse(_ text: String) throws -> Transcript
  func parseStream(_ bytes: AsyncBytes) -> AsyncThrowingStream<TranscriptFragment, Error>
}
```

**Invariants:**
- Parsed transcripts always have at least one speaker
- Timestamps are monotonically increasing
- Unknown speakers are tagged "Speaker N", not null

**Failure modes:**
- Empty input → throw `TranscriptError.empty`
- Unrecognized format → throw `TranscriptError.unsupported(format)`
- Partial data → return best-effort with a warning

**Tests (behaviors to verify):**
- Parses a well-formed VTT file into the expected structure
- Handles speaker labels with non-ASCII characters
- Errors on empty input with the correct error type
- Rejects malformed timestamps
```

**Rules:**
- **Concrete signatures, not prose.** Code blocks are more honest than "a parse method that takes text".
- **Invariants are load-bearing.** They tell future maintainers what must always be true.
- **Failure modes belong next to the interface.** Error handling isn't an afterthought.
- **Tests are behaviors, not implementation steps.** "Parses VTT" not "calls tokenizer then builds speaker map".

### Phase 5: Deliver (sequence the work)

Order the modules for execution. Wrong order causes cascading rework.

**Principles:**

1. **Foundations first.** Modules with no dependencies go first. You need data types before the services that manipulate them.

2. **Tracer bullet through the whole stack.** Before polishing any single module, prove the architecture works end-to-end with a thin vertical slice. This means building a minimal version of every layer to get one happy-path scenario working, then going back to fill in each layer.

3. **Risky modules early.** If something's likely to need rework (unfamiliar API, performance unknown, integration concern), find out early. A failed tracer bullet in week one is cheaper than a failed integration in week three.

4. **Leaf modules last.** Polish, edge cases, and non-critical paths come after the core path is proven.

**Example sequencing** (a hypothetical "add a transcript search feature"):

```
1. TranscriptIndex (foundation — data types + in-memory index)
2. TranscriptIndexer (foundation — populates the index from existing transcripts)
3. SearchQuery (tracer — minimal parser, just exact match)
4. SearchResultsView (tracer — wire UI to display results)
   ← END OF TRACER BULLET: end-to-end exact-match search works
5. SearchQuery (fill in — fuzzy match, operators, highlighting)
6. TranscriptIndexer (fill in — incremental updates, background rebuild)
7. SearchResultsView (fill in — keyboard nav, ranking, preview)
8. Performance tuning (last — only after all behavior is proven)
```

The tracer bullet comes at step 4, not step 8. After step 4 you KNOW the architecture is viable; the remaining work is filling in, not discovering.

### Phase 6: Grill gate

Invoke `max:grill-me` in spec mode against the tech spec. Threshold: 0.2 (same as PRDs — tech specs are what agents execute against).

The grill's dimensions map naturally:
- **Goals** — is the module decomposition obviously correct, or are there unresolved decisions?
- **Acceptance** — does each module have concrete "done when" criteria (tests listed)?
- **Boundaries** — are Non-Goals preserved from the PRD? Any scope creep introduced at the tech spec level?
- **Alternatives** — which decompositions did we consider and rule out?
- **Assumptions** — which constraints are verified (via Phase 2 exploration) vs. guessed?

Iterate on the spec until below threshold, or let the user override.

**Fallback if `max:grill-me` is not available:** self-review against the five dimensions, flag any gaps, ask one clarifying round, and exit.

### Phase 7: Output

Write the tech spec to `docs/tech-specs/<slug>.md` (or caller-specified destination). Print the path and ambiguity report.

Return control to the caller.

---

## Output format

```markdown
# <Feature Name> — Technical Spec

## Context
<Link to the source PRD. Summarize in 2-3 sentences what this spec implements.>

## Decomposition
<Bulleted list of modules with 1-line descriptions. This is the table of contents.>

- **TranscriptIndex** — in-memory index over transcript content
- **TranscriptIndexer** — populates the index from Bugbook pages
- **SearchQuery** — parses search input into executable queries
- **SearchResultsView** — displays ranked results with highlighting

## Modules

### TranscriptIndex
**Responsibility:** ...
**Public interface:** ...
**Invariants:** ...
**Failure modes:** ...
**Tests:** ...

### TranscriptIndexer
...

## Sequence

Ordered list of modules with rationale for the order. Call out the tracer bullet boundary.

## Open Questions

Anything unresolved that the PRD didn't cover. Tag with who needs to answer.

## Ambiguity Report

<Appended by grill-me at exit.>
```

---

## Concrete example of what "good" looks like

A small tech spec, for the "Cmd+K focuses search bar" PRD example in `max:write-prd`:

```markdown
# Cmd+K focuses search bar — Technical Spec

## Context

Implements the PRD at `docs/prds/cmd-k-search-focus.md`. Adds a Cmd+K
keyboard shortcut that focuses the sidebar search field from anywhere in
the app, expanding the sidebar first if collapsed.

## Decomposition

- **SearchFocusCoordinator** — owns the focus state and the expand-sidebar-if-needed sequence
- **ContentView shortcut binding** — attaches the Cmd+K keyboard shortcut at the app-level container

## Modules

### SearchFocusCoordinator

**Responsibility:** Own the search field's focus state and the sequencing logic
for focusing it even when the sidebar is collapsed.

**Public interface:**
```swift
@MainActor
final class SearchFocusCoordinator: ObservableObject {
    @Published var isSearchFocused: Bool = false

    func requestFocus()
    func releaseFocus()
}
```

**Invariants:**
- `requestFocus()` always results in `isSearchFocused == true` after a short delay,
  regardless of sidebar state
- The coordinator does not directly manipulate sidebar visibility — it publishes
  an intent that `ContentView` acts on

**Failure modes:**
- If the sidebar can't be shown (e.g., a modal sheet is blocking), `requestFocus`
  is a no-op. The caller is expected to check for blocking state before calling.

**Tests:**
- `requestFocus` sets `isSearchFocused` to true
- `releaseFocus` sets it back to false
- Multiple rapid `requestFocus` calls are idempotent (no focus-stealing loop)

### ContentView shortcut binding

**Responsibility:** Attach the Cmd+K keyboard shortcut at the root SwiftUI view
so it's available regardless of which child view is focused.

**Public interface:**
```swift
// In ContentView body:
.keyboardShortcut(.init("k"), modifiers: .command, action: { coordinator.requestFocus() })
```

**Invariants:**
- The shortcut is active in all app states except when a modal sheet is presented
  (macOS default behavior for `.keyboardShortcut`)

**Failure modes:**
- If `coordinator` isn't yet injected into the environment, crash early with a
  clear error — don't silently no-op

**Tests:**
- N/A (SwiftUI view code, verify via smoke test per `max:verify-before-done`)

## Sequence

1. **SearchFocusCoordinator** (foundation — pure state object, testable via `max:tdd`)
2. **ContentView shortcut binding** (tracer — wires coordinator into the view tree)
   ← END OF TRACER BULLET: Cmd+K focuses search from an expanded sidebar
3. **Collapsed-sidebar expansion** (fill in — observe `isSearchFocused` at the sidebar level, expand if needed, then focus)
4. **Escape restores previous focus** (fill in — track prior focus, restore on submit/escape)

The tracer bullet is deliberately thin. Step 2 proves the shortcut-to-focus path works end-to-end with the simplest possible sidebar state (already expanded). Steps 3-4 fill in the edge cases after we know the core wiring is right.

## Open Questions

- How do we track "previous focus" across arbitrary views in SwiftUI? macOS 14+ has
  `@FocusState` but cross-view restoration isn't built-in. Investigation needed.

## Ambiguity Report

<Appended by grill-me at exit.>
```

Notice:
- Each module has a real Swift signature, not a prose description
- Invariants call out what must always be true
- Tests distinguish "testable via tdd" vs "smoke test via verify-before-done"
- Sequence marks the tracer bullet boundary explicitly
- Open Questions capture what needs investigation, not what the spec author was too lazy to decide

---

## Anti-patterns

- **Restating the PRD as a tech spec.** If your tech spec just paraphrases the PRD in different words, you haven't added value. Tech specs answer "how", not "what".
- **Over-decomposing into shallow modules.** 20 tiny modules with bloated interfaces is worse than 5 deep modules with clean interfaces. When in doubt, merge modules.
- **Skipping the sequencing phase.** A correct decomposition in the wrong order wastes as much time as a wrong decomposition. The sequence is load-bearing.
- **Designing without reading the code.** Tech specs that don't reference existing patterns are aspirational fiction. Read first, design second.
- **Inventing abstractions the codebase doesn't need.** If the team doesn't already use dependency injection, don't propose it as a load-bearing part of the spec. Match the codebase's ambient complexity.
- **Specifying implementation details the spec shouldn't care about.** "Use a `@MainActor` on the view model" is an implementation choice. Tech specs define *what* the module should do, not *how* it's written line-by-line. If you catch yourself writing code in the spec, stop.

Wersje

RepozytoriumWynikLicencja
Ta strona · max4c/skills100MIT
duc01226/EasyPlatform100MIT
duc01226/EasyPlatform100MIT
sd0xdev/sd0x-harness100MIT
dimagi/dimagi-claude-workflows90MIT

Migawka bazy z 28.10.2026 · wersja paczki e735697a46d6 (skrót SHA-256 całej paczki)

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 90write-product-spec
    Pisze specyfikację produktową z niezmiennikami, specyfikację techniczną lub PRD w trybach product, technical i requirements.
  • 95create-tech-spec
    Pisze specyfikację techniczną z kontekstem systemu, kontraktami API, modelami danych, obsługą błędów i planem testów.
  • 100bmad-tech-spec
    Tworzy lekką specyfikację techniczną Quick Flow dla małych zakresów (1-15 historyjek) jako bmad-output/tech-spec.md, zamiast pary PRD i architektura.
  • 90create-tech-spec
    Zamienia zgłoszenie GitHub w specyfikację techniczną w pliku tech.md, przygotowując tylko zmiany w plikach.
  • 100prd-to-spec
    Przekształca PRD w techniczny dokument SPEC: architektura, projekt API, model danych, obsługa błędów i kontrakty implementacyjne.
  • 100write-tech-spec
    Pisze specyfikację TECH.md dla większej funkcji Warp po zbadaniu bieżącego kodu i ograniczeń implementacji, powiązaną ze specyfikacją produktową.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.