Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ name: CI

on:
pull_request:
# Restricted to main so a branch with an open PR is not built twice for the
# same commit: an unfiltered `push` fires alongside `pull_request` on every
# branch push. Keeping main here still covers the post-merge commit and any
# push that lands without a PR.
push:
branches: [main]

permissions:
contents: read
Expand Down
28 changes: 6 additions & 22 deletions PAA.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ where the implementation deliberately stops.
| `SqliteEventStore` | Evidence/event log substrate | Supplies the default append-only SQLite store, including storage-level update/delete rejection. |
| `store_evidence`, `verify_evidence` | Evidence record binding | Content-addresses exact evidence bytes with SHA-256 and fails closed on missing or changed bytes. |
| `OperatingRecord`, `SqliteOperatingRecordStore` | Operating accounting | Stores usage, prices and provenance separately from evidence files and autonomy events, retrievable by subject; no transition rule reads it. |
| `import_events` | Archive replay | Imports already validated contract-shaped events without regenerating identifiers or timestamps. The legacy conformance capture proves field and projection continuity across extraction. |
| `paa-contracts` conformance suite | Published contract | Checks schema vocabulary, declarations, event histories, evidence addressing, invalid semantic cases, and the pre-cutover capture against the same packaged corpus. |
| `import_events` | Archive replay | Imports already validated contract-shaped events without regenerating identifiers or timestamps. |
| `paa-contracts` conformance suite | Published contract | Checks schema vocabulary, declarations, event histories, evidence addressing, and invalid semantic cases against the same packaged corpus. |

## Lifecycle coverage

Expand All @@ -45,18 +45,7 @@ field loss, that the lifecycle can produce them, that content addresses are
re-derived from bytes, and that runtime-owned negative cases fail for the
published reason.

`examples/legacy-archive/pre-cutover-capture.json` adds the consumer-boundary
proof. It was generated with the source consumer's pre-cutover lifecycle implementation at
commit `721c37facac64f12a164e510c9a0aa647a960cba`, then imported into the
extracted runtime. The test reproduces its event rows, motion projection, and
resolved position exactly.

The source consumer's production `autonomy_events` table contained zero rows at cutover. The
capture is therefore evidence from the real pre-cutover implementation, not a
claim that a production autonomy transition occurred. Keeping that distinction
in the artifact is part of the citation bar.

## Honest non-matches
## Non-matches

### Evaluator verdict production

Expand Down Expand Up @@ -124,11 +113,6 @@ cross-document corpus validation remains in the published conformance tooling.

## Scope of the claim

The accurate claim is:

> `paa-runtime` implements PAA's declared autonomy-transition lifecycle and
> passes the published conformance corpus, including replay of a history
> captured from the source consumer's pre-cutover implementation.

It is not a claim that the runtime implements evaluation, worker attestation,
or every consumer's governed effect.
`paa-runtime` implements PAA's declared autonomy-transition lifecycle and
passes the published conformance corpus. It does not implement evaluation,
worker attestation, or any consumer's governed effect.
14 changes: 5 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ For a complete disposable propose → approve → demote walk, run the

`SqliteEventStore` is the default and most consumers should use it. `EventStore` is a protocol so that a consumer whose governed effect and the position read authorizing it must commit in a *single lock domain* can implement it over its own connection — a runtime-owned database cannot offer that guarantee across process boundaries. It is one insert, four reads, and two transaction context managers.

The trade-off is named rather than hidden. With the default store, a consumer that resolves a position and then performs the effect it authorizes does so across two lock domains: a demotion committed in between is not seen by the effect already in flight. That window is small and the failure is a stale *permit*, not a corrupt history — but it is real, and a consumer for which it is unacceptable implements `EventStore` over the same connection its effect commits on.
With the default store, a consumer that resolves a position and then performs the effect it authorizes does so across two lock domains: a demotion committed in between is not seen by the effect already in flight. That window is small and the failure is a stale *permit*, not a corrupt history — but it is real, and a consumer for which it is unacceptable implements `EventStore` over the same connection its effect commits on.

