Bootwitch Doctor — Technical
README · ARCHITECTURE · TECHNICAL
The repair subject is a Python 3.11 local notes application with a static browser interface, standard-library HTTP server, service layer, repository boundary, JSON import command, and SQLite runtime adapter. There are no third-party runtime packages.
Starting evidence
The completed repair record begins with 9 baseline tests, including 4 failures. Source inspection found additional connection problems that the unit tests did not cover:
- API and browser field names disagreed.
- Delete behavior was broken across backend and frontend paths.
- The threaded server used process-local memory.
- The documented data-path setting did not select storage.
- The import command constructed a repository the server never saw.
- Import validation happened before a sequence of independent writes, leaving no transaction boundary for a storage failure.
This is why the repair did not begin with a test-count target. We first needed a map of which behavior those tests actually exercised.
Repository contract
The service depends on a structural repository contract:
list() -> list[Note]
add(title, body, tags, created_at?) -> Note
add_many(drafts) -> list[Note]
delete(note_id) -> bool
clear() -> None
The in-memory and SQLite adapters share conformance tests. That lets fast unit tests use memory while the real runtime uses durable storage without changing the service rules.
Returned notes and tag lists are defensive copies. Both adapters serialize
mutations with one process-local lock. SQLite also starts writes with
BEGIN IMMEDIATE, making the transaction boundary explicit before IDs are
allocated.
SQLite startup behavior
Schema version 1 stores a sequential local ID, title, body, JSON-encoded tags, and a timezone-aware UTC timestamp.
The implementation treats PRAGMA user_version = 0 carefully. Zero can mean a
new database, but it can also mean an older unversioned database. Startup
inspects the table definition and existing rows before adopting it. Compatible
data is preserved; incompatible, corrupt, or unknown schemas fail visibly
without silently replacing the file or falling back to memory.
Port parsing also happens before storage opens. An invalid port should not create a database as a side effect. If HTTP binding fails after the repository opens, the server closes it before returning the failure.
Atomic import
The real command reads one UTF-8 JSON document and sends it to
POST /api/import. It does not reimplement semantic cleanup in the CLI.
The server then:
- validates the top-level payload;
- validates and normalizes every note into a storage-neutral draft;
- calls the repository once with the complete draft list;
- opens one SQLite transaction;
- inserts the ordered batch; and
- commits everything or rolls everything back.
Validation prevents predictable input errors from starting a write. The transaction protects the database from failures that happen after writing has begun. Both are required for the all-or-nothing claim.
The operation is atomic for one request, but it is not idempotent after an ambiguous lost response. A future retry contract would need an idempotency key or equivalent request identity.
Connection-level verification
At the completed repair snapshot, the 89-test check covers six levels of evidence:
| Level | What it proves |
|---|---|
| Unit | One function or class follows its local contract. |
| Adapter conformance | Memory and SQLite expose the same repository behavior. |
| Integration | Route, service, and storage work together. |
| Process | A real server receives public HTTP requests. |
| Restart | A new process reads the same committed database. |
| Failure path | Controlled failure stops at the promised boundary and preserves prior state. |
One concurrency regression races a 40-note batch against a single add. The batch IDs remain contiguous, demonstrating in this tested race that another caller sharing the repository did not interleave inside the transaction.
What the multi-agent setup changed
The five lanes were organized around dependencies rather than equal file counts. Storage and import contracts could progress in parallel. Runtime activation waited for the storage tests. Process-level restart verification waited for runtime composition. Final import verification waited for both the batch contract and the durable connection.
Each agent kept its own notes and returned a standard handoff. The integration lead reconciled those reports against the integrated application, updated the shared notes, and redrew the traces. That made concurrent discoveries visible without allowing five documents to become five competing sources of truth.
The full implementation, agent packets, diagrams, and tests are in the public bootwitch-doctor repository.