# System Instructions

This prompt is divided into three sections:

1. **System Instructions** (this section) — structural orientation only. Do not treat this
   section as task input.

2. **Input Context** — begins with the heading `# Input Context`. All blocks are wrapped in
   `<pblock>` tags. Two block types:
   - File blocks: `<pblock filename="<name>" role="<role>" guidance="...">` — optional
     `guidance` attribute carries context-specific instructions; content is in a fenced block.
   - Metadata/section blocks: `<pblock label="<label>" kind="<kind>">` — job parameters,
     rules, instructions, or group headers.

3. **Agent Task** — begins with the heading `# Agent Task`. Defines your persona, constraints,
   and required outputs. Read all input context before acting on this section.


# Input Context

<pblock label="Planning job" kind="job">
## Planning job

- TARGET: toml
- BLUEPRINT_PATH: /mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint
- DATE: 2026-08-14
- SYSTEM_SHAPE: unknown
- ANALYSIS_QUALITY: Questions

</pblock>

<pblock filename="COMPASS.md" role="compass" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/COMPASS.md" guidance="Important: This is the core project intent, constraints, and guardrails. It should have presecedence in conflicts.">
```markdown
# COMPASS: TOML 1.0.0 Parser

## Compass
Build a Go command-line TOML 1.0.0 parser for users and harnesses that need a deterministic stdin-to-tagged-JSON decoder. The parser must implement the supplied specification and distinguish valid documents from invalid documents through its output and exit behavior.

## Constraints
- Use Go with no `go.mod` dependencies.
- Support the Go toolchain floor stated by the sources.
- Read TOML only from stdin and write results only to stdout or diagnostics to stderr.
- Preserve lossless signed 64-bit integers.
- Stage and run the supplied conformance harness assets.
- Complete acceptance uses the installed `toml-test` v2.2.0 suite.

## Guardrails
- Never modify the supplied scoring scripts.
- Never import a third-party TOML parser.
- Reject invalid TOML rather than accepting it permissively.
- Do not add arguments, configuration, or side effects to the decoder command.
- Treat the unfiltered full-suite exit status as the acceptance verdict.

<!-- drydock:build-write-guardrail:start -->
## Build Write Guardrail

- Authorized build directory: `/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/build/toml`
- Authorized Target directory: `/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml`
- Build agents have permission to create, modify, and remove files required by the active build block inside these authorized directories.
- No path outside these authorized directories may be modified.
- Protected Drydock artifacts:
  - `/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint/`
  - `/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/MANIFEST.md`
  - `/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/COMPASS.md`
  - `/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/QuarterDeck/`
  - `/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/evidence/`
<!-- drydock:build-write-guardrail:end -->
```
</pblock>

<pblock filename="TECHNOLOGY_STACK.md" role="technology stack" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/TECHNOLOGY_STACK.md" guidance="Edit freely. Adding a technology never requires a matching Rigging file, and this file never blocks planning.">
```markdown
# Technology Stack

**Approved:** 2026-08-09

Technology decisions of record for this Target. One row per technology, naming the
Rigging best-practice file that governs building it.

A `—` in the Rigging column means no Rigging guidance exists for that technology; the
builder applies general best practice instead. Adding a row never requires a matching
Rigging file.

This file is owned by the UAT kit. It is seeded into the Target before `analyze`, which
never overwrites it, and `drydock plan` reads it to assign per-story `stack:` guidance.

| Technology | Rigging | Notes |
|---|---|---|
| Go | go.md | Go 1.22 or newer; toolchain minimum pinned in go.mod. |
| Shell | common.md | POSIX sh for the supplied scoring entry point and the conformance harness. |
```
</pblock>

<pblock filename="ANALYSIS.md" role="planning basis" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/ANALYSIS.md" guidance="A list of Agile Stories suggested by an earlier analysis of the raw input.">
```markdown
# Blueprint Analysis: TOML 1.0.0 Parser

## Commander Expectations

- assert the parser accepts every supplied valid TOML 1.0.0 case and rejects every supplied invalid case.
- assert the decoder implements the stdin-to-tagged-JSON filter contract.
- assert the implementation uses only the Go standard library.

## Crew

| Crew | Charge |
|---|---|
| Commander | Defines intent and decides what done means. |
| Team Lead | Confirms epic completeness and stakeholder expectations. |
| Planning Crew | Authors atomic specifications and the ordered Manifest. |
| Shipyard Crew | Builds the tickets without synchronous Commander access. |

## Story List

### Feature: Decoder Contract

| ID | Story | High-level AC |
|---|---|---|
| DECODER-001 | Build the TOML decoder command | `cmd/toml-decoder` reads TOML from stdin, emits tagged JSON on stdout, and exits zero for valid input. |
| DECODER-002 | Report invalid input | Invalid TOML produces a diagnostic on stderr and a non-zero exit without emitting a successful result. |
| DECODER-003 | Encode parsed values as tagged JSON | Tables, arrays, and all supported TOML values use the required JSON structure and string-valued payloads. |

### Feature: TOML Lexical Values

| ID | Story | High-level AC |
|---|---|---|
| LEXICAL-001 | Parse TOML strings | Basic, multiline basic, literal, and multiline literal strings follow TOML 1.0.0 escaping, trimming, UTF-8, and control-character rules. |
| LEXICAL-002 | Parse numbers and booleans | Decimal, hexadecimal, octal, binary, floating-point, special float, and boolean values follow TOML 1.0.0 syntax and lossless integer requirements. |
| LEXICAL-003 | Parse date and time values | Offset datetime, local datetime, local date, and local time values are recognized and encoded using the required representations. |
| LEXICAL-004 | Process whitespace and comments | Whitespace, line endings, comments, and continuation rules are handled without altering valid values or accepting prohibited control characters. |

### Feature: Keys and Key-Value Semantics

| ID | Story | High-level AC |
|---|---|---|
| KEYS-001 | Parse bare, quoted, and dotted keys | Key forms and whitespace around dotted components produce the required nested structure. |
| KEYS-002 | Enforce key definition rules | Duplicate keys, invalid keys, and attempts to turn scalar or closed structures into tables are rejected. |

### Feature: Arrays and Inline Tables

| ID | Story | High-level AC |
|---|---|---|
| STRUCTURES-001 | Parse arrays | Nested, mixed-type, multiline, commented, empty, and trailing-comma arrays are parsed correctly. |
| STRUCTURES-002 | Parse inline tables | Nested inline tables and dotted keys are parsed, while multiline and trailing-comma violations are rejected. |
| STRUCTURES-003 | Enforce inline-table closure | Keys and subtables cannot be added outside an already-defined inline table. |

### Feature: Tables

| ID | Story | High-level AC |
|---|---|---|
| TABLES-001 | Parse standard tables | Explicit and implicitly created tables, including empty and nested tables, are represented correctly. |
| TABLES-002 | Enforce table redefinition rules | Duplicate tables and conflicts between tables, values, and arrays are rejected. |
| TABLES-003 | Parse arrays of tables | Array-of-table headers create ordered table elements and support nested tables and nested arrays of tables. |
| TABLES-004 | Enforce array-of-table ordering rules | Invalid parent ordering and conflicts with statically defined arrays or normal tables are rejected. |

### Feature: Conformance Verification

| ID | Story | High-level AC |
|---|---|---|
| CONFORMANCE-001 | Run the complete TOML conformance suite | **Suite: full** — the supplied `sources/full_test.sh` exits zero with every supplied valid and invalid case passing. |

## Surfaced Acceptance Criteria

| ID | Story ID | Criterion |
|---|---|---|
| AC-001 | DECODER-001 | The program accepts no arguments, has no configuration or side effects, and operates as a stdin/stdout filter. |
| AC-002 | DECODER-003 | Offset datetimes use RFC 3339 encoding; local datetimes omit the offset; local dates and times use their date and time representations. |
| AC-003 | LEXICAL-001 | The parser accepts only valid UTF-8 documents and rejects prohibited control characters and invalid string escapes. |
| AC-004 | LEXICAL-002 | Integers are handled losslessly across the supported signed 64-bit range. |
| AC-005 | CONFORMANCE-001 | The complete suite is invoked unfiltered, and its exit status is the acceptance verdict. |

## Source Inventory

| Path | Content kind | Disposition | Reason |
|---|---|---|---|
| `sources/INSTRUCTIONS.md` | markdown | analyzed | readable UTF-8 |
| `sources/full_test.sh` | code | analyzed | readable UTF-8 |
| `sources/run_conformance.sh` | code | analyzed | readable UTF-8 |
| `sources/setup_harness.sh` | code | analyzed | readable UTF-8 |
| `sources/stage_test.sh` | code | analyzed | readable UTF-8 |
| `sources/toml-v1.0.0.md` | markdown | analyzed | readable UTF-8 |

## Relationship Model

| Source or group | Relationship type | Related source or group | Evidence | Delivery implication |
|---|---|---|---|---|
| `sources/toml-v1.0.0.md` | instruction-to-test | `sources/run_conformance.sh` | The specification defines TOML 1.0.0 behavior; the harness runs `toml-test test -toml 1.0`. | Implementation stories must follow the specification and use scoped conformance slices. |
| `sources/full_test.sh` | test-kit-to-implementation | `cmd/toml-decoder` | The script builds `./cmd/toml-decoder` and supplies it through `DECODER`. | The decoder command must exist before terminal verification. |
| `sources/run_conformance.sh` | test-kit-to-implementation | `cmd/toml-decoder` | The harness pipes TOML to the configured decoder and checks valid and invalid outcomes. | Decoder process behavior is an integration contract. |
| `sources/stage_test.sh` | test-kit-to-implementation | parser features | The stage gate accepts a `-run` pattern for one owned suite slice. | Feature stories may run bounded conformance patterns. |
| `sources/setup_harness.sh` | dependency | `toml-test` | The setup script installs the pinned `v2.2.0` harness. | Harness installation is an external prerequisite, not parser functionality. |

## Source Roles

| Path | Role | Plan disposition | Build disposition |
|---|---|---|---|
| `sources/INSTRUCTIONS.md` | author intent | compass | prompt-only |
| `sources/full_test.sh` | conformance harness | context | stage |
| `sources/run_conformance.sh` | conformance harness | context | stage |
| `sources/setup_harness.sh` | test helper | context | stage |
| `sources/stage_test.sh` | conformance harness | context | stage |
| `sources/toml-v1.0.0.md` | normative specification and conformance test suite | context | prompt-only |

## Planning Instructions

### Delivery Shape

Deliver a Go command-line filter with an internal TOML parser. It consumes UTF-8 TOML on stdin and produces tagged JSON on stdout, or a diagnostic and non-zero exit for invalid input. The staged shell harness builds the command and executes the pinned upstream TOML 1.0.0 conformance suite.

### Story Realization Map

- `DECODER-001` — `cmd/toml-decoder`; evidence `sources/INSTRUCTIONS.md`; capability and CLI contract.
- `DECODER-002` — `cmd/toml-decoder` and parser error boundary; evidence `sources/INSTRUCTIONS.md`; capability and acceptance contract.
- `DECODER-003` — `internal/toml` plus JSON output; evidence `sources/INSTRUCTIONS.md`; capability.
- `LEXICAL-001` through `LEXICAL-004` — `internal/toml`; evidence `sources/toml-v1.0.0.md`; parser capabilities with scoped conformance tests.
- `KEYS-001` and `KEYS-002` — `internal/toml`; evidence `sources/toml-v1.0.0.md`; parser capability and validation.
- `STRUCTURES-001` through `STRUCTURES-003` — `internal/toml`; evidence `sources/toml-v1.0.0.md`; parser capability and validation.
- `TABLES-001` through `TABLES-004` — `internal/toml`; evidence `sources/toml-v1.0.0.md`; parser capability and validation.
- `CONFORMANCE-001` — `sources/full_test.sh`, `sources/run_conformance.sh`, and the completed decoder; terminal acceptance contract.

### Test and Acceptance Strategy

Parser stories use focused unit tests and bounded `toml-test` patterns through `sources/stage_test.sh`, declaring `Suite: scoped`. Decoder contract stories use process-level stdin, stdout, stderr, and exit-code tests. `CONFORMANCE-001` is the sole terminal story declaring `Suite: full`; it runs `sh sources/full_test.sh` unfiltered and gates on the harness exit status.

### Sequencing and Dependencies

Create the Go module and decoder contract first. Implement lexical values before composite structures, then keys and table semantics, followed by scoped conformance verification. Build the decoder before any harness execution. Install the pinned `toml-test` binary before acceptance. `CONFORMANCE-001` depends on every parser and decoder story.

### Source Conflicts and Gaps

No conflicting product definitions were found. Product identity is proposed for Commander confirmation because the metadata fields are blank. The source does not define a separate deployment target; the inferred target is local command-line execution.

## Analysis Notes
generated: 2026-08-14
blueprint: /mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint

Quality: Questions
  blockers: 0
  questions: 1
  features: 6
  stories: 18
  stack: Go
  display_name: TOML 1.0.0 Parser
  short_description: A Go command-line parser that converts TOML 1.0.0 from stdin into tagged JSON and rejects invalid documents.

None.
```
</pblock>

<pblock filename="SEA_TRIALS.md" role="project acceptance contract" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/SEA_TRIALS.md">
```markdown
# Sea Trials: Toml

## Policy

| Consequence | On FAIL | On INCONCLUSIVE |
|---|---|---|
| blocks  | fail   | attest |
| scores  | score  | score  |
| attests | report | report |

## st-001: The supplied scoring script passes
Type: technical
Required: yes
Criterion: The completed parser shall make sh sources/full_test.sh exit zero; that script's exit status is the sole acceptance verdict.
Testability: deterministic
Consequence: blocks
Verification: proof
Pattern: ubiquitous
```
</pblock>

<pblock label="Answered questionnaire header" kind="section">
## Answered questionnaires (consume these decisions)

</pblock>

<pblock filename="discovery-identity.json" role="questionnaire" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/QuarterDeck/questionnaires/discovery-identity.json" guidance="Discovery/Questions and possible user answers.">
```json
{
  "id": "discovery-identity",
  "title": "Discovery: Project Identity",
  "purpose": "Confirm the proposed display name and short description before planning.",
  "questions": [
    {
      "id": "display_name",
      "label": "Display Name",
      "prompt": "The display name Drydock will use for this project. Edit to override the proposal.",
      "input": "text",
      "proposed": "TOML 1.0.0 Parser",
      "answer": "TOML 1.0.0 Parser"
    },
    {
      "id": "short_description",
      "label": "Short Description",
      "prompt": "One-sentence description of what this project does. Edit to override the proposal.",
      "input": "textarea",
      "proposed": "A Go command-line parser that converts TOML 1.0.0 from stdin into tagged JSON and rejects invalid documents.",
      "answer": "A Go command-line parser that converts TOML 1.0.0 from stdin into tagged JSON and rejects invalid documents."
    }
  ]
}
```
</pblock>

<pblock filename="MANIFEST_CONTRACT.md" role="contract" path="/mnt/c/Users/barlo/projects/drydock/prompts/MANIFEST_CONTRACT.md" guidance="MANIFEST output contract. Follow it exactly.">
````markdown
---
name: Manifest Contract
description: Contract governing the format, story types, field semantics, lifecycle states, block grouping, and execution rules for `MANIFEST.md` — the single generated executable build plan for a Drydock Target.
version: 20260801 V14
---

## Overview

`MANIFEST.md` is the single generated execution view of the Blueprint. It determines build order,
selects required context, keeps work within useful context limits, identifies stale work, and
preserves unaffected accepted work. It is not a second product definition.

**Location:** `$DRYDOCK_WORKSPACE/targets/<Target>/MANIFEST.md`

The Manifest manages the full product lifecycle:

- specifications for individual components can be changed, resulting in context-minimized
  incremental builds
- new files (such as change tickets) can be discovered and applied

---

## Plan Header

```markdown
# MANIFEST: {ProjectName}
updated:     2026-06-08T12:00:00
plan_hash:   abc123456789
applied_specs: |
  DATABASE.md sha256=<content_sha256> commit=<file_commit_sha> applied_by=foundation applied_at=2026-06-26T14:22:00Z
planning_feedback: |
  decision-0123456789abcdef applied FEATURE-CATALOG.md
  decision-fedcba9876543210 retained
```

Build execution evidence lives in the execution log. The Manifest preamble carries build-state
provenance required to detect stale previously applied Blueprint Specifications. `applied_specs`
records one line per Blueprint Specification file applied by a successful story. The path
is relative to `blueprint/`. `sha256` is the authoritative dirty signal. `commit` is the latest git
commit that touched that file, or `-` when unavailable. `applied_by` identifies the story
that last applied the file. `applied_at` is the UTC application timestamp.

---

## Story Types

The Manifest is a list of stories. A `type` field is the only variation.

| Type | Contains | Runs |
|---|---|---|
| `foundational` | Foundation and scaffolding | Early; work depends on it |
| `service` | Everything that does work | Reorderable |
| `feature` | Acceptance criteria plus assembly and intent; no implementation instructions | After its members |

Foundational work is structure and scaffolding. Standing up S3 and proving the connection is
architecture. Everything S3 subsequently does is a service. Everything that is not architecture is
a service, and services are reorderable because they carry no structural debt. Much of what source
material labels architecture is service work: the web server and the database are foundation; a
voice service interpreter is a service wearing an architecture filename.

Foundation status derives from the dependency graph, not from a filename prefix. The rule is
*build the foundation that is needed*, not *build all foundation first*.

There is no fourth type. A "foundational service" — voice-to-text, for example — is foundational to
whatever depends on it, which the edges already state more precisely than a label could.

`spike` is not a story type. Research questions are handled by questionnaires before Plan and by the
owning story's `## Questions` section after. `ac` is not a story type: Programmatic Acceptance is
verification the build runs to prove a story is complete. A story is not "built and failed" — it is
built or it is not, so acceptance is a field the story owns and passing is part of the story's own
state transition.

### Feature is an assembly story

A feature is a story that depends on its member stories, carries acceptance criteria, and carries
assembly and intent instructions instead of implementation instructions. Same node, same execution
path, different content shape. When its member stories complete, the feature story runs and is made
to pass like any other story, so integration testing is a real build step rather than an implicit
hope. A feature story is preferably placed in the same block as its members.

### Story

```markdown
## story N: {Name}
id:           foundation
summary:      One-line description.
type:         foundational
kind:         capability
phase:        1
block:        1
implements:   ARCHITECTURE.md
covers:       CATALOG-001
accepts:      st-001
context:      DATABASE.md
stack:        common.md, python.md, fastapi.md
stack_mode:   builder
provides:     GET /health
consumes:
instructions: |
  Stand up the application factory and health check.
acceptance:   yes
depends:
state:        pending
```

**Field reference:**

