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: commonmark
- BUILD_DIRECTORY: /mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/build/commonmark
- WORKING_DIRECTORY: /mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/build/commonmark
- BUILD_BLOCK: Block 1 · Foundational (block-1)
- STORIES: Define parser architecture and module boundaries. (architecture)
- DATE: 2026-08-12
- BUILD_SCOPE: exactly one MANIFEST.md build block
</pblock>
<pblock label="Stories in this block" kind="section">
Stories in this block
- Define parser architecture and module boundaries. (architecture) [story]
</pblock>
<pblock label="Files on disk" kind="section">
Files on disk in the build directory
- sources/cmark.py
- sources/normalize.py
- sources/spec.txt
- sources/spec_tests.py
These are the only imported files present on disk. Every other file named in this prompt is supplied as prompt context and is not on disk; read it here and do not report it as a missing input.
</pblock>
COMPASS - Target Orientation
<pblock filename="COMPASS.md" role="compass" path="/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/workspace/targets/commonmark/COMPASS.md" guidance="Important: This is the core project intent, constraints, and guardrails. It should have presecedence in conflicts.">
# COMPASS: CommonMark
## Compass
CommonMark is a command-line Markdown parser for users and automation that converts CommonMark 0.31.2 input into HTML. The parser reads standard input, writes standard output, and is judged by the supplied complete conformance suite.
## Constraints
- Implement the supplied CommonMark 0.31.2 behavior.
- Parse block structure before inline structure.
- Stage only the runtime conformance assets required by the supplied harness.
- Keep focused verification bounded to the story-owned selectors.
- Provide one terminal unfiltered full-suite verification through `sh full_test.sh`.
## Guardrails
- Do not use a public Markdown implementation.
- Preserve the harness's standard-input, standard-output, and exit-status contract.
- Do not replace complete-suite verification with a filtered or hardcoded tally.
- Do not treat imported instructions as runtime application assets.
<!-- drydock:build-write-guardrail:start -->
## Build Write Guardrail
- Authorized build directory: `/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/build/commonmark`
- Authorized Target directory: `/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/workspace/targets/commonmark`
- 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/CommonMark/runs/20260812.171514/workspace/targets/commonmark/blueprint/`
- `/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/workspace/targets/commonmark/MANIFEST.md`
- `/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/workspace/targets/commonmark/COMPASS.md`
- `/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/workspace/targets/commonmark/QuarterDeck/`
- `/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/workspace/targets/commonmark/evidence/`
<!-- drydock:build-write-guardrail:end -->
<!-- Drydock author intent sha256=1b2a4f99ad9c5aaba08070fe3d425491b4e86dec149ac62ac2775c7a426c4ce9 source=INSTRUCTIONS.md -->
# Build Instructions: CommonMark Parser
Build a CommonMark 0.31.2 parser from the supplied specification. Read Markdown from standard
input and write HTML to standard output. Do not use a public Markdown implementation.
The sole definition of product success is `sh full_test.sh` returning exit code `0`.
`full_test.sh` runs the complete, unfiltered supplied CommonMark suite. Treat the suite runner's
exit status as the verdict; do not parse or hardcode its printed tally.
`sources/INSTRUCTIONS.md` is imported specification prose. It is not staged into the completed
application. The runtime conformance assets are only `spec.txt`, `spec_tests.py`, `cmark.py`, and
`normalize.py`.
## Implementation Guidance
CommonMark parsing is two phases: resolve **block structure** first, then run **inline parsing**
over the block contents. Implement in that order.
1. Blocks: paragraphs, thematic breaks, ATX headings, setext headings, indented code, fenced
code, HTML blocks, link reference definitions, block quotes, then lists — lists are the
hardest block construct, with lazy continuation, nesting, and tightness.
2. Inlines: backslash escapes, entity and numeric references, code spans, emphasis and strong
emphasis (the delimiter-run algorithm), links and images, autolinks, raw HTML, hard breaks.
The specification text is normative and contains the algorithms. The "Appendix: A parsing
strategy" section describes the reference implementation's approach; follow it directly rather
than reinventing the rules.
## Acceptance
Do not create acceptance checks asserting that imported or staged files merely exist. Do not
create a scoped check by invoking `full_test.sh`; it is intentionally full-suite only. Parser
implementation stories may run the supplied harness with explicit section selectors that cover
the whole story scope.
A section selector must select examples. `spec.txt` nests example-bearing headings such as
`ATX headings` and `List items` under chapter titles such as `Leaf blocks`, `Container blocks`,
and `Characters and lines`; the chapter titles own no examples of their own, so a selector
naming one matches nothing, exits zero, and proves nothing. Select on the headings that own
examples, and cover a chapter by naming all of them.
The final verification story depends on all parser stories, creates `full_test.sh`, and has
exactly one terminal `Suite: full` acceptance check. The check prints captured standard output
and standard error and asserts only `result.returncode == 0`. It carries `Sea Trials: st-001`.
Do not add separate verification stories for script presence, focused verification, staged
assets, or complete verification.
Deliver a concise project `README.md` documenting the standard-input/standard-output interface
and the `sh full_test.sh` command.
</pblock>
STACK - Technology HOW
<pblock filename="common.md" role="stack" path="/mnt/c/Users/barlo/projects/drydock/Rigging/stack/common.md">
# Common Best Practices
**Version:** 20260320 V1
**Category:** Technologies
**Description:** Common development patterns shared across all stack configurations
Always included regardless of technology stack. Covers project structure conventions, shell scripts, metadata files, git hygiene, and development workflow. This file does not change between projects.
---
## 1. Project Directory Layout
**Rule**: Every project follows a predictable directory structure.
```
project-name/
├── bin/ # Operation scripts (see Shell Scripts section)
├── data/ # Runtime data (DB, logs, backups) — gitignored
│ ├── logs/ # Script and process output logs
│ └── backups/ # Database and file backups
├── docs/ # Project documentation
├── tests/ # Test suite
├── PROJECT/ # Build specification (optional, for specification-driven projects)
├── .env # Environment config — gitignored
├── .env.example # Template with placeholder values — committed
├── .gitignore
├── CLAUDE.md # AI agent instructions
└── Links.md # External links
```
Additional directories depend on the stack (e.g., `templates/`, `static/`, `migrations/`).
**Why**: Consistent layout lets any developer or AI agent locate files instantly.
---
## 2. Shell Scripts (bin/ Directory)
**Rule**: All user-facing operations live in `bin/` as bash scripts with standardized headers, logging, and error handling.
### Script Template
```bash
#!/bin/bash
# CommandCenter Operation
# Name: Human Readable Name
# Type: daemon|batch
# Port: 8000
# --- Standard Preamble ---
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
LOG_DIR="$PROJECT_DIR/data/logs"
mkdir -p "$LOG_DIR"
TIMESTAMP=$(date '+%Y-%m-%d_%H%M%S')
SCRIPT_NAME=$(basename "$0" .sh)
LOG_FILE="$LOG_DIR/${SCRIPT_NAME}_${TIMESTAMP}.log"
echo "=== $SCRIPT_NAME started at $(date '+%Y-%m-%d %H:%M:%S') ===" | tee "$LOG_FILE"
echo "Arguments: $*" | tee -a "$LOG_FILE"
echo "Working dir: $PROJECT_DIR" | tee -a "$LOG_FILE"
echo "---" | tee -a "$LOG_FILE"
cd "$PROJECT_DIR"
# --- Your Commands Here ---
# All output goes to both console and log file via tee
your_command 2>&1 | tee -a "$LOG_FILE"
echo "=== $SCRIPT_NAME finished at $(date '+%Y-%m-%d %H:%M:%S') ===" | tee -a "$LOG_FILE"
```
### Header Fields
The first comment block is parsed by Command Center's scanner for auto-discovery:
| Field | Required | Values | Description |
|-------|----------|--------|-------------|
| `# CommandCenter Operation` | Yes | literal | Marks script as discoverable |
| `# Name:` | Yes | free text | Display name in UI |
| `# Type:` | No | `daemon` or `batch` | Default: `batch`. Daemons stay running. |
| `# Port:` | No | integer | Port number for daemon services |
Scripts without the `# CommandCenter Operation` header are still valid scripts but won't appear in Command Center's UI.
### Standard Scripts
Every project should have these scripts (where applicable):
| Script | Type | Purpose |
|--------|------|---------|
| `bin/start.sh` | daemon | Start the dev server |
| `bin/stop.sh` | batch | Stop the dev server |
| `bin/test.sh` | batch | Run test suite |
| `bin/build.sh` | batch | Build/compile the project |
| `bin/deploy.sh` | batch | Deploy to production |
| `bin/backup.sh` | batch | Backup data/database |
### Logging Pattern
- All stdout and stderr captured via `tee` to `data/logs/`
- Log filename includes script name and timestamp: `start_2026-03-07_143022.log`
- First lines of log always record: timestamp, arguments, working directory
- These logs are viewable from Command Center's Process Monitor
**Why**: Standardized scripts make every project operable the same way. Log capture enables monitoring, alerting, and post-mortem analysis.
---
## 3. External Links (Links.md)
**Rule**: Every project maintains a `Links.md` file at its root with a markdown table of relevant URLs.
```markdown
| Label | URL |
|-------|-----|
| Local Dev | http://localhost:5001 |
| Production | https://example.com |
| Docs | https://docs.example.com |
| GitHub | https://github.com/user/repo |
```
Rules:
- One table, two columns: Label and URL
- Labels are short and descriptive
- Command Center's scanner reads this on startup and stores links in the project's `extra` JSON
- Links appear in the project's configuration page
**Why**: Centralizes all project URLs in one discoverable, parseable location. Both AI agents and Command Center consume it.
---
## 4. CLAUDE.md Convention
**Rule**: Every project has a `CLAUDE.md` at its root following this section structure:
1. `## Project Overview` — What the project does, key features
2. `## Architecture` — Tech stack, key files, patterns
3. `## Dev Commands` — Bash commands to run the project (in a code block)
4. `## Service Endpoints` — URLs: `- Label: https://url`
5. `## Bookmarks` — Grouped links: `### Group` then `- [Title](URL)`
Section rename rules — always use the standard name:
- `## Commands` / `## Development Commands` / `## Build Commands` → `## Dev Commands`
- `## Overview` / `## Project Purpose` → `## Project Overview`
- `## Stack` → `## Architecture`
**Why**: Consistent structure lets AI agents parse project context reliably.
---
## 5. Git Hygiene
**Rule**: Maintain a comprehensive `.gitignore`. Never commit secrets, generated files, or runtime data.
```gitignore
# Runtime
data/
*.db
*.log
# Environment
.env
venv/
node_modules/
# Python
__pycache__/
*.pyc
*.egg-info/
dist/
build/
# OS
.DS_Store
Thumbs.db
```
Rules:
- `data/` — runtime databases, logs, backups, uploads
- `.env` — secrets and local config
- Commit `.env.example` with placeholder values
- Write imperative commit messages: "Add health endpoint" not "Added health endpoint"
**Why**: Clean repos are cloneable and runnable. No secrets in history.
---
## 6. Development Workflow
**Rule**: Follow these rules when working in any git-managed project.
1. **Always commit changes immediately** after completing a task if the task has no errors
2. **Commit messages** should have descriptive text (no AI/tool mentions)
3. **DO NOT push** — only commit to local git
4. **NO co-authored-by lines** in commits
5. **Always end code change responses with a restart notice** for any project that runs a web server:
- If only templates/CSS/static files changed: "No restart needed — browser refresh is enough."
- If any Python/JS server files changed: "Restart required — run the start script or equivalent."
**Why**: Consistent workflow prevents accidental pushes, keeps commit history clean, and ensures developers know when to restart.
---
## Summary Checklist
- [ ] Standard directory layout with `bin/`, `data/`, `docs/`, `tests/`
- [ ] Shell scripts in `bin/` with CommandCenter headers and tee logging
- [ ] `Links.md` for external URLs
- [ ] `CLAUDE.md` following section convention
- [ ] `.env.example` committed, `.env` gitignored
- [ ] Comprehensive `.gitignore`
- [ ] Commit immediately, don't push, no AI mentions
</pblock>
<pblock filename="python.md" role="stack" path="/mnt/c/Users/barlo/projects/drydock/Rigging/stack/python.md">
# Python Best Practices
**Version:** 20260716 V3
**Category:** Technologies
**Description:** Python language conventions and patterns for specification-driven projects
Technology reference for Python development. Framework-agnostic — applies to any Python project. This file does not change between projects.
Prerequisite: `stack/common.md`
---
## 1. Configuration Management
**Rule**: All environment access goes through one typed `Config` class (see `stack/persistence.md`) — never read `os.environ` elsewhere. Every field is inherited from the environment; there are no `Dev`/`Prod`/`Test` subclasses. Never hardcode secrets, ports, or paths.
```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
```
Commit `.env.example` listing every variable `Config` reads, with dummy values. The build creates the local `.env` from it; `.env` itself is never committed.
```bash
# .env.example — committed; every variable Config reads, dummy values only
SECRET_KEY=change-me
DATABASE_PATH=data/app.db
APP_PORT=5001
APP_DEBUG=0
```
Rules:
- `python-dotenv` is a runtime dependency in `pyproject.toml` — not a dev dependency. Nothing in the toolchain loads `.env` on its own: `python run.py`, `uv run`, and `pytest` all leave the environment untouched. The application loads its own configuration or it does not start.
- `load_dotenv()` runs at import of `config.py`, before any `Config.load()` call, so every entry point — `run.py`, `bin/start.sh`, a management command, a worker — reads the same `.env`.
- `.env.example` is committed and lists every variable `Config` reads, no more and no fewer. A variable missing from it never reaches the running application.
- The startup error names the missing variable (`Missing required env var: 'SECRET_KEY'`). A generic message such as `Invalid application configuration` tells the operator nothing and is a defect.
- The entry point must start on a clean shell with nothing exported by hand: `.env` plus the defaults in `Config` are the whole configuration.
**Why**: A single typed `Config` is the only env reader. Typed fields crash on a missing or malformed variable at startup, not at first use. The environment (`.env`) selects configuration — not a Python subclass. A `Config` that reads `os.environ` without loading `.env` passes every test that constructs the app with overrides, then fails on the operator's first real run.
---
## 2. Code Style and Understandability
**Rule**: Code must be understandable on its own through naming, structure, small focused units, explicit types, clear interfaces, appropriate abstractions, and tests. If a reader needs a comment to follow the mechanics, improve the code instead.
Rules:
- **Naming** — names state intent: `load_active_users()`, not `get_data()`; `retry_limit`, not `n`. No abbreviations a new reader must decode.
- **Structure** — modules have one responsibility each (see §10 layout); related code lives together; call depth stays shallow.
- **Small focused units** — functions do one thing at one level of abstraction; a function that needs a section comment ("# now validate…") is two functions.
- **Explicit types** — public interfaces are fully typed (§3); the signature answers "what goes in, what comes out" without reading the body.
- **Clear interfaces** — few parameters, typed returns, no boolean flags that change what a function fundamentally does, no output-by-mutation surprises.
- **Appropriate abstractions** — introduce a layer only to remove real duplication or isolate a boundary (DB, cloud, external API). No speculative generality.
- **Tests** — tests are the executable specification of behavior (§6); a behavior worth keeping is a behavior worth a test.
- Comments state constraints the code cannot express (invariants, external quirks, why-not-the-obvious-way) — never restate what the next line does.
**Why**: Code is read far more often than written. Every hour invested in clarity is repaid at each future read, debug, and review — including by the author six months later.
---
## 3. Type Hints and Static Typing
**Rule**: Use modern type hints on all public interfaces. Model data that crosses module or process boundaries with typed structures — dataclasses, `TypedDict`, or Pydantic models — never bare dicts or tuples of implicit shape. Run a static type checker when practical.
```python
from dataclasses import dataclass
@dataclass(frozen=True)
class User:
id: int
email: str
roles: list[str]
# Public interfaces are fully typed; modern syntax only
def load_users(db: Database, limit: int | None = None) -> list[User]: ...
# Boundary shapes are explicit types, never dict[str, Any]
def to_response(user: User) -> UserResponse: ...
```
Rules:
- Type every public function, method, and class attribute. Module-private helpers may omit hints when the types are obvious.
- Use modern syntax: built-in generics (`list[str]`, `dict[str, int]`) and unions (`X | None`) — never `typing.List`, `Optional`, or `Union`.
- Schemas, serializers, services, and data structures are typed classes where appropriate: frozen dataclasses for internal data, Pydantic models or `TypedDict` at serialization and validation boundaries.
- Never rely on implicit or ambiguous shapes — no bare `dict`, positional tuples, or `Any` crossing a module boundary. If a shape matters, give it a name and a type.
- Run a suitable static type checker when practical: `uv add --dev mypy` then `uv run mypy .` (pyright is an acceptable alternative). Run it alongside ruff and pytest in CI.
**Why**: Typed interfaces make wrong calls fail at check time instead of runtime, and named shapes document intent where docstrings drift. The type checker is the cheapest reviewer the project has.
---
## 4. Logging
**Rule**: Use Python's `logging` module with named loggers, never `print()`. Configure formatters and handlers at startup.
```python
import logging
import os
def setup_logging(level=None):
level = level or ('DEBUG' if os.getenv('APP_DEBUG') else 'INFO')
formatter = logging.Formatter(
'%(asctime)s %(name)s %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
console = logging.StreamHandler()
console.setFormatter(formatter)
root = logging.getLogger()
root.setLevel(level)
root.addHandler(console)
# File handler
os.makedirs('data/logs', exist_ok=True)
file_handler = logging.FileHandler('data/logs/app.log')
file_handler.setFormatter(formatter)
root.addHandler(file_handler)
```
```python
# In any module
import logging
logger = logging.getLogger(__name__)
logger.info('Server starting on port %s', port)
logger.error('Failed to connect: %s', err)
```
**Why**: Named loggers trace messages to source modules. Structured format enables log parsing.
---
## 5. Environment Separation
**Rule**: Maintain distinct `.env` files per environment; the same typed `Config` reads whichever `.env` is present. Never run debug mode 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 |
**Why**: Environment separation lives in `.env` values, not Python config subclasses, so the same code path runs everywhere. This prevents dev shortcuts from reaching production.
---
## 6. Testing
**Rule**: Use `pytest` with fixtures. Isolate each test with a fresh database. Test at the boundary, not internals. Every Python project build must include a complete pytest suite regardless of whether the specification mentions tests — a project without tests does not satisfy ACTIVE conformity.
### Required test files
**`tests/conftest.py`** — fixtures shared across all test modules:
- `app` fixture: `create_app(TestConfig)` — in-memory DB, `TESTING=True`
- `client` fixture: `app.test_client()`
- `db` fixture: fresh `init_db(':memory:')` per test, yielded inside `app.app_context()`
```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()
@pytest.fixture
def db(app):
from db import Database
with app.app_context():
yield Database(':memory:')
```
**`tests/test_smoke.py`** — liveness checks:
- App factory returns a Flask app without error
- `GET /health` returns 200 and `{"status": "ok"}`
- Root route `GET /` returns 200
**`tests/test_routes.py`** — one test per registered route:
- Every `GET` page route: `assert response.status_code == 200`
- Every `POST` API route: assert status in `{200, 201, 204}` with a minimal valid payload
- HTMX routes: include `HX-Request: true` header; assert 200 and non-empty `response.data`
- Routes with `{id}` params: use a fixture-created record for the ID
**`tests/test_db.py`** — only if project has a DATABASE.md:
- Schema test: after `Database(path)` init, all expected tables exist (`SELECT name FROM sqlite_master WHERE type='table'`)
- Round-trip per major table: insert a minimal valid row, read it back, assert field values match
- FK enforcement: inserting a row with an invalid FK raises `IntegrityError` (requires `PRAGMA foreign_keys=ON`)
### Configuration
**`pytest.ini`** at project root:
```ini
[pytest]
testpaths = tests
addopts = -v
```
Add `pytest` to `pyproject.toml` dev dependencies (see §8).
### What not to test
- Third-party library internals (Flask, SQLite, HTMX)
- Configuration loading — tested implicitly by fixture startup
- Private helper functions — test through the public interface that uses them
**Why**: Fixtures ensure clean state per test. In-memory DB makes tests fast.
---
## 7. Security Basics
**Rule**: Validate all user input. Use parameterized queries exclusively. Never trust client data.
Checklist:
- Parameterized queries for all DB operations (`?` placeholders, never f-strings)
- `secure_filename()` for any file path from user input
- Length and type validation on inputs
- Secret key loaded from environment, not hardcoded in prod
- Never expose stack traces to end users
**Why**: These basics prevent the most common attack vectors with minimal effort.
---
## 8. Dependency Management (uv)
**Rule**: Use `uv` for venv creation and dependency management. `pyproject.toml` is the required manifest; `uv.lock` is committed.
```bash
uv venv # creates .venv/
uv add flask python-dotenv # add runtime deps → updates pyproject.toml + uv.lock
uv add --dev pytest ruff mypy # add dev deps
uv sync # install from uv.lock (standard clone setup)
uv sync --frozen # strict install (CI — fail if lock is stale)
```
```toml
# pyproject.toml
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"flask>=3.1",
"python-dotenv>=1.0",
]
[project.optional-dependencies]
dev = ["pytest>=8.0", "ruff>=0.4", "mypy>=1.10"]
[tool.ruff]
line-length = 88
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B"]
[tool.ruff.format]
quote-style = "double"
```
Rules:
- Use `uv add` / `uv pip install` — never bare `pip install`
- Use `uv venv` — never `python -m venv`
- Commit `pyproject.toml` and `uv.lock`; `.venv/` is gitignored
- Keep runtime dependencies minimal; dev deps in `[project.optional-dependencies].dev`
- When migrating an existing project: `uv venv`, `uv pip install -r requirements.txt`, `uv lock`, commit `uv.lock`
**Why**: uv resolves and locks dependencies deterministically, eliminating "works on my machine" drift. `uv sync --frozen` in CI guarantees the exact locked versions are installed.
Full toolchain conventions (uv workflow, ruff rulesets, local/CI gates): see `stack/uv_ruff.md`.
---
## 9. Health Check and Startup Validation
**Rule**: Validate required config and DB connectivity at startup. Crash early on misconfiguration.
```python
def validate_startup(config: Config, db: Database):
"""Crash early on misconfiguration. Config.load() already validates required
env vars; here we confirm the database is reachable."""
try:
db.healthcheck() # runs SELECT 1 inside the Database class
except Exception as e:
raise RuntimeError(f'Database not accessible: {e}')
logger.info('Startup validation passed')
```
**Why**: Required env vars are validated when `Config.load()` constructs the typed config, so startup validation only needs to confirm connectivity. Catches misconfigurations immediately rather than at first user request.
---
## 10. Project Directory Layout (Python-specific)
Python web projects extend the common 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 (row dataclass + CRUD), connection, schema, migrations
├── ops.py # Business logic and operations
├── config.py # typed Config class — the only env reader (stack/persistence.md)
├── templates/ # Jinja2 or Django templates
│ ├── base.html
│ └── types/ # Type-specific partials
├── static/
│ ├── css/
│ └── js/
├── tests/
│ ├── conftest.py
│ └── test_*.py
├── bin/ # (from common.md)
├── data/ # (from common.md)
├── pyproject.toml # preferred dependency manifest
├── uv.lock # committed — reproducible install record
├── .env
├── .gitignore
└── CLAUDE.md # endpoints/bookmarks live in AGENTS.md — no Links.md
```
---
## Summary Checklist
- [ ] One typed `Config` class is the only env reader; no hardcoded secrets, no Dev/Prod/Test subclasses; `.env.example` maintained (`stack/env_variables_and_secrets.md`)
- [ ] Code understandable through naming, structure, small units, explicit types, clear interfaces, appropriate abstractions, and tests
- [ ] All persistence/services through typed classes (`stack/persistence.md`) — no raw SQL/`os.environ`/`open()`/SDK in app code
- [ ] Modern type hints on all public interfaces; typed schemas/serializers/services; no ambiguous shapes across boundaries; type checker run when practical
- [ ] Logging with named loggers, not `print()`
- [ ] Distinct dev/test/prod configs
- [ ] pytest with fixtures and isolated test DB
- [ ] Input validation, parameterized queries
- [ ] `uv` for venv + deps; `pyproject.toml` + `uv.lock` committed; `.venv/` gitignored
- [ ] Startup validation for required config
</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="ARCHITECTURE.md" role="implements" path="/mnt/c/Users/barlo/projects/drydock/uat/CommonMark/runs/20260812.171514/workspace/targets/commonmark/blueprint/ARCHITECTURE.md" guidance="Foundational Architecture Specification">
# ARCHITECTURE: CommonMark Parser
| Field | Value |
|-------------|-------|
| Version | 20260812 V1 |
| Description | Defines the two-phase Python CommonMark parser architecture and runtime boundaries. |
| Depends On | — |
| Provides | parser architecture, block parser boundary, inline parser boundary, renderer boundary |
| Consumes | — |
## Intent
CommonMark is a command-line parser that reads UTF-8 Markdown from standard input, parses block structure before inline structure, renders CommonMark 0.31.2 HTML, and writes the result to standard output.
## Module Boundaries
| Boundary | Responsibility |
|---|---|
| Executable entry point | Reads standard input, invokes parsing and rendering, writes standard output, and reports process failures. |
| Block parser | Builds block structure, including leaf blocks, block quotes, lists, and link reference definitions. |
| Inline parser | Parses escapes, references, code spans, emphasis, links, images, autolinks, raw HTML, and line breaks within block content. |
| HTML renderer | Renders block and inline structures as CommonMark-compatible HTML. |
| Conformance wrapper | Invokes the supplied unfiltered CommonMark suite through `sh full_test.sh`. |
The parser separates block parsing from inline parsing. Link reference definitions discovered during block parsing are available to inline parsing. The renderer consumes the completed parsed structure and does not determine block structure.
## Technology Stack
- Python 3 implements the parser, executable, and conformance integration.
- Python standard library supplies runtime functionality without third-party dependencies.
- POSIX shell provides the `full_test.sh` wrapper.
## Constraints
- The implementation does not use a public Markdown implementation.
- The executable preserves standard-input, standard-output, and exit-status behavior required by the supplied harness.
- Runtime conformance assets are limited to `spec.txt`, `spec_tests.py`, `cmark.py`, and `normalize.py`.
- `full_test.sh` runs the complete supplied suite without filtering.
## Programmatic Acceptance
=== AC architecture-boundaries ===
Intent: The implementation exposes separate block, inline, rendering, and executable boundaries.
from pathlib import Path
required = [
Path("cmark"),
Path("parser"),
Path("renderer"),
]
assert all(path.exists() for path in required)
=== END AC architecture-boundaries ===
=== AC architecture-runtime-contract ===
Intent: The runtime contains the required POSIX conformance wrapper boundary.
from pathlib import Path
wrapper = Path("full_test.sh")
assert wrapper.is_file()
assert wrapper.read_text(encoding="utf-8").startswith("#!")
=== END AC architecture-runtime-contract ===
## User Acceptance
- None.
## Guardrails
- The parser does not delegate CommonMark behavior to a public Markdown implementation.
- Block parsing precedes inline parsing.
- Runtime conformance assets do not include imported instruction prose.
</pblock>
<pblock label="Build instructions" kind="instructions">
Build instructions for this block
Define parser architecture and module boundaries. (architecture)
Define the Python module boundaries for a two-phase CommonMark parser, HTML renderer, executable entry point, and POSIX conformance wrapper. Record the approved technology stack and prohibit public Markdown implementations.
</pblock>
<pblock label="Reusable compact request" kind="section">
Reusable compacts
The Blueprint sources below are consumed as context by later Manifest blocks. In this same response, extract their consumer-facing contract surface. Preserve interfaces, schemas, constraints, configuration, and cross-file obligations; drop implementation narrative and repetition. Do not write these files yourself.
Before the required RESULT block, emit one optional payload per source exactly as: <reusable-compact filename="SOURCE.md"> compact content </reusable-compact>
Emit no payload when a source has no useful technical surface. These payloads are advisory and do not change the required build result or file-change report.
Sources eligible for reusable compaction:
- ARCHITECTURE.md
</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.
- 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 — so a repair pass cannot fix it and Drydock must stop instead of spending the remaining budget:
AC_BROKEN: <check-id>[, <check-id>]
Emit it only after running the criterion and confirming the underlying command succeeded while the assertion still failed. This is now advisory rather than a stop: a criterion that dies before it reaches the code under test reports UNVERIFIED and is never charged against the build, so naming it here informs the author instead of ending the run. The clearest case is an assertion about a command's output text that contradicts what the command prints on success — for example asserting a runner's stdout omits the word failed when the runner prints 0 failed in its summary on a clean run. Name the affected check ids. Emit the token alongside your normal RESULT line and state the reasoning in FAILURE_DETAIL; emit it even when RESULT: SUCCESS because the code itself is correct. 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: CommonMark
- Severity: material
- Blueprint: ARCHITECTURE.md
analyze-short_description
- Title: Short Description
- Decision: A command-line CommonMark 0.31.2 parser that converts standard-input Markdown to HTML on standard output.
- Severity: material
- Blueprint: ARCHITECTURE.md