## Development

Expand All @@ -113,10 +113,7 @@ uv run mypy src/paa_runtime
```

The implementation-to-spec mapping, including explicit non-matches, is in
[`PAA.md`](PAA.md). The conformance corpus also includes a contract-shaped
history captured from the source consumer's pre-cutover implementation. Its production database had
zero autonomy events at cutover, so that artifact is deliberately labeled an
implementation capture rather than production transition history.
[`PAA.md`](PAA.md).

### Conformance

Expand All @@ -133,13 +130,12 @@ uv sync --extra conformance
uv run pytest conformance
```

The `conformance` path is required, not decoration. `testpaths` is `tests`, so
The `conformance` path is required. `testpaths` is `tests`, so
a bare `uv run pytest` runs the unit suite and nothing else — which is what
lets the unit suite stay green for someone who cloned only this repo. The
conformance suite is opt-in by *invocation* rather than by skip marker: when it
is asked to run and the artifacts are absent, `paa_contracts` raises at import
and the run fails loudly, because a conformance suite reporting green over an
empty corpus is the one failure mode it must not have.
and the run fails loudly rather than reporting green over an empty corpus.

What it asserts, per fixture class:

Expand Down Expand Up @@ -168,7 +164,7 @@ package has no import path to point them at — it governs motions it writes
itself, enforcing those rules at write time rather than by inspecting a
finished document.

One honest non-match: the published demotion history binds to a
One non-match: the published demotion history binds to a
`paa-decision-artifact`, while `demote` generates and content-addresses its own
evidence so an emergency demotion never blocks on an operator producing an
artifact first. Its event stream reproduces the published one in every field
Expand Down
12 changes: 5 additions & 7 deletions conformance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

Every fixture, schema, and negative case here comes from ``paa-contracts``
— the artifacts paa.dev publishes — rather than from fixtures of this
repo's own. That is the entire point: "passes the published conformance
suite" has to be a claim about the contract, not about this repo's idea
of it.
repo's own, so that "passes the published conformance suite" is a claim
about the contract, not about this repo's idea of it.

This package is deliberately not collected by ``uv run pytest``. The unit
suite under ``tests/`` must pass for someone who cloned only this repo,
Expand All @@ -15,8 +14,7 @@
uv run --with ../paadotdev/packages/paa-contracts pytest conformance