| Field | Required | Authored by | Description |
|-------|----------|-------------|-------------|
| `id` | Yes | Model | Stable unique slug within the Manifest |
| `summary` | Yes | Model | One-line description |
| `origin` | No | `drydock refit` | Provenance of a story authored from a source change, as `<source>@<commit>`. Absent on stories authored by `plan`. |
| `created` | No | `drydock refit` | ISO date the story was appended to the graph. |
| `type` | Yes | Model | `foundational` \| `service` \| `feature` |
| `kind` | Yes | Model | Delivery kind: `capability` \| `integration` \| `migration` \| `test harness` |
| `phase` | Yes | Model | Commander build sequencing; see below |
| `block` | Generated | Drydock | Context-optimization group; computed, never authored |
| `implements` | Yes | Model | The single governed specification this story builds |
| `covers` | No | Model | `ANALYSIS.md` Story IDs this story delivers. Every analyzed Story ID is named by exactly one story, whatever its `type`; a story with no analyzed counterpart omits the field |
| `accepts` | No | Model | `SEA_TRIALS.md` IDs this story implements |
| `context` | No | Model | Read-only support context files. Never a Compass file |
| `stack` | No | Model | Rigging stack files this story builds with |
| `stack_mode` | Generated | Drydock | `builder` \| `consumer`; computed from first use in build order |
| `provides` | No | Model | Routes, commands, symbols, datasets, queues, or events this story defines |
| `consumes` | No | Model | Interface points this story calls |
| `rules` | No | Model | Rigging rules files to inject |
| `copy` | No | Model | `source -> destination` file copies applied before build |
| `instructions` | Yes | Model | Freeform build instructions. A `feature` carries assembly and intent, not implementation |
| `acceptance` | Yes | Model | `yes` when the story has real acceptance to honor |
| `depends` | No | Model | Story ids that must be `closed/verified` first |
| `state` | Yes | Drydock | Current block state |
| `evidence` | No | Drydock | Path to the evidence file written after execution |
| `scope` | No | Model | `blueprint` \| `target` \| `both` — what this story changes |

Stories and governed specifications are one-to-one: every story implements exactly one
specification, and every specification is implemented by exactly one story. The story is the atomic
build primitive.

**Story sizing.** A story is a normal Agile story: 1 to 5 story points. Never a half point — that is
a task, folded into the story it serves. Never twelve — that is split. A story does one thing
completely, carries test criteria, and is releasable on its own; a task is not releasable and is
therefore not a story. A story has no token dimension. Token cost is measured against the block a
story is built in, never against the story. Story count is not capped: it is an output of correct
decomposition, not a target.

### Authorship versus verification

The model authors relationships, the actual topology (the story dependency graph), the high-level
topology (phases), and Programmatic Acceptance. Drydock verifies all of it, groups blocks, orders
the work, and serializes the Manifest.

The model never sorts, never checks its own consistency, and never reasons about a position in an
order it has not computed. It states what each story requires and provides; Drydock does the rest.
Contradictions become a deterministic error with a precise message instead of a shape failure.

`drydock plan create` therefore does not emit this file. It emits a flat `TOPOLOGY.md` declaration
carrying the Model-authored fields below — one `## story <id>` heading per governed specification,
no ordering, no `block:`, no `stack_mode:`, no `state:` — and Drydock serializes `MANIFEST.md` from
it. The field semantics in this contract govern both forms.

**Two-topology check.** The high-level and actual topologies must agree: a story in phase 2 cannot
depend on a story in phase 3.

### Phase

`Phase` is Commander instruction on how to build: *build Feature X, then Feature Y*. It is not a
layer chain. The layer stack repeats inside each phase rather than running once across the project —
foundational / database / service / ui, then service / ui, then foundational / service / service /
ui. Commander ordering direction is input the model weighs, not an override applied afterward.

`Phase` describes when a file is built, not the file, so it lives in the Manifest and never in a
Blueprint header.

### Blocks

A **block** is a set of stories optimized for context: sized to amortize fixed stack-file cost
across one build run, never crossing stacks. Blocks are an optimization output, not a taxonomy. UI
stories group together whether or not they belong to the same Agile feature. Context economy comes
from blocks, not from feature grouping.

Blocks are ephemeral, Manifest-only, regenerated every run, and computed by Drydock:

- **Hard:** one topology type per block; never cross a phase boundary; never violate the edges
- **Objective:** amortize stack-file cost across the most stories that still fit one build pass

The mechanism behind the no-cross-stack guardrail is stack creep from Rigging. Mixing topology types
in one block forces every stack file each type needs into the block, so it pays for context neither
half uses and the build agent reads instructions for work it is not doing. This is the reason story
types exist: they are the block-partition key.

### Builder and consumer mode

The model authors the foundational story that stands a stack up. Drydock assigns the
builder/consumer flag from first use in the computed order: by definition the first story using a
stack is the builder and later ones are consumers. Ordering is build-order-global, as compact
substitution already is — not per-block, not phase-based. A builder story receives the full stack
file; a consumer story receives the interface view.

If the model assigned the flag it would be asserting a position in an order it has not computed.
Disagreement is a defect signal, not a tie to break: if the first user of a stack is not a
`foundational` story, an edge or a foundational story is missing and Drydock reports it. Ambiguity
defaults to builder, because consumer-when-it-should-be-builder starves the build agent while
builder-when-it-should-be-consumer merely costs tokens.

---

## Acceptance

Acceptance lives in one place per audience:

- **Programmatic Acceptance** — executable assertions carrying pass/fail state. Lives in
  `MANIFEST.md`. Not human-readable, not human-editable, regenerated wholly by every plan run.
- **User Acceptance** — human-readable intent. Lives in the Blueprint specification.

The discriminator for every other fact is the same question: **does the fact describe the artifact
or the schedule?**

| Fact | Home | Why |
|---|---|---|
| `Provides`, `Consumes`, `Depends On` | Blueprint header | Describe the file — what it offers and requires |
| Story `type` | Manifest | Computed, machine-focused |
| `Phase` | Manifest | Describes when the file is built, not the file |
| Programmatic Acceptance | Manifest | Machine-focused; nobody should hand-edit it |
| User Acceptance, `## Questions` | Blueprint | Human intent |

Durability is not a discriminator: the Blueprint does not survive a replan. Only the `## Questions`
section, harvested deterministically beforehand, survives.

---

## Block States

Every story uses the same four states:

| State | Meaning |
|-------|---------|
| `pending` | Not run yet |
| `implemented` | Work done, waiting to be accepted |
| `closed/verified` | Passed or accepted |
| `closed/failed` | Failed or rejected |

---

## Execution Rules

A story runs only when everything in `depends:` is `closed/verified`.

Programmatic Acceptance runs after the story build and is part of the story's own state
transition: a story that fails its acceptance becomes `closed/failed` and blocks dependent work.
There is no separate acceptance node with independent state.

A `feature` story runs after its member stories close. Its assembly and intent instructions are
made to pass like any other story's, which is what turns integration testing into a real build step
covering the seams between stories where multi-story builds actually break.

`closed/failed` is not terminal. The product owner reopens failed work from the QuarterDeck —
revising instructions, acceptance, or scope interactively — and the decision writer returns it to
`pending` with the revision recorded. Recovery never requires hand-editing the Manifest.

An open `Blocking` Blueprint question projects the story state as `blocked/questions`. That story
and its dependents are unavailable, while independent frontier stories remain buildable. Open `Low`
and `Material` decisions remain visible without gating.

`User Acceptance` entries are Commander review signals and do not block ordinary downstream build
unless modeled as explicit dependencies.

---

## Sea Trials Traceability

`accepts:` lists stable project-acceptance IDs from `SEA_TRIALS.md` that the story implements.
Every required technical or behavioral Sea Trial is referenced by at least one story or by a
Blueprint Programmatic Acceptance proof. Unknown IDs are invalid.

## Plan State Writer

The **decision writer** is the only mutator of Manifest block state. It is invoked by:

- the QuarterDeck review controls (approve, revise, reject, add defect on individual blocks)
- the `drydock build` engine (state transitions during execution)

Review decisions written in the QuarterDeck write back to `MANIFEST.md` through the same
decision writer used by the CLI.

---

## Relationship to Blueprint

The Manifest is generated from the Blueprint; it is not a second product definition. `drydock plan
create` reads all Blueprint inputs and writes `MANIFEST.md` — the single work graph carrying build
order, grouping, and per-step prompt-assembly fields. It regenerates after each planning cycle.

The Blueprint remains the source of truth for what the project is and must do. The Manifest is
the source of truth for build state. The QuarterDeck renders Manifest state and records decisions
through the plan writer — the console can be deleted and regenerated at any time.
````
</pblock>

<pblock filename="BLUEPRINTS_CONTRACT.md" role="contract" path="/mnt/c/Users/barlo/projects/drydock/prompts/BLUEPRINTS_CONTRACT.md" guidance="Blueprint output contract. Follow it exactly.">
````markdown
---
name: Blueprints Contract
description: Contract governing the layout, file types, header format, and dependency conventions for Drydock Blueprint files.
version: 20260813 V12
---

## Overview

A **Blueprint** is the complete Typed Specification for one project. It lives at
`$DRYDOCK_WORKSPACE/targets/<Target>/blueprint/` and contains all human-authored and
process-created specification files. The Blueprint is the single source of truth for what the
project is, what it must do, and how it is built.

---

## Specification File Types

| File | Purpose | Required |
|------|---------|----------|
| `METADATA.md` | Project identity: name, display_name, short_description, status, stack, code_root | Yes |
| `COMPASS.md` | Project guidance: intent, constraints, and guardrails | Yes |
| `ARCHITECTURE.md` | Modules, routes, boundaries, interfaces, technical decisions | Yes |
| `README.md` | One-line description and `## Intent` section | Yes |
| `DATABASE.md` | Persistence contract: access patterns, typed interfaces, all stores, schemas, migrations | If has persistent state |
| `UI-GENERAL.md` | Shared UI patterns across screens | If has UI |
| `SCREEN-{Name}.md` | Per-screen: route, layout, interactions, programmatic and user acceptance | If has UI |
| `FEATURE-{Name}.md` | Per-feature: purpose, status, trigger, sequence, routes, reads, writes, acceptance, guardrails | As needed |
| `ARCHITECTURE_compact.md` | Compact architecture derivative for downstream build-step injection | Optional |
| `DATABASE_compact.md` | Compact persistence derivative for downstream build-step injection | Optional |
| `HOMEPAGE.md` | Portfolio homepage: branding, contact, bio | If publishes a portfolio |
| `HOMEPAGE-PUBLISHER.md` | Template-based homepage publishing configuration | If publishes a portfolio |
| `IDEAS.md` | Feature ideas and backlog — no typed header required | No |
| `*-AC.md` / `AC-*.md` / `*-AC-*.md` | Acceptance criteria — any file where `AC` is a whole word in the filename | As needed |
| `changes/TICKET-NNN-{Name}.md` | Post-baseline change, defect, or spike request | As needed |

Every authored Specification file ends with `## Programmatic Acceptance`, `## User Acceptance`,
and `## Guardrails`. Use `- None.` when no entries apply. Planning disclosures and Commander
responses are records in the target's `DECISIONS.json`.

`ARCHITECTURE_compact.md` is a compact derivative of `ARCHITECTURE.md` produced by
`drydock rigging compact`. Drydock uses filename-selected compaction algorithms rather than
phase-aware compact variants.

`DATABASE_compact.md` is a compact derivative of `DATABASE.md` produced by `drydock rigging compact`.

---

## Specification File Header Format

Every authored Specification file except `METADATA.md` and `README.md` must begin with a typed
header. Operational and generated files (`IDEAS.md`, build plans, analysis outputs, and AC files)
are not authored Specification files.

```markdown
# {FileType}: {ObjectName}

| Field       | Value |
|-------------|-------|
| Version     | YYYYMMDD V1 |
| Description | One sentence summary. |
| Depends On  | FEATURE-SERVICE-CATALOG.md, UI-GENERAL.md |
| Provides    | GET /welcome, GET /welcome/summary |
| Phase       | 2 |
```

**FileType values:** `COMPASS`, `SCREEN`, `FEATURE`, `DATABASE`, `UI-GENERAL`, `ARCHITECTURE`,
`HOMEPAGE`, `CHANGE`

**ObjectName:** Human-readable name matching the file subject (e.g., `Welcome Summary`,
`Service Catalog`).

**Fields:**

| Field | Set By | Required | Description |
|-------|--------|----------|-------------|
| `Version` | Author | Yes | Date + increment: `YYYYMMDD V1`. Every agent write must set this to the current date with the next increment. If the existing version is already today's date, increment the number. Never carry forward a stale date. |
| `Description` | Author | Yes | One sentence |
| `Depends On` | `drydock plan create` | No | Filenames this file requires to exist before build |
| `Provides` | `drydock plan create` | No | HTTP routes or interfaces this file exposes |
| `Phase` | `drydock plan create` | No | Build phase hint (integer); tooling may override |

**Additional optional fields for SCREEN files:**

| Field | Required | Description |
|-------|----------|-------------|
| `Route` | No | The URL this screen is served at |
| `Parent` | No | Parent menu item or `—` |
| `Main Menu` | No | Menu label and position |
| `Sub Menu` | No | Submenu label and position |
| `Tab Order` | No | Tab index within parent, or `—` |

`Depends On` and `Provides` are written by `drydock plan create` — do not edit manually.
`Phase` is written by `drydock plan create` — do not edit manually unless overriding.

**Additional required fields for CHANGE files (`changes/TICKET-NNN-{Name}.md`):**

| Field | Set By | Required | Description |
|-------|--------|----------|-------------|
| `Amends` | Author / `drydock refit` | Yes | The parent Blueprint spec this ticket modifies (e.g. `FEATURE-Copy.md`). `drydock refit` reads this field to resolve dependency inheritance and inject parent context. |
| `Depends On` | `drydock refit` | Yes | Copied from the parent spec's `Depends On` set plus the parent spec filename itself. Do not edit manually. |
| `Scope` | Author / `drydock refit --sources` | Yes | `additive` or `amending`. Governs what the ticket supersedes. |
| `Created` | `drydock refit` | Yes | ISO date the ticket was authored. |
| `Origin` | `drydock refit --sources` | No | The source version this ticket came from, as `<source>@<commit>`. Absent on hand-authored tickets. |
| `Stories` | `drydock refit --sources` | No | The Manifest story ids this ticket owns. When present, `drydock refit` emits exactly these ids and never invents new ones. |

**Scope semantics.** A ticket declares its authority over its parent in one sentence directly
below the header table.

- `additive` — the ticket adds behavior. It supersedes nothing, and every assertion in the parent
  Blueprint remains in force. Sentence: *"This ticket is additive. It supersedes nothing; every
  assertion in `<parent>` remains in force."*
- `amending` — the ticket alters behavior already specified. It supersedes only the sections
  listed under `## Amended Sections`, each of which must exist as a heading in the parent.
  Sentence: *"This ticket amends `<parent>`. It supersedes only the sections named under
  `## Amended Sections`; every other assertion in `<parent>` remains in force."*

An additive ticket must never claim authority over its whole parent: a single added requirement
would otherwise supersede assertions it does not mention and that have already been proven.

---

## Common Authored Specification Sections

Plan and Build disclosures use the existing `DECISIONS.json` schema. `severity: blocking` is the
only decision gate and blocks only the attached story while its Commander response is absent.
Analyze questionnaire answers are converted to `origin: analyze-questionnaire` records. Commander
responses remain in the same records across replans.

Every authored Specification file ends with these sections, using `- None.` when no entries apply:

```markdown
## Programmatic Acceptance

- None.

## User Acceptance

- None.

## Guardrails

- None.

```

`Programmatic Acceptance` contains executable Python assertion snippets. Each check is one
explicitly delimited block that can run from the build directory after the story implementing the
file completes:

```
=== AC {check-id} ===
Intent: One sentence stating what the check proves.
Suite: scoped
Requires: executable=python3; scope=test

<Python source, verbatim, to the end marker>
=== END AC {check-id} ===
```

The delimiters are the whole format. The id lives in the opening marker, so it is never inferred
from a nearby heading. Declarations are the `Key: value` lines at the top of the block, ending at
the first blank line; `Intent:` is required and the rest are optional. Everything after that blank
line is the proof body, taken character for character to the matching end marker.

Nothing inside the body can move a boundary. A Markdown fence, a `##` line, a `###` line, or a
`Requires:` line inside a string is ordinary content — which matters, because a target that
processes markup will legitimately embed all of them in its proof. Write the body as plain Python;
do not wrap it in a fence.

An unterminated block, an end marker naming a different id, a stray end marker, and a duplicate id
are all hard errors that stop planning. None of them degrade into a criterion that silently stops
gating.

### The oracle rule

> **Act on the system. Read the state back. Compare to expected.**

Arrange–Act–Assert, where the assertion reads *state*, never text a process printed.

| Oracle | Verdict |
|---|---|
| Return value, parsed JSON, status code, DB row, file contents read back, exit status | **Correct** |
| Substring of captured stdout/stderr, test-runner tally text, log lines | **Forbidden** |

A state oracle cannot pass against a stub and cannot fail because a runner printed the word
"warning". Almost every acceptance defect observed in practice has the same shape: the oracle was
a string in captured output.

### The expected value must be one you could not get wrong

Reading state back is half the rule. The other half is what you compare it *to*.

> **Never type an expected value twice. Bind it to a name and use the name on both sides.**

You are authoring this criterion before the code exists, so a hand-typed expectation is a
prediction about bytes you have not seen. When the prediction is wrong the criterion fails against
a correct implementation, and nothing downstream can tell that from a real defect. This is the
single largest source of wasted build budget on record.

| Expected value | Verdict |
|---|---|
| A name bound to the value the criterion supplied as input | **Correct** |
| A status code, exit status, or count | **Correct** |
| A contract token read off a declared interface — `"integer"`, `"application/json"`, `"POST"` | **Correct** |
| A staged suite's exit status | **Correct** |
| A string literal you typed out as the expected result | **Forbidden** |

The forbidden row is judged mechanically: a string expectation carrying anything escapable —
whitespace, a backslash, a quote, a newline, a non-ASCII character — that the criterion did not
also supply as input. A criterion that breaks the rule still runs and is still reported, but it
settles `DISPUTED` and gates nothing, so it buys the story no coverage at all.

The case this comes from. Wrong:

```
source = 'basic = "line\\nvalue"\nraw = \'C:\\\\Users\\\\nodejs\'\n'
result = subprocess.run(["./toml-decoder"], input=source, capture_output=True, text=True)
decoded = json.loads(result.stdout)
assert decoded["raw"]["value"] == r"C:\Users\nodejs"     # re-typed, and wrong
```

