The sixteen ways we try to break a milestone before it merges

2026-08-18 · edited by Aetha Editorial

A milestone whose happy path works is not finished. Our own quality-gates document says so in almost exactly those words, and then it does something more useful than saying so: it writes down the attacks.

docs/QUALITY_GATES.md §2 is a standing table of adversarial review categories, run against every milestone before it merges. The table has fifteen named rows. The sixteenth way to break a milestone sits in the sentence above the table: a category that does not apply must be stated as not applicable — never silently skipped. A review that cannot show its skips is the first thing the review process breaks, because a silent skip is indistinguishable from a pass.

The categories are not a style guide. Each one names a concrete way agent-written commercial software fails quietly: public-boundary bypass, state-machine algebra, transaction and fault injection, idempotency, two-connection concurrency, exact queries beyond page bounds, immutable boundaries, provider timeouts and late settlement, replay and reconciliation, hostile input, schema compatibility, backward compatibility, audit and trace exactness, browser behavior, documentation truthfulness. The executable form lives in the repository too, as the adversarial-review skill an agent runs before a merge. Its ground rules are the interesting part: confirm a suspicion with a runnable probe before fixing anything, attack the invariant rather than the happy path, and prefer the failure that permanently destroys evidence over the one that merely errors.

What follows is three of the categories as they look in a real run — not a description of what a review would do, but the transcript of the delivery-handover end-to-end suite, run on 2026-08-18 at commit 000aae8 and saved unedited at docs/transcripts/2026-08-18-adversarial-categories-run.txt.

Transaction and fault injection, idempotency, and two connections

The category's wording is blunt: inject a failure after every significant write; everything rolls back, no orphan rows, no fake success audit, and the retry produces exactly one complete result. Idempotency has its own row — a repeat behind the same key is refused or resolves identically, and a semantic mismatch behind that key fails closed rather than being adopted. Concurrency has a third: two connections on one database, one winner, no lost update.

The handover from an activated contract to a delivery project is where these three meet, because a handover creates a project, work packages, milestones and an optional partner engagement across a package boundary in one atomic operation (tests/delivery-handover-e2e.test.js). The transcript's slowest subtest is the one named for the attack:

# Subtest: the handover is atomic, idempotent and concurrency-safe
ok 4 - the handover is atomic, idempotent and concurrency-safe

It is slow because it does the unglamorous thing the category demands — failing the operation partway through after each write in turn, retrying, and racing a second connection — rather than asserting once that the happy path commits.

Hostile input

The hostile-input row lists its ammunition explicitly: __proto__, constructor, prototype, markup, quotes, backticks, template syntax, newlines, Unicode separators, null bytes, oversized strings — across every provider, payload, field and route. The point of writing the list down is that "we sanitize input" is a sentence, while a checked-in list is a contract a reviewer can hold a milestone to.

The delivery boundary gets its own version of the attack, because a handover copies data from one package's records into another's:

# Subtest: hostile input stays inert data across the package boundary
ok 8 - hostile input stays inert data across the package boundary

Inert is the operative word. The assertion is not that hostile input is rejected — much of it is legal text — but that it crosses the boundary as data and comes back out as data, polluting no prototype and confusing no route.

Audit, event and trace exactness — and the honest wrinkle in this transcript

This category's rule is the one most reviews get wrong: assert counts, not presence. A replay creates none. And a post-commit dispatch failure stays a business success and is visible separately, rather than failing the operation retroactively or vanishing.

The transcript holds both halves. The counting half is a named subtest:

# Subtest: audit, events and trace are exact, and reads stay exact past the list bound
ok 7 - audit, events and trace are exact, and reads stay exact past the list bound

The visible-separately half arrived uninvited. Partway through the run, this line appears on the console:

# [accordo] commercial-contract.create-delivery-handover run f257aa51-bc0d-41c1-aff2-66a6ef19a5ad: failed to persist trace: database is locked

A trace write lost a lock race against the test's own concurrent connections. The run did not hide it, and it did not convert it into a business failure either — the surrounding subtests passed, and the diagnostic stayed on the console with the run id attached. That is the category's rule doing its job in front of a witness, and it stays in this article for the same reason it stays in the transcript: a review discipline that quietly trims its own output is not one you should believe about anything else.

What the list does not prove