Opt-in by *invocation*, never by skip marker. A suite that skips when its
fixtures are missing reports green over an empty corpus, which is the one
failure mode a conformance suite must not have — so when these modules
are asked to run and the artifacts are absent, ``paa_contracts`` raises
at import and the run fails loudly.
fixtures are missing reports green over an empty corpus, so when these
modules are asked to run and the artifacts are absent, ``paa_contracts``
raises at import and the run fails loudly.
"""
15 changes: 7 additions & 8 deletions conformance/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ def pytest_report_header() -> list[str]:

Packaged data and a site checkout are the same bytes from the same
commit, so which one is active never changes an answer — but it
changes what a failure *means*, which is why it belongs in the run
output. A header prints unconditionally; a fixture only reports when
something requests it, which is how this started life and why nothing
ever saw it.
changes what a failure *means*, so it belongs in the run output. A
header prints unconditionally, unlike a fixture, which reports only
when something requests it.
"""
return [
f"paa-contracts: {contracts.__version__} ({contracts.DATA_SOURCE})",
Expand Down Expand Up @@ -54,10 +53,10 @@ def build_registry(documents: Sequence[dict[str, Any]]) -> tuple[ProducerRegistr

The registry is consumer domain data the runtime deliberately does not
own, so a conformance run has to supply one. Deriving it from the
corpus is the honest choice: it makes the claim "given a registry that
registers what these declarations reference, the loader accepts them",
which is the claim an implementation can actually make about fixtures
whose producers live in somebody else's codebase.
corpus makes the claim "given a registry that registers what these
declarations reference, the loader accepts them", which is the claim
an implementation can actually make about fixtures whose producers
live in somebody else's codebase.

Every entry is registered ``implemented``. The implemented/future
split governs whether a consumer has built the producer yet — a fact
Expand Down
4 changes: 2 additions & 2 deletions conformance/test_corpus_integrity.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ class TestUnclaimedStages:
identity drift, illegal motion ordering — which is real logic, not a
schema pass, and it does not exist in Python yet.

The ratchet that keeps this honest: the JS validator covering these
is not deleted until they are claimed here. Counts pinned so the gap
The ratchet: the JS validator covering these is not deleted until
they are claimed here. Counts pinned so the gap
stays measured.
"""

Expand Down
50 changes: 0 additions & 50 deletions conformance/test_legacy_archive.py

This file was deleted.

89 changes: 0 additions & 89 deletions examples/legacy-archive/pre-cutover-capture.json

This file was deleted.

3 changes: 1 addition & 2 deletions examples/refund_quickstart/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ The script creates an isolated temporary database and evidence tree, proposes
repository. `refund_approval.v1.yaml` remains in the shared contract corpus so
the quickstart, conformance suite, and paa.dev schema reference use one fixture.

This is adoption-oriented synthetic pedagogy. The separately labeled
pre-cutover capture is the cross-implementation evidence artifact.
The fixtures here are synthetic teaching examples, not captured history.
8 changes: 4 additions & 4 deletions packages/paa-contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The published contract artifacts of the [Progressive Autonomy Architecture](https://www.paa.dev): five normative JSON Schemas, the positive fixture corpus every implementation is checked against, and the table-driven invalid-case matrices.

No runtime logic, no dependencies. This package is data and honest paths to it.
No runtime logic, no dependencies. This package is data, plus paths to it.

## Why it exists

Expand Down Expand Up @@ -63,7 +63,7 @@ for case in contracts.invalid_cases("event", stage="event_semantic"):

## The stage split

Every invalid case declares `expected.stage`, and that field is an ownership boundary rather than a label:
Every invalid case declares `expected.stage`, an ownership boundary:

| Stage | Owner | Why |
|---|---|---|
Expand All @@ -77,9 +77,9 @@ Filter with `invalid_cases(kind, stage=...)` and take only what you own. `case_s

The artifacts are not checked into this directory. `hatch_build.py` pulls them from the repo root at build time — that hook is where the inclusion logic lives, not `pyproject.toml`, which only registers it. So the files paa.dev serves at their published URLs, the files the validator reads, and the files a conformance suite loads are the same bytes from the same commit.

Vendoring copies here would put two sources of truth one careless commit apart and make every conformance claim a claim about the copy. Build-time inclusion makes "one source of truth" a property of the build instead of a rule someone has to remember.
Vendoring copies here would put two sources of truth one careless commit apart and make every conformance claim a claim about the copy. Build-time inclusion makes one source of truth a property of the build.

The consequence: a wheel can only be built from a full checkout of this repo. That is correct — a release cut from anything less than the whole tree would be a partial contract.
The consequence: a wheel can only be built from a full checkout of this repo — a release cut from anything less than the whole tree would be a partial contract.

## Contents

Expand Down
1 change: 0 additions & 1 deletion packages/paa-contracts/hatch_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
("schemas", "schemas"),
("examples/paa-tasks", "examples/paa-tasks"),
("examples/runtime-conformance", "examples/runtime-conformance"),
("examples/legacy-archive", "examples/legacy-archive"),
)


Expand Down
1 change: 0 additions & 1 deletion packages/paa-contracts/scripts/verify_built_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"schemas",
"examples/paa-tasks",
"examples/runtime-conformance",
"examples/legacy-archive",
)

_DATA_MARKER = "/_data/"
Expand Down
Loading
Loading