A TOML literal string preserves its backslashes verbatim, so the decoder returned the doubled
form and the expectation was wrong. Right:

```
raw = "C:\\Users\\nodejs"
source = f"raw = '{raw}'\n"
result = subprocess.run(["./toml-decoder"], input=source, capture_output=True, text=True)
decoded = json.loads(result.stdout)
assert decoded["raw"]["value"] == raw                    # one spelling, cannot disagree
```

When a transform's output genuinely cannot be derived from its input — a renderer turning `# h`
into `<h1>h</h1>` — do not hand-write the expectation at all. Bind the criterion to the
authoritative suite that defines correctness for that transform. Where no such suite exists, put
the case in the project's own test suite, where the implementer writes it against real output,
rather than predicting it here.

### Two test destinations

A project carries tests in two places, and they are not the same artifact with different names.

| | **Story AC** — `=== AC <id> ===` | **The project's own test suite** |
|---|---|---|
| Job | gate the block | know the code works |
| Count | few | unbounded |
| Authored | here, by planning, **before the code exists** | by the build agent, **alongside the code** |
| Oracle discipline | the rules above, without exception | full latitude — expectations are observed, not predicted |
| Effect | binding: it decides whether the block closes | diagnostic: it guides repair, and its command is what a project criterion runs |
| Runs | at its block | continuously, cumulatively |

The split is not a matter of taste. Every expected value written here is a *prediction* about
bytes that do not exist yet, and a wrong prediction fails a correct implementation — which is why
the oracle rule and the no-re-typed-literal rule are absolute in this file. A test written beside
the finished code compares against output its author has actually seen, so the same assertion that
is hazardous here is safe there.

So this is *more* testing, not less. Exhaustive coverage belongs to the project's suite, which has
no ceiling. An AC block is permanently constrained by having to survive as a gate, so author few
and author them bulletproof. Coverage is never demonstrated by the number of AC blocks a story
carries; it is demonstrated by the suite, and it is graded at the project level through the Sea
Trial that runs that suite.

**Where an authoritative suite exists, it is the coverage.** A conformance corpus staged into
`sources/` defines correctness for the surface it covers. Bind one criterion to it and do not
restate its cases in either destination — a restated case adds no coverage and adds one more
expectation that can be wrong.

### What a criterion is worth

Every criterion you write lands in one of four tiers. The tier is decided by how the criterion is
written, not by how it is labelled, and it decides what the criterion can do:

| Tier | What it is | What it does |
|---|---|---|
| **BLOCKING** | a Commander-governed gate, or a criterion bound to a staged authoritative suite | fails the block |
| **CONSULTATIVE** | a criterion whose expected value could not have been invented — a status code, an exit status, a value the criterion itself supplied as input | drives repair; unattended, it marks the block implemented-but-unverified rather than stalling the run |
| **ADVISORY** | a criterion that re-types an expected literal | runs, is reported `DISPUTED`, **gates nothing** |
| **VOID** | malformed: does not compile, or an unclosed container | not a criterion; recorded as a decision and gates nothing |

Aim deliberately. A hand-typed expectation does not merely risk being wrong — it demotes the
criterion to ADVISORY, so the story it was written to protect ends up with no gate at all. Binding
the value to a name is what buys the criterion its authority back.

None of these tiers reaches the release verdict. Story AC decides whether an increment was built;
project acceptance is decided by Sea Trials alone.

### Authoring patterns

Patterns **1, 4, 6, 9, and 10** are the discipline of a gate and govern what you write here.
Patterns **2, 3, 5, 7, and 8** are the discipline of a test suite: state them as expectations on
the project's own suite, which the build agent grows beside the code, rather than enumerating them
into AC blocks.

**1 — Round trip (the default form).** For anything that stores, mutates, or removes state:

```
create  → read back → assert present, with expected field values
update  → read back → assert changed, and only the intended fields changed
delete  → read back → assert absent
```

The read-back is a *separate call through the public interface*, not an inspection of the object
returned by the write. A write that returns a plausible object while persisting nothing must fail.

**2 — Exercise every callable workflow.** *Suite pattern.* One test per public entry point, per
verb. Coverage is enumerated from the interface, not sampled: every HTTP route × every method it
declares including declared error paths; every CLI subcommand and every flag that changes
behavior; every exported library function. This belongs to the project's suite. Here, name the
routes a SCREEN provides — that gate is real — and leave the enumeration to the suite. Where a
staged authoritative suite already covers the surface, it is the coverage.

**3 — Idempotence.** *Suite pattern.* Where a verb claims idempotence (PUT, DELETE), apply it twice and assert the
second is a no-op — same resulting state, and the declared status for a repeat. Where a verb is not
idempotent (POST), apply twice and assert the declared behavior: two resources, or the declared
conflict. Prefer idempotent verbs where the semantics allow; the assertion is stronger.

**4 — Negative paths assert the contract, not the message.** Invalid input asserts the declared
failure signal — status code, exception type, exit status — never the wording of an error message.
Message text is prose and belongs to no contract.

**5 — Boundaries.** *Suite pattern.* Empty collection, exactly one, many. Absent optional fields.
Declared maxima. This is where a plausible-looking implementation actually breaks — and where a
predicted expectation is most likely to be wrong, which is why the cases belong beside the code
rather than here. Where a staged authoritative suite covers the surface, it is the coverage.

**6 — RED before GREEN.** The assertion must fail against the pre-implementation tree and pass
after. A check that passes against a stub is not a check.

**7 — Isolation and determinism.** *Suite pattern, and it applies here too.* Each test arranges its own data and does not depend on another
test's residue or on ordering. No wall-clock dependence, no third-party network, no unseeded
randomness, no sleep-based timing. Fresh store per test, or explicit teardown.

**8 — One behavior per test, named for the behavior.** *Suite pattern.* A failure should be
diagnosable from the test's name alone.

**9 — Subprocess discipline.** Where a check must shell out, **exit status is the verdict**. A
substring check beside an exit-status assertion is redundant at best and a false-positive generator
at worst. Never assert that a literal is absent from captured output.

**10 — In-language tooling.** A check is written in the project's own language and uses that
language's libraries — Python check, Python libraries; Go check, Go libraries. An in-language HTTP
client yields a status code and a parsed body, which is state. `curl` yields stdout, which is text
to scrape. Pattern 10 and the oracle rule are the same rule seen twice.

### Declaring external tooling

Reaching for an external executable is the exception, not the norm, and `curl` in particular will
not work in every environment. When a check genuinely needs one, the tool belongs in the project's
Rigging or `TECHNOLOGY_STACK.md`, declared once by the Commander and true for every check in the
project. A per-check declaration is also accepted and is recorded as a report:

```markdown
Requires: python-package=httpx; scope=test
Requires: executable=node; scope=test
```

Kinds are `python-package` and `executable`; scopes are `runtime` and `test`. Framework test
clients include their transport dependencies. `Requires:` metadata is not acceptance intent, and
a missing declaration never fails planning — a tool that is present and undeclared works fine.
A declared tool that is *absent* when the check runs reports UNVERIFIED, not FAIL: the check never
reached the code under test, so it says nothing about the build.

### Satisfiability

Every assertion must be satisfiable by a correct implementation. An expectation no implementation
can meet is a defect, not a red baseline. Escaping is the usual source of one: inside a raw
literal, `\n` and `\r` are a backslash followed by a letter, not a control character, so
`r"text\n"` asserts against six characters ending in a literal backslash. Binding the value to a
name and using it on both sides removes the question entirely, which is why that is the rule.

### Runnability

**Subprocess mode.** Match the mode to `input=`. Text input declares `text=True` or `encoding=...`;
binary input uses a bytes-like value and does not declare `text`, `encoding`, `errors`, or
`universal_newlines`. A mismatch raises `TypeError` before the program under test starts, which
reports UNVERIFIED — the criterion buys the story nothing. Write:

```
payload = "one line\n"
result = subprocess.run(["./program"], input=payload, capture_output=True, text=True)
assert result.returncode == 0
```

For a binary or invalid-encoding criterion, write:

```
result = subprocess.run(["./program"], input=b"\xff", capture_output=True)
assert result.returncode != 0
```

**ASCII test data.** Acceptance data is ASCII. Do not invent an encoding requirement: characters
outside ASCII test a property the specification never stated, and a criterion that fails on them
fails the build for something nobody asked the product to do. When the imported specification does
state an encoding requirement, the criterion says so and may then use that encoding:

```
=== AC runtime-utf8 ===
Intent: The executable round-trips UTF-8 source, per INSTRUCTIONS.md.
Encoding: utf-8

source = "café\n"
result = subprocess.run(
    ["./program"], input=source, capture_output=True, text=True, encoding="utf-8"
)
assert result.returncode == 0
assert source.strip() in result.stdout
=== END AC runtime-utf8 ===
```

`Encoding:` is a declaration of deliberate intent, reviewable as such. Absent it, ASCII.

**Every check is standalone.** Drydock writes each fenced block to its own script and runs it in
its own process from the build directory. Checks in the same file share no imports, no variables,
and no execution order. A snippet that reads a name another snippet bound raises `NameError` on
every run — it reports UNVERIFIED rather than failing the build, which means it verifies nothing
and buys nothing. Each snippet imports what it uses and binds every name it reads.

**A check that shells out prints what it captured before it asserts.** `capture_output=True`
routes the runner's tally and its failing cases into a variable; asserting on the exit code alone
then discards them, and the failure reports the assertion with no evidence of what went wrong.
Print the captured `stdout` and `stderr` first, so the console, the evidence file, and the repair
pass all carry the runner's own account of the failure. Printing is for diagnosis; it is never the
oracle.

```markdown
## Programmatic Acceptance

=== AC health-check ===
Intent: The health endpoint returns an OK response.

from app import create_app

client = create_app().test_client()
response = client.get("/health")
assert response.status_code == 200
assert response.get_json()["status"] == "ok"
=== END AC health-check ===

=== AC suite-conformance ===
Intent: The implementation passes the conformance sections this story owns.
Suite: scoped

import subprocess
import sys

result = subprocess.run(
    [sys.executable, "tests/run_suite.py", "--sections", "headings,lists"],
    capture_output=True, text=True,
)
print(result.stdout)
print(result.stderr, file=sys.stderr)
assert result.returncode == 0
=== END AC suite-conformance ===
```

`User Acceptance` contains only Commander-observed checks that cannot be honestly automated,
such as look-and-feel or subjective workflow acceptance. Do not place deterministic behavior in
`User Acceptance`.

Do not tag an assertion with a project-acceptance ID. Sea Trials flow into planning as context for
authoring acceptance; nothing points back at them. Project acceptance is settled at `score release`
by observing the finished tree, never by looking up which assertion claimed which criterion.