The categories measure discipline, not correctness, and the repository says so where it counts. The verification gate that runs the suite on every push states its own boundary: a test count measures effort, and real-browser tests are currently run manually rather than in CI — which makes browser behavior the weakest row in the table today, reviewed by a person at a keyboard instead of a robot on every push.

Documentation truthfulness, the last row, is also the one no script fully covers. The quality-gates document is explicit that its mechanical checks compare strings and match patterns; nothing infers whether a sentence is true. That category remains a person. The same document records the failure that keeps everyone honest about green checkmarks: a merge conflict resolved inside a measured record once ran the public ledger a whole wave behind the suite with every check green, which is why an integrator pass over shared-truth files is a gate and not a courtesy.

Every mutation in the framework goes through a module service or a named workflow and leaves audit and trace evidence behind it, which is what makes categories like exactness attackable at all — you cannot count what was never recorded. But the honest summary of the sixteen ways is narrower than it sounds: they are the ways we currently know this kind of software fails, written down so that skipping one is a visible act. The list grows when a review finds a way that is not on it. The transcript of this run, commit and command included, is in the repository — the quickest way to disagree with any of this is to re-run it.

What this post does not mean

These pages describe this repository at this commit. None of them implies the framework is deployable, and none of them is a roadmap: nothing that is not merged appears on this site, in any tense.

  • No authentication ships: the framework authenticates nobody. Production Spine v1 (ADR-038) gives the framework verified identity, organizations and memberships, server-authoritative authorization and one tenant per application instance — so tenancy and authorization now exist and are enforced. What does not exist is authentication: no login, password, session or OIDC implementation ships, and a deployment must supply the adapter that verifies the request. Production mode refuses to start without one. In local-development mode an actor header is accepted as an assertion and is not an identity, which is the default developer posture. This is not shared-database multi-tenancy and it is not a readiness claim.
  • Not shared-database tenancy. createAccordoAppAsync can boot one tenant onto dedicated PostgreSQL databases. Shared-database row-level tenancy is not implemented, and this is not a production-readiness claim.
  • Timers exist; a service that runs them for you does not. Durable jobs, a transactional outbox and scheduled asks exist for self-hosted applications that explicitly start a worker. Nothing autostarts; a timer opens an ask, never makes a decision, and no managed worker service or recurrence is included.
  • No email, calendar or marketing integrations. An in-memory notification provider contract exists. MK1 marketing records supplied funnel observations and human-reviewed proposals only; it has no sending, publishing or spending path.
  • The build benchmark has not been run. The protocol is designed and published; no Successful Agent Build Rate exists yet. Any number you see quoted for this project is not ours.
  • Ownership means vendored source: there is no framework dependency to bump. The published create-accordo@0.1.0 scaffolds vendored source; it is the August 19 snapshot, not the current repository feature set. Use a current source checkout for the capabilities described here; upgrades require merging source (L-08). The framework is copied into the project, not installed as a framework library dependency. The accordo npm name is an empty reservation; the @accordo scope is claimed and deliberately empty.

Every claim and every limitation is on one page, and the questions this project refuses to answer are published beside them.

The evidence this post rests on

Claims

  • C-11 Pending obligations hand over into a Delivery Project with work packages, milestones and an optional partner — atomically, idempotently, and across a package boundary the kernel never learns about.

    LimitIt hands work over and runs it through human-driven transitions. Nothing schedules, staffs, computes percent complete or bills. Deliverables and recorded customer acceptance exist as of M14b2, and acceptance there is evidence a user actor recorded — never an authenticated customer, a legal signature or authorization to bill.

  • C-16 Every mutation goes through a module service or a named workflow, and leaves an audit event and a step-level trace behind it.

    LimitAudit records what the process did under an asserted actor. It is not a tamper-evident or externally attestable log, and it is not a compliance control.

  • C-20 The verification gate runs on every push — source checks and then the whole test suite — covering happy paths and the policy boundaries that matter: hostile input, transaction rollback, idempotency, concurrency and immutability among them.

    LimitA test count measures effort, not correctness — read the adversarial-review categories in docs/QUALITY_GATES.md to see what is actually attacked. Real-browser tests are run manually and are not in CI.

Grounded in

  • docs/transcripts/2026-08-18-adversarial-categories-run.txt

Editor of record

  • Aetha Editorial