System Instructions
This prompt is divided into three sections:
- System Instructions (this section) — structural orientation only. Do not treat this
section as task input.
- 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.
- 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="Build block job" kind="job">
Build block job
- TARGET: ReadingList
- BUILD_DIRECTORY: /mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/build/ReadingList
- WORKING_DIRECTORY: /mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/build/ReadingList
- BUILD_BLOCK: Block 7 · Service (block-7)
- STORIES: Reject submissions missing a title or author with a clear error. (incomplete-submission)
- DATE: 2026-08-15
- BUILD_SCOPE: exactly one MANIFEST.md build block
</pblock>
<pblock label="Stories in this block" kind="section">
Stories in this block
- Reject submissions missing a title or author with a clear error. (incomplete-submission) [story]
</pblock>
COMPASS - Target Orientation
<pblock filename="COMPASS.md" role="compass" path="/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/COMPASS.md" guidance="Important: This is the core project intent, constraints, and guardrails. It should have presecedence in conflicts.">
# COMPASS: ReadingList
## Compass
ReadingList is a small web application for readers who want to maintain a personal, ordered list of books to read. A reader can add a book with its title and author, review books in insertion order, and remove books when they are no longer needed.
## Constraints
- The application must run as a web application.
- Book submissions require both a title and an author.
- Books must be shown in the order they were added.
- `bin/test.sh` must be POSIX-compatible and run from the application root.
- The complete automated test suite must pass for `bin/test.sh` to exit zero.
## Guardrails
- Never accept or store a submission with an empty title or author.
- Never reorder books relative to their addition order.
- Never report the test command as successful when any automated test fails.
- Always provide a clear reason when rejecting incomplete input.
<!-- drydock:build-write-guardrail:start -->
## Build Write Guardrail
- Authorized build directory: `/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/build/ReadingList`
- Authorized Target directory: `/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList`
- 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/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/blueprint/`
- `/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/MANIFEST.md`
- `/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/COMPASS.md`
- `/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/QuarterDeck/`
- `/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/evidence/`
<!-- drydock:build-write-guardrail:end -->
<!-- Drydock author intent sha256=c86a1a56f7d25ca5548192dbe12c57989f5b1ddd34835753e64e7deb83845e3a source=reading-list.md -->
# Reading List
Build a web application that keeps a list of books to read.
The reader can add a book with a title and author, view the books in the order added,
and remove a book. An empty title or author is rejected with a clear error message.
The application includes automated tests for each behavior.
The completed application provides a POSIX-compatible `bin/test.sh` that runs the complete
automated test suite from the application root. `sh bin/test.sh` exits zero only when every test
passes. The final build story runs this command after every implementation story and preserves its
command, exit code, standard output, and standard error as evidence.
</pblock>
STACK - Technology HOW
<pblock filename="python_compact.md" role="stack" path="/mnt/c/Users/barlo/projects/drydock/Rigging/stack/python_compact.md">
<!-- Compacted from rigging/stack/python.md on 2026-07-16 (manual update to match python.md V3) -->
# Python — Compact
## Configuration Management
One typed frozen-dataclass `Config` is the only env reader — never read `os.environ` elsewhere. No `Dev`/`Prod`/`Test` subclasses; the environment (`.env`) selects configuration. Never hardcode secrets, ports, or paths. Secret hygiene and `.env.example`: see `stack/env_variables_and_secrets.md`.
```python
# config.py
import os
from dataclasses import dataclass
from dotenv import load_dotenv
load_dotenv()
@dataclass(frozen=True)
class Config:
secret_key: str
database_path: str
port: int
debug: bool = False
@classmethod
def load(cls) -> "Config":
try:
return cls(
secret_key=os.environ["SECRET_KEY"],
database_path=os.environ.get("DATABASE_PATH", "data/app.db"),
port=int(os.environ.get("APP_PORT", "5001")),
debug=os.environ.get("APP_DEBUG") == "1",
)
except KeyError as e:
raise RuntimeError(f"Missing required env var: {e}") from e
```
## Code Style and Understandability
Code must be understandable through naming, structure, small focused units, explicit types, clear interfaces, appropriate abstractions, and tests. Names state intent; one responsibility per module; functions do one thing at one level of abstraction; no speculative abstraction layers. Comments state constraints the code cannot express — never restate mechanics.
## Type Hints and Static Typing
Modern hints on all public interfaces; typed structures across boundaries; run a type checker when practical.
- Built-in generics (`list[str]`, `dict[str, int]`) and `X | None` — never `typing.List`, `Optional`, `Union`
- Type every public function, method, and class attribute
- Schemas/serializers/services/data structures are typed classes: frozen dataclasses internally, Pydantic/`TypedDict` at serialization boundaries
- No bare `dict`, positional tuples, or `Any` crossing a module boundary
- `uv add --dev mypy` then `uv run mypy .` (or pyright) alongside ruff and pytest in CI
## Logging
Use `logging` with named loggers, never `print()`. Configure formatter + console and file handlers at startup (`data/logs/app.log`); level from `APP_DEBUG`.
```python
import logging
logger = logging.getLogger(__name__)
logger.info('Server starting on port %s', port)
```
## Environment Separation
Distinct `.env` per environment; same typed `Config` reads whichever is present. Never run debug in production.
| Setting | Dev | Test | Prod |
|---------|-----|------|------|
| APP_DEBUG | 1 | 0 | 0 |
| DATABASE_PATH | data/app.db | :memory: | data/app.db |
| SECRET_KEY | .env value | .env value | .env value (required) |
| LOGGING | DEBUG | WARNING | INFO |
## Testing
`pytest` with fixtures; fresh in-memory DB per test; test at the boundary. Every Python build must include a complete pytest suite regardless of the specification — no tests, no ACTIVE conformity.
```python
# tests/conftest.py
import pytest
@pytest.fixture
def app(monkeypatch):
monkeypatch.setenv("SECRET_KEY", "test")
monkeypatch.setenv("DATABASE_PATH", ":memory:")
from app import create_app
from config import Config
yield create_app(Config.load())
@pytest.fixture
def client(app):
return app.test_client()
```
**test_smoke.py** — app factory works; `GET /health` returns 200 `{"status": "ok"}`; `GET /` returns 200.
**test_routes.py** — one test per route: `GET` pages assert 200; `POST` APIs assert status in `{200, 201, 204}`; HTMX routes send `HX-Request: true`; `{id}` routes use fixture-created records.
**test_db.py** (only if DATABASE.md exists) — expected tables exist; round-trip per major table; invalid FK raises `IntegrityError` (`PRAGMA foreign_keys=ON`).
Do not test third-party internals, config loading, or private helpers.
```ini
# pytest.ini
[pytest]
testpaths = tests
addopts = -v
```
## Security
Validate all user input; parameterized queries exclusively; never trust client data.
- `?` placeholders, never f-strings, for all DB operations
- `secure_filename()` for user-supplied paths
- Length and type validation on inputs
- Secret key from environment, never hardcoded
- Never expose stack traces to end users
## Dependency Management (uv)
`uv` only; `pyproject.toml` is the manifest; `uv.lock` committed; `.venv/` gitignored. Full toolchain conventions: `stack/uv_ruff.md`.
```bash
uv venv # creates .venv/
uv add flask python-dotenv # runtime deps → pyproject.toml + uv.lock
uv add --dev pytest ruff mypy # dev deps
uv sync --frozen # CI — fail if lock is stale
```
- Never bare `pip install` or `python -m venv`
- Dev deps in `[project.optional-dependencies].dev`; runtime deps minimal
## Startup Validation
`Config.load()` already validates required env vars; startup validation confirms DB connectivity. Crash early on misconfiguration.
```python
def validate_startup(config: Config, db: Database):
try:
db.healthcheck() # SELECT 1 inside the Database class
except Exception as e:
raise RuntimeError(f'Database not accessible: {e}')
logger.info('Startup validation passed')
```
## Directory Layout
```
project-name/
├── app.py # Entry point / app factory
├── routes.py # Route handlers
├── models.py # Data models and type registries
├── db.py # Database class: typed tables, connection, schema, migrations
├── ops.py # Business logic and operations
├── config.py # typed Config class — the only env reader
├── templates/ # base.html + types/ partials
├── static/ # css/, js/
├── tests/ # conftest.py, test_*.py
├── bin/ # (from common.md)
├── data/ # (from common.md)
├── pyproject.toml
├── uv.lock
├── .env # gitignored; .env.example committed
└── .gitignore
```
</pblock>
<pblock filename="flask_compact.md" role="stack" path="/mnt/c/Users/barlo/projects/drydock/Rigging/stack/flask_compact.md">
<!-- Compacted from Rigging/stack/flask.md sha256=b8c03c04dac9186ff6e7ca1fac685236f87c7e5bdf1b9ad54e002d2b93c35c8c on 2026-08-06 by drydock rigging compact — regenerate with: drydock rigging compact --include-file {rel_source} -->
# Flask Best Practices — Contract Surface
## Application Factory
### `create_app(config=None)`
Creates and returns a configured Flask application.
| Input | Type | Required |
|---|---|---|
| `config` | configuration object or `None` | No |
Returns: Flask application instance.
Constraints: Load real configuration even when overrides are supplied; `SECRET_KEY` is required from the environment and must not be hardcoded or defaulted in production.
### `run.py`
Provides an importable application entry point and runs the application only when executed directly.
Constraints: Load `.env` before creating the application. Use `APP_PORT`, defaulting to `5001`, for the development server.
## Routes
### `GET /projects`
Renders the projects page.
Returns: `projects.html` with `projects` data.
### `POST /api/project/<int:project_id>/start`
Starts the specified project service.
| Input | Type |
|---|---|
| `project_id` | integer path parameter |
Returns: JSON object containing at least `status` and `pid`; successful status is `'started'`.
### `POST /api/project/<int:project_id>/toggle`
Toggles the specified project's status.
| Input | Type |
|---|---|
| `project_id` | integer path parameter |
Returns: Rendered `types/_project_row.html` fragment containing the updated project.
Constraints: Support HTMX requests and return HTTP `200` on success.
### `GET /api/projects`
Returns project data as JSON.
Returns: `application/json` response.
### `GET /health`
Checks database connectivity.
Returns on success: `{"status": "ok"}`, HTTP `200`.
Returns on failure: `{"status": "error", "detail": "<error detail>"}`, HTTP `500`.
## Error Responses
### Rule: error-handling
404 and 500 responses use JSON for paths beginning with `/api/` and HTML error templates for other paths.
Constraints: Unhandled exceptions are logged and must not expose stack traces to clients.
| Condition | API response | Page response |
|---|---|---|
| 404 | `{"error": "Not found"}`, HTTP `404` | `404.html`, HTTP `404` |
| 500 | `{"error": "Internal server error"}`, HTTP `500` | `500.html`, HTTP `500` |
## Template Contracts
### Rule: template-inheritance
All pages extend `base.html`; reusable partials use `_` prefixes; type-specific partials reside under `templates/types/`.
Constraints: Static assets use `url_for('static', filename=...)`; auto-escaping remains enabled; templates receive ready-to-render data without Python logic.
### Rule: navigation-context
The navigation context processor provides four template variables.
| Variable | Shape | Required |
|---|---|---|
| `util_links` | list of `{"label": str, "url": str}` | Yes |
| `nav_items` | list of `{"label": str, "url": str}` | Yes |
| `cta_label` | string or `None` | Yes |
| `cta_url` | string | Yes |
Constraints: The CTA is omitted when `cta_label` is `None`; navigation content comes from the project UI specification.
## Configuration and Security
### `SECRET_KEY`
Configures Flask sessions and flash messages.
Constraints: Read from the environment; required in production; never hardcode or default it in production.
### Rule: input-validation
All form input is validated for length, type, and allowed values. File uploads use Werkzeug `secure_filename()`.
### Rule: secure-headers
Responses include:
| Header | Value |
|---|---|
| `X-Content-Type-Options` | `nosniff` |
| `X-Frame-Options` | `DENY` |
### Rule: production-debug
Debug mode is enabled only in development; production runs with `FLASK_DEBUG=0`. Startup-only operations are guarded against duplicate execution under the Werkzeug reloader.
## Database and Concurrency
### `get_db()`
Returns a database connection for the current application context.
Returns: Thread-owned database connection.
Constraints: Connections must not be shared across request threads.
## Testing
### Rule: flask-test-client
Routes are tested through the Flask test client with fixtures for the application, client, and database.
Constraints: Tests must verify HTTP status, response content type, rendered content, and HTMX endpoint behavior.
</pblock>
CONTEXT - Read-Only Support
<pblock filename="ARCHITECTURE_compact.md" role="context" path="/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/blueprint/ARCHITECTURE_compact.md">
<!-- Compacted from ARCHITECTURE.md sha256=c42125d1c9a4d632e46f7b88523442ceb51348a2893aa1bb01dcd7b11bbd892b on 2026-08-15 by drydock build agent -->
Flask app factory: `from app import create_app`; supports isolated overrides including `TESTING` and `DATABASE`. HTTP routes live in `app.routes`; SQLite access is confined to typed `app.persistence`; templates/static assets live under `app/`; tests use pytest; `bin/test.sh` runs the complete suite. Root `/` must return 200, and independent app instances must not share state.
</pblock>
<pblock filename="DATABASE_compact.md" role="context" path="/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/blueprint/DATABASE_compact.md">
<!-- Compacted from DATABASE.md sha256=78e782f3b44cbf8f06bf8af3062dfbc659139e71f0edda468bbe62514cb03467 on 2026-08-15 by drydock build agent -->
SQLite `books` persistence via `app.persistence.get_book_store()`:
- `BookStore.add(title, author) -> Book`
- `BookStore.list_ordered() -> list[Book]`
- `BookStore.remove(book_id) -> bool`
- Schema: `id`, required `title`, required `author`, `created_at`; insertion order follows ascending SQLite primary key.
- Initialization is idempotent and preserves rows.
- SQLite access remains encapsulated; connections are scoped to Flask application contexts.
- Empty titles/authors are rejected and never stored.
</pblock>
IMPLEMENTS - Authoritative Step Specifications
<pblock label="Implementation recency anchor" kind="section"> The files in this section are the load-bearing specifications for this build block. Build these files exactly. Treat earlier sections as constraints and context.
</pblock>
<pblock filename="FEATURE-Incomplete-Submission.md" role="implements" path="/mnt/c/Users/barlo/projects/drydock/uat/ReadingList/runs/20260815.171255/workspace/targets/ReadingList/blueprint/FEATURE-Incomplete-Submission.md" guidance="Feature Specification">
# FEATURE: Incomplete Submission
| Field | Value |
|-------------|-------|
| Version | 20260815 V1 |
| Description | Rejects book submissions that omit a title or author and reports the missing requirement. |
| Depends On | FEATURE-Book-Creation.md |
| Provides | validate_book_submission |
| Consumes | POST /books, book_creation |
## Purpose
Validate book submissions at the submission boundary before persistence.
## Workflow
A submission is invalid when its title is empty, its author is empty, or both are empty. Invalid submissions are rejected, are not persisted, and return a clear user-facing indication that the required field is missing. Valid submissions continue through the existing creation workflow.
## Programmatic Acceptance
=== AC validation-rejects-empty-title ===
Intent: A submission with an empty title is rejected with a client validation response.
from app import create_app
app = create_app({"TESTING": True})
client = app.test_client()
author = "Known Author"
response = client.post("/books", data={"title": "", "author": author})
assert response.status_code == 400
=== END AC validation-rejects-empty-title ===
=== AC validation-rejects-empty-author ===
Intent: A submission with an empty author is rejected with a client validation response.
from app import create_app
app = create_app({"TESTING": True})
client = app.test_client()
title = "Known Title"
response = client.post("/books", data={"title": title, "author": ""})
assert response.status_code == 400
=== END AC validation-rejects-empty-author ===
=== AC validation-does-not-persist-invalid-submission ===
Intent: Invalid submissions do not appear in the public list.
from app import create_app
app = create_app({"TESTING": True})
client = app.test_client()
title = "Rejected Title"
author = "Rejected Author"
response = client.post("/books", data={"title": title, "author": ""})
assert response.status_code == 400
listed = client.get("/")
assert listed.status_code == 200
assert title.encode() not in listed.data
assert author.encode() not in listed.data
=== END AC validation-does-not-persist-invalid-submission ===
=== AC validation-preserves-valid-submission ===
Intent: A valid submission remains supported by the creation workflow.
from app import create_app
app = create_app({"TESTING": True})
client = app.test_client()
title = "Valid Title"
author = "Valid Author"
response = client.post("/books", data={"title": title, "author": author})
assert response.status_code in (200, 302, 303)
listed = client.get("/")
assert listed.status_code == 200
assert title.encode() in listed.data
assert author.encode() in listed.data
=== END AC validation-preserves-valid-submission ===
## User Acceptance
- A reader receives a clear indication when title or author is required.
## Guardrails
- Never accept or store a submission with an empty title or author.
- Validation must occur before persistence.
</pblock>
<pblock label="Build instructions" kind="instructions">
Build instructions for this block
Reject submissions missing a title or author with a clear error. (incomplete-submission)
Add validation at the book-submission boundary. Reject an empty title, an empty author, or both, do not persist rejected submissions, and return a clear user-facing indication that the required field is missing. Preserve valid submissions through the existing creation workflow.
</pblock>
Agent Task
You are a Drydock build agent implementing exactly one build step of a larger plan. The build job block below names the target, the build working directory, and the step. Everything you need is stacked into this prompt under role headings:
compass— the Target's COMPASS.md orientation.implements— the Typed Specification files this step builds. These are
authoritative; implement them exactly.
context— read-only support specifications. Do not reimplement them.stack— enterprise stack and technology rules. Honor them.rules— governance and branding rules. Honor them.
Operating contract:
- Follow the write authorization and protected paths in the stacked
COMPASS.mdexactly.
That persisted guardrail is the sole authority for paths this build may modify.
- Start by inspecting the build working directory. Preserve existing application
files unless this step's specifications require a change. Its sources/ subdirectory holds staged build assets — imported test corpora, conformance harnesses, and fixtures — placed there for you. They are read-only inputs: run them, import them, and write code against them, but never create, rewrite, trim, regenerate, or substitute one, even to make a check pass. A step that modifies a staged asset fails and the asset is restored. If an asset you expect is absent, report that; do not author a replacement.
- Implement only this step. Use
context,stack, andrulesas constraints,
not as additional work to perform.
- Follow the stack and rules for languages, structure, naming, and branding.
- The programmatic acceptance assertions in the
implementsspecifications are
this step's Definition of Done — human-owned, declared before the build, and fixed. Build the story and, in this same step, write the deterministic tests that prove each declared assertion, as a TDD master would; add finer tests for coverage. Every test you write follows the same rule the acceptance assertions do: act on the system, read the state back, compare to expected. The oracle is a return value, parsed JSON, a status code, a stored row, file contents read back, or an exit status — never a substring of captured stdout or stderr, a test-runner tally, or a log line. Write tests in the project's own language using that language's libraries; an in-language HTTP client yields a status code and a parsed body, where curl yields text to scrape. Round-trip anything that stores state: act, then read back through the public interface. Assert declared failure signals on negative paths, never message wording. You may add tests but must never remove, soften, or weaken a declared acceptance assertion. A Suite: full conformance check gates on the entire imported test suite: the step is done only when it passes in full, never on a representative subset — reproduce the standard exactly rather than wrapping a third-party library that approximates it. For a suite, the runner's exit status is the verdict and the whole verdict: print its captured output for diagnosis, never assert on the text of its summary. When an assertion is a static or filesystem scan (import boundary, "X never appears outside Y," grep/AST gate), honor the scope the specification states and never widen it: scan production source only, exclude .venv/, site-packages, and vendored or generated code, and do not flag test doubles or fixtures that use the guarded dependency. Run every declared acceptance assertion before returning. For a conformance suite, use its section or example filters to diagnose coherent root-cause clusters, but rerun the full declared scope before reporting the result. Treat failing examples as a work queue for fixing general behavior; never add example-specific exceptions.
- Grow the project's own test suite as you write the code, and treat it as the project's
real coverage. The acceptance assertions in implements are gates: few, fixed, and written before any code existed, so every expectation in them is a prediction. The tests you write are written beside the finished code, so their expected values are observed rather than predicted — which is why exhaustive coverage belongs here and not there. Extend the suite in the project's established location and runner, keep it runnable by the project's declared test command, and leave it green when you return. Cover, at minimum: every public entry point and every verb it declares, including declared error paths; the boundaries — empty, exactly one, many, absent optional fields, declared maxima; declared idempotence, applied twice; one behavior per test, named for the behavior; and isolation — each test arranges its own data, with a fresh store or explicit teardown, so a run leaves no residue behind in the build directory. Where a staged authoritative suite already covers a surface, that suite is the coverage: run it, and do not restate its cases. Report the suite's pass/fail counts in your SUMMARY so a reader can see coverage moving across steps.
- Treat
User Acceptanceentries as review evidence requirements. Implement
the supporting behavior, but do not claim to have performed human judgment.
- The
implementssection is authoritative and intentionally stacked late in
the prompt as the recency anchor. Build that WHAT exactly; do not substitute generic framework defaults.
- Before adding or installing Python dependencies, verify each package name
against the declared registry. Do not invent package names. If a needed package cannot be verified or appears newly published, fail explicitly instead of installing it.
- Use the stack's required package manager workflow for dependency changes.
When the stack requires uv, update manifests through uv conventions rather than bare pip install.
- Do not claim success unless you actually created or modified project files in
the build working directory. If you cannot write files or cannot complete the step, report failure explicitly.
- Do not run
git add,git commit, create branches, create tags, rewrite
history, or otherwise mutate Git history. Drydock owns the final build directory commit after you return.
- End your response with this exact closing structure:
RESULT: SUCCESS | FAILED
FILES CHANGED:
- relative/path
SUMMARY:
<brief reviewable summary>
BLOCKERS:
- <only if any>
Before RESULT, you may emit one optional JSON payload when implementation required a bounded choice not already settled by the owning specification. This records what you did; it does not ask permission, create a questionnaire, or excuse incomplete work:
<blueprint-decisions>
[{"spec":"FEATURE-Example.md","severity":"Material","subject":"Chosen behavior","decision":"Options A and B were available. I implemented B because ... Is that acceptable, or should this change on replan?"}]
</blueprint-decisions>
Name only a specification implemented by this build block. Use Low or Material; Build never emits a Blocking decision. Omit the payload when no implementation decision was necessary.
FILES CHANGEDmust list only files actually written in the build working
directory. If no files were written, use RESULT: FAILED.
- On
RESULT: FAILED, append two additional lines so the failure is actionable
without opening logs. FAILURE_SUMMARY is one line naming the cause; FAILURE_DETAIL states what happened, why, and what to change before a rerun. Name concrete conditions when they apply: token or context limit exceeded, could not execute commands in this environment, a required input was missing, or a specific tool or command failed.
FAILURE_SUMMARY: <one line naming the cause>
FAILURE_DETAIL: <what happened, why, and what to change before rerunning>
- When a declared acceptance criterion cannot pass no matter how the code is written,
say so with this exact token. You may not edit the criterion — it is staged and restored before grading:
AC_BROKEN: <check-id>[, <check-id>]
This is a report, not a verdict, and it stops nothing. A criterion reaches you only when its expected value is one its author could not have invented — a status code, a staged suite's exit status, a value the criterion itself supplied as input — so your claim that the criterion rather than the code is at fault is the less likely explanation, and the budget is spent as it would be for any other failure. A criterion whose expectation was hand-typed already settles DISPUTED on its own, without you naming it. Emit the token only after running the criterion and confirming the underlying command succeeded while the assertion still failed. Name the affected check ids, emit it alongside your normal RESULT line, state the reasoning in FAILURE_DETAIL, and emit it even when RESULT: SUCCESS. Do not use it for a criterion you merely failed to satisfy.
Active Commander guidance
Commander decisions
Apply these decisions as constraints; do not recreate them as questions.
analyze-display_name
- Title: Display Name
- Decision: ReadingList
- Severity: material
- Blueprint: ARCHITECTURE.md
analyze-short_description
- Title: Short Description
- Decision: A web application for maintaining an ordered list of books to read.
- Severity: material
- Blueprint: ARCHITECTURE.md