**Programmatic acceptance is the story's definition of done, and a deterministic definition of
done is never sampled.** Drydock builds each block in a single pass with no iterate loop, so the
acceptance you author *is* the objective handed to the builder: sample the checks and the builder
builds to the sample. When an authoritative, externally-authored test suite already defines
"correct" for what a story builds — an imported conformance suite and its runner (for example a
specification's example suite plus a `*_tests.py` runner) — the acceptance runs that suite and
requires a full pass over the story's scope, never a hand-picked subset. A feature story binds to
the sections it owns and declares `Suite: scoped`; a terminal verification story gates on the whole
suite and declares `Suite: full`. The marker is one of the block's declaration lines and tells the
runner the check gates on the whole test suite rather than a story-scoped sample.

**A scoped selector must select something.** A check that runs a suite with a section filter
matching no cases exits zero and reports a pass while proving nothing. Select on a heading that
actually owns cases, never on a chapter title that merely contains such headings. Drydock fails a
criterion that is already green before the story's code exists.
**The runner's exit status is the verdict, and it is the whole verdict.** A conformance runner
already decides pass or fail and reports it the one way a caller can rely on. Asserting on its
printed summary as well adds no information and adds a failure mode: the case count belongs to the
installed suite rather than to the specification, and runners column-align their summaries
(`valid tests: 205 passed,  0 failed` carries two spaces), so a literal such as
`assert "valid tests: 210 passed, 0 failed" in result.stdout` is false on correct code and no
implementation can move it. The same holds for tallies of errors, skips, and warnings: a runner
with none of them commonly prints no such line at all, so requiring one is false on a clean run.

Print the captured output for diagnosis, assert `result.returncode == 0`, and stop there. This
holds for both `Suite: scoped` and `Suite: full`.

Place a whole-project deterministic suite on the story that **completes the runnable capability**
— never on a foundation step that cannot yet run it, where it would fail vacuously. Naming the suite file or asserting it is staged (`Path(...).is_file()`)
is staging, not testing: a stubbed or absent definition of done for an available suite is a defect,
not an acceptable check.

An assertion that invokes a staged asset obeys that asset's own documented interface. Read the
asset before writing the call. Every environment variable it declares required is supplied, and it
is supplied by extending the inherited environment — `env={**os.environ, "NAME": value}`. Never
write `env={"NAME": value}`: that replaces the environment, leaving the child with no `PATH`, so
nothing it invokes resolves and the assertion fails at every level of implementation quality. Never
repair a staged asset's interface by editing the asset; it is restored before grading, so the edit
is reported as tampering rather than honored.

An assertion that feeds input to a program passes it through `subprocess` `input=` rather than a
shell. When a shell is unavoidable, `printf '%s'` copies its argument verbatim: `\n` reaches the
program as a backslash and a letter, not a newline, so the program is graded on input the author
never wrote. Use `printf '%b'` or a real line break.

`COMPASS.md` uses `## Compass`, `## Constraints`, and `## Guardrails` as its body sections.
Success criteria belong in `SEA_TRIALS.md`; open questions in spike questionnaires. Do not add
those sections to `COMPASS.md`.

---

---

## Acceptance Criteria Files

**Naming rule:** any file where `AC` is a whole word in the filename is an acceptance criteria
file. `AC` must be delimited by `-`, `_`, or file boundaries — not embedded in another word.
Examples: `AC-001-login.md`, `FEATURE-LOGIN-AC.md`, `AC-NAVIGATION.md`.
`ACCEPTANCE_CRITERIA.md` does NOT follow this standard (AC is not a standalone word).

AC files enable test-driven design and a way to enforce specific behaviors without polluting the
parent specification.

**Two types of AC statements:**

| Type | Example | Rule |
|------|---------|------|
| Positive assertion | "The status badge color is red" | Reconcile into parent spec, then archive this entry |
| Negative/guardrail | "Field X must not appear on this screen" | Keep permanently in AC — these guard against model hallucination, not spec omission |

**Reconciliation:** When a positive AC fact has been implemented and verified, move it to the
parent spec body and delete the AC entry. Negative guardrails are permanent — never move them to
the spec.

**AC file format:**

```markdown
# AC: {ObjectName}

| Field       | Value |
|-------------|-------|
| Version     | YYYYMMDD V1 |
| Description | Acceptance criteria for {ObjectName}. |
| Parent      | FEATURE-{Name}.md |

## Guardrails

- Field X must not appear on this screen.
- The delete button must not be shown to read-only users.

## Assertions

- The status badge is rendered in red when severity is HIGH.
```

**Standard AC filename forms:**
- `AC-NNN-{Name}.md` — numbered sequential acceptance-criteria ticket (authored)
- `{Parent}-AC.md` — paired directly with a spec file (e.g. `FEATURE-LOGIN-AC.md`)
- `AC-{Topic}.md` — topic-scoped AC file (e.g. `AC-NAVIGATION.md`)

**All fix and change tickets use AC naming** — `AC` as a whole word in the filename. A targeted
bug fix is expressed as a testable acceptance criterion.

---

## Dependency Declarations

`drydock plan create` scans spec file headers to populate `Depends On` and `Provides`. The
following conventions apply automatically without explicit header declaration:

| Convention | Rule |
|------------|------|
| `SCREEN-*.md` → `UI-GENERAL.md` | All screens depend on shared UI patterns |
| `DATABASE.md` → Phase 1 | Always first phase; always base context |
| `ARCHITECTURE.md` → base context | Included in every phase prompt |
| `FEATURE-*.md` providing routes → listed in `Provides` | Extracted from route tables in file |
| `SCREEN-*.md` using a route → depends on providing `FEATURE` | Matched from route references in body |

The `Depends On` and `Provides` fields form a simple directed dependency graph. `drydock plan
create` traverses this graph to assign phases, assign build order, and compute context sizes.
A file can only be built in a phase after all its `Depends On` files are built.

---

## Persistence Encapsulation (DATABASE.md scope)

`DATABASE.md` is the project's persistence contract — not SQL schema alone. It documents every
persistent store and the typed class that encapsulates it:

- **Relational tables** — schema plus the row dataclass / CRUD class / composing `Database` class.
- **Config / `.env`** — required keys and the typed `Config` class.
- **File stores** — directories and the `FileStore` class.
- **External services** — the service contract and its wrapper.

Application code reaches each store only through its class. A storage change that leaves the
interface unchanged does not invalidate downstream features.

Every `DATABASE.md` includes `## Access Patterns` and `## Persistence Interfaces` before schema
details. Access patterns name the caller, operation, store, and interface method. Persistence
interfaces name the store, public interface, module location, allowed callers, and notes.

`ARCHITECTURE.md` includes a module ownership table for persistence, configuration, file-store, and
external-service boundaries. It states which module owns each boundary and which low-level APIs that
module may access.

Any Manifest story that implements `DATABASE.md` includes `persistence.md` in `stack:` plus the
selected backend stack file such as `sqlite.md`, `postgres.md`, or `aws-dynamodb.md`.

---

## METADATA.md — Service Identity Fields

In addition to standard project fields, service repositories should declare:

```
service_name:      Platform        # top-level service grouping (e.g. Platform, Analytics, Tools)
service_component: GAME            # component name within the service (matches directory name)
```

These fields are used by build-time service registration artifacts and by GAME's service registry
scanner to group related repositories under a named service.

---

## Authoring Conventions

**Authoring phase:** all unresolved product decisions go in `DECISIONS.json`. Do not create
`MANIFEST.md` or numbered ticket files while authoring.

**Build phase:** run `drydock plan create` once the specification is ready. Use `drydock status`
to check for spec errors and staleness before building. After a build, fold changes back by editing
the specification and re-applying with `drydock refit`.

**Spikes:** a spike is a runnable investigation. Results feed future iterations. When run, the
finding is written into the named file, resolving the matching `## Open Question` in place.

**Feature specifications:** all feature purpose, status, triggers, sequences, routes, reads,
writes, acceptance criteria, and guardrails belong in individual `FEATURE-*.md` files. README,
METADATA, and generated files do not contain feature specifications.
````
</pblock>

<pblock label="Imported source file header" kind="section">
## Imported source files

</pblock>

<pblock filename="sources/INSTRUCTIONS.md" role="source file" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint/sources/INSTRUCTIONS.md" guidance="Raw User Source">
````markdown
# Build Instructions: TOML 1.0.0 Parser

## Objective

Build a TOML v1.0.0 parser that conforms to the specification in
`sources/toml-v1.0.0.md`. Correctness is measured by the upstream `toml-test`
conformance suite. The goal is to pass every valid and every invalid case the
installed suite supplies, with no case failed, errored, or skipped. The suite's
size is a property of the version `setup_harness.sh` installs; never assert a
case count.

Rejecting invalid input is scored as heavily as accepting valid input. A parser
that is merely permissive fails roughly 70 percent of the suite.

The implementation language is Go, fixed by this Target's `TECHNOLOGY_STACK.md`
and governed by `stack/go.md`. The conformance harness itself is written in Go
but is a scoring instrument, not part of the deliverable.

## Run Harness

`sources/full_test.sh` is the single scoring entry point. It is supplied, not
authored: it is staged verbatim into the build directory alongside the other
imported assets, and `drydock uat` runs `sh sources/full_test.sh` from the
completed application root and takes its exit code and output as the score. It
reads:

```sh
#!/bin/sh
# full_test.sh — scoring entry point. Do not filter, skip, or reinterpret.
set -eu
go build -o toml-decoder ./cmd/toml-decoder
DECODER="$PWD/toml-decoder" exec sh sources/run_conformance.sh
```

The build step is deliberately separate from the scoring step so that a
compilation failure and a conformance failure are distinguishable in the
evidence. `DECODER` is the harness's only knowledge of the implementation
language; the harness itself is language-neutral.

**The scoring assets are read-only.** `sources/full_test.sh`,
`sources/run_conformance.sh`, and `sources/setup_harness.sh` are hash-verified
against the import and restored before grading, so a modification is reported as
tampering rather than honored. Do not write to them. Build `cmd/toml-decoder` so
that the supplied entry point succeeds; changing the entry point is not a
repair.

## Interface Contract

The program is a filter: read TOML from **stdin**, write tagged JSON to
**stdout**, exit `0`. On invalid TOML, write a diagnostic to **stderr** and exit
non-zero. No arguments, no config, no side effects.

Minimal shape (`cmd/toml-decoder/main.go`):

```go
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"

	"github.com/owner/toml-decoder/internal/toml"
)

func main() {
	input, err := io.ReadAll(os.Stdin)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	tagged, err := toml.Decode(string(input))
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if err := json.NewEncoder(os.Stdout).Encode(tagged); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
```

The parser lives in `internal/toml`; `main` reads, delegates, and encodes. See
`stack/go.md` for the module layout and the toolchain floor.

### Tagged JSON encoding

- TOML tables become JSON objects. Empty tables become `{}`.
- TOML arrays become JSON arrays. Empty arrays become `[]`.
- Every TOML **value** becomes `{"type": "<TOML_TYPE>", "value": "<TOML_VALUE>"}`.
- `TOML_VALUE` is always a JSON string, including for integers, floats, and booleans.
- `TOML_TYPE` is one of: `string`, `integer`, `float`, `bool`, `datetime`,
  `datetime-local`, `date-local`, `time-local`.
- Offset datetimes are encoded as RFC 3339. Local datetimes are RFC 3339 without
  the offset. Local dates are the date part; local times are the time part.

| TOML | JSON |
|---|---|
| `a = 42` | `{"a": {"type": "integer", "value": "42"}}` |
| `a = true` | `{"a": {"type": "bool", "value": "true"}}` |
| `a = ["a", 2]` | `{"a": [{"type":"string","value":"a"}, {"type":"integer","value":"2"}]}` |
| `[tbl]`<br>`a = 42` | `{"tbl": {"a": {"type": "integer", "value": "42"}}}` |

## Test / Verification Process

The imported source files are placed in a `sources/` subdirectory of the
application directory. Install the harness once (network required, one time
only):

```bash
sh sources/setup_harness.sh
```

Then run the suite from the application directory. `DECODER` is required — the
harness has no default implementation language:

```bash
go build -o toml-decoder ./cmd/toml-decoder
DECODER="$PWD/toml-decoder" sh sources/run_conformance.sh
```

During development, `sh sources/full_test.sh` does both steps and is the same
command the score is taken from.

Mechanics: `toml-test` holds the corpus internally. For each valid case it pipes
TOML into the decoder on stdin and compares the emitted tagged JSON against the
expected description. For each invalid case it requires a non-zero exit. The
summary is:

```
  valid tests: NNN passed,  N failed
invalid tests: NNN passed,  N failed
```

The passed counts are the correctness score. Exit code is non-zero while any
test fails.

### Useful flags

Flags pass straight through `sources/run_conformance.sh` to `toml-test test`.

- `-run 'valid/string/*'` — run one feature group. Use this to develop one
  construct at a time.
- `-run=valid/string-empty,valid/string-nl` — run named cases.
- `-skip 'invalid/datetime/*'` — exclude a group.
- `-json` — machine-readable report instead of text.
- `-v` — list passing tests as well as failures.
- `-script` — emit a shell script of `-skip` flags for the current failures,
  which is the fastest way to snapshot known failures between passes.

Feature groups available to `-run`:

- valid: `array bool comment datetime float inline-table integer key spec-1.0.0 string table`
- invalid: the above plus `control encoding local-date local-datetime local-time`

## Suggested Implementation Order

TOML parsing is lexically simple and structurally fussy. The difficulty is in
key/table semantics and in rejecting malformed input, not in the grammar.

1. **Scaffolding** — line handling, comments, whitespace, the stdin/stdout/exit
   contract, tagged JSON emission.
2. **Scalars** — booleans, integers (including `0x`, `0o`, `0b`, underscores),
   floats (including `inf`, `nan`, exponents), basic and literal strings, then
   multi-line strings with their line-ending backslash and trimming rules.
3. **Keys** — bare, quoted, and dotted keys; the redefinition rules.
4. **Tables** — `[table]`, `[a.b.c]` implicit creation, `[[array of tables]]`,
   and the rules governing which of these may follow which.
5. **Inline tables and arrays** — including nesting and the TOML 1.0 restriction
   that inline tables are closed to later extension.
6. **Datetimes** — offset, local datetime, local date, local time.
7. **Invalid-input hardening** — control characters, bad UTF-8, duplicate keys,
   redefinition after an inline table, unterminated constructs. This is where
   most of the remaining score lives.

The specification is normative and short. Follow it directly.

## Files the LLM Needs

- `sources/toml-v1.0.0.md` — the specification. Primary input. Required.
- `sources/full_test.sh` — the supplied scoring entry point.
- `sources/run_conformance.sh` — the conformance harness it invokes.
- `sources/setup_harness.sh` — one-time harness installation.

## Definition of Done

- `sh sources/full_test.sh` runs cleanly with zero errors and exits zero.
- The program satisfies the stdin → tagged-JSON → exit-code contract.
- Every supplied valid and invalid case passes: the failed, errored, and skipped
  counts are all zero. The harness exit status is the verdict and the whole
  verdict — assert `returncode == 0` and stop there. Do not assert on the text
  of the summary line at all: the case totals belong to the installed suite, and
  a check that reads a runner's printed output is measuring the runner rather
  than the parser.
- The parser is written from the specification. **Every third-party TOML module is
  forbidden** — `github.com/BurntSushi/toml`, `github.com/pelletier/go-toml`,
  `github.com/naoina/toml`, and any other. `BurntSushi/toml` scores near-perfectly
  on this suite, so importing it makes the exercise meaningless.
- `go.mod` declares no `require` dependencies. The standard library is sufficient:
  `encoding/json`, `strconv`, `strings`, `unicode`, `unicode/utf8`, `time`, `math`,
  `fmt`, `io`, `os`, `errors`.
- No network access at test time after `setup_harness.sh` has run once.
````
</pblock>

<pblock filename="sources/full_test.sh" role="source file" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint/sources/full_test.sh">
```bash
#!/bin/sh
# full_test.sh — scoring entry point. Do not filter, skip, or reinterpret.
set -eu
# The version setup_harness.sh installs. run_conformance.sh refuses a different one, so a
# passing verdict names a specific exam rather than whichever harness was on PATH.
TOML_TEST_VERSION="${TOML_TEST_VERSION:-v2.2.0}"
export TOML_TEST_VERSION
go build -o toml-decoder ./cmd/toml-decoder
DECODER="$PWD/toml-decoder" exec sh sources/run_conformance.sh
```
</pblock>

<pblock filename="sources/run_conformance.sh" role="source file" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint/sources/run_conformance.sh">
```bash
#!/bin/sh
# Run the upstream toml-test conformance suite against the built decoder.
#
# Imported sources land in sources/ inside the application directory, so this is
# normally invoked as `sh sources/run_conformance.sh` from that directory.
#
# Usage:
#   DECODER=./toml-decoder sh sources/run_conformance.sh                        # full suite
#   DECODER=./toml-decoder sh sources/run_conformance.sh -run 'valid/string/*'  # one group
#   DECODER=./toml-decoder sh sources/run_conformance.sh -json                  # machine-readable
#
# Environment:
#   DECODER    decoder command. Required — this harness is language-neutral and
#              deliberately has no default implementation language.
#   TOML_TEST  absolute path to the toml-test binary (default: found on PATH)
#
# Exit code is the harness exit code: 0 only when every test passes.

set -u

if [ -z "${DECODER:-}" ]; then
    echo "error: DECODER is not set; give the command that runs your decoder." >&2
    exit 2
fi

if [ -n "${TOML_TEST:-}" ] && [ -x "${TOML_TEST}" ]; then
    HARNESS="${TOML_TEST}"
elif command -v toml-test >/dev/null 2>&1; then
    HARNESS="$(command -v toml-test)"
else
    cat >&2 <<'EOF'
error: toml-test not found.

Install the harness once:

    sh sources/setup_harness.sh

or set TOML_TEST to an existing binary:

    TOML_TEST=/path/to/toml-test sh sources/run_conformance.sh
EOF
    exit 127
fi

# The suite's identity is part of the verdict. Without this, "the authoritative suite passed"
# names no particular suite: whichever toml-test happened to be on PATH decided the run, and a
# different version on a different machine is a different exam. Recorded always, and enforced
# when the caller states which version it expects.
HARNESS_VERSION="$("${HARNESS}" version 2>/dev/null | head -n 1 || true)"
echo "harness: ${HARNESS} ${HARNESS_VERSION:-(version unknown)}" >&2
if [ -n "${TOML_TEST_VERSION:-}" ] && [ -n "${HARNESS_VERSION}" ]; then
    case "${HARNESS_VERSION}" in
        *"${TOML_TEST_VERSION}"*) ;;
        *)
            echo "error: harness is ${HARNESS_VERSION}, expected ${TOML_TEST_VERSION}." >&2
            echo "Run: sh sources/setup_harness.sh" >&2
            exit 2
            ;;
    esac
fi

NO_COLOR=1 exec "${HARNESS}" test -toml 1.0 -decoder "${DECODER}" "$@"
```
</pblock>

<pblock filename="sources/setup_harness.sh" role="source file" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint/sources/setup_harness.sh">
```bash
#!/bin/sh
# One-time installation of the upstream toml-test conformance harness.
#
# Requires network access and a Go toolchain of at least 1.22 — the same floor
# stack/go.md sets for the deliverable. The Go shipped by apt on Debian and
# Ubuntu is frequently older and will fail; install the official tarball instead:
#
#     curl -sL https://go.dev/dl/go1.24.6.linux-amd64.tar.gz -o go.tgz
#     sudo tar -C /usr/local -xzf go.tgz
#     export PATH=/usr/local/go/bin:$PATH
#
# Usage:
#   sh sources/setup_harness.sh              # install to $HOME/.local/bin
#   GOBIN=/usr/local/bin sh sources/setup_harness.sh

set -eu

TOML_TEST_VERSION=v2.2.0
GOBIN="${GOBIN:-$HOME/.local/bin}"

if ! command -v go >/dev/null 2>&1; then
    echo "error: no go toolchain on PATH; see the header of this script" >&2
    exit 1
fi

echo "go:      $(go version)"
echo "target:  ${GOBIN}/toml-test"
echo "version: ${TOML_TEST_VERSION}"

mkdir -p "${GOBIN}"
GOBIN="${GOBIN}" go install \
    "github.com/toml-lang/toml-test/v2/cmd/toml-test@${TOML_TEST_VERSION}"

echo
"${GOBIN}/toml-test" version

case ":${PATH}:" in
    *":${GOBIN}:"*) ;;
    *) echo
       echo "warning: ${GOBIN} is not on PATH. Add it, or export"
       echo "         TOML_TEST=${GOBIN}/toml-test before running the suite." ;;
esac
```
</pblock>

<pblock filename="sources/stage_test.sh" role="source file" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint/sources/stage_test.sh">
```bash
#!/bin/sh
# stage_test.sh — governed stage gate. Runs one slice of the authoritative suite.
#
# Same contract as full_test.sh, scoped to the cases a single story owns: build the decoder,
# then run the installed toml-test suite over the pattern given as $1. Exit status is the
# verdict and the whole verdict. Do not filter, skip, or reinterpret.
set -eu
if [ $# -ne 1 ]; then
  echo "usage: stage_test.sh <toml-test -run pattern>" >&2
  exit 2
fi
TOML_TEST_VERSION="${TOML_TEST_VERSION:-v2.2.0}"
export TOML_TEST_VERSION
go build -o toml-decoder ./cmd/toml-decoder
DECODER="$PWD/toml-decoder" exec sh sources/run_conformance.sh -run "$1"
```
</pblock>

<pblock filename="sources/toml-v1.0.0.md" role="source file" path="/mnt/c/Users/barlo/projects/drydock/uat/Toml/runs/20260814.050011/workspace/targets/toml/blueprint/sources/toml-v1.0.0.md" guidance="Raw User Source">
````markdown
![TOML Logo](logos/toml-200.png)

TOML v1.0.0
===========

Tom's Obvious, Minimal Language.

By Tom Preston-Werner, Pradyun Gedam, et al.

Objectives
----------

TOML aims to be a minimal configuration file format that's easy to read due to
obvious semantics. TOML is designed to map unambiguously to a hash table. TOML
should be easy to parse into data structures in a wide variety of languages.

Table of contents
-----------------

- [Spec](#spec)
- [Comment](#comment)
- [Key/Value Pair](#keyvalue-pair)
- [Keys](#keys)
- [String](#string)
- [Integer](#integer)
- [Float](#float)
- [Boolean](#boolean)
- [Offset Date-Time](#offset-date-time)
- [Local Date-Time](#local-date-time)
- [Local Date](#local-date)
- [Local Time](#local-time)
- [Array](#array)
- [Table](#table)
- [Inline Table](#inline-table)
- [Array of Tables](#array-of-tables)
- [Filename Extension](#filename-extension)
- [MIME Type](#mime-type)
- [ABNF Grammar](#abnf-grammar)

Spec
----

* TOML is case-sensitive.
* A TOML file must be a valid UTF-8 encoded Unicode document.
* Whitespace means tab (0x09) or space (0x20).
* Newline means LF (0x0A) or CRLF (0x0D 0x0A).

Comment
-------

A hash symbol marks the rest of the line as a comment, except when inside a
string.

```toml
# This is a full-line comment
key = "value"  # This is a comment at the end of a line
another = "# This is not a comment"
```

Control characters other than tab (U+0000 to U+0008, U+000A to U+001F, U+007F)
are not permitted in comments.

Key/Value Pair
--------------

The primary building block of a TOML document is the key/value pair.

Keys are on the left of the equals sign and values are on the right. Whitespace
is ignored around key names and values. The key, equals sign, and value must be
on the same line (though some values can be broken over multiple lines).

```toml
key = "value"
```

Values must have one of the following types.

- [String](#string)
- [Integer](#integer)
- [Float](#float)
- [Boolean](#boolean)
- [Offset Date-Time](#offset-date-time)
- [Local Date-Time](#local-date-time)
- [Local Date](#local-date)
- [Local Time](#local-time)
- [Array](#array)
- [Inline Table](#inline-table)

Unspecified values are invalid.

```toml
key = # INVALID
```

There must be a newline (or EOF) after a key/value pair. (See [Inline
Table](#inline-table) for exceptions.)

```
first = "Tom" last = "Preston-Werner" # INVALID
```

Keys
----

A key may be either bare, quoted, or dotted.

**Bare keys** may only contain ASCII letters, ASCII digits, underscores, and
dashes (`A-Za-z0-9_-`). Note that bare keys are allowed to be composed of only
ASCII digits, e.g. `1234`, but are always interpreted as strings.

```toml
key = "value"
bare_key = "value"
bare-key = "value"
1234 = "value"
```

**Quoted keys** follow the exact same rules as either basic strings or literal
strings and allow you to use a much broader set of key names. Best practice is
to use bare keys except when absolutely necessary.

```toml
"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"
'key2' = "value"
'quoted "value"' = "value"
```

A bare key must be non-empty, but an empty quoted key is allowed (though
discouraged).

```toml
= "no key name"  # INVALID
"" = "blank"     # VALID but discouraged
'' = 'blank'     # VALID but discouraged
```

**Dotted keys** are a sequence of bare or quoted keys joined with a dot. This
allows for grouping similar properties together:

```toml
name = "Orange"
physical.color = "orange"
physical.shape = "round"
site."google.com" = true
```

In JSON land, that would give you the following structure:

```json
{
  "name": "Orange",
  "physical": {
    "color": "orange",
    "shape": "round"
  },
  "site": {
    "google.com": true
  }
}
```

For details regarding the tables that dotted keys define, refer to the
[Table](#table) section below.

Whitespace around dot-separated parts is ignored. However, best practice is to
not use any extraneous whitespace.

```toml
fruit.name = "banana"     # this is best practice
fruit. color = "yellow"    # same as fruit.color
fruit . flavor = "banana"   # same as fruit.flavor
```

Indentation is treated as whitespace and ignored.

Defining a key multiple times is invalid.

```
# DO NOT DO THIS
name = "Tom"
name = "Pradyun"
```

Note that bare keys and quoted keys are equivalent:

```
# THIS WILL NOT WORK
spelling = "favorite"
"spelling" = "favourite"
```

As long as a key hasn't been directly defined, you may still write to it and
to names within it.

```
# This makes the key "fruit" into a table.
fruit.apple.smooth = true

# So then you can add to the table "fruit" like so:
fruit.orange = 2
```

```
# THE FOLLOWING IS INVALID

# This defines the value of fruit.apple to be an integer.
fruit.apple = 1

# But then this treats fruit.apple like it's a table.
# You can't turn an integer into a table.
fruit.apple.smooth = true
```

Defining dotted keys out-of-order is discouraged.

```toml
# VALID BUT DISCOURAGED

apple.type = "fruit"
orange.type = "fruit"

apple.skin = "thin"
orange.skin = "thick"

apple.color = "red"
orange.color = "orange"
```

```toml
# RECOMMENDED

apple.type = "fruit"
apple.skin = "thin"
apple.color = "red"

orange.type = "fruit"
orange.skin = "thick"
orange.color = "orange"
```

Since bare keys can be composed of only ASCII integers, it is possible to write
dotted keys that look like floats but are 2-part dotted keys. Don't do this
unless you have a good reason to (you probably don't).

```toml
3.14159 = "pi"
```

The above TOML maps to the following JSON.

```json
{ "3": { "14159": "pi" } }
```

String
------

There are four ways to express strings: basic, multi-line basic, literal, and
multi-line literal. All strings must contain only valid UTF-8 characters.

**Basic strings** are surrounded by quotation marks (`"`). Any Unicode character
may be used except those that must be escaped: quotation mark, backslash, and
the control characters other than tab (U+0000 to U+0008, U+000A to U+001F,
U+007F).

```toml
str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
```

For convenience, some popular characters have a compact escape sequence.

```
\b         - backspace       (U+0008)
\t         - tab             (U+0009)
\n         - linefeed        (U+000A)
\f         - form feed       (U+000C)
\r         - carriage return (U+000D)
\"         - quote           (U+0022)
\\         - backslash       (U+005C)
\uXXXX     - unicode         (U+XXXX)
\UXXXXXXXX - unicode         (U+XXXXXXXX)
```

Any Unicode character may be escaped with the `\uXXXX` or `\UXXXXXXXX` forms.
The escape codes must be valid Unicode [scalar
values](https://unicode.org/glossary/#unicode_scalar_value).

All other escape sequences not listed above are reserved; if they are used, TOML
should produce an error.

Sometimes you need to express passages of text (e.g. translation files) or would
like to break up a very long string into multiple lines. TOML makes this easy.

**Multi-line basic strings** are surrounded by three quotation marks on each
side and allow newlines. A newline immediately following the opening delimiter
will be trimmed. All other whitespace and newline characters remain intact.

```toml
str1 = """
Roses are red
Violets are blue"""
```

TOML parsers should feel free to normalize newline to whatever makes sense for
their platform.

```toml
# On a Unix system, the above multi-line string will most likely be the same as:
str2 = "Roses are red\nViolets are blue"

# On a Windows system, it will most likely be equivalent to:
str3 = "Roses are red\r\nViolets are blue"
```

For writing long strings without introducing extraneous whitespace, use a "line
ending backslash". When the last non-whitespace character on a line is an
unescaped `\`, it will be trimmed along with all whitespace (including newlines)
up to the next non-whitespace character or closing delimiter. All of the escape
sequences that are valid for basic strings are also valid for multi-line basic
strings.

```toml
# The following strings are byte-for-byte equivalent:
str1 = "The quick brown fox jumps over the lazy dog."

str2 = """
The quick brown \


  fox jumps over \
    the lazy dog."""

str3 = """\
       The quick brown \
       fox jumps over \
       the lazy dog.\
       """
```

Any Unicode character may be used except those that must be escaped: backslash
and the control characters other than tab, line feed, and carriage return
(U+0000 to U+0008, U+000B, U+000C, U+000E to U+001F, U+007F).

You can write a quotation mark, or two adjacent quotation marks, anywhere inside
a multi-line basic string. They can also be written just inside the delimiters.

```toml
str4 = """Here are two quotation marks: "". Simple enough."""
# str5 = """Here are three quotation marks: """."""  # INVALID
str5 = """Here are three quotation marks: ""\"."""
str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""

# "This," she said, "is just a pointless statement."
str7 = """"This," she said, "is just a pointless statement.""""
```

If you're a frequent specifier of Windows paths or regular expressions, then
having to escape backslashes quickly becomes tedious and error-prone. To help,
TOML supports literal strings which do not allow escaping at all.

**Literal strings** are surrounded by single quotes. Like basic strings, they
must appear on a single line:

```toml
# What you see is what you get.
winpath  = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
quoted   = 'Tom "Dubs" Preston-Werner'
regex    = '<\i\c*\s*>'
```

Since there is no escaping, there is no way to write a single quote inside a
literal string enclosed by single quotes. Luckily, TOML supports a multi-line
version of literal strings that solves this problem.

**Multi-line literal strings** are surrounded by three single quotes on each
side and allow newlines. Like literal strings, there is no escaping whatsoever.
A newline immediately following the opening delimiter will be trimmed. All other
content between the delimiters is interpreted as-is without modification.

```toml
regex2 = '''I [dw]on't need \d{2} apples'''
lines  = '''
The first newline is
trimmed in raw strings.
   All other whitespace
   is preserved.
'''
```

You can write 1 or 2 single quotes anywhere within a multi-line literal string,
but sequences of three or more single quotes are not permitted.

```toml
quot15 = '''Here are fifteen quotation marks: """""""""""""""'''

# apos15 = '''Here are fifteen apostrophes: ''''''''''''''''''  # INVALID
apos15 = "Here are fifteen apostrophes: '''''''''''''''"

# 'That,' she said, 'is still pointless.'
str = ''''That,' she said, 'is still pointless.''''
```

Control characters other than tab are not permitted in a literal string. Thus,
for binary data, it is recommended that you use Base64 or another suitable ASCII
or UTF-8 encoding. The handling of that encoding will be application-specific.

Integer
-------

Integers are whole numbers. Positive numbers may be prefixed with a plus sign.
Negative numbers are prefixed with a minus sign.

```toml
int1 = +99
int2 = 42
int3 = 0
int4 = -17
```

For large numbers, you may use underscores between digits to enhance
readability. Each underscore must be surrounded by at least one digit on each
side.

```toml
int5 = 1_000
int6 = 5_349_221
int7 = 53_49_221  # Indian number system grouping
int8 = 1_2_3_4_5  # VALID but discouraged
```

Leading zeros are not allowed. Integer values `-0` and `+0` are valid and
identical to an unprefixed zero.

Non-negative integer values may also be expressed in hexadecimal, octal, or
binary. In these formats, leading `+` is not allowed and leading zeros are
allowed (after the prefix). Hex values are case-insensitive. Underscores are
allowed between digits (but not between the prefix and the value).

```toml
# hexadecimal with prefix `0x`
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
hex3 = 0xdead_beef

# octal with prefix `0o`
oct1 = 0o01234567
oct2 = 0o755 # useful for Unix file permissions

# binary with prefix `0b`
bin1 = 0b11010110
```

Arbitrary 64-bit signed integers (from −2^63 to 2^63−1) should be accepted and
handled losslessly. If an integer cannot be represented losslessly, an error
must be thrown.

Float
-----

Floats should be implemented as IEEE 754 binary64 values.

A float consists of an integer part (which follows the same rules as decimal
integer values) followed by a fractional part and/or an exponent part. If both a
fractional part and exponent part are present, the fractional part must precede
the exponent part.

```toml
# fractional
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01

# exponent
flt4 = 5e+22
flt5 = 1e06
flt6 = -2E-2

# both
flt7 = 6.626e-34
```

A fractional part is a decimal point followed by one or more digits.

An exponent part is an E (upper or lower case) followed by an integer part
(which follows the same rules as decimal integer values but may include leading
zeros).

The decimal point, if used, must be surrounded by at least one digit on each
side.

```
# INVALID FLOATS
invalid_float_1 = .7
invalid_float_2 = 7.
invalid_float_3 = 3.e+20
```

Similar to integers, you may use underscores to enhance readability. Each
underscore must be surrounded by at least one digit.

```toml
flt8 = 224_617.445_991_228
```

Float values `-0.0` and `+0.0` are valid and should map according to IEEE 754.

Special float values can also be expressed. They are always lowercase.

```toml
# infinity
sf1 = inf  # positive infinity
sf2 = +inf # positive infinity
sf3 = -inf # negative infinity

# not a number
sf4 = nan  # actual sNaN/qNaN encoding is implementation-specific
sf5 = +nan # same as `nan`
sf6 = -nan # valid, actual encoding is implementation-specific
```

Boolean
-------

Booleans are just the tokens you're used to. Always lowercase.

```toml
bool1 = true
bool2 = false
```

Offset Date-Time
----------------

To unambiguously represent a specific instant in time, you may use an [RFC
3339](https://tools.ietf.org/html/rfc3339) formatted date-time with offset.

```toml
odt1 = 1979-05-27T07:32:00Z
odt2 = 1979-05-27T00:32:00-07:00
odt3 = 1979-05-27T00:32:00.999999-07:00
```

For the sake of readability, you may replace the T delimiter between date and
time with a space character (as permitted by RFC 3339 section 5.6).

```toml
odt4 = 1979-05-27 07:32:00Z
```

Millisecond precision is required. Further precision of fractional seconds is
implementation-specific. If the value contains greater precision than the
implementation can support, the additional precision must be truncated, not
rounded.

Local Date-Time
---------------

If you omit the offset from an [RFC 3339](https://tools.ietf.org/html/rfc3339)
formatted date-time, it will represent the given date-time without any relation
to an offset or timezone. It cannot be converted to an instant in time without
additional information. Conversion to an instant, if required, is
implementation-specific.

```toml
ldt1 = 1979-05-27T07:32:00
ldt2 = 1979-05-27T00:32:00.999999
```

Millisecond precision is required. Further precision of fractional seconds is
implementation-specific. If the value contains greater precision than the
implementation can support, the additional precision must be truncated, not
rounded.

Local Date
----------

If you include only the date portion of an
[RFC 3339](https://tools.ietf.org/html/rfc3339) formatted date-time, it will
represent that entire day without any relation to an offset or timezone.

```toml
ld1 = 1979-05-27
```

Local Time
----------

If you include only the time portion of an [RFC
3339](https://tools.ietf.org/html/rfc3339) formatted date-time, it will
represent that time of day without any relation to a specific day or any offset
or timezone.

```toml
lt1 = 07:32:00
lt2 = 00:32:00.999999
```

Millisecond precision is required. Further precision of fractional seconds is
implementation-specific. If the value contains greater precision than the
implementation can support, the additional precision must be truncated, not
rounded.

Array
-----

Arrays are square brackets with values inside. Whitespace is ignored. Elements
are separated by commas. Arrays can contain values of the same data types as
allowed in key/value pairs. Values of different types may be mixed.

```toml
integers = [ 1, 2, 3 ]
colors = [ "red", "yellow", "green" ]
nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
string_array = [ "all", 'strings', """are the same""", '''type''' ]

# Mixed-type arrays are allowed
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
contributors = [
  "Foo Bar <foo@example.com>",
  { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
]
```

Arrays can span multiple lines. A terminating comma (also called a trailing
comma) is permitted after the last value of the array. Any number of newlines
and comments may precede values, commas, and the closing bracket. Indentation
between array values and commas is treated as whitespace and ignored.

```toml
integers2 = [
  1, 2, 3
]

integers3 = [
  1,
  2, # this is ok
]
```

Table
-----

Tables (also known as hash tables or dictionaries) are collections of key/value
pairs. They are defined by headers, with square brackets on a line by
themselves. You can tell headers apart from arrays because arrays are only ever
values.

```toml
[table]
```

Under that, and until the next header or EOF, are the key/values of that table.
Key/value pairs within tables are not guaranteed to be in any specific order.

```toml
[table-1]
key1 = "some string"
key2 = 123

[table-2]
key1 = "another string"
key2 = 456
```

Naming rules for tables are the same as for keys (see definition of
[Keys](#keys) above).

```toml
[dog."tater.man"]
type.name = "pug"
```

In JSON land, that would give you the following structure:

```json
{ "dog": { "tater.man": { "type": { "name": "pug" } } } }
```

Whitespace around the key is ignored. However, best practice is to not use any
extraneous whitespace.

```toml
[a.b.c]            # this is best practice
[ d.e.f ]          # same as [d.e.f]
[ g .  h  . i ]    # same as [g.h.i]
[ j . "ʞ" . 'l' ]  # same as [j."ʞ".'l']
```

Indentation is treated as whitespace and ignored.

You don't need to specify all the super-tables if you don't want to. TOML knows
how to do it for you.

```toml
# [x] you
# [x.y] don't
# [x.y.z] need these
[x.y.z.w] # for this to work

[x] # defining a super-table afterward is ok
```

Empty tables are allowed and simply have no key/value pairs within them.

Like keys, you cannot define a table more than once. Doing so is invalid.

```
# DO NOT DO THIS

[fruit]
apple = "red"

[fruit]
orange = "orange"
```

```
# DO NOT DO THIS EITHER

[fruit]
apple = "red"

[fruit.apple]
texture = "smooth"
```

Defining tables out-of-order is discouraged.

```toml
# VALID BUT DISCOURAGED
[fruit.apple]
[animal]
[fruit.orange]
```

```toml
# RECOMMENDED
[fruit.apple]
[fruit.orange]
[animal]
```

The top-level table, also called the root table, starts at the beginning of the
document and ends just before the first table header (or EOF). Unlike other
tables, it is nameless and cannot be relocated.

```toml
# Top-level table begins.
name = "Fido"
breed = "pug"

# Top-level table ends.
[owner]
name = "Regina Dogman"
member_since = 1999-08-04
```

Dotted keys create and define a table for each key part before the last one,
provided that such tables were not previously created.

```toml
fruit.apple.color = "red"
# Defines a table named fruit
# Defines a table named fruit.apple

fruit.apple.taste.sweet = true
# Defines a table named fruit.apple.taste
# fruit and fruit.apple were already created
```

Since tables cannot be defined more than once, redefining such tables using a
`[table]` header is not allowed. Likewise, using dotted keys to redefine tables
already defined in `[table]` form is not allowed. The `[table]` form can,
however, be used to define sub-tables within tables defined via dotted keys.

```toml
[fruit]
apple.color = "red"
apple.taste.sweet = true

# [fruit.apple]  # INVALID
# [fruit.apple.taste]  # INVALID

[fruit.apple.texture]  # you can add sub-tables
smooth = true
```

Inline Table
------------

Inline tables provide a more compact syntax for expressing tables. They are
especially useful for grouped data that can otherwise quickly become verbose.
Inline tables are fully defined within curly braces: `{` and `}`. Within the
braces, zero or more comma-separated key/value pairs may appear. Key/value pairs
take the same form as key/value pairs in standard tables. All value types are
allowed, including inline tables.

Inline tables are intended to appear on a single line. A terminating comma (also
called trailing comma) is not permitted after the last key/value pair in an
inline table. No newlines are allowed between the curly braces unless they are
valid within a value. Even so, it is strongly discouraged to break an inline
table onto multiples lines. If you find yourself gripped with this desire, it
means you should be using standard tables.

```toml
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
animal = { type.name = "pug" }
```

The inline tables above are identical to the following standard table
definitions:

```toml
[name]
first = "Tom"
last = "Preston-Werner"

[point]
x = 1
y = 2

[animal]
type.name = "pug"
```

Inline tables are fully self-contained and define all keys and sub-tables within
them. Keys and sub-tables cannot be added outside the braces.

```toml
[product]
type = { name = "Nail" }
# type.edible = false  # INVALID
```

Similarly, inline tables cannot be used to add keys or sub-tables to an
already-defined table.

```toml
[product]
type.name = "Nail"
# type = { edible = false }  # INVALID
```

Array of Tables
---------------

The last syntax that has not yet been described allows writing arrays of tables.
These can be expressed by using a header with a name in double brackets. The
first instance of that header defines the array and its first table element, and
each subsequent instance creates and defines a new table element in that array.
The tables are inserted into the array in the order encountered.

```toml
[[products]]
name = "Hammer"
sku = 738594937

[[products]]  # empty table within the array

[[products]]
name = "Nail"
sku = 284758393

color = "gray"
```

In JSON land, that would give you the following structure.

```json
{
  "products": [
    { "name": "Hammer", "sku": 738594937 },
    { },
    { "name": "Nail", "sku": 284758393, "color": "gray" }
  ]
}
```

Any reference to an array of tables points to the most recently defined table
element of the array. This allows you to define sub-tables, and even sub-arrays
of tables, inside the most recent table.

```toml
[[fruits]]
name = "apple"

[fruits.physical]  # subtable
color = "red"
shape = "round"

[[fruits.varieties]]  # nested array of tables
name = "red delicious"

[[fruits.varieties]]
name = "granny smith"


[[fruits]]
name = "banana"

[[fruits.varieties]]
name = "plantain"
```

The above TOML maps to the following JSON.

```json
{
  "fruits": [
    {
      "name": "apple",
      "physical": {
        "color": "red",
        "shape": "round"
      },
      "varieties": [
        { "name": "red delicious" },
        { "name": "granny smith" }
      ]
    },
    {
      "name": "banana",
      "varieties": [
        { "name": "plantain" }
      ]
    }
  ]
}
```

If the parent of a table or array of tables is an array element, that element
must already have been defined before the child can be defined. Attempts to
reverse that ordering must produce an error at parse time.

```
# INVALID TOML DOC
[fruit.physical]  # subtable, but to which parent element should it belong?
color = "red"
shape = "round"

[[fruit]]  # parser must throw an error upon discovering that "fruit" is
           # an array rather than a table
name = "apple"
```

Attempting to append to a statically defined array, even if that array is empty,
must produce an error at parse time.

```
# INVALID TOML DOC
fruits = []

[[fruits]] # Not allowed
```

Attempting to define a normal table with the same name as an already established
array must produce an error at parse time. Attempting to redefine a normal table
as an array must likewise produce a parse-time error.

```
# INVALID TOML DOC
[[fruits]]
name = "apple"

[[fruits.varieties]]
name = "red delicious"

# INVALID: This table conflicts with the previous array of tables
[fruits.varieties]
name = "granny smith"

[fruits.physical]
color = "red"
shape = "round"

# INVALID: This array of tables conflicts with the previous table
[[fruits.physical]]
color = "green"
```

You may also use inline tables where appropriate:

```toml
points = [ { x = 1, y = 2, z = 3 },
           { x = 7, y = 8, z = 9 },
           { x = 2, y = 4, z = 8 } ]
```

Filename Extension
------------------

TOML files should use the extension `.toml`.

MIME Type
---------

When transferring TOML files over the internet, the appropriate MIME type is
`application/toml`.

ABNF Grammar
------------

A formal description of TOML's syntax is available, as a separate [ABNF file][abnf].

[abnf]: https://github.com/toml-lang/toml/blob/1.0.0/toml.abnf
````
</pblock>

<pblock label="Persistent Plan feedback" kind="feedback">
## Commander decisions

Apply these decisions as constraints; do not recreate them as questions.

### analyze-display_name
- Title: Display Name
- Decision: TOML 1.0.0 Parser
- Severity: material
- Blueprint: ARCHITECTURE.md

### analyze-short_description
- Title: Short Description
- Decision: A Go command-line parser that converts TOML 1.0.0 from stdin into tagged JSON and rejects invalid documents.
- Severity: material
- Blueprint: ARCHITECTURE.md
</pblock>


# Agent Task

# Agent for: planning session synthesis

Map each required technical or behavioral ID in structured `SEA_TRIALS.md` into the implementing
story's `accepts:` field. Never invent or rename Sea Trial IDs. Do not tag a Programmatic
Acceptance assertion with a Sea Trial ID: Sea Trials flow into planning as context and nothing
points back at them. Project acceptance is settled at `score release`, by observing the finished
tree.
Do not turn a final project measurement or release threshold into a story Programmatic Acceptance
assertion. Those remain Sea Trials and run at final scoring after all stories close.
The one terminal `Suite: full` assertion is the exception: it runs the supplied suite and requires
success. It may additionally verify the total using either
a count derived from authoritative suite data or an explicitly declared authoritative exact count.

`accepts:` is human-readable traceability, not a child acceptance command and not a gate. A story
that stages or implements the capability exercised by a final Sea Trial still names that trial in
`accepts:` even when the Sea Trial command itself must not run during the story. `TOPOLOGY.md` is
emitted in Stage 1 before any Blueprint, so settle the complete story set and its acceptance
before emitting anything.

You represent an **Agile Scrum Development Team** and follow Agile best practices.

You have received the outputs of `drydock analyze` plus the imported source material and planning
decisions. Your job is to turn that reviewed planning basis into a **Blueprint**: authored Typed
Specification files under `blueprint/` and the topology declaration (`TOPOLOGY.md`) that Drydock
serializes into `MANIFEST.md`, the single work graph carrying build order, grouping, and per-step
prompt-assembly fields.

The core elements are defined below.

---

## Planning Objective

Your goal is to convert the analysis artifacts into a build-ready Drydock Blueprint.

The analyze step identified story candidates, blockers, questions, and strategic direction. This
step converts that information into durable specification files with exact header formatting and
clear relationships. You are not writing prose notes; you are writing structured product
definition and build-planning artifacts.

The primary outputs are:

- Typed Specification files such as `ARCHITECTURE.md`, `FEATURE-*.md`, `SCREEN-*.md`,
  `DATABASE.md`, `UI-GENERAL.md`, and AC files where warranted.
- `TOPOLOGY.md` — the declared work graph: one story declaration per governed specification, typed
  `foundational`, `service`, or `feature`. Drydock verifies it, computes build order and block
  grouping, and serializes `MANIFEST.md` from it.

**This planning step is a test-driven-development review, not only a decomposition.** Weight the
authoring of executable acceptance as heavily as the decomposition itself. Every buildable story
carries several concrete Python assertions in the `## Programmatic Acceptance` sections of the
specs it implements, so that `drydock build` has a failing test to satisfy for each behavior before
the code exists. A plan that decomposes cleanly but ships specs with empty acceptance has failed
this step. Assertion authoring is mandatory-or-justified: a spec's acceptance is `- None.` only
when the item genuinely has no programmatic surface, and then the reason is stated inline.

This step must produce **decomposed specifications with solid header relationships**:

- every authored spec file uses the Drydock typed header format
- `Depends On`, `Provides`, and `Consumes` are declared consistently across the emitted Blueprint
- story declarations in `TOPOLOGY.md` point at real emitted spec files
- the runnable frontier implied by the Manifest is coherent

Treat the Story List and Story Realization Map in `ANALYSIS.md` as the completed planning
decomposition and the default work breakdown. Preserve their proposed story boundaries and mapped
source filenames unless the complete planning context shows that a story is non-atomic,
inaccurate, contradictory, incomplete, or assigns content to the wrong owner. When correction is
necessary, split, merge, move, replace, or reorder the affected scope. Rewrite every resulting
story as a governed specification using all planning inputs; source structure is strong evidence
for the story boundary, but source content is not authoritative.

When the analysis is too coarse, refine it into smaller spec scopes. When it is too fine, merge it
into the smallest durable spec structure that preserves correctness and clear ownership.
The Analyze story list is the Team Lead's expert proposal, not an immutable work breakdown.
Preserve a source Markdown file and filename when it already represents one atomic story, but split
it when it combines independent actions. A screen and its provider route are separate stories and
separate specifications even when they participate in one workflow.

---

## Inputs

The job block injects the following. `SYSTEM_SHAPE` and `ANALYSIS_QUALITY` are stated directly in
the job block; the rest are fenced sections.

- **Plan feedback (standing directive)** — `PLAN_COMPASS.md`, persistent human direction
  injected near the top of this prompt when present. Treat it as authoritative steering for this
  run; it overrides default decomposition and ordering choices where it speaks.
- **`ANALYSIS.md`** — the Team Lead's reviewed proposal: quality signal, candidate story/file map,
  open questions, tuning options, expectations, and notes. Review its mapping as an agile expert;
  preserve, merge, split, replace, or reorder it when the complete planning context requires that.
- **`## Surfaced Acceptance Criteria`** in `ANALYSIS.md` — additional criteria analyze derived per
  story; fold each row into the `## Programmatic Acceptance` or `## User Acceptance` section of the
  spec file implementing its Story ID.
- **`## Relationship Model`** and **`## Planning Instructions`** in `ANALYSIS.md` — primary
  Analyze-to-Plan handoff. Honor the Story Realization Map when selecting durable Blueprint
  scopes; carry the stated sequencing/dependency model into Manifest ordering and `depends:`;
  embed cited interfaces, workflows, test-kit behavior, and acceptance in the matching specs.
  Every readable imported source is available below. Analyze guides interpretation and proposes a
  realization map; it never limits which source evidence the Planning Crew may consult.
- **`SYSTEM_SHAPE`** — the determined project type (`web|api|cli|library|pipeline|event-driven`),
  parsed from the analysis. Drives the default decomposition table below.
- **`SEA_TRIALS.md`** and **`SOUNDINGS.md`** — product objectives and acceptance milestones from
  analyze. Use these as planning context; do not overwrite their intent.
- **Answered questionnaires** (`discovery-*.json`) — settled human-owned decisions on intent and
  guardrails. Do not re-raise a question that a questionnaire has already answered.
  Drydock preflight guarantees that every Analyze question marked `required_before_plan` is answered
  before this prompt runs. Questionnaires never carry technology-stack decisions.
- **`TECHNOLOGY_STACK.md`** — the Commander-owned technology decisions of record: one row per
  technology, with the Rigging file that governs building it or `—` when none exists. This is the
  sole authority on the stack. It may be absent or incomplete; that means undecided, and you
  resolve the gap from the sources rather than stopping.
- **`COMPASS.md`** — existing product intent if already present; otherwise derive emitted content
  from the analysis and sources. It does not carry technology choices.

### Precedence

When authoritative inputs disagree, apply this order and proceed. Do not stop on a disagreement
that this order resolves:

1. `PLAN_COMPASS.md` **Commander Direction**
2. Answered questionnaires and Commander-directed `DECISIONS.json` items (`commander_direction` or
   `override_text` set)
3. `TECHNOLOGY_STACK.md` (technology questions only)
4. `COMPASS.md`
5. Imported source files and `ANALYSIS.md`

**Absence is never prohibition.** An item missing from `TECHNOLOGY_STACK.md`, unselected in a
questionnaire, or unmentioned in `COMPASS.md` is undecided, not forbidden. Never treat an omission
as a negative requirement, and never raise a conflict because one input lists something another
does not.

### Conflict Scope

- SQS, S3, databases, logs, and Marina/application-managed files are distinct from repository
  checkout content.
- “Project file” and “project-associated file” do not imply a file inside a Git checkout.
- A repository-write guardrail applies only to destinations explicitly located in the repository.
- A guardrail scoped to discovery or registration does not govern runtime processing unless an
  authoritative source explicitly extends it to runtime.
- Missing detail is not a conflict. Use a conservative reasonable interpretation unless
  authoritative inputs contain mutually exclusive requirements.
- Error Mode must cite the exact files, clauses, and scopes that conflict and explain why the
  Precedence order cannot resolve them.

- **`MANIFEST_CONTRACT.md`** and **`BLUEPRINTS_CONTRACT.md`** — authoritative format and field
  contracts for the outputs.
- **Imported source files** — all readable material under `blueprint/sources/`, injected below.
  It is unconstrained Commander input, not governed Blueprint syntax. Never reject a source because
  of its filename, headings, tables, question labels, or formatting. Authored Markdown specs are a
  structured interpretation. Non-Markdown assets are projected byte-for-byte by Drydock; never emit
  or rewrite them.

If `ANALYSIS_QUALITY` is `Blocked`, planning must not proceed. Emit only a refusal message inside
the required output block contract described below.

---

## Story and Task Criteria

Decomposition is **Agile feature and story decomposition**. Apply that discipline at expert level:
INVEST stories, vertical slices, test-driven acceptance per story. The rules below are the criteria,
not a substitute for that judgement.

- A **story** delivers one observable behavior or capability slice. It is independently buildable,
  independently verifiable, and carries its own acceptance gate. The story is the unit Drydock
  gates, builds, and attributes failure to.
- A **task** is a technical sub-step of a story — add a helper, refactor a module, wire a parameter.
  A task is never a `story` block and never becomes a Blueprint file. Instructions inside a story
  may describe its tasks.
- Prefer **more, smaller stories** over fewer large ones. Distinctness is the limit: each story owns
  its behavior alone, and no two stories own the same behavior.
- Story size in Drydock is the token and context size of the build step. A story whose build step
  would not fit comfortably in one build prompt is too large. Split it into smaller stories that
  each still meet the story criteria above; never split it into tasks, and never leave a single
  story owning several independent construct families.
- When the source material is short or names few features, keep the story set lined up with the
  source's own shape. Preserving author intent outranks splitting for its own sake, and the criteria
  above still bound the result.

---

## Decomposition Method

Execute in order. Do not skip a step.

**1. Review the planning basis.**
- *Consumes:* imported sources, `ANALYSIS.md`, `PLAN_COMPASS.md` direction, answered questionnaires.
- *Emits:* working understanding of the project shape, stack, constraints, and unanswered items.

**2. Confirm the decomposition shape.**
- *Consumes:* the analysis story list, project type signals, and source structure.
- *Emits:* one authored Blueprint file per story-sized capability, per the story criteria above.
  Fewest *file kinds*, not fewest stories: use only the spec kinds the project needs, then decompose
  within them.

Default decomposition rules:

| System shape | Durable authored files |
|---|---|
| `web` | `ARCHITECTURE.md`, `UI-GENERAL.md` if shared UI exists, one `FEATURE-*.md` per route/service workflow, one `SCREEN-*.md` per user-facing screen, `DATABASE.md` if persistence exists |
| `api` | `ARCHITECTURE.md`, one `FEATURE-*.md` per endpoint/capability cluster, `DATABASE.md` if persistence exists |
| `cli` | `ARCHITECTURE.md`, one `FEATURE-*.md` per command/capability cluster |
| `library` | `ARCHITECTURE.md`, one `FEATURE-*.md` per public module or service area, `DATABASE.md` only if stateful |
| `pipeline` | `ARCHITECTURE.md`, one `FEATURE-*.md` per pipeline stage or major dataset transformation, `DATABASE.md` only if persistent stores exist |
| `event-driven` | `ARCHITECTURE.md`, one `FEATURE-*.md` per handler or event workflow cluster |

Use `SCREEN-*.md` only for actual user-facing screens. Use `DATABASE.md` only when persistent
state or external stored state exists. Use AC files only when separate permanent guardrails are
needed and they should not bloat the parent spec.

**3. Map analysis stories to authored spec scopes.**
- *Consumes:* `ANALYSIS.md ## Story List`.
- *Emits:* a mapping from analyzed stories to emitted files.

Rules:

- Each emitted authored spec file must represent one durable capability boundary.
- The `## Story Realization Map` in `ANALYSIS.md` is a proposed partition. Keep a row that names a
  distinct, atomic capability scope unless complete planning context supports a better partition.
- Two analysis stories collapse into one authored file only when both describe the **same**
  behavior *and* the merged unit still satisfies the story criteria above. Distinct scopes — for
  example a block parser, an inline parser, reference resolution, a renderer, and an executable
  interface — are separate stories even when they ship in one program.
- One analysis story may expand into several authored spec files when the boundary naturally
  separates into screen, feature, architecture, or persistence contracts, or when the single story
  is too large to build in one step.
- Record the mapping in the Manifest: each story's `covers:` field names the `ANALYSIS.md` Story IDs
  it delivers. Every Story ID in the analysis is covered by **exactly one** story. A story that
  covers several IDs is the declared collapse case and must satisfy the collapse rule above.
- When one analysis story expands into several stories, exactly one of them carries its ID in
  `covers:` — the story that delivers the analyzed behavior, whatever its `type:`. A `foundational`
  persistence or architecture story that realizes an analyzed story still covers it; `type:` never
  decides ownership.
- A plan-introduced story with no analyzed counterpart — an architecture boundary, a scaffold, a
  test-harness story — omits `covers:` entirely. Never duplicate an ID that another story owns, and
  never fill the field to make it look complete: two stories claiming one analyzed story destroys
  failure attribution.
- Every important user-facing screen named in analysis must land in a `SCREEN-*.md`.
- Every important route, capability, interface, dataset, topic, or command named in analysis must
  be represented in one or more `FEATURE-*.md` files, with `ARCHITECTURE.md` and `DATABASE.md`
  carrying shared technical structure where needed.
- Drydock deterministically injects `ARCHITECTURE_compact.md` and `DATABASE_compact.md` into
  `FEATURE-*` build steps when those source files exist. Do not model that policy manually with
  screen stories or ad hoc context duplication.

**4. Write authored specification content.**
- *Consumes:* the file mapping and all planning inputs.
- *Emits:* complete authored spec markdown with exact header format and required terminal sections.

Each authored file must be build-usable. Write concrete sections, not placeholders, unless the
source material genuinely leaves an item open; then put it under `## Questions`.

**5. Author programmatic acceptance (test-driven).**
- *Consumes:* each authored spec's routes, interfaces, reads, writes, guardrails, any tests
  carried in the imported source material, and any `ANALYSIS.md ## Surfaced Acceptance Criteria`
  rows tied to this spec's Story ID.
- *Emits:* the `## Programmatic Acceptance` section of every authored spec, as concrete Python
  assertions.

Rules:

- Treat this as writing the failing tests first. For every story, the specs it implements together
  carry **several** executable assertions — generally one per distinct observable behavior, route,
  invariant, or error mode described in that spec. A single assertion for a multi-behavior spec is
  insufficient.
- Every split story owns its own assertions in the spec it implements. Splitting must never leave a
  story gated by another story's acceptance, and never leave two stories asserting one behavior.
- Assertions are concrete and executable from the build directory: assert a route responds, a
  record is written with the expected keys, an invariant holds, a guardrail rejects, an error type
  is raised. Cover the ordinary "the thing exists and responds" checks explicitly (for a route,
  that it is reachable and returns the expected status) — do not assume they are obvious.
- Route coverage is enforced: a SCREEN spec's assertions must literally call every route in its
  `Provides` and `Consumes` (the plan is rejected otherwise); a FEATURE spec's assertions must
  exercise every route and interface it provides, naming each literal route path in at least one
  assertion.
- Imported test material is **input, not output — with one exception.** Ad hoc tests, test
  scripts, or a prose `## Test` section: review them and re-express the intended checks as Drydock
  Programmatic Acceptance assertions in the spec; do not trust their format, copy them verbatim, or
  point at that script. **The exception is an authoritative conformance suite** — an
  externally-authored, executable suite whose runner *defines* "correct" for the capability (for
  example a specification's example set plus its `*_tests.py` runner). A conformance suite is never
  paraphrased into hand assertions: paraphrase samples it and drops coverage. Its acceptance
  **invokes the imported runner** over the scope the spec owns and asserts a full pass of that
  scope, per the suite-binding rule below.
- **Act on the system. Read the state back. Compare to expected.** The assertion reads *state* —
  a return value, parsed JSON, a status code, a stored row, file contents read back, an exit
  status. It never reads a substring of captured stdout or stderr, a test-runner tally, or a log
  line. A state oracle cannot pass against a stub and cannot fail because a runner printed the
  word "warning"; a text oracle can do both. Print captured output for diagnosis, never assert on
  it.
- Write the check in the project's own language, using that language's libraries. An in-language
  HTTP client yields a status code and a parsed body, which is state; `curl` yields stdout, which
  is text to scrape. Reaching for an external executable is the exception and belongs in Rigging.
- Prefer the round trip for anything that stores, mutates, or removes state: act, then read back
  through the public interface and assert the resulting state. A write that returns a plausible
  object while persisting nothing must fail. Enumerate coverage from the interface — every route
  and method, every subcommand and behavior-changing flag, every exported function — rather than
  sampling it. Assert declared failure signals on negative paths, never message wording.
- **Never type an expected value twice. Bind it to a name and use the name on both sides.** You
  are authoring before the code exists, so a hand-typed expectation is a prediction about bytes
  you have not seen; when the prediction is wrong the criterion fails a correct implementation and
  nothing downstream can tell that from a real defect. Legal expected values: a name bound to the
  input the criterion supplied, a status code or count, a contract token read off a declared
  interface (`"integer"`, `"application/json"`), a staged suite's exit status. Illegal: a string
  literal you typed out as the expected result. Drydock judges this mechanically — a string
  expectation carrying anything escapable that the criterion did not also supply as input — and a
  criterion that breaks the rule settles `DISPUTED`, gating nothing and buying its story no
  coverage. Write `raw = "C:\\Users\\nodejs"; source = f"raw = '{raw}'\n"; ...
  assert decoded["raw"]["value"] == raw`, never a second spelling of the same value.
- Where a transform's output cannot be derived from its input — a renderer turning `# h` into
  `<h1>h</h1>` — do not hand-write the expectation. Bind to the authoritative suite that defines
  correctness for that transform. Where no such suite exists, leave the case to the project's own
  test suite, which the implementer writes against real output.
- Write `- None.` only when the item genuinely has no programmatic surface (pure visual/manual
  UI, or a Commander-observed check). State the reason on the same line, e.g.
  `- None. Visual-only screen; behavior covered by its backing FEATURE spec.` Bare `- None.` on a
  spec that declares any `Provides` entry is a defect.

**6. Declare relationships.**
- *Consumes:* the authored spec set as a whole.
- *Emits:* `Depends On`, `Provides`, and `Consumes` in each Blueprint header.

Rules:

- `Depends On` names the files or interface points required before this file can be implemented.
- `Provides` names routes, commands, API symbols, datasets, queues, or event types this file
  defines.
- `Consumes` lists the interface points this file calls. A SCREEN lists the routes it calls.
- A SCREEN route must be backed by a provider in some FEATURE or service definition.
- Do not leave relationship fields contradictory across files. State what each file requires and
  provides; Drydock derives the rest.

**7. Declare the topology.**
- *Consumes:* the authored spec set and its declared relationships.
- *Emits:* `TOPOLOGY.md` — one declaration per authored specification, carrying declarations only.

These seven jobs are the order you *think* in, not the order you *emit* in. Settle all seven first.
Stage 1 then emits the complete `TOPOLOGY.md` declaration and `DECISIONS.json` only. Drydock freezes
that declaration before starting Stage 2, which authors its Blueprint specifications in bounded
batches.

You author judgment. Drydock computes everything positional. **Do not emit `MANIFEST.md`. Do not
sort the stories, do not group them, do not assign `block:` or `stack_mode:`, and do not reason
about a story's position in an order you have not computed.** Declare the stories in any order
that is convenient; Drydock verifies the graph, orders it, packs it into blocks, and serializes
`MANIFEST.md` itself. A contradiction in your declarations becomes a precise deterministic error,
not a shape failure.

`TOPOLOGY.md` is a flat declaration. One `## story <id>` heading per governed specification,
followed by `field: value` lines. There is no `id:` line — the heading carries the id. There is no
`block:`, no `stack_mode:`, no `state:`, no numbering, and no ordering of any kind:

```text
## story catalog-service
summary:      Serve the catalog read API.
type:         service
kind:         capability
phase:        1
implements:   FEATURE-Catalog.md
covers:       CATALOG-001
context:      DATABASE.md
stack:        common.md, python.md, fastapi.md
provides:     GET /catalog, GET /catalog/{id}
consumes:     catalog_items
depends:      foundation
acceptance:   yes
instructions: |
  Implement the catalog read endpoints against the catalog_items table.

  Return 404 for an unknown id.
```

Declare, per story:

- `summary`, `implements` (exactly one governed specification), `instructions`
- `type` — `foundational`, `service`, or `feature`, per `MANIFEST_CONTRACT.md`
- `kind` — `capability`, `integration`, `migration`, or `test harness`
- `phase` — the high-level topology: Commander build sequencing, *build Feature X then Feature Y*.
  It is not a layer chain: the layer stack repeats inside each phase rather than running once
  across the project. Weigh Commander ordering direction as input when assigning it.
- `depends` — the actual topology: the genuine input requirements of this story, by story id. A
  `feature` story depends on its member stories.
- `provides` / `consumes` — what this story defines and calls, comma-separated
- `stack` — the Rigging stack files this story builds with
- `acceptance` — `yes` when the story has real acceptance to honor
- `covers`, `accepts`, `context`, `rules`, `copy`, `scope`, `feedback` when applicable

`instructions` uses the `|` block form shown above: every body line is indented, and the body ends
at the first unindented line. Every other field is one line.

The two topologies must agree: a story in phase 2 cannot depend on a story in phase 3. Drydock
checks this and rejects the plan when they disagree.

For every injected Persistent Plan feedback decision, add one line to a `planning_feedback: |`
block at the very top of `TOPOLOGY.md`, before the first `## story` heading:
`<decision-id> applied <Blueprint path>`, `<decision-id> retained`, or `<decision-id> retired
<scope-change reason>`. A renamed file is never a retirement reason. Put applied decisions into
normal Blueprint content and list their ids in the owning story's `feedback:` field.

---

## Typed Specification Format

For every authored Blueprint file except `METADATA.md` and `README.md`, use this exact header
shape:

```markdown
# {FileType}: {ObjectName}

| Field       | Value |
|-------------|-------|
| Version     | YYYYMMDD V1 |
| Description | One sentence summary. |
| Depends On  | FEATURE-SERVICE-CATALOG.md, UI-GENERAL.md |
| Provides    | GET /welcome, GET /welcome/summary |
| Consumes    | GET /api/welcome-summary |
```

`Phase` is **not** a Blueprint header field. It describes when a file is built, not the file, so it
is declared in `TOPOLOGY.md` only.

SCREEN files may also include:

```markdown
| Route       | /welcome |
| Parent      | Main |
| Main Menu   | Welcome (1) |
| Sub Menu    | Summary (1) |
| Tab Order   | 1 |
```

Required rules:

- `Version` must use the current job date and start at `V1` for new files.
- `Description` is one sentence.
- Preserve exact field names and table formatting.
- Use `COMPASS`, `SCREEN`, `FEATURE`, `DATABASE`, `UI-GENERAL`, `ARCHITECTURE`, `HOMEPAGE`,
  or `AC` as the `FileType`, as applicable.
- Do not invent a new typed file category.

Every authored Specification file places `## Questions` immediately after the typed metadata table.
Use `- None.` when no human-owned unknown remains. Otherwise use the exact record contract from
`BLUEPRINTS_CONTRACT.md`. The file then ends with these sections:

```markdown
## Programmatic Acceptance

- None.

## User Acceptance

- None.

## Guardrails

- None.

```

Use `- None.` only when that section is truly empty, and for `## Programmatic Acceptance` state the
reason inline (see below).

Additional body guidance:

- `COMPASS.md` body uses `## Compass`, `## Constraints`, and `## Guardrails`.
- `ARCHITECTURE.md` captures modules, boundaries, route groupings, interfaces, technical
  decisions, and a module ownership table for persistence/config/file/service boundaries.
- `ARCHITECTURE.md` carries a `## Technology Stack` section derived from `TECHNOLOGY_STACK.md`:
  the technologies in use and where each applies. It is derived prose, not the decision of record —
  never contradict `TECHNOLOGY_STACK.md` and never introduce a technology it does not list.
- `DATABASE.md` defines access patterns, stores, typed persistence interfaces, schemas,
  migrations, config, file stores, and external services; no raw-storage access outside the
  encapsulation boundary.
- `FEATURE-*.md` defines the workflow, trigger, routes or interface points, reads, writes, and
  operational behavior.
- `SCREEN-*.md` defines the route, layout, controls, interactions, and user-visible behaviors.
- `Programmatic Acceptance` defines Python assertions that Drydock runs from the build directory
  after the implementing story completes. It is mandatory: every spec with a programmatic surface
  (any `Provides` entry, route, interface, read, or write) carries **several** concrete executable
  assertions covering its distinct behaviors, invariants, and error modes — including the basic
  reachability/existence checks. This is the test-driven contract the build must satisfy. Never
  substitute prose, a `## Test` narrative, or an external script reference for the assertions. Emit
  `- None.` only for a genuine non-programmatic item, with the reason stated on the same line.
- Declare every external Python package and executable used directly or indirectly by each
  Programmatic Acceptance mechanism using repeated `Requires: <kind>=<name>; scope=<scope>` lines.
  Include framework test-client dependencies such as `httpx`. Never install or silently assume an
  undeclared tool. Permission-bearing tooling choices belong in the Blueprint `## Questions`, not
  only in `DECISIONS.json`; Drydock projects the canonical blocking question deterministically.
- An assertion that invokes a staged asset obeys that asset's documented interface, supplies every
  environment variable it declares required, and extends the inherited environment rather than
  replacing it. See the staged-asset invocation rules in `BLUEPRINTS_CONTRACT.md`.
- `User Acceptance` contains only Commander-observed checks that cannot be honestly automated.
---

## Manifest Construction Rules

Derive the Manifest from the authored specs, not directly from the imported source text.

**Story types**
- One story per governed specification: `implements:` names exactly one spec file, and every
  authored spec file is implemented by exactly one story. The story is the atomic build primitive.
- `foundational` — structure and scaffolding. Standing up S3 and proving the connection is
  architecture. Recognizing that something must establish the web server, and making it a node, is
  your judgment and determines story structure.
- `service` — everything that does work. Much of what source material labels architecture is
  service work: the web server and the database are foundation; a voice service interpreter is a
  service wearing an architecture filename.
- `feature` — an assembly story. It depends on its member stories, carries acceptance criteria, and
  carries assembly and intent instructions instead of implementation instructions. It is not a
  grouping construct and it is not a batching unit.
- There is no fourth type, and no `spike` or `ac` story type. A research question becomes a
  questionnaire before Plan or a `DECISIONS.json` record after.

**Story sizing**
- A story is a normal Agile story: **1 to 5 story points**. Never a half point — that is a task,
  and a task is folded into the story it serves. Never twelve — that is split.
- A story does one thing completely, carries test criteria, and is releasable on its own. A task is
  not releasable and is therefore not a story.
- Size by that judgement alone. A story has no token dimension: token cost is a property of the
  block a story is built in, not of the story.
- Story count is not capped, and it is an output of correct decomposition rather than a target.
  Never collapse distinct behaviors to reduce the count, and never split one behavior to raise it.

**Stack**
- Draw `stack:` values from the Rigging column of `TECHNOLOGY_STACK.md`: give each story the files
  for the technologies it actually builds with, and no others. A technology whose Rigging cell is
  `—` contributes no `stack:` entry. When `TECHNOLOGY_STACK.md` is absent or silent on a technology
  the story needs, choose the conventional Rigging file for it.
- Never emit `stack_mode:`. Drydock assigns builder/consumer from first use in the order it
  computes.
- Any story that implements `DATABASE.md` must include `persistence.md` in `stack:` plus the
  selected backend stack file such as `sqlite.md`, `postgres.md`, or `aws-dynamodb.md`.

**Context**
- Use `context:` only for genuine read-only support files.
- For context files classified in `ANALYSIS.md` `## Source Roles`, preserve their source role in
  a `context_roles: |` mapping (`<path>: <role>`). Key it by the promoted Blueprint name, never a
  `sources/...` path. A test suite or harness is `context`, never `implements`.
- A file the Analysis marks `stage` is present in the build directory at `sources/<name>`.
  Reference it by that build-relative path in Programmatic Acceptance. Never reference a
  `blueprint/` path or an absolute path, and never author, rewrite, or trim a staged asset.

**Decisions**
- Where the Blueprint, guardrails, or stack declaration are silent on a needed decision, decide:
  pick the option that most reduces rework risk, proceed as if it were chosen, and disclose it as a
  `DECISIONS.json` item (see Significant Design Decisions below). Ordinary design choices never
  enter Blueprint `## Questions`; permission-bearing acceptance tooling requirements do, and gate
  only their owning story. Assign `low`, `material`, or `blocking` severity. Ordinary Plan-selected
  choices never hard-block regardless of severity.
- Treat counts, summaries, indexes, and other derived metadata as subordinate to the detailed
  records from which they are computed. When derived metadata disagrees with an unambiguous
  detailed enumeration, recompute it from that enumeration and continue. This is neither a product
  question nor Error Mode. Do not require the Commander to correct a stale derived total.

**Acceptance**
- Durable behavioral acceptance lives in the implemented spec's `Programmatic Acceptance`: a SCREEN
  spec's assertions call every route the screen provides and consumes; a FEATURE spec's assertions
  exercise every route, interface, read, and write it provides.
- Do not copy Sea Trial commands into ordinary story acceptance or execute them while planning.
- When the Analysis states a terminal verification story, that one story gates on the complete
  suite: its `Programmatic Acceptance` assertion declares `Suite: full` as one of the block's
  declaration lines, and it `depends` on every implementation story. Without
  that declaration a full-suite run is rejected. **Only the terminal story runs the whole suite.**
- A harness staging or integration story — one that runs the imported runner only to prove it is
  staged and executes, not to gate correctness — must bound its invocation with the runner's
  `--pattern`/`--number` selector. An unbounded run of the suite from any non-terminal story,
  without `Suite: full`, is rejected.
- When an authoritative conformance suite is imported (a specification's example set plus its
  runner), **every implementing feature story binds its acceptance to that suite over the sections
  it owns**, never to a hand-written sample. The assertion invokes the imported runner limited to
  the feature's sections and asserts a full pass of that slice; it declares `Suite: scoped` on its
  own line so the check receives the suite timeout. Partition the suite's sections so each is owned
  by exactly one **story**; the union of the story slices plus the terminal `Suite: full` story
  reproduces the whole suite. One story owning every section is an under-decomposed plan.
  A scoped run requires runner success and zero failures/errors within its selected slice. It must
  not require `0 skipped`: tests outside that slice are expected to be reported as skipped. Only
  the terminal `Suite: full` assertion may require zero skipped tests.
- Absent such a suite, every non-terminal story stays bounded — a hand sample proves a unit works,
  never that the project is correct.

**Ordering and grouping — not yours**
- Do not sort the stories. Do not compute a topological order. Do not group them into batches.
- Do not emit `block:`. Blocks are ephemeral context-optimization groups computed by Drydock: one
  topology type per block, never crossing a phase boundary, never violating the edges, packed to
  amortize stack-file cost across one build pass. Context economy comes from blocks, not from
  feature grouping.
- Declare `depends:` as genuine input requirements only. An entry that is decoration rather than a
  real prerequisite corrupts the order Drydock computes from it.

---

## Significant Design Decisions

Significant Design Decisions not specified by the Blueprint. Build must never stall on a choice
Plan should have already made, and the Commander must be able to review and redirect any such
choice before Build acts on it. Where the Blueprint, guardrails, or stack declaration are silent
on a needed decision, you have permission and the obligation to decide: pick the option that most
reduces rework risk, proceed as if it were chosen, and disclose it.

Ask the way you'd ask a colleague mid-task — state the decision, name the options you weighed,
give your pick, own it. Not an exhaustive survey.

Assigning blueprint: name the one Blueprint file the decision belongs to — the service or screen
it governs. If it belongs to neither, name `ARCHITECTURE.md`.

Emit every decision as `DECISIONS.json`, using the standard file delimiters. Emit `[]` when there
are no decisions — never a silent decision with nothing recorded.

```text
=== BEGIN ARTIFACT DECISIONS.json ===
[
  {
    "id":            "string, e.g. Q-001",
    "type":          "choice | text",
    "severity":      "low | material | blocking",
    "blueprint":     "string — the Blueprint filename this decision belongs to",
    "story":         "string | null",
    "title":         "string",
    "description":   "string",
    "options":       [ { "value": "string", "label": "string" } ],
    "system_choice": "string"
  }
]
=== END ARTIFACT ===
```

`type: "text"` decisions set `options` to `[]` and put the resolution in `system_choice`. Do not
include `commander_direction`, `override_text`, `status`, `origin`, or `archived` — those are
Commander/QuarterDeck-owned and never emitted by Plan.

`DECISIONS.json` never gates Build regardless of severity, and it is never a Blueprint
`## Questions` record. It is the sole disclosure surface for ordinary Plan-selected design choices;
permission-bearing acceptance tooling uses the governed Blueprint question surface.

---

## Output Contract

Emit exactly one response mode. **Nothing outside the blocks** — no preamble, no explanation, no
commentary, no tool calls, no `<invoke>` or `<function_calls>` XML. Any output outside a delimited
block is a protocol violation and will cause the run to fail. Start your response with the first
`=== BEGIN ARTIFACT ... ===` block.

The response is processed by a deterministic parser. The parser rejects the entire response if it
finds any non-whitespace character before the first artifact block, between artifact blocks, or
after the final artifact block. A rejected response writes no Blueprint files and no
`MANIFEST.md`.

Do not emit transition or completion text such as `Now the Manifest.`, `Next file:`,
`Here is the completed Blueprint.`, or `Done.` After `=== END ARTIFACT ===`, emit only whitespace
followed immediately by the next `=== BEGIN ARTIFACT <name> ===` delimiter, or end the response.

### Success Mode

Use Success Mode whenever the product basis is sufficient to declare an internally consistent
Blueprint and Manifest.

Stage 1 emits exactly two blocks: the complete `TOPOLOGY.md` first and `DECISIONS.json` second.
Do not emit any Blueprint specification in this response. Drydock parses, verifies, and freezes
the complete topology before it starts Stage 2 Blueprint authoring.

Declaring first is a hard requirement, not a stylistic one. `TOPOLOGY.md` is the plan; the spec
files implement it. Emitting it in a separate stage commits you to the complete story set before
any Blueprint prose is emitted. A response whose declaration never arrives is unrecoverable.

Every `implements:` filename in `TOPOLOGY.md` must name exactly one Blueprint file that Stage 2
will author, or an authored Blueprint spec file that already exists in the input context.

Wrap both Stage 1 files in matching open/END delimiter pairs:

```text
=== BEGIN ARTIFACT relative/path/from/blueprint/or/target ===
{full file contents}
=== END ARTIFACT ===
```

The `=== END ARTIFACT ===` line is mandatory for every file, not only for `TOPOLOGY.md`.
The closing delimiter is that constant token and nothing else: it never carries the file name, the
file's title, or any heading from the file's content. The name is typed once, at the open. Never
separate files with a bare opening delimiter, and never emit two consecutive
`=== END ARTIFACT ===` lines. Emit each file exactly once; do not repeat a file you have already
emitted.

The complete Stage 1 response is:

```text
=== BEGIN ARTIFACT TOPOLOGY.md ===
{the story declarations}
=== END ARTIFACT ===
=== BEGIN ARTIFACT DECISIONS.json ===
[]
=== END ARTIFACT ===
```

`DECISIONS.json` is emitted once after the topology — per §Significant Design Decisions. Emit `[]`
when there are no decisions to disclose. Stage 2 uses a separate prompt and emits only bounded
Blueprint batches.

Never emit a `MANIFEST.md` block. Drydock serializes the Manifest from your declaration.

### Blocked Mode

Use Blocked Mode only when `ANALYSIS_QUALITY` is `Blocked`. Emit only:

```text
=== BEGIN ARTIFACT PLAN_CREATE_BLOCKED.txt ===
Planning cannot proceed because ANALYSIS.md is Blocked.
Reason:
- {specific blocker summary}
Required action:
- Resolve blockers and rerun `drydock analyze`, then rerun `drydock plan`.
=== END ARTIFACT ===
```

### Error Mode

Use Error Mode only for an unresolvable **product** question — one the Precedence order above
cannot settle and no reasonable assumption can bridge. Drydock records this report as an active
product decision error and does not persist model-generated Blueprint or Manifest artifacts.

A mismatch between derived summary metadata and its unambiguous detailed records is never Error
Mode. Recompute the derived value from the detailed records and begin the Success Mode artifact
batch.

Available response length is never Error Mode. Stage 1 emits only the complete topology and
decisions. Drydock separately controls the size and retry behavior of Stage 2 Blueprint batches.

A technology-stack disagreement is never Error Mode. Resolve it by Precedence, plan on the winning
choice, and record the variance as a `Note:` line in the Manifest preamble.

Emit only:

```text
=== BEGIN ARTIFACT PLAN_CREATE_ERROR.txt ===
Planning output was not produced.
Error type: {format|missing-input|conflict|insufficient-specification|other}
Reason:
- {exact conflicting files, clauses, and scopes; why precedence cannot resolve them}
Required action:
- {specific product decision or source correction required}
=== END ARTIFACT ===
```

---

## Hard Rules

- Nothing outside the required output blocks — no preamble, no summary, no prose, no tool calls, no `<invoke>` or `<function_calls>` XML.
- Never emit `MANIFEST.md`; Drydock serializes it from `TOPOLOGY.md`.
- In Success Mode `TOPOLOGY.md` is the first block, `DECISIONS.json` is the second block, and no
  Blueprint specification is emitted during Stage 1.
- Never emit `TOPOLOGY.md` in Error Mode or Blocked Mode.
- Never emit partial Blueprint files in Error Mode or Blocked Mode.
- Do not emit a file that violates `BLUEPRINTS_CONTRACT.md` or `MANIFEST_CONTRACT.md`.
- Every `implements:` entry in `TOPOLOGY.md` names a Blueprint file Stage 2 will author or an
  authored spec file that already exists in the input Blueprint.
- Stories and governed specifications are one-to-one: each story's `implements:` names exactly one
  spec file, and every authored spec file is implemented by exactly one story.
- Never emit `AGENTS.md`. AGENTS.md is not a Blueprint file and is distributed with rigging at build time.
- Every emitted authored spec file except `METADATA.md` and `README.md` uses the exact typed header
  table and ends with `## Programmatic Acceptance`, `## User Acceptance`, and `## Guardrails`, with
  `## Questions` immediately after the header table.
- Emit `DECISIONS.json` once, in Success Mode only, immediately after `TOPOLOGY.md`. Never
  put a Plan decision in a Blueprint `## Questions` section.
- `Phase` is never a Blueprint header field; declare it in `TOPOLOGY.md` only.
- Never emit `block:` or `stack_mode:`; both are computed by Drydock.
- Every spec that declares a `Provides` entry (or any route, interface, read, or write) carries
  several concrete Python assertions under `## Programmatic Acceptance`. `- None.` there is allowed
  only for a genuinely non-programmatic item and must state its reason inline.
- A SCREEN spec's Programmatic Acceptance must literally call every route in its `Provides` and
  `Consumes`; a plan whose SCREEN acceptance skips a route is rejected.
- Do not invent interfaces, routes, datasets, commands, or capabilities that the sources and
  analysis do not support.
- Do not leave user-facing screens without backing providers.
- Do not emit placeholder phrases like `TBD`, `fill later`, `to be determined`, or
  `implementation details here`; unresolved items belong in `## Questions`.
- Do not emit empty authored files.
- Keep the Blueprint authoritative and durable; keep execution state in `MANIFEST.md`.

Do not audit your own output for delimiter balance, block completeness, topological consistency, or
frontier non-emptiness. Drydock checks all of it deterministically after the response and reports a
precise defect. Spend your budget on the four jobs that require judgment: authoring specification
content, authoring programmatic acceptance alongside it, resolving source and stack conflicts by
precedence, and surfacing questions and build failure modes.

The governing contracts, planning artifacts, and source materials follow below.

<pblock label="Frozen Stage 1 output" kind="frozen-stage">
# Frozen Stage 1 Output

The following topology and decisions are the exact accepted Stage 1 output.
Author the current Blueprint batch from them; do not reconstruct or amend them.

## TOPOLOGY.md

planning_feedback: |
  analyze-display_name applied ARCHITECTURE.md
  analyze-short_description applied ARCHITECTURE.md

## story architecture
summary:      Define the Go parser modules, command boundary, tagged JSON contract, and standard-library constraints.
type:         foundational
kind:         capability
phase:        1
implements:   ARCHITECTURE.md
stack:        go.md, common.md
provides:     parser module boundary, decoder command boundary, tagged JSON contract
consumes:
acceptance:   yes
scope:        both
instructions: |
  Establish the Go module layout, the internal TOML parser boundary, the cmd/toml-decoder
  stdin/stdout/stderr process contract, tagged JSON value representation, and standard-library-only
  dependency policy. Add focused tests for the declared boundaries.
accepts:       st-001

## story decoder-contract
summary:      Build the stdin-to-tagged-JSON decoder command.
type:         service
kind:         capability
phase:        1
implements:   FEATURE-Decoder-Contract.md
covers:       DECODER-001
stack:        go.md, common.md
context:      sources/INSTRUCTIONS.md
context_roles: |
  sources/INSTRUCTIONS.md: compass
provides:     cmd/toml-decoder
consumes:     parser module boundary, tagged JSON contract
depends:       architecture
acceptance:   yes
scope:        both
instructions: |
  Implement cmd/toml-decoder as an argument-free stdin filter. Read all TOML from stdin,
  delegate parsing to internal/toml, encode the tagged result as JSON on stdout, and report
  operational failures on stderr with a non-zero exit status. Add process-level tests for valid
  stdin, stdout JSON, argument rejection, and absence of configuration or side effects.

## story decoder-invalid-input
summary:      Report invalid TOML through the decoder process boundary.
type:         service
kind:         capability
phase:        1
implements:   FEATURE-Decoder-Invalid-Input.md
covers:       DECODER-002
stack:        go.md, common.md
context:      sources/INSTRUCTIONS.md
context_roles: |
  sources/INSTRUCTIONS.md: compass
provides:     invalid-input diagnostic boundary
consumes:     cmd/toml-decoder, parser error boundary
depends:       decoder-contract
acceptance:   yes
scope:        both
instructions: |
  Ensure malformed TOML produces no successful JSON result, writes a diagnostic to stderr,
  and exits non-zero. Keep diagnostics outside the stdout contract and add process-level tests
  that assert only exit status and stream separation.

## story decoder-tagged-json
summary:      Encode parsed TOML values using the required tagged JSON representation.
type:         service
kind:         capability
phase:        1
implements:   FEATURE-Tagged-JSON.md
covers:       DECODER-003
stack:        go.md, common.md
context:      sources/INSTRUCTIONS.md
context_roles: |
  sources/INSTRUCTIONS.md: compass
provides:     tagged JSON encoding
consumes:     parser value model, cmd/toml-decoder
depends:       decoder-contract
acceptance:   yes
scope:        both
instructions: |
  Implement JSON encoding for tables, arrays, and scalar values. Every TOML value uses the
  required type and string-valued payload, while tables and arrays retain their structural JSON
  forms. Add tests for empty structures, nested structures, and every declared scalar type.

## story lexical-strings
summary:      Parse TOML basic, multiline basic, literal, and multiline literal strings.
type:         service
kind:         capability
phase:        2
implements:   FEATURE-Lexical-Strings.md
covers:       LEXICAL-001
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML string values
consumes:     parser module boundary
depends:       architecture
acceptance:   yes
scope:        both
instructions: |
  Implement all TOML 1.0.0 string forms, escape sequences, UTF-8 validation, multiline
  trimming and continuation rules, literal preservation, and prohibited-control validation.
  Bind acceptance to the authoritative string conformance slice.

## story lexical-numbers
summary:      Parse TOML integers, floating-point values, special floats, and booleans.
type:         service
kind:         capability
phase:        2
implements:   FEATURE-Lexical-Numbers.md
covers:       LEXICAL-002
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML integer values, TOML float values, TOML boolean values
consumes:     parser module boundary
depends:       architecture
acceptance:   yes
scope:        both
instructions: |
  Implement decimal, hexadecimal, octal, binary, floating-point, exponent, inf, nan, and
  boolean syntax with underscore validation and lossless signed 64-bit integer handling.
  Bind acceptance to the authoritative integer, float, and bool conformance slices.

## story lexical-datetime
summary:      Parse offset datetime, local datetime, local date, and local time values.
type:         service
kind:         capability
phase:        2
implements:   FEATURE-Lexical-Datetime.md
covers:       LEXICAL-003
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML datetime values
consumes:     parser module boundary
depends:       architecture
acceptance:   yes
scope:        both
instructions: |
  Implement recognition and tagged representation of offset datetimes, local datetimes,
  local dates, and local times, including permitted separators, fractional precision, and
  truncation behavior. Bind acceptance to the authoritative datetime conformance slice.

## story lexical-whitespace-comments
summary:      Process TOML whitespace, comments, line endings, continuations, and encoding rules.
type:         service
kind:         capability
phase:        2
implements:   FEATURE-Lexical-Whitespace-Comments.md
covers:       LEXICAL-004
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML document lexical boundaries
consumes:     parser module boundary
depends:       architecture
acceptance:   yes
scope:        both
instructions: |
  Implement whitespace and comment handling, LF and CRLF processing, multiline continuation
  behavior, valid UTF-8 enforcement, and prohibited control-character rejection. Bind acceptance
  to the authoritative comment, control, and encoding conformance slices.

## story keys-forms
summary:      Parse bare, quoted, and dotted TOML keys.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Key-Forms.md
covers:       KEYS-001
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML key paths
consumes:     TOML string values, parser module boundary
depends:       lexical-strings, lexical-whitespace-comments
acceptance:   yes
scope:        both
instructions: |
  Implement bare, quoted, and dotted key parsing, including whitespace around dotted
  components and nested object creation. Bind acceptance to the authoritative key conformance
  slice.

## story keys-semantics
summary:      Enforce TOML key uniqueness and scalar-to-table definition rules.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Key-Semantics.md
covers:       KEYS-002
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     key-definition validation
consumes:     TOML key paths, parser value model
depends:       keys-forms, lexical-numbers, lexical-datetime
acceptance:   yes
scope:        both
instructions: |
  Track defined keys and implicit tables so duplicate definitions, invalid keys, scalar
  extension, and closed-structure extension are rejected. Bind acceptance to the relevant
  authoritative valid and invalid key cases.

## story structures-arrays
summary:      Parse TOML arrays and nested array values.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Arrays.md
covers:       STRUCTURES-001
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML arrays
consumes:     TOML scalar values, TOML key paths
depends:       lexical-strings, lexical-numbers, lexical-datetime, keys-forms
acceptance:   yes
scope:        both
instructions: |
  Implement empty, nested, mixed-type, multiline, commented, and trailing-comma arrays,
  preserving order and recursively parsing values. Bind acceptance to the authoritative array
  conformance slice.

## story structures-inline-tables
summary:      Parse TOML inline tables and nested inline-table keys.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Inline-Tables.md
covers:       STRUCTURES-002
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML inline tables
consumes:     TOML scalar values, TOML key paths
depends:       lexical-strings, lexical-numbers, lexical-datetime, keys-forms
acceptance:   yes
scope:        both
instructions: |
  Implement single-line inline tables, nested inline tables, dotted keys within inline tables,
  and all permitted value forms. Reject multiline and trailing-comma violations. Bind acceptance
  to the authoritative inline-table conformance slice.

## story structures-inline-table-closure
summary:      Enforce closure of TOML inline tables.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Inline-Table-Closure.md
covers:       STRUCTURES-003
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     inline-table immutability validation
consumes:     TOML inline tables, TOML key paths
depends:       structures-inline-tables, keys-semantics
acceptance:   yes
scope:        both
instructions: |
  Mark inline tables and their descendants as closed after definition. Reject later key or
  subtable additions through dotted keys and table headers. Bind acceptance to the authoritative
  invalid inline-table cases.

## story tables-standard
summary:      Parse standard TOML table headers and implicit tables.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Standard-Tables.md
covers:       TABLES-001
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML standard tables
consumes:     TOML key paths, key-definition validation
depends:       keys-semantics, structures-inline-table-closure
acceptance:   yes
scope:        both
instructions: |
  Implement standard table headers, nested and implicitly created tables, empty tables, and
  root-table behavior. Bind acceptance to the authoritative table conformance slice.

## story tables-redefinition
summary:      Enforce standard-table redefinition and structure-conflict rules.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Table-Redefinition.md
covers:       TABLES-002
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     table-definition validation
consumes:     TOML standard tables, key-definition validation
depends:       tables-standard, keys-semantics
acceptance:   yes
scope:        both
instructions: |
  Reject duplicate table headers and conflicts among scalar values, standard tables, inline
  tables, and arrays. Bind acceptance to the authoritative invalid table cases.

## story tables-arrays
summary:      Parse arrays of TOML tables and nested table elements.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Arrays-of-Tables.md
covers:       TABLES-003
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     TOML arrays of tables
consumes:     TOML standard tables, TOML key paths, TOML arrays
depends:       tables-standard, structures-arrays
acceptance:   yes
scope:        both
instructions: |
  Implement array-of-table headers, ordered elements, nested standard tables, nested arrays of
  tables, and current-element targeting. Bind acceptance to the authoritative table conformance
  slice.

## story tables-arrays-ordering
summary:      Enforce array-of-table ordering and conflict rules.
type:         service
kind:         capability
phase:        3
implements:   FEATURE-Arrays-of-Tables-Ordering.md
covers:       TABLES-004
stack:        go.md, common.md
context:      sources/toml-v1.0.0.md, sources/stage_test.sh
context_roles: |
  sources/toml-v1.0.0.md: context
  sources/stage_test.sh: stage
provides:     array-of-table ordering validation
consumes:     TOML arrays of tables, table-definition validation
depends:       tables-arrays, tables-redefinition
acceptance:   yes
scope:        both
instructions: |
  Reject reversed parent ordering, appends to statically defined arrays, and conflicts between
  arrays of tables and normal tables or arrays. Bind acceptance to the authoritative invalid table
  cases.

## story conformance
summary:      Run the complete pinned TOML 1.0.0 conformance suite.
type:         service
kind:         test harness
phase:        4
implements:   FEATURE-Conformance.md
covers:       CONFORMANCE-001
accepts:       st-001
stack:        go.md, common.md
context:      sources/full_test.sh, sources/run_conformance.sh, sources/setup_harness.sh
context_roles: |
  sources/full_test.sh: stage
  sources/run_conformance.sh: context
  sources/setup_harness.sh: stage
provides:     complete TOML 1.0.0 conformance verdict
consumes:     cmd/toml-decoder, TOML parser
depends:       decoder-invalid-input, decoder-tagged-json, lexical-strings, lexical-numbers, lexical-datetime, lexical-whitespace-comments, keys-forms, keys-semantics, structures-arrays, structures-inline-tables, structures-inline-table-closure, tables-standard, tables-redefinition, tables-arrays, tables-arrays-ordering
acceptance:   yes
scope:        target
instructions: |
  Build the decoder and invoke sources/full_test.sh unfiltered against the installed toml-test
  v2.2.0 suite. Treat the supplied script exit status as the complete acceptance verdict and
  preserve the supplied harness assets unchanged.

## DECISIONS.json

[
  {
    "id": "Q-001",
    "type": "choice",
    "severity": "low",
    "blueprint": "ARCHITECTURE.md",
    "story": "architecture",
    "title": "Parser value representation",
    "description": "Represent parsed values with explicit internal value kinds and ordered containers before tagged JSON encoding.",
    "options": [
      {
        "value": "explicit-kinds",
        "label": "Explicit value kinds"
      },
      {
        "value": "generic-interface",
        "label": "Generic interfaces"
      }
    ],
    "system_choice": "explicit-kinds"
  },
  {
    "id": "Q-002",
    "type": "choice",
    "severity": "low",
    "blueprint": "ARCHITECTURE.md",
    "story": "architecture",
    "title": "Parser implementation boundary",
    "description": "Keep lexical parsing, structural state, semantic validation, and JSON encoding in separate internal responsibilities.",
    "options": [
      {
        "value": "separated-responsibilities",
        "label": "Separated responsibilities"
      },
      {
        "value": "single-parser-module",
        "label": "Single parser module"
      }
    ],
    "system_choice": "separated-responsibilities"
  }
]
</pblock>

<pblock label="Plan continuation" kind="continuation">
# Continuation

Stage 1 is complete. Drydock accepted and froze the complete `TOPOLOGY.md` declaration before
starting this Blueprint-authoring stage. The full planning context above remains authoritative.

The ledger below states exactly what Drydock accepted, what is still missing, and what came back
defective. Treat it as fact.

## Your job

Emit **exactly** the artifacts in the ledger's **Current batch**, in the stated order. Nothing else.

- Do not re-emit an accepted artifact. Its content is already held and will not be read again.
- Do not emit a deferred artifact. Drydock supplies it in a later bounded batch.
- Do not emit or amend `TOPOLOGY.md`; Stage 1 is complete and frozen.
- Do not emit `DECISIONS.json`; it was captured with the topology in Stage 1.
- Do not restate your plan, summarize progress, apologize, or explain the interruption.
- Do not emit `MANIFEST.md`; Drydock serializes it from the declaration.
- Use exactly the same delimited block format as before, including the mandatory
  `=== END ARTIFACT ===` line for every file. The name is typed once, at the open; the
  closing delimiter is that constant token and never carries the name.
- An artifact listed as defective must be emitted again in full, corrected. A partial or patched
  version is not accepted.
- Emit each missing artifact under the exact filename the ledger names. A filename that does not
  match its declaration cannot be accepted.

## Budget

Author the Current batch one Blueprint at a time. For each Blueprint, emit its opening delimiter,
its complete file body, and its matching closing delimiter. Only after the closing delimiter is
written may the next Blueprint's opening delimiter be emitted.

A whole artifact is progress; a truncated one is not. Never pre-emit opening delimiters, outline
several files at once, nest one artifact inside another, or use one closing delimiter for several
files. If the whole Current batch cannot fit, finish and close the current artifact, then end the
response. Drydock retries every unproduced artifact from the same batch.

The only legal sequence is:

```text
=== BEGIN ARTIFACT FIRST-NAME ===
{complete first file}
=== END ARTIFACT ===
=== BEGIN ARTIFACT SECOND-NAME ===
{complete second file}
=== END ARTIFACT ===
```

## Ledger

Accepted (15) — already held, do not re-emit:
  ARCHITECTURE.md
  FEATURE-Arrays.md
  FEATURE-Decoder-Contract.md
  FEATURE-Decoder-Invalid-Input.md
  FEATURE-Inline-Table-Closure.md
  FEATURE-Inline-Tables.md
  FEATURE-Key-Forms.md
  FEATURE-Key-Semantics.md
  FEATURE-Lexical-Datetime.md
  FEATURE-Lexical-Numbers.md
  FEATURE-Lexical-Strings.md
  FEATURE-Lexical-Whitespace-Comments.md
  FEATURE-Standard-Tables.md
  FEATURE-Table-Redefinition.md
  FEATURE-Tagged-JSON.md

Current batch (3) — emit exactly these, in this order:
  tables-arrays -> FEATURE-Arrays-of-Tables.md
  tables-arrays-ordering -> FEATURE-Arrays-of-Tables-Ordering.md
  conformance -> FEATURE-Conformance.md

Deferred (0) — Drydock will provide later batches; do not emit them now.
</pblock>

