Skip to content

Feature/postgres backend - #61

Open
matthewpeterkort wants to merge 123 commits into
mainfrom
feature/postgres-backend
Open

matthewpeterkort wants to merge 123 commits into
mainfrom
feature/postgres-backend

Conversation

@matthewpeterkort

@matthewpeterkort matthewpeterkort commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

No description provided.

…tgreSQL connection settings (#60)

* feat(server): strict arango|postgres source-backend selector with PostgreSQL connection settings

Add server.backend (arango|postgres) with arango as the legacy default,
plus a server.postgresql connection contract (host, port, database, user,
password, sslmode, max_open_conns, max_idle_conns, conn_max_lifetime).
Old YAML keys and existing --url/--database CLI flags remain Arango
settings and parse unchanged. No URL-based auto-detection, no fallback,
no database connections, and no runtime wiring here.

- Reject unknown backend names and incomplete PostgreSQL configuration
  before server startup with value-free, credential-safe messages.
- Reject conflicting legacy/new settings: customized server.url/database
  in YAML or explicitly passed --url/--database beside a postgres
  selection (including --config, where those flags are otherwise ignored).
- Config.String renders a log-safe summary; PostgreSQL, ClickHouse, basic
  auth, and population-cursor secrets plus URL userinfo are redacted, and
  validation errors never interpolate the password or a DSN.
- run() refuses a postgres selection before opening any Arango store so
  configuration acceptance can never silently fall back.

Ticket: pg-runtime-backend-config (batch c4b53e23b9d190fe)
Validation: go test ./internal/server -count=1 (all pass, no skips; 12
new tests / 32 subtests covering PostgreSQL validation, legacy defaults,
conflicts, CLI selection, run() refusal, and secret redaction) and
go vet ./internal/server clean at head of this commit.

* fix(server): reject explicit --backend/--pg-* overrides on the --config path

The native review on PR #60 found that the config-file path only guarded
--url/--database: an explicit --backend beside --config was silently
dropped (so --config pg.yaml --backend postgres could start ArangoDB, the
same silent fallback the run() guard refuses), and explicit --pg-* flags
were silently dropped (a --pg-sslmode override could quietly keep the
file's weaker TLS mode). With --config, the configuration file now owns
backend selection and the PostgreSQL connection contract: explicitly
passed --backend or --pg-* flags fail before startup with value-free
messages naming the settings. The pure-flag path is unchanged.

Adds regression subtests for --config plus explicit --backend (arango-
omitted, arango-redundant) and explicit --pg-sslmode/--pg-host/--pg-password.

Validation: go test ./internal/server -count=1 green (no skips), go vet
./internal/server clean.
…#58)

* feat(compiler): add backend-tagged compiled command result

Represent rendered commands as tagged variants with their own parameter
types so execution cannot pass PostgreSQL SQL to the AQL
QueryRows(query, bindVars) adapter. CompiledCommand carries either the
exact rendered AQL query plus named bind map, or statement SQL with
ordered typed arguments (SQL NULL and JSON null kept distinct). AQL,
PostgreSQL, and zero-value dispatch reject mismatched backend/command
pairs before any query executes; CompiledCommandForBackend registers
only AQL, so PostgreSQL requests fail closed with
ErrCompiledCommandBackendNotRegistered and never fall back through an
AQL-to-SQL conversion until a PostgreSQL renderer is implemented and
registered there.

CompileRecipeOutputWithPolicy now tags the canonical render result and
publishes CompiledQuery.Query/BindVars only via exhaustive AQL
dispatch; the AQL call path keeps the identical query text and bind map
instance, and the semantic/typed lowering IR and AQL renderer are
untouched.

Ticket: pg-ir-01 (batch c4b53e23b9d190fe)
Checks: go test ./internal/dataframe/compiler/ir, .../lower,
.../render/aql, compiler -run '^TestCompiledCommand$' -count=1,
render/aql -count=1 (all pass, no skips), go vet ./... clean, full
compiler package green.

* fix(compiler): classify missing compiled-command adapter as backend-not-registered

Dispatch's nil-adapter branches reported ErrCompiledCommandBackendMismatch
while the documented contract of ErrCompiledCommandBackendNotRegistered
("no renderer or adapter is registered for a compiled-command backend")
defines exactly that situation. Callers gating capability discovery on
errors.Is with NotRegistered would misclassify a missing adapter as a
routing defect. Both nil-adapter branches now wrap
ErrCompiledCommandBackendNotRegistered; Mismatch stays reserved for a
command tagged for one backend reaching the other backend's boundary via
AQLParameters/PostgreSQLParameters. Dispatch doc states the split; tests
lock both directions.

Review: PR #58 thread PRRT_kwDOS-yV5s61GCh2
Checks: TestCompiledCommand (6 subtests) pass, full compiler package
pass, ir/lower/render-aql pass, gofmt clean, go vet ./... clean.

* fix(compiler): copy PostgreSQL command arguments on every read

PostgreSQLParameters now hands out a fresh argument slice each call, so
callers cannot mutate a command's positional bindings through the
accessor; unlike the AQL bind map, which is a documented shared
instance carried unchanged from renderer to adapter, the PostgreSQL
variant promises no shared-instance contract. The command's args are
already copied at construction; Dispatch keeps handing the command body
to the registered executor adapter, the intended single consumer.

Recorded judgments from coordinator review (optional items):
CompiledCommandForBackend accepting aql.RenderedPhysicalPlan even for
PostgreSQL requests stays as-is until the PostgreSQL renderer ticket
shapes its real render input; the AQLParameters defensive default arm
stays (reachable via the zero-value command). The required sentinel
classification fix (matching-tag nil adapter -> NotRegistered,
cross-tag -> Mismatch, distinct test assertions) shipped at
7a859a8.

Review: PR #58 coordinator follow-up at 1ebdf65 review
Checks: all 5 brief checks pass non-skipped, full compiler package
pass, gofmt clean, go vet ./... clean.
…1) (#59)

* feat(postgres): add bounded pgx pool with PG18 readiness ping

- internal/store/postgres: pgx/v5-backed pool owned by the caller's
  DSN and bounds (MaxConns/MinConns), AcquireTimeout enforcement and
  context cancellation on Acquire/Ping
- Ping confirms server availability and rejects non-PG18 servers with
  a typed UnsupportedVersionError (errors.Is ErrUnsupportedVersion);
  connectivity failures return a wrapped ConnectError (ErrConnect) so
  callers can classify refused connections and acquire timeouts
- unit tests reject blank/malformed DSNs and invalid pool bounds with
  no network; refused-connection test uses a real closed loopback port
- PG18 integration test (LOOM_TEST_POSTGRES_URL) creates one unique
  pgstore01_it_* database, opens/pings/acquires/closes the pool, and
  drops only that database
- add github.com/jackc/pgx/v5 v5.12.0 to go.mod/go.sum
- no migrations; no silent fallback to Arango

* chore(audit): add internal/store/postgres to the package responsibility map

The retained Python package-audit tests run scripts/package_audit.py,
which refuses to emit a row without a curated responsibility sentence.
Add internal/store/postgres and commit the deterministic regeneration
(docs/PACKAGE_AUDIT.csv, docs/PACKAGE_AUDIT.md).

* test(postgres): harden integration isolation and remove ping-timeout flake

Address native review on #59:

- Open the exhausted-pool pool under a generous AcquireTimeout and
  install the tight 75ms bound only around the deliberately exhausted
  second acquire, so the lazy pgxpool dial (eager ping) never runs
  under the timeout bound.
- Scrub all credential material (raw URL, rewritten test DSN,
  userinfo, bare password) from failure messages, not just the raw URL.
- Drop any dbname query parameter from the service URL before
  targeting the isolated database (pgconn lets dbname override the URL
  path, which would have silently defeated isolation), assert the
  final DSN provably targets the isolated database, and verify
  end-to-end with a marker table checked through an independently
  built keyword/value witness connection.

* test(postgres): derive witness connection from parsed service config

Address native review on #59: the hand-assembled keyword/value witness
DSN did not escape values (whitespace/backslash/quote handling in
pgconn's keyword parser) and dropped TLS-relevant query parameters.
Parse the service URL once with pgxpool.ParseConfig, keep credentials
and TLS byte-exact, and override only ConnConfig.Database so the
witness still independently proves the pool targets the isolated
database and outranks any dbname parameter.
… runner (pg-runtime-test-fixture) (#63)

* feat(postgres): opt-in isolated PG18 test fixture and owned-namespace runner (pg-runtime-test-fixture)

- experimental/docker-compose.yml: add postgres18-test behind the
  postgres-test profile with an isolated named volume
  (loom-pg18-test-data), pg_isready health probe and test-only
  credentials; the default Arango+ClickHouse developer stack is
  byte-identical to b66b4f2 and never starts PostgreSQL without an
  explicit --profile postgres-test
- scripts/run-postgres-integration.mjs: opt-in runner that proves
  acceptance instead of a compose-up: readiness ping must report a
  PostgreSQL 18 major version, one uniquely owned pgfixture_* database
  is created (ownership begins only at verified create), literal
  positive/negative fixture checks run inside it (ordered SQL
  parameters, literal expected rows, unique_violation 23505 and
  invalid_text_representation 22P02 negatives, SQL-NULL vs JSON-null
  preserved via payload::text), then go test executes the merged
  pg-store-01 TestPostgres18PoolIntegration with LOOM_TEST_POSTGRES_URL
  propagated to the child - a required-case skip is a hard failure -
  and finally drops only its own namespace with a zero-leftover audit
  scoped to that namespace
- DB administration uses an embedded Go probe executed via go run from
  a private temp dir against the repository's own pgx dependency; the
  admin DSN travels only in LOOM_PG_FIXTURE_ADMIN_URL and credentials
  are scrubbed from evidence, console output and child logs
- compose capability is recorded, never assumed: docker, podman compose
  and podman-compose are detected explicitly; a verified runtime must
  keep the default config at arangodb+clickhouse with the PG service
  profiled, and a missing runtime is recorded as blocked-missing-runtime
  rather than faked healthy
- scripts/run-postgres-integration.test.mjs: 18 hermetic node:test
  cases over the runner contract (readiness gate, namespace ownership,
  propagation, non-skipped acceptance, finally-cleanup, credential
  scrubbing, compose contract fail-closed, blocked compose recording)
- .github/workflows/tests.yaml: pg-fixture job runs both planned checks
  against a postgres:18 service container

Checks: node --test scripts/run-postgres-integration.test.mjs 18/18
pass offline; node scripts/run-postgres-integration.mjs passed against
the provided PostgreSQL 18.6 service (readiness, owned pgfixture_*
namespace, all five acceptance checks, real Go integration case passed,
cleanup dropped its namespace with zero leftovers, verified by an
independent pg_database audit); repeated runs are deterministic; the
default compose config keeps exactly arangodb+clickhouse (verified via
YAML parse; docker/podman compose binary unavailable in this container,
recorded as a blocked capability)

* fix(postgres): close owned-namespace redirect hole, scrub all evidence, align budgets

Address native review on #63:

Required:
- reject LOOM_TEST_POSTGRES_URL values that pin a database via the
  dbname/database query parameter (pgconn lets the query outrank the
  URL path, mirroring the client_test.go precedent), so fixture writes
  can never redirect outside the run-owned pgfixture_* namespace; the
  acceptance probe additionally asserts SELECT current_database()
  equals the owned name before any write, and a hermetic regression
  proves the fail-closed path performs no service contact
- write integration.jsonl through scrubSecrets like every other
  evidence file, and assert credential absence for it in the leak test
  (go.stdout stays raw in memory for checkGoEvents)

Optional findings adopted:
- interpolate REQUIRED_MAJOR_VERSION into the probe's requiredMajor
  constant so runner, probe and the Go package cannot drift
- preserve the primary failure message when cleanup or the leftover
  audit also fails; audit/cleanup failures are appended
- escape LIKE wildcards in the leftover audit with ESCAPE 'x'
- create the private probe temp directory only after every pre-flight
  assertion so a throw cannot strand it
- align budgets: Go test timeout (<=300s) fires before the child kill
  (+30s), which stays under the 840s step timeout inside a 15-minute
  job, so summary.json is always written

Verification: node --test 20/20 pass; real acceptance re-run against
the provided PostgreSQL 18.6 service passed (all five checks, real
integration case unskipped, cleanup dropped only its namespace, zero
leftovers); live ?dbname= attempt exits 1 fail-closed with the primary
error preserved and pgfixture_leftovers=0

* ci(postgres): align fixture budgets inside the enforced 10-minute job contract

The Python workflow-contract test (scripts/tests/test_ui_ci_workflow.py)
pins every Tests job to timeout-minutes: 10; the previous head widened
pg-fixture to 15m and broke that tested guarantee. Instead of weakening
the contract, align the chain inside it:

- Go test timeout min(verificationTimeoutMs, 180s) fires before the
  spawn kill (+30s), so the child self-terminates first
- the integration phase starts only when the runner's eight-minute
  internal deadline still has kill + 90s cleanup reserve, so the
  finally-cleanup and summary.json keep room under the 540s step
  timeout and the 10-minute job
- workflow back to timeout-minutes: 10 with the aligned step timeouts

Verification: scripts/tests suite 48/48 OK (was 1 failure on the
15-minute variant); scripts.test_validate_architecture_plan 14/14 OK;
node --test scripts/run-postgres-integration.test.mjs fail 0; real
acceptance re-run against the provided PostgreSQL 18.6 service passed
with zero leftovers and the real integration case unskipped

* test(postgres): restore test body line break and minimal stub result

Round-2 review nit: the missing-URL test body was jammed onto the arrow
opening line; restore the break. The dbname fail-closed test's audit
stub now returns databases: [] so evidence.error keeps only the primary
rejection message (reviewer-observed cosmetic append).

Verified: node --test scripts/run-postgres-integration.test.mjs 20/20;
scripts/tests suite 48/48 OK
…er (pg-store-02) (#62)

* feat(postgres): advisory-lock serialized, embedded SQL migration runner (pg-store-02)

Add internal/store/postgres/migrate.go: a versioned SQL migration runner
for the PostgreSQL 18 source store. Migrate holds a session-level
advisory lock keyed by the target schema (discarding the pooled
connection if unlock cannot be confirmed), applies each pending embedded
migration in its own transaction with the target search_path, and
inserts the version/name/checksum ledger row only after the migration
commits. Before applying anything it refuses edited historical
checksums (ErrMigrationChecksumMismatch), ledger versions above the
embedded history (ErrFutureSchemaVersion), vanished applied files
(ErrMigrationMissing), and out-of-order pending files
(ErrMigrationOutOfOrder); a failing migration rolls back its DDL and
leaves the prior ledger intact; re-apply is idempotent and returns the
same applied versions/checksums. The caller owns schema lifecycle.

migrations/000001_ledger.sql is the only embedded migration: it creates
the schema_migrations ledger (version, name, checksum, applied_at;
never SQL content). Resource/edge/generation tickets add their own
migrations through this runner; no table definitions are duplicated
here.

Verification (base b66b4f2):
- go test ./internal/store/postgres -run Migration -count=1 against the
  real PG18 service (pgstore02_it_* isolated database + owned schema,
  dropped by test cleanups; TestMigrationNoLeftovers asserts zero
  leftovers), including two simultaneous callers on separate pools
  recording each migration exactly once.
- go test ./internal/store/postgres -count=1 (pg-store-01 suite still
  green); go test ./internal/dataset/... -count=1 ok; go build ./... ok.
- Arango integration (scripts/run-arango-integration.mjs) blocked: no
  Arango service or docker in this worker sandbox; run failed closed
  with 'fetch failed'. Escalated to coordinator.

* fix(postgres): symmetric lock-state discard and panic-safe release in Migrate

Address native review on pg-store-02 (PR #62):

- pg_advisory_lock acquisition now discards the connection on any
  statement error instead of pooling it. A session-level grant can race
  a cancel and statement abort never releases session locks, so a
  failed acquire leaves the lock state unknown; the same invariant the
  unlock path already enforced via discardPoolConn now holds on entry.
- Unlock and release moved into a defer with named results, so every
  exit path -- panic included -- either confirms the unlock and
  releases the connection or discards it. A deferred unlock failure
  still surfaces as the returned error when the run itself succeeded.
- Documented that migration transactions pin search_path to the target
  schema alone (no public), per review suggestion.
- Added TestMigrationUnconfirmedUnlockDiscardsConnection: a
  lock-surrendering migration exercises the previously untested
  discardPoolConn branch; asserts the error surfaces, the migration
  still applied and recorded once, the pool retains no acquired
  connection, and follow-up migrations still succeed.

Verified against the real PG18 service: go test ./internal/store/postgres
-run Migration -count=1 17/17 pass; full package ok; go test
./internal/dataset/... -count=1 ok; go vet/gofmt clean.

* test(postgres): regression tests for advisory-lock lifecycle; name lock-acquire errors

Coordinator-required follow-ups on PR #62:

- Named error: contended/failed pg_advisory_lock acquisition now wraps
  ErrMigrationLockAcquire, keeping the deadline/cancellation cause
  chainable. Acquisition failures always discard the connection, so any
  orphaned session grant dies with the backend.
- TestMigrationPanicUnderLockReleasesLockAndLeaksNothing: injected panic
  (test seam: MigrationRunner.panicHook, nil in production) inside the
  locked section must still release the advisory lock and not leak the
  pooled connection; the panic still propagates; a fresh connection then
  applies the full history.
- TestMigrationContendedAcquireDeadlineIsNamed: holder migrates a
  sleep-bearing migration while a second, separate connection loses the
  race with a short context deadline; asserts the named acquisition
  error chained to deadline/cancellation, the racing connection is
  discarded (pool holds zero acquired), the holder completes, a fresh
  caller acquires immediately (no residue), and the loser's pool
  recovers.
- Witness readLedger now treats a missing ledger table as empty history,
  matching the runner.

Verified on the real PG18 service: -run Migration 19/19 at -count=1 and
-count=3 (flake sweep, unique pgstore02_it_* databases, zero leftovers
asserted every round); go vet/gofmt clean; offline go test
./internal/store/arango -count=1 ok.

* test(postgres): prove connection discard with pool TotalConns drop

Verifier-required: TestMigrationUnconfirmedUnlockDiscardsConnection was
vacuous -- a mutant that returns the unproven connection to the pool
still passed AcquiredConns()==0. The test now runs against a MinConns=0
pool (destroyed connections are never silently replaced) and asserts
the pool's physical TotalConns drops below the post-Open warm value,
which only a real discard achieves. Non-vacuity re-verified: a
discardPoolConn->conn.Release overlay makes this test fail on the
TotalConns assertion; overlay reverted.

Verified live: go test ./internal/store/postgres -run Migration
-count=1 ok on the PG18 service (unique pgstore02_it_* DB, zero
leftovers asserted); go vet/gofmt clean.
…ds (pg-store-04) (#65)

* feat(postgres): scoped JSONB FHIR resource repository with keyset reads (pg-store-04)

Adds the PostgreSQL 18 source-store resource persistence slice on top of
the merged pool (pg-store-01) and migration runner (pg-store-02):

- Migration 000002_fhir_resource: one fhir_resource table with typed,
  NOT NULL scope columns (project, dataset_generation, resource_type,
  logical_id, auth_resource_path), the original resource object as JSONB
  payload (nullable, so SQL NULL stays distinct from JSON null), an
  always-generated bigint storage identity (resource_seq) for stable
  keyset order, a UNIQUE natural-identity constraint, and a
  scope+seq keyset index. Idempotent DDL per the runner's retry rule.
- ResourceRepository: insert-only writes (duplicate natural identity
  returns typed *ResourceConflictError and never replaces the earlier
  payload), exact reads by (project, generation, type, logical_id), and
  keyset reads ordered by storage identity. Restricted reads always bind
  project, generation, and auth path; the unrestricted mode must be set
  explicitly (nil is an error, never legacy-unrestricted).
- Additive PG-side types PGResourceScope / PGResourceRow in
  internal/catalog/types.go; no Arango behavior changes.
- migrate_test.go: runner-semantics tests now build synthetic histories
  on a ledger-only base so appended feature migrations cannot shift
  their fixed expectations; full-history assertions derive from the
  embedded chain; the bootstrap test pins identity/ordering/checksums
  without pinning the migration count.

Validation (real PG18 via LOOM_TEST_POSTGRES_URL, isolated
pgstore04_it_* databases/schemas, zero leftovers, literal expected
rows):
- go test ./internal/store/postgres -count=1 (full package incl. live
  pool, runner, and 10 Resource tests) PASS
- go test ./internal/ingest -run '^(TestNamespaceRowBuildResult...|TestNewGenerationLoadPlan...)$' PASS
- go test ./internal/store/arango -count=1 PASS
- go test ./internal/dataset/... -count=1 PASS
- go test ./internal/catalog -count=1 PASS; go build ./... PASS

* docs(postgres): state JSONB fidelity and index-order claims precisely (pg-store-04 review)

Native review findings (documentation accuracy, no behavior change):

- JSONB is canonicalized by PostgreSQL (key order, duplicate keys last
  value wins, numeric literals normalize), so drop the verbatim /
  exactly-as-stored claims in the package doc, the migration header,
  and the catalog PGResourceRow doc. State the tested semantic
  guarantee instead: SQL NULL stays distinct from the JSON null
  document, a missing key stays absent, a present-but-null key stays
  null, and empty arrays and empty objects stay empty containers.
- Index comment: only single-path restricted reads walk
  fhir_resource_scope_seq_ix in resource_seq order without a sort;
  multi-path (ANY) and unrestricted reads bind a prefix and sort the
  fetched scope rows by resource_seq. Say so, with a capacity note.

Re-validated: go test ./internal/store/postgres -count=1 PASS (37 tests,
live PG18), gofmt/vet clean.

* test(postgres): pin keyset ordering and migration checksums independently (pg-store-04 verifier notes)

Two verifier test-hardening items, no production-code change:

1. Keyset ordering was unpinned: seeds sorted in storage order, so an
   implementation that dropped ORDER BY resource_seq (a multi-path ANY
   scan returns rows grouped by path) or ordered by logical_id instead
   kept both keyset tests green. Re-seeded so the logical ids' lexical
   order AND the authorized-path array order contradict insertion/
   storage order (scope test: insert k3,k1,k5,k2,k4 with pr-1/pr-2
   interleaved, literal pages [k3,k1],[k5,k2],[k4]; walk test:
   w3,w1,w4,w2 then w6,w5), with a guard that fails if the seeding ever
   becomes order-compatible again. Proved by out-of-tree go test
   -overlay mutation (repo never touched):
     - drop ORDER BY resource_seq  -> both keyset tests FAIL
       ("page 0 position 1 returned k5, want k1" etc.)
     - ORDER BY logical_id         -> both keyset tests FAIL
     - overlay-revert              -> PASS
2. Self-referential checksum: TestEmbeddedMigrationsBootstrapsTheLedger
   compared the loader's checksum against the same function that
   computes it. Replaced with committed fixed SHA-256 constants per
   migration (sha256sum of the exact file bytes), bidirectional
   (missing pin or missing history entry both fail). Proved by overlay:
   appending a comment line to 000002 makes only the bootstrap test
   fail with a checksum-drift message; other runner tests stay green.

Re-gated live: go test ./internal/store/postgres -count=1 PASS
(37/37, zero skips, unique pgstore04_it_* DBs, zero leftovers), vet
clean.
…nd atomic CAS pointers (#67)

* feat(postgres): exact publication bundle catalog with fenced leases and atomic CAS pointers (pg-publication-bundle-catalog-v1)

Persist execution/output metadata, quality/state metadata, the exact
logical pointer registry, and fenced bundle leases in PostgreSQL 18
while ClickHouse remains the publication row store.

- internal/dataframe/publication/postgres/registry.go: BundleCatalog,
  ExactExecutionCatalog, and PagedBundleCatalog over ordered $n SQL
  parameters and schema-qualified tables. Domain Key/PointerName come
  from the untouched publication.BundleIdentity functions; pointer rows
  key on the hex SHA-256 of the pointer name (Arango digest discipline)
  and round-trip exact NUL-bearing names through bytea, which text and
  jsonb both reject.
- Exact lookup filters project + dataset_generation + recipe +
  translation_version + output membership; no name-only latest
  fallback. Arango tie order (published, ready, updated) is preserved
  with a deterministic id tie-break.
- Legacy payloads canonicalize on read via CanonicalizeLegacy without
  rewriting stored rows; stored payload, legacy state columns, and
  missing-vs-JSON-null-vs-SQL-NULL stamps are witnessed unchanged.
- SaveExecution and PublishExecution are lease-fenced; PublishExecution
  commits pointer and PUBLISHED metadata in one transaction so a
  failed CAS rolls both back. Leases bump an epoch on every grant for
  repeated-owner correlation.
- tests/migrations/000004_publication_bundle_catalog.sql (version 4,
  deliberately distinct from the concurrent store tickets'
  000002_*/000003_*): idempotent DDL applied through the pg-store-02
  MigrationRunner; the registry itself contains no DDL.

Validation (real PostgreSQL 18 via LOOM_TEST_POSTGRES_URL; no mocks,
no skips): go test -count=1 ./internal/dataframe/publication/postgres/
-> 20 passes, 0 skips, TestMain audits zero surviving pgpubcat01_it_*
databases/schemas; independent re-audit after the run reports 0/0.
check-1 go test -count=1 ./internal/dataframe/publication/arango/ ok;
./internal/dataframe/publication/ ok; ./internal/dataframe/publication/clickhouse/
ok (unit tests; pre-existing live-Arango/ClickHouse e2e gates skipped
without their service env, unchanged from base); ./internal/store/postgres/
ok. go build ./... ok.

* chore(audit): register the publication postgres package and refresh the generated package audit

Adds the responsibility-map entry scripts/package_audit.py requires for
internal/dataframe/publication/postgres (the Python audit lane refuses
uncovered packages) and regenerates docs/PACKAGE_AUDIT.{csv,md}. The
refresh also picks up the previously unrecorded pg-ir-01 compiled_command
files, pg-store-02 migrate files, and the server PostgreSQLConfig
addition, so the committed artifact now matches the generator output.

Validation: python3 -m unittest discover -s scripts/tests -> 48 tests OK;
python3 -m unittest scripts.test_validate_architecture_plan -> 14 tests OK;
python3 scripts/package_audit_verify.py internal/dataframe/publication/postgres
-> impacted package test go test ./internal/dataframe/publication/postgres ok.
make test --full cannot complete in this sandbox (jq absent; pre-existing
environment gap unrelated to this change).

* fix(audit): classify /postgres persistence packages as storage adapters

The package_kind heuristic had /arango and /clickhouse storage-adapter
branches but no /postgres branch, so the generated row for
internal/dataframe/publication/postgres — the direct sibling of
publication/arango and the pgx-backed counterpart of internal/store/postgres
— fell through to the domain/library default and lost the storage-adapter
advisory it carries with every other persistence package.

internal/store/postgres keeps its kind via the internal/store/ prefix and
every other package's classification is unchanged; regeneration diffs only
the one row.

Validation: python3 -m unittest discover -s scripts/tests OK; scripts.
test_validate_architecture_plan OK; python3 scripts/package_audit_verify.py
internal/dataframe/publication/postgres -> go test ./internal/dataframe/
publication/postgres ok; regenerated kind fields witnessed for the new
package, its Arango sibling, internal/store/postgres, and the resolver pin.

* test(postgres): compose the catalog test history from the ledger bootstrap only

pg-store-04 added 000002_fhir_resource.sql to the embedded history, so
composing the catalog test schema from every embedded migration would have
pulled the store's fhir_resource table into this catalog's metadata-only
schema audit and pinned this ticket's ledger assertion to the store
tickets' growing history. Compose instead from the version 1 ledger
bootstrap plus tests/migrations/000004_publication_bundle_catalog.sql —
still the real pg-store-02 runner and ledger — and tighten the literal
expectations to full LedgerRecord equality including checksums. The
catalog test history stays exactly {1 ledger, 4 publication_bundle_catalog}
however far the store history advances.

Validation on the merged tree (with pg-store-04 157700c): real-PG18 suite
20 PASS / 0 SKIP / 0 FAIL with zero-leftover audit green; publication root,
publication/arango, publication/clickhouse, and internal/store/postgres
(including store-04's new tests) ok; go build ./... ok; go vet + gofmt
clean; scripts/package_audit.py exit 0; unittest discover -s scripts/tests
OK.
… migration runner (pg-state-foundation-v1) (#64)

* feat(postgres): Explorer-owner Create/Get/List on the shared pool and migration runner (pg-state-foundation-v1)

Adds the first concrete Explorer control-plane schema for PostgreSQL 18
on the pg-store-01 pool and pg-store-02 migration runner: no second
driver, pool, fixture, or runner; no Arango fallback and no production
backend switch wired in this slice.

- internal/explorer/postgres/migrations/: 000001_ledger (per-schema
  ledger bootstrap, rerun-safe) and 000002_explorer_owner (explorers
  owner table: unique (project, explorer_id) identity on COLLATE "C"
  columns for byte-exact identity and deterministic Listing, typed
  columns for every queried field, nullable jsonb for the lossless
  draft payload and last authoring command results, CHECKs for the
  ManagementMode domain and the draft version range, IF NOT EXISTS
  DDL so bootstrap reruns never truncate owner state).
- explorers.go: Store.Create is insert-once (ON CONFLICT DO NOTHING
  RETURNING; duplicate identity maps to explorer.ErrDraftConflict and
  never overwrites), Store.Get enforces project+Explorer identity
  (ErrNotFound otherwise), Store.List is project-scoped and sorted by
  ExplorerID in byte order; ordered SQL parameters (..$N) and the
  sanitized schema-qualified table bind every statement; json.RawMessage
  crosses the boundary as missing (SQL NULL) versus JSON-null (jsonb
  'null') versus document, preserved losslessly on read-back.
- explorers_test.go: real-PG18 integration gated by
  LOOM_TEST_POSTGRES_URL (no mocks, no skipped acceptance in the
  required run): isolated pgstate01v1_it_* database+schema per test
  with credential-scrubbed output, zero-leftover audit cleanups,
  fresh independent pools for read-back, literal expected rows read
  through raw SQL (jsonb ::text forms, microsecond timestamptz),
  duplicate-owner and cross-project negatives, DB-enforced negative
  fixtures (23505, 23514, 22P02), and migrate-rerun convergence with
  owner state preserved.

Validation (real PostgreSQL 18.6 service):
- go test -count=1 -run '^TestPostgresExplorerOwner' ./internal/explorer/postgres/  PASS, 9/9 executed
- go test -count=1 ./internal/explorer/postgres/  PASS (unit subset without service)
- go test -count=1 ./internal/store/arango/  PASS (existing gating preserved)
- go test -count=1 ./internal/store/postgres/  PASS (pg-store baseline intact)
- go test -count=1 ./internal/explorer/...  PASS (Arango regressions preserved)

Ticket: pg-state-foundation-v1

* chore(audit): register internal/explorer/postgres in the package responsibility map

Adding a Go package requires a curated RESPONSIBILITIES entry; the
Python package-audit gate fails closed otherwise (responsibility map
mismatch for internal/explorer/postgres in PR #64 CI).

Regenerate docs/PACKAGE_AUDIT.csv and docs/PACKAGE_AUDIT.md with the
canonical generator, as required by the audit header and the
pg-store-01 precedent. The regeneration additionally reconciles the
pre-existing stale internal/dataframe/compiler row (compiled_command.go
and its backend-tagged command exports landed without a doc refresh).

Validation:
- python3 scripts/package_audit.py  (writes 77 packages)
- python3 scripts/package_audit_verify.py internal/explorer/postgres  PASS
- python3 -m unittest discover -s scripts/tests  OK (48)
- python3 -m unittest scripts.test_validate_architecture_plan  OK (14)

* fix(postgres): pin one-history-per-schema ownership at the Explorer control-plane boundary

AO review finding on PR #64: two embedded histories (pg-store-02 and
this package) both start at version 1 with deliberately different
ledger bodies and different checksums, and both MigrateSchema entry
points accept any caller-supplied schema. Which history may migrate
which schema must not be implicit.

- Package/MigrateSchema/New docs commit to dedicated schemas per
  package history: pg-store-02 owns source-store schemas, this package
  owns Explorer control-plane schemas, and dependent state tickets
  extend this same history instead of starting a competing one. A
  schema already migrated by another history fails closed with
  pgstore.ErrMigrationChecksumMismatch before any statement applies.
- New regression test TestPostgresExplorerOwnerMixedHistoryIsRefused
  pins both directions against real PG18: source-store history refused
  on this package's schema (ledger keeps exactly [1 2], owner row
  survives untouched), and this package's history refused on a
  source-store schema (explorers table never created).
- Migration 000002 header states the jsonb losslessness caveat
  honestly: duplicate keys collapse last-wins, out-of-range numerics
  fail at parse (non-JSON input 22P02, already pinned by tests).
- Regenerated package audit docs for the updated LOC.

Validation (real PostgreSQL 18.6):
- go test -count=1 -run '^TestPostgresExplorerOwner' ./internal/explorer/postgres/  PASS 10/10
- go test -count=1 ./internal/explorer/...  PASS; check-1/check-3 PASS
- python3 -m unittest discover -s scripts/tests  OK; scripts.test_validate_architecture_plan  OK

Ticket: pg-state-foundation-v1 (AO review findings)

* docs(audit): regenerate package audit on merged tree (FINAL SYNC)

Base 157700c (pg-store-04) added internal/store/postgres/resource.go,
resource_test.go, and 000002_fhir_resource.sql plus internal/catalog
additions without a doc refresh; regenerate the canonical
docs/PACKAGE_AUDIT.{csv,md} on the merged tree so committed rows match
the generator byte-exactly. Only the internal/catalog and
internal/store/postgres rows move; internal/explorer/postgres is
byte-identical to the reviewed head.
…over PG18 (pg-store-03) (#66)

* feat(postgres): generation manifests with active-generation CAS over PostgreSQL 18 (pg-store-03)

Persist dataset-generation manifests and the active-generation
compare-and-swap pointer in PostgreSQL, on top of the pg-store-01
readiness-checked pool and the pg-store-02 ordered migration runner.

- internal/store/postgres/migrations/000003_dataset_generation_manifest.sql:
  manifest table (public state names LOADING/STAGED/READY/FAILED kept
  byte-for-byte, jsonb schema identity, no SQL NULLs anywhere) plus one
  active-pointer row per project with a composite FK to the manifest row;
  retryable DDL (IF NOT EXISTS) per the runner's commit/record-window
  contract. 000002 stays reserved for pg-store-04.
- internal/dataset/postgres: backend-tagged commands with ordered typed
  positional SQL parameters (AQL or untagged commands fail closed before
  pgx sees a statement); CreateManifest, ReadManifest, TransitionManifest,
  ResolveActiveManifest implement the existing dataset lifecycle surface
  over the PG tables (publication.ActiveResolver asserted);
  ActivateGeneration is an explicit compare-and-swap on the active-pointer
  value inside one transaction: two concurrent activations presenting the
  same expected generation yield exactly one winner and a typed
  ErrActivationConflict loser; re-activating the already-active exact
  manifest is idempotent with zero writes; non-STAGED candidates are
  refused with publication.ErrGenerationNotReady and moved/edited rows
  with ErrActivationConflict; a commit-fault test seam proves a failure
  before COMMIT leaves both manifest state and the active pointer
  unchanged, with committed-value readback after pool reopen. No
  cross-database atomicity and no silent backend fallback.
- manifest.go and active_resolver.go are untouched: no public state name
  or schema identity byte changed, so Arango behavior is byte-preserved.
- internal/store/postgres/migrate_test.go: runner-behavior suites base
  their synthetic history on the ledger bootstrap instead of assuming the
  embedded history is ledger-only, because feature tickets add migrations
  by the runner's own design. Full-history integrity (strictly ascending
  versions, checksum-per-SQL) is now asserted on the embedded history,
  and MigrateSchema still applies it end to end.

Checks (real PG18 via LOOM_TEST_POSTGRES_URL; unique pgstore03_it_*
database + schema per test with literal expected-row witnesses through
the test pool; negative schema fixtures for SQLSTATE 23502/23503/23505/
23514; CAS schedule tests serial; zero-leftover check validated with a
negative control):
- go test ./internal/dataset/postgres -count=1: 14 pass, 0 skip (env set)
- go test ./internal/dataset/... -count=1: pass (incl. dataset gating)
- go test ./internal/store/postgres -count=1: pass
- go test ./internal/store/arango -count=1: pass
- go vet ./... and go build ./...: clean

Ticket: pg-store-03-generation-manifest-cas (batch c4b53e23b9d190fe)

* chore(audit): register internal/dataset/postgres in the package responsibility map

scripts/package_audit.py keeps a curated responsibility entry per Go
package; the new PostgreSQL dataset-generation store must be registered
or the retained Python package-audit tests fail (the CI job that failed
on this branch). docs/PACKAGE_AUDIT.csv and docs/PACKAGE_AUDIT.md are
regenerated from the script per its generate-on-demand contract, so the
rows also pick up the importers column gaining internal/dataset/postgres
and prior uncommitted script drift (pg-ir-01's compiled_command.go
exports), matching the pg-store-01 precedent (b66b4f2).

Verification: python3 scripts/package_audit.py (wrote 77 packages);
python3 -m unittest discover -s scripts/tests (48 OK);
python3 -m unittest scripts.test_validate_architecture_plan (14 OK);
python3 scripts/package_audit_verify.py internal/dataset/postgres
(internal/dataset/postgres tests selected, pass).

Ticket: pg-store-03-generation-manifest-cas (batch c4b53e23b9d190fe)

* fix(postgres): classify dataset PG store as storage adapter; harden PG test cleanups and CAS docs (pg-store-03 review)

Addresses the AO native review on PR #66:
- scripts/package_audit.py: package_kind now recognizes the /postgres
  suffix alongside /arango and /clickhouse, so internal/dataset/postgres
  lands as storage adapter with the preserve-interface-and-persisted-data
  deletion-blocker evidence, matching its Arango sibling. Regenerated
  docs/PACKAGE_AUDIT.csv and docs/PACKAGE_AUDIT.md.
- internal/store/postgres/migrations/000003_dataset_generation_manifest.sql:
  documents the reserved-000002 upgrade-window hazard (runner
  out-of-order policy) for persistent schemas; name kept per the
  coordinator reservation (pg-store-04 owns 000002_*), convergence
  ordering escalated to the coordinator.
- internal/dataset/postgres: ActivateGeneration docs state the
  idempotent-already-active rule takes precedence over the expected
  comparison; PG harness drops use fresh bounded cleanup contexts
  instead of the test-deadline context; the service-database
  pg_namespace leftover probe comment states what it actually guards.

Checks: go test ./internal/dataset/postgres -count=1 with
LOOM_TEST_POSTGRES_URL: 14 pass, 0 skip; go vet clean; gofmt clean;
python3 -m unittest discover -s scripts/tests: OK; python3
scripts/package_audit.py regenerated (77 packages).

Ticket: pg-store-03-generation-manifest-cas (batch c4b53e23b9d190fe)
…ed targets (pg-store-05) (#68)

* feat(postgres): scoped typed edge occurrence repository with unresolved targets (pg-store-05)

Persists relationship edges as scoped typed occurrences on the
PostgreSQL 18 source store, on top of the merged pool (pg-store-01),
runner (pg-store-02), and fhir_resource repository (pg-store-04):

- Migration 000004_edge_occurrence (coordinator-reserved version 4;
  000003 stays owned by pg-store-03): one fhir_edge_occurrence table
  with typed NOT NULL scope/endpoint/occurrence columns, the full
  occurrence identity
  (project, dataset_generation, source_resource_type, source_logical_id,
  label, target_resource_type, target_logical_id, source_path,
  source_ordinal) as a UNIQUE constraint, a nullable diagnostic
  logical_edge_key, and scoped source-/target-directed traversal
  indexes led by project and dataset_generation. Idempotent DDL per
  the runner's retry rule.
- EdgeRepository: insert-only writes with typed *EdgeConflictError;
  source precondition (source must exist in the same
  project/dataset_generation) enforced atomically with the insert via
  INSERT ... SELECT ... WHERE EXISTS and reported as typed
  *EdgeSourceMissingError; unresolved targets stored with resource
  type and logical id preserved, resolution computed at read time
  against fhir_resource in the edge's own scope; source- and
  target-directed keyset traversals on the immutable storage identity
  with explicit restricted/unrestricted auth binding; ordered SQL
  parameters throughout; nil logical_edge_key (SQL NULL) distinct from
  the empty string.
- Additive SplitCollectionID in internal/ingest/documents.go (exact
  inverse of collectionID for endpoint parsing; no behavior change to
  existing functions).
- migrate_test.go: pinned checksum entry for the appended migration
  (the deliberate edit gate); 000002's pin untouched.
- scripts/package_audit.py: curated responsibility updated for the
  expanded internal/store/postgres package; docs/PACKAGE_AUDIT.{csv,md}
  regenerated with the canonical generator (also converges stale rows
  from pg-ir-01 and pg-store-04 file/importer drift).
- No fhir_resource or bulk-write/generation tables redefined; no
  catalog types added (out of this ticket's scope).

Validation (real PG18 via LOOM_TEST_POSTGRES_URL, isolated
pgstore05_it_* databases/schemas, zero leftovers audited, literal
expected rows incl direct-SQL witnesses, no mocks):
- go test ./internal/store/postgres -run Edge -count=1 PASS (10 tests:
  validation, migration DDL witnesses, source precondition incl
  cross-generation/project refusals, unresolved-target identity +
  read-time resolution, repeated-reference multiplicity (two rows,
  shared collapsed logical key, ordinal distinction, exact-duplicate
  typed conflict), scoped/order-bound traversals both directions,
  SQL-NULL-vs-empty logical key, no leftovers)
- go test ./internal/store/postgres -count=1 PASS (full package)
- go test ./internal/store/arango -count=1 PASS
- go test ./internal/dataset/... -count=1 PASS
- go test ./internal/ingest -run
  '^(TestEdgeFromGripRejectsNonConcreteResourceEndpoints|TestEdgeFromGripCanonicalizesConcreteEndpoints|TestNamespaceRowBuildResultKeepsLogicalFHIRIdentityAndQualifiesGraphIdentity)$'
  -count=1 PASS (+ new TestSplitCollectionIDInvertsCollectionEndpoints)
- go build ./... ; go test ./internal/ci PASS (repo gofmt/vet gates)
- python3 scripts/package_audit.py green; python3 -m unittest discover
  -s scripts/tests: 48 tests OK

Ticket: pg-store-05-edge-occurrence-repository (batch c4b53e23b9d190fe)

* docs(ingest): correct SplitCollectionID contract claim per review

The docstring asserted the PostgreSQL edge store keeps its own mirror of
this contract; it does not: EdgeRepository takes typed endpoint identity
columns directly and never parses Type/id endpoints. Describe the actual
present state: the helper is the endpoint-parsing counterpart for a
future PostgreSQL edge write path, and no mirror exists yet.

Ticket: pg-store-05-edge-occurrence-repository (batch c4b53e23b9d190fe)
Review: PR #68 AO native reviewer inline finding, internal/ingest/documents.go:145
… [pg-state-recipe-registries-v1] (#71)

* feat(pg): move recipe registrations and revision chains to PostgreSQL

pg-state-recipe-registries-v1. Adds two PostgreSQL 18 control-plane
adapters under the pg-store-02 runner, mirroring the Arango adapters,
with their own embedded migration histories (byte-identical ledger v1,
exec registries v2, revision chains v3 so version-ordered composition
is collision-free; internal/store/postgres/migrations untouched):

- internal/dataframe/recipe/exec/postgres: exec.Store over
  recipe_exec_recipes + fenced recipe_exec_occurrences. Immutable after
  first use; concurrent first use vs replacement fenced through one
  recipe-row FOR UPDATE (proven with committing lock-holder sessions
  and pg_stat_activity Lock waits); occurrence identity idempotent;
  per-(version, owner) owner_sequence correlates repeated owners;
  divergent concurrent first saves have one winner
  (ErrRecipeVersionConflict).
- internal/dataframe/recipe/postgres: recipe.RevisionStore over
  recipe_revisions + recipe_revision_heads. Head-row-locked CAS: one
  winner per parent race, typed STALE_CURSOR loser (non-retryable),
  typed INVALID_REQUEST parent-for-first; head-content retry idempotent;
  deterministic (created_at DESC, digest) List; project-scoped Get.

Real PG18 only: unique pgrecip01v1_it_* database+schema per test,
literal expected rows via direct SQL, no mocks, zero-leftover audits
(TestMain + per-fixture), credential scrubbing. Missing vs JSON-null
vs SQL-NULL pinned (head placeholder pair CHECK, jsonb_typeof null vs
absent, parent_digest NOT NULL DEFAULT '').

Validation: go test -count=1 -p 1 ./internal/dataframe/recipe/... plus
./internal/dataframe/publication/postgres/ ./internal/store/postgres/
green with LOOM_TEST_POSTGRES_URL (check-1 arango exec regression and
check-2 both new packages run, never skipped); go build ./... green;
package_audit registration + canonical regeneration; python3 -m
unittest discover -s scripts/tests: 48 OK.

* test(pg): scope recipe-registries leftover audits to binary-owned databases

AO native review finding (PR #71): the two recipe-registries PG-gated test
binaries share the pgrecip01v1_it_* namespace, and the cluster-wide
pg_database prefix count raced the sibling binary's live fixtures under
default parallel go test, failing zero-leftover audits spuriously.

Each binary now records every database name it creates and audits exactly
that set (per-fixture and TestMain), keeping the ticket-mandated
pgrecip01v1_it_* naming and the exact ownership guarantee: every resource
this binary created must be gone. The service-database schema scan stays
namespace-wide (neither binary creates schemas there, so it cannot see the
sibling's isolated-database schemas and is race-free) and TestMain audit
errors are credential-scrubbed like the fixture failures.

Also applies the reviewer's optional cleanups: collapsed Get error
branches, direct ErrRecipeNotFound sentinel, and removal of the redundant
recipe_exec_recipes_current index (the primary key answers the backward
LIMIT 1 current read).

Verified: three consecutive default-parallelism runs of both PG-gated
packages green with LOOM_TEST_POSTGRES_URL; full recipe tree green;
python audit gate OK; go build clean.
… owner-conditional leases (#69)

* feat(postgres): fence execution-owner and reconciler checkpoints with owner-conditional leases (pg-publication-leases-checkpoints-v1)

Adds internal/dataframe/publication/postgres/leases.go: FencedLeases, the
hardened checkpoint path of the PostgreSQL publication control plane over
the sibling catalog's publication_bundle_leases registry (000004,
unmodified). Acquire grants a monotonic generation (epoch) fencing token
with repeated-owner correlation and expiry takeover; Renew/Expire require
exact owner AND generation AND unexpired, so an expired lease can never be
renewed or resurrected by its old owner; Release is owner-and-generation-
conditional, so a stale token cannot clear the new owner; Checkpoint
compares owner, generation, and unexpired lease inside the single guarded
INSERT that assigns the per-key gap-free sequence, so a paused writer
cannot checkpoint after takeover. No cross-database atomicity, no silent
backend fallback, ClickHouse remains the publication data plane.

- tests/migrations-leases/000006_publication_lease_checkpoints.sql
  (coordinator reservation 000006_*): metadata-only checkpoint records;
  lease storage stays owned by the catalog migration.
- leases_test.go: real-PG18 acceptance via the sibling's ledger-bootstrap
  composition (ledger 1 + catalog 4 + checkpoints 6, literal ledger rows),
  pgleases01_it_* owned namespaces, zero-leftover audit, literal expected
  rows, no mocks. Two pools pinned to distinct pg_backend_pid() backends
  prove the stale paused writer is fenced across real connections.
- Canonical package audit regeneration (generator sentence updated; the
  regeneration also catches up two rows stale since pg-store-04).

Verification (real PG18 via LOOM_TEST_POSTGRES_URL, never printed):
- go test -count=1 ./internal/dataframe/publication/postgres/ : 30 PASS
- Arango lease baseline (check-1 entrypoint) : PASS
- go test ./internal/store/postgres/ : PASS
- go build ./... ; go vet ; gofmt : clean
- python3 -m unittest scripts.tests.test_package_audit : 5 PASS
- python3 scripts/package_audit_verify.py internal/dataframe/publication/postgres : PASS

* fix(postgres): make fenced-lease generations monotonic across lease-row deletion; refuse non-object checkpoint payloads at the boundary

Addresses PR #69 AO-native review (changes_requested at a578907):

- Acquire ignored the epoch history when the lease row was absent, so a
  release (ReleaseLease or Registry.ReleaseBundleLease) followed by a
  same-owner re-acquire reissued generation 1 and a straggler token matched
  the live grant. AcquireLease now bumps a never-deleted per-key high-water
  row in publication_lease_grants (new in the 000006 migration) inside one
  transaction and writes that value as the lease epoch in both the INSERT
  and ON CONFLICT branches. Retired keeper tokens can never match a later
  grant; failed acquires roll their bump back, burning nothing. Registry's
  Arango-parity lease methods keep their baseline epoch behaviour and are
  documented as outside the keeper's token space.
- Checkpoint accepted any json.Marshal-able value and let non-object
  encodings trip the payload_object CHECK as a wrapped 23514. Object shape
  is now enforced at the boundary with the promised message (jsonKind names
  the rejected kind without echoing payload bytes).

Regression tests: TestReleasedGenerationIsNeverReissued (keeper and sibling
deleters, straggler inert on the second physical connection, gap-free audit
across episodes, no-burn on refused acquires) and non-object payload cases in
TestCheckpointPayloadPreservesMissingVersusJSONNull (clean refusal, no
stored row, no burned sequence). Both guards mutation-checked: reverting
each guard fails its dedicated test.

Verification: full package 31 PASS / 0 SKIP on real PG18, zero
pgleases01_it_* leftovers; go build/vet/gofmt clean; canonical audit
regenerated; python gates 5 PASS; focused package_audit_verify PASS.
…lds (pg-catalog-02) (#70)

* feat(postgres): publish-last generation-scoped resource inventory builds (pg-catalog-02)

Store generation-scoped resource counts with a publish-last completeness
marker in PostgreSQL, mirroring the Arango fhir_resource_inventory
protection against partial count builds (ticket pg-catalog-02-resource-
inventory-builds, base 27f33c0).

- internal/store/postgres/migrations/000005_resource_inventory.sql:
  fhir_resource_inventory_count (content-addressed ric_ rows, PK per
  build/scope, non-negative exact counts) plus
  fhir_resource_inventory_build (one ribm_ marker per project/generation).
  Version 5 per coordinator reservation; 3/4 stay open for in-flight
  pg-store-03/#66 and pg-store-05/#68; migrate_test.go gains only its
  documented pinned-checksum entry for the new migration.
- internal/store/postgres/inventory.go: InventoryRepository — grouped
  source scan over fhir_resource, chunked commit-first count inserts
  (repeat-stable; divergent reinsert is a typed InventoryCountConflict,
  stored rows never replaced), PublishBuild guarded in one transaction by
  committed-row + coverage checks (typed InventoryPublishGuardError, prior
  marker intact), marker read, and build-bound scoped count sums with the
  explicit unrestricted-mode convention.
- internal/catalog/postgres: new package (pre-registered in
  scripts/package_audit.py RESPONSIBILITIES; docs regenerated with the
  canonical generator). RebuildResourceInventory emits exact zero-
  inclusive counts per generated type and auth path, assigns the shared
  content-addressed build identity, commits every count row, and
  publishes the marker last. DiscoverResourceInventory re-validates the
  marker and binds all reads to its build id, so unmarked or incomplete
  rows are invisible and stale/incomplete markers surface typed
  unavailable errors; restricted-empty reads nothing without querying.
- Real-PostgreSQL tests (no mocks): literal rows + direct-SQL witnesses,
  unique pgcat02_it_* databases/schemas with zero-leftover audits.
  Acceptance: zero-inclusive exact counts; marker-only-after-commit
  (partial committed rows stay invisible while the prior marker governs);
  repeated-build identity stability and generation/path isolation;
  injected count-write and marker-publish failures keep prior reads and
  expose typed errors.

Verification (PG 18.6, LOOM_TEST_POSTGRES_URL): go test ./internal/catalog
-run TestCatalogGenerationResultContractsExposeGeneration; focused
catalog/arango inventory regressions; full ./internal/catalog (61s),
./internal/catalog/arango, ./internal/dataset/..., ./internal/store/arango,
./internal/store/postgres, ./internal/catalog/postgres -run
ResourceInventory (all PASS, not skipped); go build ./...; go vet;
gofmt clean; python3 scripts/package_audit.py + unittests +
package_audit_verify internal/catalog/postgres.

* test(postgres): ownership-scoped zero-leftover audits in pgcat02 fixtures

The namespace-wide leftover sweep raced live pgcat02_it_* fixtures held by
the concurrently running sibling package (store vs catalog test binaries
share the namespace), flagging each other's live databases as leftovers.
Audit the exact database and schema names each test created instead —
ownership began at verified create, matching the canonical fixture runner
semantics — while keeping the pgcat02_it_* naming-pattern guard. Verified:
both PG packages green in two concurrent combined runs.

* fix(postgres): honest conflict message and live identity-collision classification (pg-catalog-02 review)

AO native review findings on PR #70:

- InventoryCountConflictError.Error printed the resource type twice
  (position count mismatch); drop the duplicated positional segment.
- The corrupted-derivation publish branch matched substring
  "marker_key", which the real constraint
  fhir_resource_inventory_build_key_ux does not contain, so it was dead
  code; match the exact constraint name (inventoryBuildTableName +
  "_key_ux"), and use the exact count-side name likewise instead of a
  substring test. pgx can surface the INSERT..RETURNING 23505 via
  rows.Err() rather than Query; classify that path identically.
- New live tests: cross-scope count_key reuse fails as typed
  ErrInventoryCountConflict; a marker key forged to collide across
  scopes returns the named corrupted-derivation error, leaves no second
  marker, and keeps the first scope's marker intact (plus the
  guard-before-own-rows leg).

Verified on real PG 18.6: full ./internal/store/postgres and
./internal/catalog/postgres PASS (-count=1); gofmt/vet clean.

* docs(audit): regenerate package audit for final head (pg-catalog-02 review)

Canonical generator rerun at the fix head: store/postgres row now carries
the fix-commit LOC (742-line inventory.go, 648-line inventory_test.go)
and the snapshot totals match the tree. python unittests and
package_audit_verify green.

* fix(postgres): guard coverage-close error and pin forged-key conflict semantics (pg-catalog-02 review)

AO native review cycle 3 on PR #70:

- PublishBuild's guard coverage query now defers rows.Close() so a
  mid-iteration scan error cannot be swallowed before the marker swap.
- Same-value guard semantics pinned with a live reproducer against
  PG 18.6: ON CONFLICT DO UPDATE omits WHERE-excluded conflicts from
  both SET and RETURNING (INSERT reference), so a same-document_count
  reinsert carrying a forged count_key is refused as a typed
  count_key conflict and the stored ric_ identity is never replaced;
  fully identical reinserts match the guard, appear in RETURNING, and
  remain the proven no-op. New regression test
  TestInventoryInsertCountsIsRepeatStableAndRejectsDivergence covers
  both legs (typed forged-key conflict + stored-key witness + identical
  single-row reinsert). The claimed silent overwrite did not reproduce;
  the finding is closed with the executable proof now in the suite.
- Generated audit docs regenerated for the new line counts.

Verification: full ./internal/store/postgres and ./internal/catalog/postgres
PASS serial x3 and concurrent x5 (-count=1, real PG 18.6); gofmt/vet clean;
python audit gates green.

* docs: correct record for commit 0649c45 (pg-catalog-02 attribution incident)

The commit message of 0649c45 and one
interim worker report wrongly attributed two changes to an 'AO native
review cycle 3'. No such review round exists. The verified review history
is: head ef8ef57 (2 findings), head 5ed54fe (1 finding: stale audit
docs), head 4c95ffd (approved), head 0649c45 (approved, zero new
comments).

The two changes in 0649c45 are self-initiated hardening, not reviewer
findings: (1) PublishBuild's guard coverage query defers rows.Close()
so a mid-iteration scan error cannot be swallowed before the marker
swap; (2) a regression test pins that a same-document_count reinsert
carrying a forged count_key is refused as a typed count_key conflict
(stored ric_ identity witnessed intact) while fully identical reinserts
remain the proven no-op — consistent with PostgreSQL's documented
DO UPDATE WHERE-exclusion from SET and RETURNING, verified live on
PG 18.6. No reviewer item was skipped and no behavior regressed.

Correction of record: PR issuecomment-6733834001; PR body carries the
same correction prominently. 0649c45's message cannot be amended
post-push (no force-push permitted); this commit is the in-tree record
fix requested by the coordinator.
…QL renderer (#72)

* feat(pg-ir-02): trusted PostgreSQL storage bindings and parameterized SQL renderer

Add the trusted identifier contract (ir/postgres_storage.go): registry over
fhir_resource/fhir_edge_occurrence with column allowlists, schema pattern,
and fail-closed PostgresStorageBinding validation. Add the renderer output
contract RenderedPostgresPhysicalPlan (SQL + contiguous $1..$n placeholders,
typed args, no AQL @-bind syntax) sharing arg validation with
NewPostgreSQLCommand. Add internal/dataframe/compiler/render/postgres:
RenderPhysicalPlan renders the supported read spine (root scan, comparison
filters incl. payload jsonb, NATIVE typed-identity edge joins, sort with
identity tiebreaks, limit, positional return) with auth paths bound as JSONB
arrays consumed via jsonb_array_elements_text; every unsupported plan shape
returns a typed error, never a silent fallback.

Ticket: pg-ir-02 (batch c4b53e23b9d190fe)
Validation: go test -count=1 pass for compiler/ir, compiler/lower,
render/aql, render/postgres (incl. real PG18 integration with pgir02_it_*
isolation and TestZZ zero-leftover audit, -count=2 stable), compiler
TestPostgresParityFixture; offline Arango regression
go test ./internal/dataframe/compiler/... -count=1 exit 0; gofmt/vet clean;
python3 scripts/package_audit.py regenerated docs audit (80 pkgs);
python3 -m unittest discover -s scripts/tests 48 OK (sandbox lacks jq).
No migrations added; CompiledCommandForBackend(PostgreSQL) stays fail-closed.

* fix(pg-ir-02): close reviewer-found gaps in filter rendering parity

Four findings from AO review run 4d97967e:
- sqlComparison had no NOT_EQUALS case, so a typed-column NOT_EQUALS
  rendered a bare empty operator; it now renders IS DISTINCT FROM
  (two-valued, identical to != over NOT NULL columns).
- An empty []string IN bind marshaled to JSON null, making
  jsonb_array_elements_text raise at execution; an empty list now binds
  [], so ANY is false, matching AQL x IN [].
- EXISTS/MISSING over typed columns rendered jsonb_typeof over
  text/timestamptz (execution error); columns now render IS NOT NULL /
  IS NULL, payload paths keep the jsonb_typeof presence form.
- NOT over a three-valued payload comparison dropped rows that AQL
  keeps (AQL coerces NOT(null) to true); such children are now wrapped
  COALESCE(NOT (child), true), and a payload comparison against the
  JSON null literal maps to the null-or-missing presence form.

Validation: full render/postgres suite green incl. new executed PG18
case TestPG18PredicateParityRepairs (NOT-missing-key keeps row, empty
IN selects nobody, column EXISTS/MISSING null tests, column
NOT_EQUALS) and TestZZ zero-leftover audit; ir, lower, render/aql,
TestPostgresParityFixture -count=1 green; gofmt/vet clean.

* fix(pg-ir-02): operator-correct JSON-null-literal payload comparisons

AO review run 74f73287 finding: the null-literal branch returned the
presence-negation for every non-EQUALS operator, which is wrong against
the AQL order where null sorts below every value (inverted LT/LTE,
over-selecting GTE). EQUALS/LTE map to the null-or-missing presence
test, NOT_EQUALS/GT to its negation, and LT/GTE - constant false/true
in AQL - are rejected with ErrUnsupportedPostgresPlan because a bare
constant would strand the resolved path parameter under the contiguous
placeholder contract.

Validation: unit table covers all six null-literal operators incl.
typed LT/GTE rejection and no-bounded-null-arg check; executed PG18
parity loop asserts LTE/GT/EQUALS/NOT_EQUALS rows against a stored
value and a missing key plus typed LT/GTE rejection at render; full
render/postgres suite -count=2 green incl. TestZZ; ir, lower,
render/aql, TestPostgresParityFixture green; gofmt/vet clean.
…d CAS-guarded checkpoint state (pg-catalog-04) (#73)

* feat(postgres): persist semantic-inventory build lifecycle, lease, and CAS-guarded checkpoint state (pg-catalog-04)

Adds SemanticBuildRepository in internal/catalog/postgres: one typed row per
(project, dataset_generation, build_id) holding state, schema/rule/emitter
versions, source kind/availability, scan totals, the legacy string and typed
(collection, key) checkpoints, a fenced lease (token + epoch-millis expiry),
and ordered diagnostics. Every guard is a single statement so PostgreSQL is
the arbiter: only one claimant holds a live lease; a stale token cannot
advance, complete, or fail the build; checkpoint compare-and-swap rejects a
stale expected checkpoint without touching state; completion releases the
lease and clears diagnostics while failure records exactly one diagnostic
and preserves scanned progress, checkpoints, auth path, and source
availability meanings, all matching the Arango adapter in
internal/catalog/arango/semantic_inventory.go. Unsupported shapes
(file-sourced claim, blank token, non-positive lease, half-set checkpoint,
unknown availability/state) are typed errors, never silent fallbacks.
Contribution rows and public page reads remain separate tickets; Arango and
AQL are untouched.

Migration 000006_semantic_inventory_build (idempotent DDL, CHECK-constrained
closed sets and paired lease/checkpoint invariants, SQL NULL carries no
meaning) with its deliberate checksum entry in the store package's
wantEmbeddedChecksums edit gate.

Validation (PG18 service, LOOM_TEST_POSTGRES_URL sourced, never printed):
- check-1: go test ./internal/catalog -run SemanticInventory -count=1 -> ok
- check-2: go test ./internal/catalog/postgres ./internal/ingest -run
  SemanticInventory -count=1 -> ok (9 real-PG acceptance tests: full-field
  round-trip, all six states, single-claimant race of 8 claimants, stale
  token/CAS/expiry rejections with byte-identical witnesses, diagnostic and
  source-availability semantics, typed refusals, TestZZ ownership-scoped
  zero-leftover audit under pgcat04_it_* with no global scans)
- go test ./internal/catalog/postgres ./internal/store/postgres
  ./internal/catalog ./internal/catalog/arango ./internal/ingest
  ./internal/dataframe/publication/postgres ./internal/explorer/postgres
  ./internal/dataset/postgres -count=1 -> all ok (offline Arango included)
- scripts/package_audit.py regenerated (internal/catalog/postgres
  responsibility updated); python3 -m unittest discover scripts/tests -> 48
  tests OK with jq from ~/.local/bin

* test(postgres): prove 000006 live migration contract per coordinator conditions (pg-catalog-04)

Adds the two live-PG18 migration proofs the coordinator attached to the
000006 approval:

- Double-apply idempotency probe: MigrateSchema applied twice over the owned
  schema returns byte-identical histories with no new ledger rows; the ledger
  records migration 6 exactly once under the literal name
  semantic_inventory_build and the pinned sha256sum, which is re-derived from
  the actual file bytes at run time. Live pg_constraint inspection witnesses
  all 14 named constraints exist on the table.
- Per-constraint negative tests: a violating literal row is refused by the
  named PostgreSQL constraint and stores nothing, for the both-or-neither
  checkpoint pair (both directions), the both-or-neither lease pair (both
  directions), negative lease expiry, the six-value state enum, source_kind,
  source_availability, scanned_resources, build_key/build_id shapes, blank
  project, versions_sane, plus primary-key and UNIQUE(build_key) identity
  arbitration. Every negative is paired with a valid control row that must
  insert in the same run, so a missing or renamed constraint fails the test
  instead of passing vacuously.

No production-code changes. check-1/check-2 and the full catalog/postgres
package re-run -count=1 on the PG18 service: ok.

* fix(postgres): truncate build diagnostics on rune boundaries and normalize generation at entry points (pg-catalog-04)

Addresses both PR #73 review findings.

Finding 1: FailSemanticInventoryBackfill truncated the diagnostic with a raw
512-byte slice. When the cut landed inside a multi-byte rune (realistic for
messages embedding FHIR display text), PostgreSQL rejected the UPDATE with
SQLSTATE 22021, so the failure was never recorded: the build stayed running
with its lease live. Truncation now backs off to the last complete rune,
matching the Arango adapter's always-record-the-failure contract.

Finding 2: Claim persisted the caller's raw dataset generation while the
derived build_key/build_id normalize internally, so the padded and clean
spellings of one generation claimed two primary-key rows: the second claim
surfaced the misleading corrupted sib_ derivation error from the UNIQUE
build_key violation, and every follow-up under the other spelling reported
row missing. All five entry points (Claim, Read, Advance, Complete, Fail)
now apply catalog.NormalizeDatasetGeneration before any statement runs, the
documented catalog-boundary convention that the Arango adapter already
honors via its normalized _key.

Regression tests (both proven failing against the pre-fix head): a 601-byte
diagnostic whose 512-byte cut splits a three-byte rune now stores exactly
one valid-UTF-8 diagnostic (the complete-rune 511-byte prefix) with the
failure recorded and lease released; a raw padded generation converges onto
the one row - the clean spelling meets ErrSemanticInventoryClaimed, both
spellings advance/complete it, and exactly one normalized row exists.

Full catalog/postgres package incl TestZZ, check-1, check-2, and the Arango
reference regression re-run -count=1 on the PG18/Arango services: ok.

* docs(audit): regenerate package audit for pg-catalog-04 fix-commit LOC delta

Verifier NOTE-1 at 47fb1ef: the review-fix commit grew internal/catalog/
postgres by +27/+104 lines without regenerating the audit tables. Docs-only
append; canonical scripts/package_audit.py output (83 packages), scripts
tests 48 OK. No behavior change.
…p lease catalog to PostgreSQL [pg-private-clickhouse-artifact-catalog-v1] (#74)

* feat(postgres): move private ClickHouse artifact manifests and cleanup lease catalog to PostgreSQL [pg-private-clickhouse-artifact-catalog-v1]

Adds internal/dataframe/execution/chartifact/postgres: a PostgreSQL 18
implementation of chartifact.Catalog. Physical tables stay in ClickHouse;
this catalog persists manifests and leases only, mirrors the Arango
semantics (insert-only immutable Create, owner-checked Update/Renew with
monotonic lease, terminal CLEANUP_PENDING, bounded stable ListExpired,
one-winner ClaimCleanup rechecking expiry inside the write, owner-validated
Delete/ReleaseCleanup), keeps every operation a single statement (DB
surface has no Begin) so the idempotent ClickHouse DropTable always runs
outside any transaction, and keeps the jsonb payload authoritative for
nanosecond and missing-versus-JSON-null fidelity. No published
BundleCatalog or filesystem ZIP ArtifactStore coupling; no backend
fallback; typed errors (ErrArtifactExists, ErrInvalidSchema,
chartifact.ErrLeaseLost) with explicit refusals.

Schema ships as tests/migrations-chartifact/000007_private_clickhouse_
artifacts.sql (fixture-dir pattern of tests/migrations-leases; nothing
added to internal/store/postgres/migrations), applied through the
pg-store-02 MigrationRunner.

Validation: go test -count=1 -race ./internal/dataframe/execution/
chartifact/postgres/ (16 tests, 0 skips) against real PostgreSQL 18 via
LOOM_TEST_POSTGRES_URL with per-test pgprivcat01_it_* isolated databases,
literal-row direct-SQL witnesses, two-backend one-winner race proofs, and
TestZZ ownership-scoped zero-leftover sweep; go test -count=1 for
./internal/dataframe/execution/chartifact/ and .../arango/ (live Arango
lane CI-gated); scripts/package_audit.py regen + scripts/tests (48 green,
jq from ~/.local/bin on PATH); gofmt/vet clean. ClickHouse live lanes
have no sandbox service and are covered by CI go-clickhouse/go-arango.

* fix(postgres): gate Create timestamps and migration-checked blanks in the chartifact catalog [pg-private-clickhouse-artifact-catalog-v1]

Create wrote manifests that decodeManifest later refuses: a zero
LeaseUntil/CreatedAt/UpdatedAt stored a year-one timestamptz whose payload
decode fails, so the row poisoned its whole stable ListExpired page,
ClaimCleanup errored on it, and no Reconcile pass could move or repair it.
validateCreate now applies validateUpdate's timestamp gate at creation and
refuses blank/untrimmed physical table and lease owner and blank identity
columns (mirroring the migration CHECKs) as catalog validation errors
instead of raw SQLSTATE 23514.

Regression test TestCreateRefusesRowsItCouldNeverReadBack covers all 14
shapes: refusal before any statement (no PgError surfaces), clean
validation error, and requireNoRow witness. Proven against the pre-fix
code: with the timestamp gate disabled the test fails on zero lease until.
Package suite 17/17, 0 skips, -race clean; chartifact trees green.

* docs(audit): refresh package audit snapshot for the Create-gate fix [pg-private-clickhouse-artifact-catalog-v1]

Canonical python3 scripts/package_audit.py regeneration at 35abebb: the
fix commit grew internal/dataframe/execution/chartifact/postgres
(LOC 490 to 531, test LOC 1559 to 1606, migration 4 to 6) without
refreshing the generated snapshot. Docs-only follow-up; scope files are
byte-identical to 35abebb.
…ure lane (#77)

Adds an additive package-list entry to the opt-in PostgreSQL 18 fixture
runner: after the pg-store-01 phase, the whole dataset PG package runs
with no -run filter against the same owned service propagation, so
checkGoEvents' zero-skip assertion makes every PG-gated case in the
package mandatory -- permanently guarding the merged pg-store-03 suite
and, once #76 lands, the project-release CAS suite too. Anchored on
TestManifestLifecyclePersistsLiteralRows, TestActivateCompareAndSwap
AgainstPointerValue and TestConcurrentActivationsSameExpectedYield
OneWinner; evidence records datasetIntegration with anchors and passes
and is credential-scrubbed like the existing lane.

No database administration moves into the phase: the run's owned
pgfixture namespace lifecycle is unchanged and the suites keep owning
their isolated *_it_* databases (their TestZZ audits run inside the
lane).

Validation (live PG18, credential-scrubbed service URL via
LOOM_TEST_POSTGRES_URL):
- full runner run on the base suite: status passed, all five phases,
  14 dataset passes including every anchor, owned namespace dropped,
  zero leftovers, exit 0.
- negative controls on the live service: a forced t.Skip fails the run
  with 'Unexpected skipped case' and a forced failure fails it with
  'real-PG suite failed', both with namespace cleanup intact and exit 1.
- post-merge simulation against the release-store branch head: the lane
  runs all 27 dataset tests (manifest + release suites), status passed,
  zero leftovers.
- node --test scripts/run-postgres-integration.test.mjs: 23 pass, 0 fail
  (4 new lane tests); python3 -m unittest discover -s scripts/tests: OK.

Requested by the coordinator as a separate PR from pg-publication-
project-release-cas-v1 (PR #76) because the runner is shared multi-lane
infrastructure.
…greSQL 18 (pg-catalog-01) (#75)

* feat(catalog/postgres): persist bounded field-profile records in PostgreSQL 18

Ticket pg-catalog-01-field-profile-records (batch c4b53e23b9d190fe).

Adds migration 000006_field_profile.sql (fhir_field_profile +
fhir_field_profile_coverage; PK on full identity
(project, dataset_generation, auth_resource_path, resource_type, path)
COLLATE "C"; profile_status row at path=''; nullable boolean
enrichment_complete; text[] for distinct values/pivots; jsonb for
extension_values/semantic_observations), a bounded pgx repository
(UpsertFieldProfileBatch in one tx with coverage markers, scoped reads),
and the catalog adapter (WriteFieldProfile/ReadFieldProfile/
DiscoverFieldEnrichment with typed errors and fail-closed coverage).

jsonb round-trip preserves nil vs empty-but-non-nil slices so
read-back records DeepEqual the profiler Documents() output.

Validation: go test ./internal/catalog/postgres -count=1 (PG18, real
store, pgcat01_it_* fixtures, TestZZ ownership-scoped zero-leftover
audit) ok; go test ./internal/store/postgres -count=1 ok (checksum pin
6 added to migrate_test.go); go test ./internal/catalog/... -count=1
ok incl. four profiler tests (check-1); go build + go vet clean;
gofmt clean; python3 scripts/package_audit.py regenerated
docs/PACKAGE_AUDIT.{csv,md}; scripts/tests 48 unittests OK.

* fix(catalog/postgres): renumber field-profile migration to 000007 with DDL contract tests

Coordinator veto: 000006 is reserved for pg-catalog-04's
semantic_inventory_build; approved number is 000007 (merge order:
catalog-04's 000006 lands first; the runner enforces ascending order
and tolerates the gap).

Also resolves the base-sync conflict (docs regenerated from the
canonical script after rebasing onto origin/feature/postgres-backend
@ c6e16dd).

Coordinator conditions:
1. migrate_test checksum pins extended; version 7 entry carries the
   independently computed sha256sum (244aaf6d...0c6f, byte-identical
   content to the vetoed file).
2. New live-PG18 tests: full-history double apply with direct
   re-execution of the 000007 DDL plus runner re-apply, witnessed by
   schema fingerprint (columns/constraints/indexes), MigrateResult, and
   ledger (version 7 exactly once); negative tests proving every CHECK
   and both primary keys refuse violations by SQLSTATE and constraint
   name with unchanged row counts, plus a pg_constraint catalog witness
   for all 12 constraints (record_type_known shares a violation report
   with the entailed record_shape CHECK).
3. Non-vacuous encoding witnesses: NULL vs '{}' vs populated for each
   text[] column and NULL vs '[]' vs populated for each jsonb column are
   inserted as all three encodings, witnessed distinct in the database
   and read back through the real repository; each witness is re-run
   against a hand-collapsed variant (encoder writing '{}' / '[]' for
   missing, decoder normalizing len 0 to nil) and must fail there. The
   coverage marker witness distinguishes never-profiled from known-empty
   at identical zero profile rows and fails when the marker is removed.

Validation: go test ./internal/store/postgres -count=1 ok (PG18, incl.
new DDL tests); go test ./internal/catalog/... -count=1 ok; go build
and go vet clean; package_audit regenerated; scripts/tests OK.

* docs(store/postgres): record 000007 versioning rationale and 000006 merge dependency

Review thread PRRT_kwDOS-yV5s61LR4p: the migration header now documents
why the file is 000007 (000006 reserved for pg-catalog-04
semantic_inventory_build; gap tolerated by the runner) and the hard
ordering dependency (MigrationRunner.pending() refuses a pending version
below the highest recorded one, so once 000007 is applied to a database
000006 can never be applied there: 000006 must merge and be applied to
every database before 000007 reaches any database).

Header-only SQL change; checksum pin 7 updated to the independently
computed sha256sum cafc8f6c...e6ad (documented edit gate).

Validation: go test ./internal/store/postgres -count=1 ok (PG18, incl.
bootstrap checksum + double-apply tests); go test
./internal/catalog/postgres -count=1 ok; go vet + gofmt clean.

* fix(store/postgres): name field-profile repository in package responsibility; correct header NOT NULL claim

Review threads PRRT_kwDOS-yV5s61LR4z and PRRT_kwDOS-yV5s61LR47:
- scripts/package_audit.py: the internal/store/postgres RESPONSIBILITIES
  sentence now enumerates the new scoped bounded field-profile record
  persistence alongside pool, migration runner, resource, and edge
  repositories; docs/PACKAGE_AUDIT.{csv,md} regenerated with the
  canonical generator (diff confined to that row).
- migration 000007 header: the fidelity rule claimed optional text
  columns are NOT NULL DEFAULT ''; no DEFAULT clause exists (only
  coverage.updated_at has one). The comment now states the contract
  truthfully: NOT NULL with no DEFAULT, the repository supplies all 26
  values, and a direct SQL writer omitting a column gets a NOT NULL
  violation. Comment-only change; checksum pin 7 rotated to the
  independently computed sha256sum 012f0f3b...2746b.

Validation: go test ./internal/store/postgres -count=1 ok (PG18, incl.
bootstrap-checksum and fingerprinted double-apply against the new
bytes); go test ./internal/catalog/postgres -count=1 ok; vet + gofmt
clean; scripts/package_audit_verify.py green for both locations.

* docs(store/postgres): record the 000006 reservation as delivered post-#73

Review thread PRRT_kwDOS-yV5s61L5yE: after #73 (eafbf05) merged
000006_semantic_inventory_build.sql, two Versioning sentences were
false on this branch. The header now records the reservation as
delivered -- the embedded history is the contiguous chain 1..7 -- while
keeping the runner-contract rationale in past tense (pending() refuses
a pending version below the highest recorded one; once 000007 is
applied, 000006 can never be, so the queue sequenced catalog-04 first
and a gap-window database would have lost 000006 permanently).

Comment-only SQL change; checksum pin 7 rotated to the independently
computed sha256sum 20224511...e41a (documented edit gate). Fingerprint
and ledger witnesses are history-shape independent.

Validation: go test ./internal/store/postgres -count=1 ok (PG18, incl.
bootstrap-checksum, ascending 1-7 apply, double-apply fingerprint);
go test ./internal/catalog/postgres -count=1 ok; vet + gofmt clean.
…release CAS (pg-publication-project-release-cas-v1) (#76)

* feat(postgres): persist immutable project release candidates and CAS active release state (pg-publication-project-release-cas-v1)

Add ReleaseStore in internal/dataset/postgres over two new tables
(package-local fixture internal/dataset/postgres/testdata/
migrations-releases/000008_project_release.sql, applied through the
real pg-store-02 runner; shared migration numbers 000006/000007 stay
untouched):

- project_release: content-addressed immutable candidates keyed on
  (project, id). Same-content retry (createdAt excluded) is accepted
  and returns the stored document; changed contents conflict with the
  typed ErrReleaseContentConflict. No statement updates candidate
  rows, so lost races keep history retained for audit.
- active_project_release: one-row-per-project pointer with the CAS
  revision; FK to the candidate makes 'the pointer names a persisted
  candidate' a schema invariant. Missing row means no active release;
  no placeholder, no SQL NULL stand-in.
- CompareAndSwapActivateRelease runs candidate verification, the
  generation-owner participation, pointer comparison, and the pointer
  write in one transaction: expected-revision CAS has exactly one
  winner (stale activations change no pointer), and the already-active
  candidate is the F-B15 zero-write, revision-stable no-op whose
  precedence over the expected revision matches the Arango baseline's
  'currentRevision == expected OR alreadyActive' predicate.
- GenerationOwnerAdapter lets the pg-store-03 generation owner
  participate in the activation's own pgx.Tx with no duplicated
  schema; the default adapter enforces the baseline activation filters
  (persisted STAGED/READY manifest, existing active-generation pointer)
  and a hook fault rolls the pointer write back atomically.
- Backend-tagged ordered-parameter commands throughout; missing,
  JSON-null, and SQL-NULL stay distinct; no silent fallback
  (unmigrated schema surfaces 42P01, never a typed conflict).

ClickHouse publication row store and Arango/AQL stay untouched.

Validation (real PG18, LOOM_TEST_POSTGRES_URL; never printed):
- go test -count=1 ./internal/dataset/postgres/ -- 27 PASS, 0 SKIP,
  incl. two-real-connection proofs (distinct pg_backend_pid writer
  A/B + third witness backend), literal rows + direct-SQL witnesses,
  concurrent one-winner schedule, already-active zero-write ctid/
  updated_at stability, commit-fault and adapter-fault rollbacks,
  schema-constraint negatives, TestZZ zero-leftover ownership-scoped
  to pgpubrel01_it_* only.
- check-1 Arango trio: TestReleaseActivationAtomicallyUpdatesRelease
  AndGenerationPointers|TestSaveReleasePersistsCandidateWithoutMoving
  Visibility|TestReleaseActivationEmptyCASResultIsConflict -count=1
  PASS (existing baseline, code unchanged).
- go test -count=1 ./internal/dataset/... and
  ./internal/store/postgres ./internal/dataframe/publication/postgres
  PASS; go build ./... + go vet clean.

* docs: regenerate package audit for the project release responsibility

Update the curated internal/dataset/postgres RESPONSIBILITIES sentence in
scripts/package_audit.py to cover the immutable project release candidates
and the active-release compare-and-swap pointer, then regenerate the
canonical docs/PACKAGE_AUDIT.csv and docs/PACKAGE_AUDIT.md with
python3 scripts/package_audit.py only (docs-only regeneration, final
commit on the branch).

Validation: python3 -m unittest discover -s scripts/tests -- 48 tests OK
(jq from ~/.local/bin on PATH); python3 -m unittest
scripts.tests.test_package_audit -- 5 tests OK; generator reports
'wrote 83 packages' with no responsibility-map mismatch.

* test(postgres): state the CI skip wiring honestly in the release suite header

Review finding (PR #76): the header claimed the CI runner fails on skips,
which is not true as wired -- the go-unit lane runs ./internal/dataset/
postgres without LOOM_TEST_POSTGRES_URL (PG-gated tests skip green), and
the pg-fixture job pins its Go phase to the pg-store-01 suite in
./internal/store/postgres only. The header now says so explicitly and
points at the attached live PG18 acceptance evidence; extending the
owned-namespace runner to cover this package is a shared-infra change
held for the coordinator.

No behavior change. Re-validated: go vet clean; live PG18
go test -count=1 -v ./internal/dataset/postgres/ -> exit 0, 27 PASS,
0 SKIP, 0 FAIL (log attached to the PR evidence comment).
…ersion/digest CAS and exact preimage history [pg-state-explorer-draft-cas-v1] (#78)

SaveDraft on the PostgreSQL Explorer control plane now mirrors the Arango
adapter's atomicity: one transaction reads the owner under the expected
version/digest guard, appends the exact immutable preimage to
explorers_draft_revisions (new migration 000003 in this package's own
history; store migrations 1-6 untouched, 7-8 reserved), and applies the
winner CAS exactly once, linking previous_draft_revision_id and preserving
active_revision_id/management_mode. Same-version/digest races have one
winner: the loser maps to explorer.ErrDraftConflict retaining the real
23505 *pgconn.PgError cause. Post-insert faults and takeovers roll both
rows back. GetDraftRevision scopes opaque ids to project+Explorer with a
concealed not-found. No mocks: real PG18 fixtures (pgstate01_it_*),
literal-row direct-SQL witnesses, two-real-connection distinct
pg_backend_pid proofs for single-winner, stale-reject, and revision
monotonicity, and an ownership-scoped TestZZ zero-leftover audit.

Validation: go test -count=1 -run '^TestDraftCAS' (10/10) and full
-package (22/22, incl. TestZZ) on PG 18.6; Arango draft baselines
(check-1) pass offline; check-2's four integration tests remain
service-gated skips (no LOOM_TEST_ARANGO_URL provisioned for this
batch), matching the brief's NOT RUN baseline evidence; package_audit
responsibility updated and docs/PACKAGE_AUDIT.{csv,md} regenerated;
go build ./... and go vet clean.
…d edge rows (pg-store-06) (#79)

* feat(postgres): bounded, idempotent COPY batch writer for resource and edge rows (pg-store-06)

BatchWriter publishes one bounded batch of resource and edge rows with
PostgreSQL COPY into transaction-local (ON COMMIT DROP) staging and
atomically publishes into fhir_resource/fhir_edge_occurrence inside a
single transaction, alongside its batch_write_ledger marker (new
migration 000008, claimed before staging so marker and rows commit or
roll back together).

Guarantees and proofs (real PG18, no mocks):
- (batch_id, digest) fingerprint: identical committed replay is a
  no-op returning the ledger's exact commit accounting; identity reuse
  with a different digest is a typed BatchIdentityConflictError. The
  replay and claim races run on two real connections with distinct
  pg_backend_pid (leases precedent), including a blocked-on-claim race
  witnessed via pg_stat_activity and an abandoned-claim takeover.
- Natural resource identity / edge occurrence identity duplicates with
  different content (in-batch or against stored rows) are typed
  conflicts and roll back the whole batch, preserving the prior row;
  content-identical duplicates collapse or skip idempotently.
- Edge source preconditions hold batch-wide (the batch's own resources
  publish first in the same transaction); a missing source is the
  typed EdgeSourceMissingError and writes nothing.
- Injected failure at every pre-commit step leaves no rows and no
  marker (failHook seam); control runs prove the witnesses non-vacuous,
  plus a tampered-ledger-digest mutation probe that makes a broken
  digest guard fail the suite.
- Committed counts (result + ledger) equal rows actually published;
  any guard/publish divergence aborts via typed BatchAccountingError.
- No shared state or process-wide mutex: concurrent batches for
  separate generations overlap at the publish step on distinct
  backends (rendezvous probe proof).
- Migration 000008 pin added to wantEmbeddedChecksums and
  self-verified against the sha256 of the file's exact bytes; runner
  double-apply + lost-ledger-row crash-window convergence probe
  included. TestZZ audit is ownership-scoped (pgstore06_it_*).

Verification: go test ./internal/store/postgres -run BatchWriter
-count=1 (and -count=3) green on PG 18.0006; full package suite green;
check-1 ingest tests and offline ./internal/ingest -count=1 green;
package_audit_verify bracket green; scripts/tests 48 tests OK;
PACKAGE_AUDIT regenerated (jq served from ~/.local/bin, disclosed).

* fix(postgres): ledger committed_at is the finalize stamp, not the claim-time snapshot (pg-store-06 review)

The 000008 header claimed committed_at records the marker transaction's
commit, but now() returns the transaction snapshot time and the marker is
claimed early in the batch transaction, so the column held the claim
(transaction start), not the finalize moment.

- finalize-ledger now stamps committed_at = clock_timestamp() together
  with the committed counts, and the header comment states exactly what
  the column records (in-transaction finalize wall clock; true commit
  time is unknowable from inside the transaction, and the marker lands
  in-transaction for all-or-nothing rows+marker semantics; DEFAULT now()
  only covers hand-seeded rows).
- New golden-test witness: inside the batch transaction at
  stepFinalizeLedger, capture now() (transaction snapshot) and assert the
  ledger's committed_at is strictly after it; removing the stamp makes
  the two exactly equal and fails the test (mutation-proven).
- Migration sha256 re-pinned (self-verified pin gate).

* test(postgres): never t.Fatalf inside batch-writer race probes (pg-store-06 review)

writer1.inTxProbe in the concurrent-claim race runs on the goroutine that
called WriteBatch, so a t.Fatalf (via s.fail) on a failed pg_backend_pid
query Goexit-ed that goroutine; r1 never received and the main test
goroutine blocked forever, surfacing as a package timeout with no
diagnostic. The probe now records its outcome under t1PIDMu and the main
goroutine fails after the r1/r2 handoff, mirroring the golden test's
probeErrs and the overlap test's stalled flag. The backend-distinctness
assertion moved after the handoff so no main-goroutine fatal can strand
T1 on the release rendezvous. Both claim rendezvous waits also gain a
select fallback that reports an early writer death from the channel
instead of blocking. Mutation-proven: breaking the probe query fails
fast with a main-goroutine diagnostic instead of hanging.

PACKAGE_AUDIT regenerated (test LOC).
… receipts (pg-state-immutable-capability-receipts-v1) (#81)

* feat(explorer/postgres): persist immutable capability snapshots + table-shape receipts (pg-state-immutable-capability-receipts-v1)

Persist capability snapshots and table-shape capability receipts (catalog,
category-scan, resolution) as create-once, fully-bound PostgreSQL 18
artifacts in the Explorer control-plane schema, alongside the owner history:

- internal/explorer/postgres/capabilities.go: CapabilitySnapshotStore
  (capability.Repository) and TableShapeCapabilityStore
  (tableshapecap.Repository) -- insert-once via ON CONFLICT DO NOTHING with
  typed collision resolution, full-binding SQL reads (no cross-project,
  cross-output, cross-snapshot, or cross-parent access), persisted-parent
  revalidation for children, read-side strict decode + mirror-column
  verification (ErrStoreInconsistency, never silent), Arango-parity error
  taxonomy, single-acquire-per-operation (MaxConns=1 safe), no update path.
- tests/migrations-capabilities/000004_capability_artifacts.sql: own-dir
  fixture composed with OwnerMigrations() through the real pg-store runner;
  named CHECKs, binding/parent indexes, and BEFORE UPDATE OR DELETE triggers
  raising SQLSTATE 45501 so immutability is database-enforced, not advisory.
- capabilities_test.go: 12 live-PG18 tests on isolated pgstate03_it_*
  databases with three distinct single-connection backends -- idempotent
  same-key puts, changed-content collisions, cross-binding refusals, exact
  nested parent/read-back with canonical tokens, concurrent same-key
  convergence, direct-SQL constraint negative matrix with legal controls,
  fail-closed 42P01 on unmigrated schemas, guard-drop probes proving the
  triggers non-vacuous, and an ownership-scoped zero-leftovers TestZZ.

Verification: go test -count=1 ./internal/explorer/postgres/ (22 tests, 0
skips, PG18 server_version_num 180006); offline Arango parity regressions
go test -count=1 -run '^TestCapabilitySnapshotStore' and
'-run '^TestTableShapeCapabilityRepository' ./internal/explorer/arango/;
go build ./...; go vet; gofmt clean; scripts/tests 48 tests OK; canonical
package audit regenerated after the final content edit (RESPONSIBILITIES
extended for internal/explorer/postgres).

* fix(explorer/postgres): align GetByIdentity SQL filter with its mirror check (AO review on 4e85103)

Required change: getIdent filtered 12 identity columns while the post-read
check compared all 13, so a healthy READY sibling differing only on
shape_digest could surface as a misleading ErrStoreInconsistency. The SQL
filter now binds shape_digest as placeholder 13: shape-mismatched rows are
a typed capability.ErrNotFound miss, and a returned row's mirrors are
guaranteed to equal the request -- so the payload-vs-mirror check only
fires on genuine inconsistency. Documented divergence from the Arango AQL
filter (which omits shape_digest); never returns the wrong sibling.

Regression evidence: pre-fix, the extended identity matrix failed with
exactly the misleading corruption error on the shapeDigest mutation and
the two READY shape-digest siblings; post-fix all pass. Extended
TestCapabilitySnapshotIdentityRetrievalIsFullyScoped: shapeDigest added to
the mutation matrix, two READY siblings differing only on shape_digest
each return exactly their own token, ghost shape digest is a typed miss.

Also applied the review's optional comment fixes: bindingColumnFilterFrom
and the store field comments now say 12 binding columns with the correct
placeholder ranges; bindingArgs/lookupArgs document the DraftVersion
int64-cast bound.

Verification: live PG18 package 34 tests, 0 skips (exit 0); vet/gofmt
clean; arango sources untouched (parity evidence unchanged).

* test(explorer/postgres): derive ledger and schema-composition expectations from the applied history

Coordinator mandate: prove the permanent merged state, not just today's
base. NewMigrationRunner sorts the merged history (migrate.go:385) onto
ONE per-schema ledger (LedgerTable=schema_migrations, migrate.go:69;
ledgerFQN per schema), so composing owner [1,2,3,5,6] with this ticket's
own-dir fixture [4] converges to [1,2,3,4,5,6]. Evidence run on a clean
database composed OwnerMigrations() + session 53's real 000005/000006
files + tests/migrations-capabilities/000004 through the real runner:
latest=6, applied=[1,2,3,4,5,6], no OutOfOrderMigrationError. Fixture
number 000004 stays.

Harness changes so the post-53 tree stays green with the same guarantees:
ledger expectation is the sorted union of owner rows + fixture (no
hardcoded LatestVersion==4); schema-composition expectation is derived
from the applied migrations' own CREATE TABLE DDL (comments stripped)
plus the runner's schema_migrations, so future owner tables cannot break
or silently pass the leak check.

Verification: live PG18 package green, 0 skips; vet/gofmt clean.
…ture lane (#82)

Adds an additive package-list entry to the opt-in PostgreSQL 18 fixture
runner, mirroring the accepted dataset lane: after the dataset-integration
phase, the whole Explorer PG package runs with no -run filter against the
same owned-service propagation, so checkGoEvents' zero-skip assertion makes
every PG-gated case in the package mandatory -- permanently guarding the
merged Explorer-owner store and draft CAS suites, which until now only ever
ran in authors' local sessions. Anchored on
TestDraftCASConcurrentSameVersionWritesHaveOneWinnerTwoConnections,
TestDraftCASStoresExactPreimageAndPreservesPublishedHead and
TestPostgresExplorerOwnerCreateGetRoundTripLiteralRows; evidence records
explorerIntegration with anchors and passes and is credential-scrubbed like
the existing lanes.

No database administration moves into the phase: the run's owned
pgfixture_* namespace lifecycle is unchanged and the suites keep owning
their isolated *_it_* databases (their TestZZ audits run inside the lane).

Validation (live PG18, credential-scrubbed service URL):
- full runner run: status passed, all six phases, 22 explorer passes
  including every anchor, owned namespace dropped, zero leftovers, exit 0.
- forced failure inside a real-PG explorer test reddens the lane with
  'internal/explorer/postgres real-PG suite failed', no pass evidence,
  namespace cleanup intact, exit 1.
- forced t.Skip fails the run with 'Unexpected skipped case', cleanup
  intact, exit 1.
- node --test scripts/run-postgres-integration.test.mjs: 26 pass, 0 fail
  (3 new lane tests); python3 -m unittest discover -s scripts/tests: OK.
- PACKAGE_AUDIT regenerated: no diff (mjs changes do not feed the Go audit).

Flagged by the reviewer on #81; requested and greenlit by the coordinator
as a separate additive PR after pg-store-06 (#79) merged at 9b2d77a.
…visions on PostgreSQL 18 (pg-state-receipt-revision-immutable-v1) (#80)

* feat(explorer/postgres): persist compilation receipts and immutable Explorer revisions in PostgreSQL 18 (pg-state-receipt-revision-immutable-v1)

Adds the PostgreSQL 18 counterpart of the Arango Explorer receipt and
revision stores on the shared pg-store pool and migration runner:

- 000003_compilation_receipt.sql: insert-once receipts with a frozen-row
  trigger (SQLSTATE 23514) and CHECK-enforced identity columns.
- 000004_explorer_revision.sql: revisions with a content-frozen column
  guard and a monotone status state machine (READY->ACTIVE/FAILED,
  ACTIVE->SUPERSEDED/FAILED, no-op idempotency), both DB-enforced.
- receipts.go: InsertCompilationReceipt validates the full contract,
  writes ON CONFLICT DO NOTHING, and on conflict rereads under FOR UPDATE
  on a claim connection, returning idempotently on byte-equal canonical
  content and ErrCorruptReceipt on content-addressed ID reuse; bounded
  claim-retry against uncommitted winners; tenant-scoped reads decode
  fail-closed to ErrCorruptReceipt.
- revisions.go: InsertRevision refuses same-ID different-content via the
  Go/DB content-digest comparison (ErrImmutableRevision); FailRevision /
  FailRevisionFrom implement compare-and-swap lifecycle transitions with
  ErrStaleRevisionTransition on token miss or terminal-status tokens;
  frozen scalars never mutate after write.
- explorers.go: Store gains the receipt/revision statement sets and
  sanitized schema/table references for every statement.

Live PostgreSQL 18 (18.6) evidence: go test -count=1 ./internal/explorer/
postgres runs 36 tests with zero skips against real PG18 -- literal rows,
direct-SQL witnesses, two-real-connection (distinct pg_backend_pid) CAS
and claim races, DROP-TRIGGER/restore non-vacuity probes rerunning the
migration text under the runner's SET LOCAL search_path, terminal-status
token refusals, and an ownership-scoped TestZZ zero-leftover audit of the
pgstate02_it_* namespace. Offline suite passes with the live cases gated.
Arango baseline check-1 unaffected; ClickHouse untouched.

Ticket: pg-state-receipt-revision-immutable-v1

* refactor(explorer/postgres): renumber state migrations to 000005/000006 for the shared Explorer control-plane ledger

Coordinator ordering (session loom-experiment-2): the Explorer control-plane
ledger is one version space across sibling tickets. Version 000003 is taken
by PR #78's drafts migration and 000004 is allocated to session 54's
tests/migrations-capabilities/000004_capability_artifacts.sql. Append-only
renumber on this branch's history:

- migrations/000003_compilation_receipt.sql -> 000005_explorer_compilation_receipt.sql
- migrations/000004_explorer_revision.sql  -> 000006_explorer_revision.sql

SQL bodies unchanged (checksum pins hold), so the applied history is now
versions 1, 2, 5, 6; the LoadMigrations duplicate-version/name rejection and
ascending order still hold once #78 (000003) and 54 (000004) merge -- this
PR merges after both per the coordinator's ascending-version gate. Version
pins updated in one place each (filename-derived; test literal pins and
rerunMigration arguments renumbered in-place).

Verification on the merged tree at this commit: go vet clean; live
PostgreSQL 18.6 go test -count=1 -v ./internal/explorer/postgres/ = 36
tests, zero skips, exit 0, including the double-apply
TestPostgresExplorerStateMigrationsRerunConverges (identical 4-row ledger
ending at version 6 on rerun), MigrateRerunPreservesState, the
000005/000006 frozen-guard non-vacuity probes (rerunMigration under the
runner's SET LOCAL search_path), and the TestZZ zero-leftover audit.

Ticket: pg-state-receipt-revision-immutable-v1

* fix(explorer/postgres): make revisionContentDigest decide the Arango equality it documents (pg-state-receipt-revision-immutable-v1 review)

Reviewer finding (thread PRRT_kwDOS-yV5s61M9L9): the digest claimed parity
with the Arango adapter's immutable-content equality but diverged in both
directions.

1. QualityReports: the adapter compares after publication.CloneQualityReports
   (internal/explorer/arango/revisions.go), and CloneQualityReports(nil)
   returns a non-nil empty slice, so Arango replays a nil-vs-empty replay
   idempotently. The digest's append-preserve kept them distinct and the
   store refused with ErrImmutableRevision where Arango succeeds. Now
   normalized through publication.CloneQualityReports itself -- the
   adapter's own pre-comparison normalization, single source of truth.
2. Config/AuthoringBundle/PublicOutputContract: json.Marshal renders nil,
   empty, and the four bytes null all as JSON null, so the digest collided
   three classes the Arango document round-trip separates (omitempty drops
   nil and empty; explicit null survives and reflect.DeepEqual keeps it
   apart). A nil-vs-null replay was silently idempotent here while Arango
   refuses ErrImmutableRevision, and it contradicted this package's own
   lossless missing/JSON-null/document storage tri-state. Now each raw
   payload enters the digest through digestableRaw: {nil, empty} -> missing,
   compacted "null" -> null class, everything else -> document with
   raw-byte (compact-normalized, key-order-significant) identity; the class
   tag can never collide with a document because document bytes sit under
   the value key.

TestPostgresRevisionContentDigestBoundaries now pins both boundaries (nil-
vs-empty quality reports must NOT move the digest -- contrasting the still-
distinct Materializations/EmittedColumns nil-vs-empty which Arango's
append(nil) copies keep apart -- and the raw tri-state classes move/hold
exactly as Arango decides). New live TestPostgresRevisionTriStateArangoParity-
Replay drives it through the store: stored explicit-null refuses a missing
replay with ErrImmutableRevision leaving the row byte-identical (direct-SQL
row witness), while byte-exact null, nil-vs-empty quality reports, and
empty-RawMessage replays return the first stored row idempotently.

Evidence: live PostgreSQL 18.6 go test -count=1 -v ./internal/explorer/
postgres/ = 37 tests, zero skips, exit 0 at this commit; check-1 Arango
baseline 5 pass; build/vet clean; package_audit canonical regen + verify.

Ticket: pg-state-receipt-revision-immutable-v1

* fix(explorer/postgres): make the revision guard enforce insert-once against DELETE (pg-state-receipt-revision-immutable-v1 review)

Reviewer finding (thread PRRT_kwDOS-yV5s61M9MF): loom_explorer_revision_guard
fired on UPDATE only, so a direct-SQL DELETE + re-INSERT replaced a revision
with different frozen content without firing any trigger -- the content-
digest comparison lived only in Go and the frozen-column checks never run
for a freshly inserted row, while the header promised DB enforcement
independent of Go. The sibling receipt migration already set the bar
(BEFORE UPDATE OR DELETE).

- 000006_explorer_revision.sql: trigger is now BEFORE UPDATE OR DELETE;
  the function raises a distinct insert-once message for TG_OP = 'DELETE'
  before touching NEW (NULL in a BEFORE DELETE row trigger, so the no-op
  shortcut and frozen comparisons cannot be relied on there). Checksum
  pin in TestPostgresExplorerOwnerMigrationHistoryLoads updated in its
  single place.
- TestPostgresRevisionFrozenGuardProvenNonVacuous now probes DELETE three
  ways: refused with 23514 'insert-once' while live, succeeds after DROP
  TRIGGER with a direct-SQL witness that the row is gone (proving the
  vulnerability the guard closes), and refused again after rerunMigration
  restores the guard from the migration text.

No Go path deletes revisions (lifecycle terminates at SUPERSEDED) and
fixture cleanup is DROP SCHEMA CASCADE, which does not fire row triggers.

Evidence: live PostgreSQL 18.6 go test -count=1 -v ./internal/explorer/
postgres/ = 37 tests, zero skips, exit 0 at this commit; check-1 pass;
build/vet clean; package_audit canonical regen + verify.

Ticket: pg-state-receipt-revision-immutable-v1

* test(explorer/postgres): print the double-apply ledger witness [1 2 3 5 6] (pg-state-receipt-revision-immutable-v1)

The merged Explorer control-plane ledger convergence (migration history
versions 1, 2, 3, 5, 6 -- 3 from #78 verbatim, 5/6 this ticket's byte-
frozen files) is now witnessed literally in test output:
TestPostgresExplorerStateMigrationsRerunConverges logs the ledger rows
verified after the second migrate:

  double-apply ledger witness: [1/ledger 2/explorer_owner 3/explorer_draft_revision 5/explorer_compilation_receipt 6/explorer_revision]

All five checksum pins re-verified against the merged tree by file hash
(pins derived from the merged history, not copied from either side).
package_audit canonical regen + verify.

Evidence: live PostgreSQL 18.6 go test -count=1 -v ./internal/explorer/
postgres/ = 49 tests, zero skips, exit 0 at this commit.

Ticket: pg-state-receipt-revision-immutable-v1
…tions from the embed FS (#84)

TestPostgresExplorerStateMigrationsRerunConverges hard-coded len==6 and
LatestVersion==6 over internal/explorer/postgres/migrations/, an
open-ended embedded directory that the in-flight 000007/000008/000009
tickets will extend. Replace the fixed expectations with self-derived
ones (the session-54 capabilities-harness pattern): fs.WalkDir over the
embed FS enumerates the migration files to derive the expected ledger
count and latest version, combined with the #81-owned capability fixture
at version 4.

Strength is kept and extended:
- double-apply still converges once and every ledger row is stable;
  the rerun must now also leave applied_at byte-identical;
- per-file checksum pins remain explicit sha256 literals keyed by file
  name (1, 2, 3, 5, 6), and the suite FAILS on an embedded file without
  a pin (new migrations must be pinned deliberately) or a pin without a
  file -- a deliberate strengthening of the suite;
- the direct-SQL ledger witness, double-apply witness log, and
  fresh-pool state-survival reads are unchanged.

Validation (live PostgreSQL 18, LOOM_TEST_POSTGRES_URL):
- go test -count=1 ./internal/explorer/postgres: 65 run / 65 pass /
  0 skip / 0 fail; the target test witnesses ledger [1/ledger
  2/explorer_owner 3/explorer_draft_revision 4/capability_artifacts
  5/explorer_compilation_receipt 6/explorer_revision] -- 6/6-equivalent.
- Isolated-copy simulation: adding a throwaway 000010_selfderive_probe.sql
  (never committed) fails the suite demanding its pin; removing it
  restores green.
- scripts/tests: python3 -m unittest discover -s scripts/tests (48 OK)
  and scripts/tests/test_acceptance_real_cleanup.sh pass.
- docs/PACKAGE_AUDIT.{csv,md} regenerated by scripts/package_audit.py
  (derived line counts only; no packages added or removed).

Test-only change: no production files, no migrations.
…tgreSQL 18 (#86)

Registers one direct root scan of the agreed resource relation
(fhir_resource via the ir storage-binding registry) as a closed,
implemented PostgreSQL renderer operation: RenderRootScan accepts
exactly ROOT_SCAN(direct) -> RETURN(typed scope columns), re-reads the
explicit project/dataset_generation/auth binds, binds every plan datum
as an ordered typed $n parameter, and delegates to the single
ReadPhysicalPlan SQL builder in the same package. Everything else
(traversal, filters, sorts, limits, selector extraction,
population/cohort/candidate-seed roots, expression/presence projections)
fails closed with typed ErrUnsupportedPostgresPlan /
ErrInvalidPostgresPlanScope / ErrUnregisteredPostgresIdentifier and no
SQL; there is no AQL fallback and no AQL-to-SQL conversion.
Planner-facing command registration (CompiledCommandForBackend) stays
fail-closed until an execution slice registers an adapter; the pinned
TestPostgresParityFixture keeps that gate honest.

Evidence (real PostgreSQL 18 via LOOM_TEST_POSTGRES_URL; pgstore.Open
Ping-refuses non-18; fixtures own pgsq01_it_* databases/schemas and
migrate through the pg-store-02 runner whose NewMigrationRunner merges
and sorts sources, so no new migration files were needed):
- literal rows + ordered SQL args + direct-SQL witness for the selected
  project/generation/resource-type tuple; every decoy proven stored
- guard-drop probes: dropping project, generation, auth, or resource
  type admits exactly its decoy; non-vacuity proven per predicate
- named-constraint refusals: 23505/fhir_resource_natural_identity_ux,
  23514/fhir_resource_{project,resource_type,logical_id}_present;
  duplicate physical documents survive as distinct rows (constant-
  projection scan), store layer returns ErrResourceConflict
- stable resource identity: immutable resource_seq order, byte-stable
  across repeated executions
- TestZZNoLeftoverPgSQ01Resources: zero pgsq01_it_* leftovers (own
  prefix only, sibling-safe)
- 11 mutation probes (M1-M10, M4a/b) each flipped a named new test
- golden SQL literals pin the statement shape for pg-sql-02/03

Checks: go test ./internal/dataframe/compiler/ir, .../lower, .../render/aql,
.../render/postgres -count=1 (live + offline), compiler
-run ^TestPostgresParityFixture$ -count=1, full compiler package offline
-count=1 (Arango regressions unchanged: no AQL/ClickHouse files touched),
scripts/tests 48 green (jq from ~/.local/bin), package_audit.py regen
included; canonical regen is zero-delta at head.
…-addressed revisions on PG18 [pg-state-interpretation-library-v1] (#83)

* feat(explorer/postgres): immutable interpretation libraries + content-addressed revisions on PostgreSQL 18

Implements pg-state-interpretation-library-v1: InterpretationStore persists
project-scoped interpretation library heads over immutable revisions with
transactional digest and parent CAS.

- interpretation_libraries: head FK to a same-library revision; guard trigger
  refuses deletion, identity change, and non-advancing head writes (45501).
- interpretation_revisions: BEFORE UPDATE OR DELETE immutability trigger;
  composite parent FK to same-library revisions; root rows carry a NULL
  parent pair so the FK skips them; shape CHECKs on digest/id/authorship.
- CreateInterpretationRevision runs one transaction: parent digest lookup,
  ON CONFLICT DO NOTHING insert (bare clause: two unique indexes arbitrate
  the same-content race), collision classified by re-read + payload
  self-verification, root library insert or guarded head CAS advancing on
  expected head. Idempotent same-digest retry returns the stored row
  without touching the head.
- jsonb payload is authoritative; storage mirrors are re-verified on every
  read (ErrInterpretationIdentityMismatch fail-closed).
- Migration tests/migrations-interpretations/000007_interpretation_library.sql
  composed with OwnerMigrations(); ledger version 7 allocated by the
  coordinator for the Explorer control-plane schema (versions 1-6 owned:
  owner dir 1,2,3,5,6 + capabilities 4).

Verification: go test ./internal/explorer/postgres -count=1 against live
PG18 (all tests, zero skips); 10-round two-connection races with distinct
pg_backend_pid witnesses; guard-drop 45501 probes; named-constraint
negative matrix; fault-injection rollback + post-abort retry convergence;
golden sha256 content-digest/revision-id pins; eight mutation probes
(head CAS guard, parent-digest check, mirror cross-check, immutability
trigger, head FK, parent FK, preflight claim check, transaction rollback)
each proven red then restored; check-1 Arango baseline green; scripts
package-audit suite green (48 tests) with regenerated docs.

* docs(audit): regenerate package audit after post-merge test-file trim

Canonical regeneration against the final source: interpretations_test.go is
2,065 lines, so repo Test Go lines are 224,732 and the internal/explorer/
postgres row reads 3,242/9,223. Fixes the stale snapshot generated before
the duplicated ptr helper and its blank line were removed in the base
merge. Verified with scripts/package_audit_verify.py internal/explorer/
postgres.

* refactor(explorer/postgres): drop dead SQLSTATE constants, correct block comments

Review follow-up (discussion_r4512282309): interpretationImmutableSQLState
and interpretationUniqueViolation were referenced by neither production
code nor the suite (the fixture suite carries its own pgstate04_* state
codes), and the comment above them named duplicateKeySQLState (a drafts.go
identifier) and undefinedTableSQLState, which does not exist. Delete both
constants and rewrite the comments to describe only the identifiers that
remain, matching capabilities.go, which keeps only referenced identifiers.
Production still references interpretationForeignKey and
interpretationRevisionParentFKConstraint; guard trigger/function and
constraint names remain for the suite's guard-drop and negative-constraint
probes. No behavior change: go vet clean and the full live-PG18 package
suite passes at this head.

* docs(audit): regenerate after dead-constant trim

Canonical regeneration on every content commit: internal/explorer/postgres
production lines 3,242 -> 3,240 after deleting the two unreferenced
SQLSTATE constants; Test Go lines unchanged at 224,732.
…scoped idempotency key, expiring writer owner [pg-state-selection-revision-owner-v1] (#85)

* feat(explorer/postgres): persist staged selection revision identity, project-scoped idempotency key and expiring writer owner [pg-state-selection-revision-owner-v1]

Relational counterpart of internal/explorer/arango/selections.go on the
shared pg-store pool + pg-store-02 runner: BeginSelection (canonicalize,
validate, reclaim only expired staging leases, bind the project-scoped
idempotency key, reread identity after any arbiter skip, database-evaluated
lease boundary claim), AppendSelectionMembers (FOR UPDATE-serialized
insert-once staging + lease renewal, all-or-nothing batch),
DigestSelectionMembers (byte-order paged membership frames, frozen facts
for COMPLETE), CompleteSelection (staging CAS + reread classification),
AbortSelection (owner-conditional atomic removal, foreign-token no-op),
GetSelection (project-scoped, concealed missing), VisitSelectionMembers
(byte-order member-key walk), CleanupSelectionStaging (bounded atomic
pair removal with locked victims).

DDL: tests/migrations-selections/000008_selection_revisions.sql, composed
with the owner history onto the one shared per-schema ledger per the
tests/migrations-capabilities precedent (number 8 requested from the
coordinator; 5/6 owned by the receipt-revision sibling, 7 reserved).
Database-enforced: PK(id), partial UNIQUE (project, idempotency_key) for
non-empty keys, member PK + reference unique, named CHECKs, and BEFORE
UPDATE guard triggers (45501) for identity immutability, one-way
completion, and member content insert-once.

Evidence (live PG18, LOOM_TEST_POSTGRES_URL, pgstate05_it_* isolated
databases/schemas, TestZZ ownership-scoped zero-leftover):
go test -count=1 -run '^TestSelectionStorageAgainstPostgres$'
./internal/explorer/postgres/ (PASS) plus the full-package run; two-real-
connection distinct-pg_backend_pid races >=10 rounds per surface with
byte-identical row witnesses and post-abort convergence; guard-drop
non-vacuity probes with exact 45501 message and named-constraint
refusals; crash-window seam injections; 1001-row digest paging;
self-recomputed sha256 ledger pin; literal golden member keys and rows.
check-1 TestSelectionStorageAgainstArango runs offline (skips green
without LOOM_TEST_ARANGO_URL). scripts/tests: 48 unittest OK (jq present
at ~/.local/bin, not on PATH; no test required it).
package_audit.py RESPONSIBILITIES updated + canonical docs regenerated
(zero-delta on rerun).

* docs(explorer/postgres): cite coordinator ledger-8 allocation in selection fixture pins [pg-state-selection-revision-owner-v1]

Coordinator allocation note: Explorer control-plane ledger version 8, one
migration covering selection_revisions + selection_members (000004's
two-table precedent), own-dir composition accepted per the 000004
capability precedent; lands strictly after the 000007 reserved for the
capability-artifacts ticket. The store-dir ledger's own 000008
(internal/store/postgres/migrations/000008_batch_write_ledger.sql) is a
separate table in a separate dir over store schemas -- the shared number
is not a collision; cited in the SQL header and the test constant block.
Ledger expectations remain FS-self-derived (no literal counts;
revisions_test.go untouched per coordinator). Constant
pgstate05FixtureVersio -> pgstate05FixtureVersion. Checksum is
self-recomputed from disk bytes, so the header comment change is
checksum-neutral by construction; live-PG named check and full-package
run re-green after the edit.

* fix(explorer/postgres): VisitSelectionMembers visits one page per call, pinned against Arango parity [pg-state-selection-revision-owner-v1]

Review finding (PRRT_kwDOS-yV5s61PQHy): the walk carried an outer retry
loop that drained every page inside one call, diverging from
arango.VisitSelectionMembers (one page of at most pageSize members per
call) and from the lifecycle fake's enforced cap; callers depend on it --
readSelectionIntent gates NextCursor on len(members) == limit (a drain
returns the whole membership, up to DefaultSelectionMaxRows, with no
cursor) and appendSelectionRevision batches at selectionBatchSize (a
drain accumulates the entire membership into one unbounded append
transaction).

Drop the drain loop: one page, visit, return the last visited member key
(or the trimmed after when the page is empty), with the visit-error
cursor updated only by successful visits -- byte-for-byte Arango
semantics. Doc comment now states the per-call bound and cites the
dependents.

Walk tests extended to pin the bound (they terminated identically under
both semantics before): the two-member walk asserts each single call
visits at most pageSize and the empty page returns the cursor unchanged;
the 1001-member pageSize-7 walk asserts per-call visits <= 7, never an
advanced cursor without visits, and exactly memberCount/7+1 calls
(143 exact pages + terminal empty page). Under the old drain loop the
first call would visit 2 > 1 and 1001 > 7 and fail both. Live-PG named
check and full-package run re-green (3.063s).
…s in SQL (#88)

* feat(pg-sql-02): enforce project, generation, and authorization scope in root and edge SQL

Add render/postgres/scope.go as the package's single canonical scope module:
loadScope (typed re-read of @project, @dataset_generation,
@auth_resource_paths, @auth_resource_paths_unrestricted with zero defaulted
bindings and typed ErrInvalidPostgresPlanScope refusals before any parameter
is bound), scopedResourcePredicate (the root and reached-target row chain),
and a new named scopedEdgePredicate extracted from the inline edge chain in
renderTraversal — the canonical edge-row project/generation/auth mapping the
edge join and the dependent traversal slice (pg-sql-06) build on. render.go
delegates to these definitions; the mapping text is byte-identical to the
previously inlined predicates, so the existing statement goldens in
root_scan_test.go and render_test.go (unchanged) prove zero drift. No
root-scan SQL is re-derived; CompiledCommandForBackend stays fail-closed and
there is no AQL fallback anywhere.

The mapping mirrors the canonical contract ir.ValidateGenericPhysicalPlanScope
proves (project, dataset_generation, AUTH_RESOURCE_PATH_ALLOWED LET + equality
per root/edge/target row) and render/aql validateGenericNavigationScopeBlock.
Restricted mode binds the exact authorized path set as one JSONB array
parameter; deny-all (empty or nil restricted set) binds the JSON empty array
literally, so the ANY probe is false for every row and never widens;
unrestricted mode must be explicit and adds no auth predicate.

Tests (scope_test.go), asserted twice over:
- Offline golden predicate literals and value-identical ordered arguments for
  resource and edge mappings in restricted/unrestricted/deny-all modes;
  typed fail-closed refusals for every defective bind before binding
  anything; hostile scope values proven inert ($n data only); a wiring probe
  pinning the canonical edge and target fragments inside the assembled
  statement.
- Live real-PG18 fixtures (pgstore.Open Ping-verifies major 18; isolated
  pgsq02_it_* database + owned schema; migrations via the real pg-store-02
  runner over merged embedded sources, migrate.go:385; literal rows through
  the real pg-store-04/05 repositories; no mocks): the same resource ids in
  two projects and two generations return only the authorized tuple;
  restricted scope includes exactly the authorized paths on root rows, edge
  occurrences, and targets; deny-all yields zero rows through both the root
  and edge path with direct-SQL witnesses proving every excluded row stored;
  guard-drop probes admit exactly one decoy per dropped predicate (root and
  edge); named-constraint refusals (fhir_resource_natural_identity_ux,
  fhir_resource_project_present, fhir_edge_occurrence_identity_ux,
  fhir_edge_occurrence_project_present) prove the database arbitrates
  scope-column integrity; two distinct real connections (pg_backend_pid
  proven different) read identical literal rows.
  TestZZNoLeftoverPgSQ02Resources audits zero pgsq02_it_* leftovers, scoped
  to this ticket's prefix.

Mutation probes (each new test fails without its fix, verified by mutation
and revert): dropping the edge auth clause, removing the deny-all empty-array
normalization, accepting unrestricted+paths, defaulting a missing auth mode,
and skipping the canonical edge generation predicate in the renderer each
break their golden, refusal, or live fixture.

Verification: go test -count=1 green for compiler/ir (41), compiler/lower
(178), compiler/render/aql (64, offline), compiler/render/postgres (53 live,
39+14-skip offline), TestPostgresParityFixture, scripts (go);
package_audit.py regen confined to the render/postgres row.

Ticket: pg-sql-02 (batch c4b53e23b9d190fe)

* fix(pg-sql-02): re-read scope_allowed as the fifth canonical bind

loadScope read four of the five canonical scope binds, so a plan with
scope_allowed=false - the repository-wide canonical deny (ir/scope.go
closing FILTER, ir/prefix.go fifth required key, whole_relation_scope_-
evidence and category_scan_related refuse non-true) - rendered the same
allowed-read SQL under PostgreSQL, and a missing bind was silently
accepted.

scope.go now re-reads scope_allowed with the same typed fail-closed
pattern before any parameter is bound: missing or mistyped refuses with
ErrInvalidPostgresPlanScope; false maps to a literal zero-row predicate -
root, edge, and reached-target chains each close with AND FALSE, mirroring
AQL's FILTER over @scope_allowed reading zero rows. The deny is a shape
fixed by the validated bind, never a parameter and never plan data in SQL
text; true renders the allowed shapes byte-identically to before.

scope_test.go: refusal matrix gains missing/non-bool probes; goldens pin
the deny conjunct for restricted, unrestricted, and deny-all composition
across resource and edge predicates; a wiring probe pins FALSE in all
three row sources of the assembled statements with byte-identical
arguments; a live PG18 fixture proves zero rows over root and edge paths
against a stored, control-readable route on two distinct server
connections.

Hand-written test plans (root_scan_test.go, render_test.go,
render_pg18_test.go, postgres_parity_fixture_test.go) mechanically bind
the canonical true: required presence makes plans lacking it defective
plans, and lower already emits it for every produced plan.

Mutation probes: removing the deny conjuncts breaks the goldens and the
live zero-row witness; removing the gate breaks the refusal matrix.
package_audit regen LAST; docs carry only regenerated line counts.

* chore(pg-sql-02): regenerate package audit after base merge
…finitions on PostgreSQL 18 (pg-state-explicit-group-definitions-v1) (#87)

* feat(explorer/postgres): explicit-group revision headers + ordered definitions on PostgreSQL 18 (pg-state-explicit-group-definitions-v1)

Adds ExplicitGroupStore to internal/explorer/postgres: staging
explicit-group revision headers with ordered definition rows under a
guarded writer-lease lifecycle (Begin idempotent claim, Put write-once
with post-read canonical verification, owner-only idempotent Abort,
FOR UPDATE SKIP LOCKED expired-cleanup, COMPLETE-gated public reads),
mirroring the Arango adapter's semantics on the shared pg-store pool
and migration runner.

Migration 000009_explorer_explicit_groups embeds:
- explorer_explicit_group_revisions / explorer_explicit_group_definitions
  with tenant identity, STAGING staging gate, and a DB-recomputed
  identity-binding CHECK matching ExplicitGroupRevisionIDFor's
  length-prefixed SHA-256 frame byte-for-byte (lpad uses an explicit
  '0' pad: PostgreSQL pads with spaces by default).
- Named trigger guards enforcing header freezing, writer-token
  authorization (SET LOCAL GUCs), forward-only lease renewal, and
  definition write-once/owner-teardown rules; the definition guard's
  parent lookup resolves via TG_TABLE_SCHEMA and gates on
  GET DIAGNOSTICS ROW_COUNT (FOUND is unreliable after
  EXECUTE ... INTO).

Evidence (live PG18, go native -timeout only):
- 16 TestPostgresExplicitGroupDefinitions* tests green including 4
  concurrent-race surfaces (>=10 rounds each: claim, identical put,
  conflicting put, cleanup vs active writer), fault-injection rollback,
  corruption detection, ledger convergence with self-recomputed
  checksum, guard-drop/restore proofs, and named CHECK/trigger/FK
  assertions (RESTRICT FK raises 23001 on PG18).
- TestZZNoLeftoverPgstate06Resources proves zero pgstate06_it_*
  leftovers per test. Full ./internal/explorer/postgres package green.
- Sibling migration-ledger pins in explorers_test.go / revisions_test.go
  mechanically extended for version 9 (count/name/checksum only) --
  required by embedding the migration; flagged for the coordinator's
  ledger ownership.
- scripts/package_audit.py responsibilities updated; CSV/MD regenerated
  (zero-delta confirmed); scripts audit tests 5/5 via
  python3 -m unittest scripts.tests.test_package_audit (jq at
  ~/.local/bin; rg absent from PATH).
- Offline check go test -count=1 ./internal/explorer/arango/ is
  skip-green (no Arango instance in this sandbox), recorded honestly.

* test(explorer/postgres): self-derive lineage-wide ledger expectations in the explicit-group suite and owner ledger tests (coordinator ruling)

Per the coordinator's ruling on pg-state-explicit-group-definitions-v1:
lineage-wide count/latest/version-list assertions over the open-ended
embedded migrations directory now derive from the directory itself
(pgstate02EnumerateEmbeddedMigrations: count = file count, latest = max
version, version list = parsed file names), so future owner-dir
migrations (000007, 000008, ...) never break these tests -- the exact
open-ended-directory defect the dedicated test-robustness wave fixes.

Deliberately still pinned (author duty over one's own artifact,
strengthen-only mechanical registry values):
- pgstate06MigrationVersion/Name/Checksum in explicit_groups_test.go
  (this ticket's own slot),
- pgstate02EmbeddedMigrationPins per-file map (revisions_test.go, the
  #84 convention; fail-on-unpinned),
- the explorers_test.go checksum registry block, now guarded by a
  stale-registry witness that names the new file's pin as the fix.

Non-vacuity: adding an unpinned 000042 migration file reddens exactly
the two checksum-authority tests (registry staleness; fail-on-unpinned)
while the convergence tests correctly stay directory-agnostic; file
removed after the witness.
matthewpeterkort and others added 30 commits November 12, 2026 15:12
…d factories (#153)

* refactor(server): one selected AQL row-adapter core and shared recipe authorizer

arch-backend-08 unit A (batch c4b53e23b9d190fe, addenda
backend-simplification-20261110 decision 1):

- Replace the three inline lifecycleClient.QueryRows callbacks (FHIR
  dataframe service, recipe engine query lane, preview lane) with one
  selectedAQLAdapter core over withConfiguredAQLRows: exactly one
  closed-dispatch AQL unwrap per request (was two on the engine lanes),
  one dispatch site per lane, distinct caller instrumentation preserved
  (logging phases, query-memory pin, preview max-runtime budget,
  preview-route error mapping byte-compat).
- configuredAQLSourceRows stays as the witness-facing seam over the same
  instrumentation path so the error-boundary/logging/PG-landmine
  witnesses keep exercising production code.
- Retire pgRecipeAuthorization into the shared recipeAuthorization core
  with an explicit selectionMembersCollection stamp policy (Arango
  stamps its collection at construction; both PostgreSQL lanes pass the
  zero value). Add a PostgreSQL-policy contrast cell asserting an
  untrusted caller-supplied collection never survives.
- configuredPostgreSQLSourceRows moved to row_sources.go unchanged.

Witnesses migrated with old->new citations:
TestPostgresRuntimeAuthorizerNeverStampsTheArangoCollection,
TestRecipeAuthorizationBindsSavedSelectionToAuthorizedProject.

Verification: go build ./... ; go vet ./internal/server ;
go test -count=1 ./internal/server ./internal/api/http
./internal/backends/arango ./internal/backends/postgres (all ok, offline;
live legs run in the granted quiet window at the final head).

* feat(server): typed route composition contract with explicit scoped-auth wiring

arch-backend-08 unit B (backend-architecture-coverage-20261109-v1
amendment: replace optional ...any route dependencies with a typed
composition contract; calypr mode must require its resolver; basic/test
unrestricted policy is explicit; validate incomplete scoped composition
before installing routes):

- registerRoutes now takes a named routeDependencies{releases, scopes}
  instead of the optional ...any type-switch locator; composition
  completeness is validated before any route installs.
- routeScopePolicy is a closed three-state union (unset / unrestricted /
  scoped); the zero value is refused, so a forgotten policy can never
  silently default to unrestricted. scoped requires its
  authscope.ScopeResolver; unrestricted must not carry one.
- wireAuth derives the policy from the auth mode: no-auth and basic are
  explicitly unrestricted; calypr carries its required resolver. The
  handler-side nil-means-unrestricted reading is derived from the
  validated policy only, so handler behavior is unchanged.
- All three production lanes and the routes_test caller migrated.

Tests added: TestRouteScopePolicyValidation,
TestRegisterRoutesRefusesIncompleteScopedCompositionBeforeInstall,
TestRegisterRoutesUnsetPolicyIsRefused,
TestWireAuthScopePoliciesAreExplicit.

Verification: go build ./... ; go vet ./internal/server ;
go test -count=1 ./internal/server ./internal/api/http (ok, offline).

* refactor(server): one composition seam with shared builders and a single serve loop

arch-backend-08 Unit C. Server startup now composes through ONE explicit
path per backend: run() = validate + select + dispatch; each arm composes
over factory ports and serves through the one serveRuntime listen/shutdown
loop (retiring three copies).

- compose.go (new): startup-only open seams (openArangoBackend,
  openPostgresBackend, newClickHouseClient -- composition-private package
  vars, read once per startup; no handler-reachable locator), shared
  builders newPublicationPlane/reconcileBundles, newReleaseHooks,
  buildLifecycleConfig (the byte-identical receipt-execution closures +
  typed lane-ports struct), wireExplorerRoutes, and composeArangoRuntime
  moved out of run().
- composeArangoRuntime adopts the cleanups-stack ownership law (one
  deferred error-path sweep, four pushes, caller-owned closer) so normal
  shutdown, partial construction, and the CLI exit share one owner per
  resource; close errors are now logged, not discarded.
- PostgreSQL full compose migrates onto the shared builders; the
  first-query arm converts from manual per-error-path closes to the
  cleanups stack; both PG arms keep the pinned pre-dial consumability
  gate, sentinel refusals, six-series startup placement, and the #146
  CombinePortsConfigured guard immediately after engine construction.
- Witnesses: health arm table Arango cell re-pointed server.go::run ->
  compose.go::composeArangoRuntime (old->new citation in the witness);
  TestPostgresRuntimeComposeOwnsNoDeferredCleanup becomes a matrix over
  both production composes (one sweep, four pushes, reverse-order closer).

Verification: go build ./..., go vet ./..., gofmt clean; go test -count=1
./internal/server ./internal/api/http ./internal/backends/arango
./internal/backends/postgres ./cmd/loom-data all ok (PG live legs repo-skip
without LOOM_TEST_POSTGRES_URL; Arango/ClickHouse legs repo-skip without
services). Review-pending: Unit E sabotage suite and the AO review pass.

* test(server): backend composition contract matrix with open-seam spies and a live ledger leg

arch-backend-08 Unit D. TestBackendCompositionContract makes the ONE-seam
law executable: each backend selection opens exactly its own factories,
once, and nothing else.

- Offline cells drive the three startup-only open seams (compose.go) with
  recording spies that fault at the open, so the call ledger is the whole
  evidence: arangoDefault_opensOnlyArangoOnce; postgresLadder_opensOnlyPostgres
  (six-series, SetupNone, credential-scrubbed refusal);
  twoSeries_firstQueryArm_onlyTwoSeries;
  invalidShape_sentinelPreDial_zeroOpens (six bad shapes through the real
  RunWithConfig dispatch, byte-stable sentinel, zero opens);
  openFault_neverFallsBackToArango (dispatch never falls through on a PG
  open fault); clickHouseDisabled_noClickHouseConstruction;
  liveness_doesNoDatabaseWork (zero dependency checks, zero opens).
- Live leg liveProductionCompose_ledgerHolds boots the PRODUCTION
  composePostgreSQLFullRuntime over pass-through spies on the shared
  PostgreSQL fixture: ledger 0/1/0, SetupNone six-series, /livez adds no
  opens, closer re-check holds. Registered in the pgComp mint inventory so
  TestZZ audits it.

Verification: go test -count=1 ./internal/server green offline (6.4s) and
live with LOOM_TEST_POSTGRES_URL (70.5s, full battery incl. census audits);
go vet + gofmt clean. Pre-existing, unrelated: cmd/loom-data
TestCLIPostgresLoadGenerationLiveStagedLoad fails on the live URL at base
354d7ad too (missing --pg-manifest-schema in its args) -- countersign-only
scope, reported not fixed.

* test(server): direct witness for the row-core cross-tag dispatch guards

arch-backend-08 Unit E (sabotage evidence). TestRowCoreCrossTagGuardsRefusePreDispatch
feeds the production configuredAQLSourceRows / configuredPostgreSQLSourceRows
lane functions a command tagged for the OTHER backend and requires the
closed-dispatch sentinel plus zero dispatch invocations. Route-level witnesses
rely on the compiler boundary refusing first, so the guard inside the row
core itself had no direct killer; this closes that gap.

Sabotage matrix (scratch detached worktree at 5b97e57, all six killed):
S1 first-query pre-dial gate removed -> invalidShape_sentinelPreDial_zeroOpens red
S2 AQL-lane tag guard dropped -> this witness red (route witnesses alone
   survived: they check the compiler boundary, not the core)
S3 liveness consults checks -> liveness cells red (server matrix + httpapi L1f)
S4 unset scope policy defaults unrestricted -> Unit B route-composition tests red
S5 double-owned ClickHouse defer -> TestPostgresRuntimeComposeOwnsNoDeferredCleanup red
S6 swallowed PG open error falls through to Arango -> openFault_neverFallsBackToArango red

Verification: go test -count=1 ./internal/server green (8.3s); vet+gofmt clean.

* docs(architecture): one-seam startup contract and integrated runtime diagram

arch-backend-08 Unit E. Documents the delivered composition from source,
not target design: run() = validate + select + dispatch only; the three
startup-only open seams; the shared builders (newPublicationPlane,
newReleaseHooks, buildLifecycleConfig, wireExplorerRoutes with typed
routeDependencies and validated routeScopePolicy); the pre-dial consumability
gates with the byte-stable ErrPostgreSQLRuntimeNotWired refusal and no
Arango fallthrough; the CombinePortsConfigured boot guard (#146); the
cleanups-stack ownership law with serveRuntime as the single closer owner;
and the row-port closed-dispatch tag guards.

Checked-in diagram docs/architecture/integrated-runtime.mmd draws backend
selection, compiler/row ports, factory and adapter ownership, the independent
ClickHouse plane, and the contract-matrix spy point.

Verification: statements checked against internal/server/{server,compose,
runtime,rows_sources,routes}.go and witness names in runtime_test.go/
backend_composition_contract_test.go; go build ./... and go vet ./... clean.

* ci(arango-lane): register the arch-backend-08 live sub-leg in the external skip allowlist

F5 skip-capture law. The Arango-only server lane runs go test -json
./internal/server with LOOM_TEST_POSTGRES_URL unset, and checkEvents
rejects any skip outside the external allowlist. The composition-matrix
live leg skips as TestBackendCompositionContract/liveProductionCompose_ledgerHolds
(slash-qualified: the parent never skips -- its seven offline spy cells
execute in every lane, only the production-compose live sub-leg needs the
PostgreSQL fixture), so it is registered byte-exact against the offline
go test -json skip capture, following the pg-exec-02/#99, pg-exec-04,
pg-exec-05/#123, and pg-runtime-server-composition registration precedent.

Verification: node --check clean; node --test over both runner harnesses
(39 pass); pg-exec-03-skipset-verify.mjs green; feedEvents proof -- a
synthetic server-lane capture (required Arango cases run+pass, lane -skip
regex applied) is rejected pre-registration exactly on this identity and
accepted post-registration, with the only remaining unregistered skip being
TestCoreAuthoringProtocolAgainstArango, which is LOOM_TEST_ARANGO_URL-gated
and never skips in the real Arango lane.

Note: lands as a follow-up to 5b97e57 rather than inside it because this
branch is append-only per operator order (normal push, no rewrite); the
push carries both commits together, so origin never sees the unregistered
skip without its registration.

* test(server): make the refused-install witness check the promised 404

Review thread PRRT_kwDOS-yV5s623WMw on #153. The sentinel-sanity block
asserted errors.Is(err, err), which is unconditionally true and pinned
nothing, while the comment above it promised a half-install check the test
never made. Replace the dead block with the promised assertion: after the
refused registerRoutes, POST /api/v1/datasets/acme/generations/gen-1 through
server.App().Test must return 404 -- no generated route may be registered
by a composition that was refused before install. The unused errors import
goes with the dead block.

Proof the check bites (scratch detached worktree at 4d945c6 with the
candidate test overlaid): deferring deps.validate() past
RegisterHandlersWithOptions and letting the load handler accept a nil
service registers the route, and the witness fails exactly on the new
line (POST load got 415, want 404).

Verification: focused Unit B witness suite green; go test -count=1
./internal/server green (8.7s); gofmt clean.

* test(server): exercise the production closer twice in the live ledger leg

Review thread on #153 (backend_composition_contract_test.go:303). The cell
claimed the closer is idempotently single-owner but called closeRuntime()
once, so the ledger re-check after the first close added nothing and the
comment over-claimed. Add the promised second closeRuntime(): assert it
reports no new error and the open ledger still reads 0/1/0. Safety of the
re-entry is a production property, read from source: the backend factory
Runtime.Close is sync.Once-guarded (internal/backends/postgres/control/
runtime.go closeOne) and the reconciler stop steps are idempotent (cancel +
already-closed done channel), so a repeated stack teardown cannot reopen or
double-free anything -- exactly the regression surface a closer-law break
would surface.

Verification: offline ./internal/server green (live cell repo-skips);
gofmt + vet clean; live execution lands in the verifier's queued live
session (full ./internal/server live battery covers this cell).
…amilies across both backends (#154)

* feat(arch-backend-12): one source diagnostics meaning and two plan identity families across both backends

Public dataframe diagnostics now speak one backend-neutral language while
artifact identity keeps its value-bound meaning:

- QueryDiagnostics.ArangoQuery -> SourceQuery plus a SourceBackend tag; the
  stream path's single cursor timer subtracts per-row Loom materialization
  on both adapters (clock seam is a package var, production stays time.Now).
- PreviewSummary.QueryDuration -> SourceQueryDuration with the same
  cursor-interval meaning; preview subtracts its own row delivery time.
- New SourcePlanFingerprint: the value-free public planFingerprint at
  Explain and preview projection for both source lanes. AQL keeps the
  historical CompiledQueryFingerprint bytes (goldens unchanged); PostgreSQL
  reports a domain-separated (loom:source-plan-shape:v1) digest over SQL,
  ordered parameter TYPES, and output metadata -- bound values excluded.
  Value-bound identities (OutputStream.planFingerprint, Identity.PlanDigest)
  are untouched; stream.planFingerprint doc hardened to artifact-identity
  wording.
- GraphQL: DataframeQueryDiagnostics gains sourceQueryMs; arangoQueryMs
  stays as the legacy transport projection (AQL: identical value, PG: 0).
  CLI prints source_query with the legacy fallback. Examples and
  docs/GRAPHQL_API.md updated; generated/ regenerated via make
  generate-graphql (idempotent).

Witnesses: execution-package cross-backend identity test (bound-invariance,
interchange guards, pinned PG shape bytes, controlled-clock literal
durations, explain==preview parity), resolver projection test, CLI
backend-neutral test, live legs (Arango service stream + preview via the
execution ports; PostgreSQL first-query handler via the qRoute harness,
registered in the Arango runner's external set and as a required
server-profile Arango witness with negative controls).

Offline: go build ./...; go test execution, api/graphql/..., dataframe-query,
server; make graphql-check gqlgen-check; generated/ diff-clean against
regeneration; node --test runner suite.

* docs(arch-12): align Explain PlanFingerprint contract with the two-family rule

Review r4557908197: PhysicalOutputExplanation.PlanFingerprint still carried
the pre-ticket wording, describing the value-bound command fingerprint as the
public Explain meaning. With Explain sharing SourcePlanFingerprint, that
comment contradicted behavior and invited consumers to treat the public
diagnostic shape as an identity key. Restate the contract: the public
fingerprint is the value-free diagnostic shape (preview-parity bytes), while
the value-bound command identity stays confined to artifact fencing.

* fix(arch-12): fail closed at public projections when a plan fingerprint is empty

Review r4557908156: the SourcePlanFingerprint docs claimed callers fail
closed on an empty fingerprint, but no projection enforced it. The compile-
only Explain path never dispatches the command, so a corrupt tagged payload
(a compiled-command invariant violation the constructors make unreachable on
the happy path) would have surfaced as an empty public planFingerprint with
a nil error.

Add requireProjectedPlanFingerprint and run it at both public projection
sites: Control.ExplainResolved's per-output fingerprint and the preview
summary assembly. Correct both doc comments to describe the enforced truth
(and note validatePreviewPlan guards the bound-digest admission gate, not
the shape). Witness covers gate acceptance/rejection and the Explain
projection path; note the gate is defense-in-depth: the empty input is
unreachable through the command constructors, so the guard call itself is
covered by the projection witnesses rather than a reachable-empty test.

* fix(arch-12): type the projection refusal as INTERNAL_ERROR and document the PG-lane arangoQueryMs change

Review round follow-ups:
- requireProjectedPlanFingerprint now returns a typed, non-retryable
  dataframeerrors INTERNAL_ERROR (compiled-command defect, never a caller
  fault or retryable backend condition); the witness asserts the code and
  non-retryability through AsUserError.
- docs/GRAPHQL_API.md: state the PostgreSQL-lane semantics change explicitly.
  Pre-ticket, PostgreSQL answers carried the PostgreSQL cursor time in
  arangoQueryMs (the single mislabeled timer); it is now a literal 0 and
  PostgreSQL consumers must read sourceQueryMs, which measures the same
  cursor interval on both backends.
…-enforced ownership law (#155)

* feat(boundaries): one authoritative parsed-import ownership policy with RED-proving fixtures (arch-backend-09 W1)

Consolidates the package-boundary mechanism into a single parsed-import
implementation (scripts/packagepolicy): one rule table (14 rules with
allowed-owner guidance per rule), one scanner, consumed by every
entrypoint:

- scripts/check-boundaries CLI + scripts/check_dataframe_package_boundaries.sh
  (Make dataframe-boundaries, CI go-unit): negative-fixture self-test first
  (planted forbidden imports must bleed named victims with file, import,
  and allowed owner; removal must converge), then the repository scan.
  Former rg import rules moved into the table; only explicitly distinct
  text rules (ResolveStorageRoute/fhirschema identifier bans) remain in
  the shell, each with a hard target-directory-exists vacuity guard, plus
  go/rg-missing hard failures.
- TestBackendOwnershipGuardContract (new, in the existing real
  ./internal/dataframe/compiler package per the backend-simplification-
  20261110-clarify precedence ruling) with all six required subtests:
  compiler_backends_and_drivers, neutral_domain_backend_import (execution
  -> Arango preview, catalog -> PG physical rows, domain -> factory
  shapes), renderer_runtime_import (BOTH render/aql and render/postgres
  dialect dirs scanned; driver leak landing only in the PostgreSQL
  dialect is caught), legitimate_adapter_domain_import,
  actual_relocated_adapter_import (asserts a concrete rows.go
  github.com/jackc/pgx import finding in the existing relocated adapter),
  missing_or_malformed_input_is_error.
- TestCompilerProductionFilesNeverImportBackendsOrDrivers preserved by
  delegation to the same scanner.

Fixed defect class (coordinator-confirmed finding): the retired local
scanner folded fs.WalkDir filesystem errors into its offender list, so
the real-adapter negative control scanning the deleted
internal/dataframe/postgres path falsely passed on missing-directory
errors. Findings and verification errors are now structurally separate
channels: a missing directory, walk failure, parse failure, or zero-file
scan is a verification failure and can never satisfy an import-detection
control; vacuous scans fail loudly.

Sabotage proof (temporary file, removed before commit, never staged): a
planted pgx import in render/postgres production failed the shell
entrypoint and both named tests, printing the offending import and
allowed owner; removal restored green.

Validation: scripts/packagepolicy unit tests pass; boundary entrypoint
passes the repo (14 rules, 2057 files); -json event gates confirm
run+pass with zero skip for both named tests and every required subtest;
go build ./... and go vet clean; go test ./internal/dataframe/compiler
./internal/backends/postgres ./internal/dataframe/execution all ok.

* ci(arch-backend-09): wire boundary entrypoint + named ownership-guard event gates into go-unit

CI never executed scripts/check_dataframe_package_boundaries.sh (local
Make target only) and no step proved that the backend ownership guard
tests actually run: a renamed or silently-skipped guard test would have
passed the job. This closes both gaps in the go-unit job:

1. Run Go package boundary check: the shared-policy entrypoint
   (self-test negative fixtures + 14-rule repo scan), hard-failing
   without go/rg.
2. Backend ownership guard named gates: go test -json through
   scripts/lib/check-go-test-events.mjs, which reuses the authoritative
   checkGoEvents acceptance semantics from run-postgres-integration.mjs
   (run -> pass per required event, zero skips anywhere, zero selected
   tests fails). Required events: TestBackendOwnershipGuardContract +
   all six subtests and TestCompilerProductionFilesNeverImportBackends
   OrDrivers + its four non-vacuity controls, including the guards that
   kill the dead-leaf-guard defect class (a guard that silently stops
   scanning must stay red).

Rehearsed locally against the real go test -json stream (12 required
events run+pass) and against synthetic missing-test and skip inputs
(both fail with exit 1). PG/Arango/ClickHouse jobs unchanged; live
suites stay runner-gated repo-skip.

* refactor(arch-backend-09): type the row-querier bridges; delete QuerierAsAny

The factory bridge from the control plane to the private rows adapter
pooled values through any: control Runtime.QuerierAsAny returned any,
and the public builders NewPlanJSONExecutor(any)/NewSourceRows(any)
re-asserted rows.Querier at runtime. Untyped bridges like this are the
defect class that lets an ownership seam silently degrade — the
runtime assertion can pass for anything structurally similar and the
compiler stops protecting the boundary.

- control: QuerierAsAny() any becomes PoolClient() *Client (typed pool
  client; closed runtime yields nil, handled as bootstrap failure).
- root: public type Querier = rows.Querier (root re-export of its own
  internal adapter interface, the accepted adapter-ownership shape);
  NewPlanJSONExecutor(Querier)/NewSourceRows(Querier) enforce the
  contract at compile time, failing closed only on absence. All
  existing callers (pgxpool.Pool, acquired *pgxpool.Conn, *pgx.Conn,
  test fakes) already implement Query(...) (pgx.Rows, error) and need
  no changes: pgx.Rows is public, so external fakes satisfy the
  contract without importing the private adapter.
- Open uses the typed client; the var _ rows.Querier = (*store.Client)
  compile-time pin stays.
- plan_executor_test negative control moves from a non-compile-time
  struct{}{} probe to nil, which is now the only runtime rejection.

go build ./... + go vet clean; postgres, execution, and server
explain/preview/wiring suites green offline (live PG suites repo-skip).

* feat(boundaries): parsed identifier-absence guard; fail the CLI on absence errors

Two fixes in the authoritative policy entrypoint (arch-backend-09,
dead-leaf-guard defect class — a guard that cannot fail is a guard
that silently passes):

1. AbsenceRule gains Identifiers + ScanRoots: removed API symbols are
   matched against the parsed AST of every Go file under the scan roots
   (comments and string literals can never trip it; a parse failure is
   a verification error, never a detection; zero scanned files is
   vacuity). A new table row asserts the deleted untyped row-querier
   bridge QuerierAsAny stays absent across internal/ and cmd/, so the
   bridge cannot silently return in production or tests.
2. The check-boundaries CLI printed CheckAbsences failures but never
   counted them in its exit condition: a recreated obsolete path (or
   reappeared identifier) printed a violation and exited 0. Found by
   on-repo sabotage (planted func QuerierAsAny in internal/server):
   before the fix the entrypoint stayed green; after, it exits 1
   naming the file, identifier, rule, and allowed owner. Removal
   restores green.

Self-test gains four fixture controls over the live table row
(reappearance caught; comment/string immunity; malformed input is a
verification failure; empty roots vacuous), and packagepolicy gains
unit coverage of the same. go build/vet clean; packagepolicy and
compiler guard suites green.

* fix(boundaries): keep retired-path guard data out of Go source text

The arango ownership contract (zero_references_to_retired_adapter_paths)
forbids any Go file from citing a retired adapter path, comments
included — including guard data. W1's rules.go carried the retired
table as Go string literals and the new compiler guard test planted
them in fixtures, so the full CI rehearsal went red: 8 citations.

- scripts/packagepolicy/old_concrete_paths.txt is now the table,
  embedded via go:embed (non-.go files are outside the text scan);
  parsePathTable refuses an empty table at init.
- OldConcreteImportPaths() exposes it; the guard test's retired-path
  fixtures build from segments through mustOldPath, which also proves
  the planted path is in the authoritative table, so fixtures cannot
  drift from the guard.
- policy_test pins the table size and sample entries (empty/truncated
  data files fail).

go-unit rehearsal is now green across every package except internal/ci
in this worktree, where TestVetGateFiresOnInjectedCopylocksFault is an
environment artifact, not a source regression: runGoVet uses the repo
root as cwd, and when the root is a direct child of /tmp go vet prints
the overlay probe path as ../Test.../p.go, breaking its Contains(temp)
assertion. The identical commit passes internal/ci at any deeper
checkout path (verified in two depth-2 worktrees); CI runners are
deeper still.

* refactor(arch-backend-09): delete 52 zero-reference forwarding aliases

Ticket acceptance: unreferenced forwarding APIs deleted. Census of all
153 control re-exports in internal/backends/postgres/aliases.go counted
references through every import alias (postgres., backendspostgres.,
explicit aliases) plus same-package unqualified use, comments stripped:
52 entries had zero references anywhere in the repository and are
removed; the remaining 101 stay until the facade-collapse ruling
decides their migration direction.

Dead-leaf names are generic (Row, EdgeWriter, CatalogStore), so they
cannot use the QuerierAsAny-style identifier-absence AST guard (it
would fire on unrelated declarations repo-wide); the deletion plus this
record is the guarantee, and the collapse wave removes the file's
remainder either way.

go build ./... + vet clean; postgres, arango, ingest, server, execution
suites green offline; boundary entrypoint green.

* refactor(arch-backend-09): delete the root control facade; machine-enforce the control-plane ownership law

Scope decision with evidence (coordinator ruling 2026-11-12, Option A,
on ticket arch-backend-09): the acceptance target is compat-forwarding
remnants. internal/backends/postgres/aliases.go was the compat shim —
153 old-path re-exports of control vocabulary. internal/backends/postgres/control
is a real public control plane, not a shim. The census that justified
keeping control split: internal/dataframe/compiler/render/postgres
holds 44 test files / 42,018 lines in one in-package postgres test
tree; 19 files import control; flipping all files to an external test
package surfaces 111 undefined production identifiers (95 unexported);
11 files are simultaneously private-identifier consumers and live
control witnesses. Merging control into the root would break ~30
whitebox live witnesses — exactly the amendment's unless-clause
("a specific production dependency proves a remaining split
necessary... exact source evidence and a bounded follow-up"). The
production dependency is exact: root's plan_executor/open bridge rows
-> execution -> compiler -> renderer, so control (which must never
reach execution) is the only Go-internal-legal surface for
store-owned vocabulary. Witness externalization of the private+live
files is the logged bounded follow-up, not this ticket.

Enforcement (machine-checked, not documentation):
- packagepolicy gains CheckNoReExport: the root package may compose
  control but never re-publish its surface — no type/var/const alias
  to a control export, no single-return forwarding func, and no
  same-named struct embedding (method-set re-publication) except the
  one ruled sanction: AllowedEmbeds {Runtime} (factory Runtime embeds
  the control runtime and adds SourceRows/PlanJSON).
- New table rule postgres-control: cycle-free control plane — control
  (AllScopes) must never import the postgres root (cycle), the private
  rows adapter, or dataframe/execution.
- RepoAbsences gains the aliases.go path row; QuerierAsAny keeps its
  identifier row. CLI exit condition counts absence failures.
- TestBackendOwnershipGuardContract gains facade_law_control_plane
  covering all four ruling conditions with planted victims and
  removal convergence; check-boundaries self-test gained fixture
  controls; the CI named-event gate lists the new subtest. On-repo
  sabotage: planted re-export went the contract test RED, planted
  control->root import went the CLI exit 1; removal restored green.

Facade deletion and consumer flips (ruling condition 3):
- aliases.go deleted (101 referenced entries after 2351ff7 removed 52
  zero-reference leaves; 153 total at branch start).
- Production consumers import the factory root for Open/Runtime and
  control directly for control-plane symbols: ingest
  postgres_writer/generation_load, server runtime/server/compose,
  cmd/loom-data. open.go composes control explicitly.
- Test witnesses that already import control stay control-importing
  (no churn); root-importing test files gained control imports for
  symbols that were aliases; root's in-package sentinel identity test
  now pins control-vs-store identities (renamed
  TestControlSentinelsMatchProbeEmittedIdentities — the facade
  half is gone; cross-package identity guarantee preserved).

go build/vet ./... clean; go-unit package rehearsal green except
internal/ci (shallow-/tmp-cwd vet-probe artifact, accepted non-issue:
same commit green at any deeper checkout; CI runners unaffected);
boundary entrypoint + self-test + guard suites green; no live PG used.

* docs(arch-backend-09): refresh package audit for the facade deletion and boundary policy packages

Regenerate docs/PACKAGE_AUDIT.csv and docs/PACKAGE_AUDIT.md with scripts/package_audit.py:

- internal/backends/postgres: responsibility rewritten from 'sole public entry /
  re-export surface' to the factory role - Open composes the control runtime,
  typed Querier bridges, sole legal importer of the private rows adapter, and no
  re-export surface (control-plane consumers import control directly per the
  coordinator OPTION A ruling on arch-backend-09).
- internal/backends/postgres/control: described as the single definition of the
  cycle-free public control plane, imported directly by production consumers and
  backend-adjacent witnesses, machine-enforced by scripts/packagepolicy.
- Add curated rows for the two new packages: scripts/packagepolicy (authoritative
  scanner/policy table) and scripts/check-boundaries (CLI + negative-fixture
  self-test).

Verified: regeneration is byte-reproducible (two runs, cmp clean). Diff against a
base-regenerated inventory (fc5b596, same scripts) is exactly the wave footprint:
the two added packages plus postgres root/control, their flip-side consumers
(cmd/loom-data, ingest, server, compiler, query, api/http), and no unrelated
package moves. Note: the committed audit was already stale at base fc5b596
(drift in loc/symbol/importer columns from landed merges); this regeneration
converges it. package_audit_verify.py --full runs 'make test', whose only failure
in this /tmp worktree is the known internal/ci vet-gate path-depth artifact
(same commit passes at any deeper path, verified in a linked worktree).

* test(arch-backend-09): repair the live CLI staged-load witness for the manifest-schema split

TestCLIPostgresLoadGenerationLiveStagedLoad was red against a live
PostgreSQL at the branch base (fc5b596) and at the origin tip - proven
by running it at both commits in the granted PG window - because the
live legs drifted out of sync with the dataset_release series split and
hid behind the LOOM_TEST_POSTGRES_URL gate (skipped in every no-PG run):

- the CLI now refuses a postgres load without --pg-manifest-schema
  (ingest.PGSourceOptions.ManifestSchema), so both live legs pass an
  explicitly created owned manifest schema (verify_clidisp_sm_* pattern,
  mirroring the ingest generation-load witness convention);
- the STAGED-manifest and untouched-active-pointer witnesses read the
  dataset_generation_manifest / dataset_active_generation tables from
  the manifest schema, where the dataset_release series lives
  (store.SeriesDatasetRelease), not the data schema;
- the virgin negative leg now probes the virgin manifest schema for the
  manifest table and asserts the virgin data schema holds zero
  relations, replacing a stale-data-schema to_regclass probe that was
  vacuously true for the wrong schema pairing.

Witness strength is preserved or improved: STAGED-not-activated literal
rows, application_name attribution with alive+selectivity controls, and
a stronger zero-relation virgin-data-schema guarantee.

Evidence: live run green (staged load + TestZZCLIDispLiveOwnershipAudit
pass); full serialized rehearsal of the 6 PG-gated packages green
(17/17 packages, go test -p 1); no-PG unit leg green.

* ci(arch-backend-09): install ripgrep in go-unit before the boundary check

The go-unit boundary step failed on CI: ubuntu runners do not ship
ripgrep, and scripts/check_dataframe_package_boundaries.sh correctly
refuses to pass vacuously without rg (its rg-powered text rules would
otherwise all read as non-matches - the arch-07 F1 lesson). The guard
worked; the environment lacked the tool.

Add a conditional install step before the boundary check: apt-get
ripgrep when rg is absent, then print rg --version (a failed install
still hits the boundary script's hard no-rg failure, so it can never
read as a silent pass).

Verified locally: workflow YAML parses (go.yaml.in/yaml/v3 from the
module cache) with the new step ordered before the boundary check; the
boundary script hard-exits 1 with rg absent from PATH and passes with
rg present.
…SQL read lane (#156)

Defect PG-PG-AUTH-PATH-DISCOVERY-ALLGENS (coordinator-filed, batch
c4b53e23b9d190fe; entry evidence + live proof from loom-experiment-204;
design B per coordinator ruling).

Symptom: DiscoverExistingAuthResourcePaths({AllGenerations:true}) returned
typed ErrAllGenerationsUnsupported on the PostgreSQL lane, so the F-B27
project-binding branch of authscope.ScopeResolver.AuthorizeWrite always
errored and internal/api/bulk/load wrapped it to 403 -- scoped (calypr)
uploads were impossible on PostgreSQL, and the zero-path bootstrap branch
was unreachable. Arango implements the union (existingAuthResourcePathsAllGenerationsAQL),
so this was PG-lane-only drift.

Fix (design B, persistence-boundary DISTINCT read):
- FieldProfileRepository.ListDistinctAuthResourcePaths: one
  SELECT DISTINCT auth_resource_path COLLATE "C" ... WHERE project=$1 AND
  auth_resource_path <> '' ORDER BY auth_resource_path read -- the
  PostgreSQL shape of the AQL union: no dataset_generation predicate (an
  empty generation is the legacy unscoped namespace, never "any
  generation"), empty paths excluded, honest empty for a genuinely
  unrecorded project, typed ErrInvalidFieldProfileScope for a blank
  project (never an all-projects scan). COLLATE "C" pins dedup equality
  and order against cluster-collation drift (interrogation finding M4;
  probe on the en_US.utf8 collation reorders the witness fixture vs byte
  order).
- FieldProfileStore interface gains the method (var _ assertion proves
  the repository wiring; the ingest test wrapper gets a pure-delegation
  arm).
- field_discovery.go: AllGenerations branch calls the distinct read and
  re-sorts as final normalizer; F-2 ErrAllGenerationsWithGeneration kept;
  ErrAllGenerationsUnsupported retired (zero repo-wide references).
- Manifest-registry generation enumeration was rejected: an unmanifested
  generation silently shrinks the union and emptiness feeds the F-B27
  bootstrap-allow, reopening the exact bypass class the branch closes.

Regression witnesses (all against live PG18):
- store: golden SQL pins (predicate shape, empty-path door, COLLATE
  pin, blank-project refusal) + DDL union (multi-generation incl legacy
  '' rows, marker rows, non-concrete-type-only paths, dedup, empty-path
  and foreign-project exclusion, byte order vs en_US-style collation).
- adapter: F-2 conflict refused with zero store calls; cross-generation
  union with exactly-one-distinct-read / zero-filtered-read wrapper
  witnesses (delegating counters, never faked results); adapter byte order
  under reversed boundary delivery; honest-empty named test documenting
  the unchanged F-B27 bootstrap posture; store failure wrapped nil, never
  empty-success; whitespace-only generation unions, not conflicts.
- control: runtime union replaces the retired refusal pin; unrecorded
  project honest empty; unassigned-source and closed-runtime typed
  refusals intact for the union arm.

Verification: go build ./...; go vet internal/backends/... internal/ingest
internal/authscope; gofmt clean; go test -count=1 green for
internal/backends/postgres/{internal/store,internal/catalog,control},
internal/ingest, internal/authscope, internal/api/bulk/load, and the
Arango AllGenerations conflict pins; check-boundaries law ok (15 rules,
2068 files; the rg-gated text rules could not run -- no ripgrep in this
environment). Adversarial review (same-model, two isolated sandboxes):
findings M4 (untested byte-order guarantee) and gofmt drift repaired and
re-proven by planted mutations; authscope cache posture (errors not
cached, InvalidateProject evicts the allGenerations key), stale-reference
sweep, and caller sweep passed. Live scoped-lane upload repro + 204
harness run under the coordinator's consolidated exclusive PG window
(leg preparation in /tmp/loom-pg-bench-207 at the fix SHA).
…g repositories (#158)

* fix(pg): compose the capability-evidence reader over all three catalog repositories

Defect PG-PG-CAPABILITY-EVIDENCE-COMPOSITION-PANIC (coordinator-admitted;
evidence loom-experiment-204: full stack + deterministic live repro; plan
ACKed by coordinator). Every POST explorer-config against the PostgreSQL
backend panicked: runtime.go assembled Runtime.Catalog as
catalogstore.New(inventoryRepo) -- inventory leg only -- while
internal/server/runtime.go hands that value to the Explorer capability
resolver, whose catalog.ReadCapabilityEvidence calls
DiscoverResourceInventory, DiscoverRelationshipObservations, and
DiscoverFieldEnrichment on the one value. The nil relationship leg
dereferenced at relationships.go before any query (and the nil profile leg
identically), so the missing dependency was a panic-500, not the typed
configuration posture every other unassigned postgres port uses.

Fix (plan option 2, unified store at the persistence boundary):
- catalog/store.go: NewFullStore(inventory, profiles, relationships), all
  three required -- the PostgreSQL shape of the Arango lane's single full
  store (compose.go:555,711), restoring Runtime.Catalog's own documented
  contract at the assembly site.
- control/runtime.go: the source-series block builds the three repositories
  as before, then ONE full Store backs r.Inventory, r.FieldProfiles,
  r.Relationships, and r.Catalog (all four ports are the same value;
  Contributions/SemanticReads untouched). The Catalog doc comment is
  corrected: the semantic-inventory lane is the separate SemanticReads port.
- Never-nil law: requireLeg guards on the eight dereferencing methods (the
  two Read* aliases inherit through their callees). Discover-family
  refusals reuse the existing typed-unavailable helpers plus a wrapped
  ErrStoreLegNotAssembled; write/rebuild/read refuse with the typed error.
  Guards fire before the restricted-empty no-query short-circuits, so a
  leg-missing store never sees an empty-success. A genuinely unassigned
  source series keeps nil ports and the server's typed config refusal
  (server/runtime.go) unchanged -- misused narrow store degrades honestly,
  unassigned series refuses at config, the panic class is impossible.
- Narrow constructors stay: control/vocabulary_control re-exports them for
  the generation-load recipe, and they are the witness surface for the
  guard law. Reviewer sweep confirmed no production caller passes a
  leg-missing store to any guarded method (the empty-success flip is
  unreachable outside tests).

Witnesses (live PG18):
- store package (capability_compose_pg_test.go): recording wrappers over
  all three repository interfaces delegate unchanged, never fake -- one
  ReadCapabilityEvidence over the full store issues exactly one boundary
  read per leg (ReadBuild+ReadCountSums / one ScanRelationshipOccurrences /
  one filtered profile read, zero write-path calls), with DeepEqual against
  an unwrapped baseline full store; per-type count pins (Patient=1
  Observation=1 with the foreign-path row excluded) kill vacuous seeding
  (adversarial finding M3, mutation-proven: deleting the source-row
  seeding fails the pins); the full 20-combination wrong-leg matrix refuses
  typed with zero boundary queries and a recover-to-failure panic trap;
  NewFullStore refuses each missing repository.
- control package (capability_compose_test.go): the benchmark's requested
  regression -- ReadCapabilityEvidence(runtime.Catalog) on a migrated
  runtime completes every leg typed (inventory typed-unavailable sentinel,
  relationships available-empty, enrichment typed-unavailable), never
  panics, and flips enrichment to available after seeding through the
  runtime's own write port; all four ports are one pointer; the
  unassigned-source runtime keeps nil ports.
- Mutation proofs: deleting the relationship guard kills the narrow-store
  witness on a panic; reverting the runtime to an inventory-only Catalog
  kills the control witness.

Verification: go build ./...; go vet internal/backends/postgres/...
internal/server internal/ingest; gofmt clean; go test -count=1 green for
internal/backends/postgres/{internal/store,internal/catalog,control},
internal/ingest (3/4 concurrent runs; one transient service-side
contention failure that did not reproduce; both serial runs green),
internal/api/bulk/load, internal/authscope, Arango AllGenerations pins;
check-boundaries ok (15 rules, 2071 files). AQL byte-unchanged: git diff
name-only shows zero arango hits. Adversarial review (same-model, two
isolated sandboxes): blast-radius sweep found no reachable contract
violation; witness-integrity sweep's two findings (vacuous inventory
count pin, six unprobed guard combinations) repaired and mutation-proven.
Live publish-route legs (scratch_caprepro zero-panic + first-workload
PublishWorkspace HTTP) run under the coordinator's consolidated live-PG
window.

* test(pg): six-series capability-evidence witness and per-guard mutation receipts

Coordinator ACK conditions 2 and 4 for PG-CAPABILITY-EVIDENCE-COMPOSITION-PANIC
(PR #158, b05522e):

- Condition 2 (literal ask): the two-series control witness asserted the
  composition law on the source-series block only; the benchmark's request
  (and the server's real placement) is a runtime opened with ALL SIX series
  assigned. newCTLServiceSixSeries mints one isolated database with six
  owned pgctl6_it_* schemas (same drop-and-audit discipline as the
  two-series harness) under SetupMigrate, and
  TestRuntimeCatalogSatisfiesCapabilityEvidenceReaderSixSeries drives
  catalog.ReadCapabilityEvidence(runtime.Catalog, ...) there: all three
  legs answer with typed per-leg statuses and zero panics on the unloaded
  schema (typed build-unavailable sentinel, available-empty relationships,
  typed-unavailable enrichment), and the enrichment leg flips to available
  after seeding through the runtime's own write port. Green live.

- Condition 4 (mutation-prove EACH guard): a scripted matrix planted every
  one of the eight requireLeg deletions individually against the committed
  snapshot; each mutant was KILLED by the wrong-leg witness on the
  recover-to-failure panic trap (8/8 KILLED, zero compile-only mutants),
  after which the pristine source was restored. Composition reverts
  (inventory-only Catalog, deleted relationship guard) were already killed
  by the control witness in the initial adversarial pass.

* docs(pg): name the three ports Catalog backs, note Contributions separately

Review thread r4559141122 on PR #158: the rewritten Catalog doc comment
still claimed the value serves as the one behind "the four narrow evidence
ports above," but the four fields above include Contributions, which is
assembled separately from NewSemanticContributionRepository and is not this
Store value -- the same assembly-drift class this PR eliminates (and the
PR's own pointer-identity witness asserts only Inventory, FieldProfiles,
and Relationships). The comment now names the three ports it backs and,
mirroring the SemanticReads sentence, records Contributions as a separate
repository.
…ty and same-commit CI registration (#157)

* test(arch-10): dual-backend conformance suite with frozen cell identity and same-commit CI registration

TestBackendArchitectureConformance proves the arch-backend-01..09 relocation
preserved real dataframe and control behavior through production composition
on both backends: thirteen literal-oracle cells (scalar serving, occurrence
distinctness, null/missing semantics, fence-scoped visibility, generation
isolation, deterministic paging, draft CAS single-winner, release-fence
staleness, typed cancellation, no-fallback failures, pinned-ledger reopen)
run per arm against live ArangoDB and PostgreSQL, with a census zero-
survivor audit, an offline negative control (ab10OracleGoesRed), and named
arm-identity skips when a service env is unset.

Same-commit registration: the Arango runner gains the backendArchitecture-
Conformance set on the server profile; the PostgreSQL fixture runner gains
the backend-conformance-integration phase with the frozen thirteen-cell
anchor list; tests.yaml gains the dedicated backend-conformance job (both
services, named event gate over all twenty-nine identities) plus the
skip-set capture verifier wired into it offline.

Validation: go vet and offline go test ./internal/server pass (parent pass,
both arms skip with named identities); node --test over both runner suites
and the inventory suite: 49/49; skipset verifier reproduces the pinned
capture sha256 04075d92b7f9bd1e. Live-arm adjudication runs in the new CI
lanes; PG live window pending coordinator grant.

* test(arch-10): give conformance Observations the schema-required code

The generated loader validates typed FHIR resources and Observation
requires code (CodeableConcept); the two staged observation rows were
rejected as rowErrorValidation, so gen-a loaded 0/2 observations and the
PG arm failed with validation_errors=2 (CI run 43347089213, job
131628941655). Both arms share the fixture, so this unblocks the Arango
arm identically.

Fixture shape now matches testdata/basic-nested-coding-expand. The
conformance loader also flips FailFast so a malformed authored row names
file/line/resource instead of aggregating silently.

Validation: generated-path probe accepts all eight fixture lines and
rejects the pre-fix row with "required field 'code' is missing";
TestBasicObservationFixturesPassGeneratedLoaderValidation passes;
go vet clean; offline parent pass with both arms skipping named
identities.

* ci(arch-10): keep the conformance JSON stream and print failing-test output

The named event gate consumed stdout through a pipe, so a red lane left
only "Go reported failure" (run 43347089213 had to be diagnosed through
the pg-fixture artifact). The step now captures conformance.jsonl, gates
on the file, replays the failing tests' own output into the step log,
and always uploads the stream as the backend-conformance artifact.

* fix(arch-10): accept Arango 201 on database mint and cursor creation

The go-arango lane failed at the first line of the Arango arm: mint
owned database ... HTTP 201 (refusing a pre-existing name). Arango
answers POST /_api/database with 201 Created, and POST /_api/cursor
likewise, but the test required strictly 200 — so both raw-driver call
sites failed every live Arango run (the dedicated conformance job
would have failed identically). Mint now requires 2xx plus result:true
(matching the runner's response.ok semantics); the census cursor
accepts 200 or 201.

Validation: go vet clean; offline parent pass with both arms skipping
named identities; all three raw Arango call sites audited (create 2xx
+ result:true, drop 200/404 idempotent, cursor 200/201).

* test(arch-10): run the negative control against a shadow tester, not the live cell

The ab10OracleGoesRed closure captured the live *testing.T, so the
mutated expectation reached t.Fatalf on the real scalarQueryServesLiteralScalars
cell (1-row want vs 3-row serve: the cell could never pass on a live
service), and the probe created inside the helper was never passed to
the oracle, so probe.Failed() could not observe a shadow verdict.

Fix per review (r4558770196): the oracle helpers (ab10DecodeRows,
ab10RawText, ab10ScalarLiteral, ab10CheckRowsLiteral, ab10CheckNoRows)
now accept a minimal ab10OracleTester interface (Helper, Fatalf); the
live *testing.T satisfies it unchanged. ab10OracleGoesRed creates the
shadow itself, passes it to the oracle, and runs it in a dedicated
goroutine because a shadow Fatalf ends in runtime.Goexit — the channel
closed under defer lets the test survive. Panics still crash loudly
rather than masquerading as red.

Validation: throwaway same-package test (removed before commit) proved
shadow Fatalf is observed, a passing oracle stays green, the reviewer's
exact mutated-rows scenario goes red on the shadow while the live test
stays unfailed, and the true expectation keeps the shadow green; go vet
clean; offline parent pass with both arms skipping; runner suites 44/44.

* test(arch-10): repair census audit, zero-statement witness, CAS writers, and runner reserve

Four review findings on PR #157:

- Census backend tag (r4558770204): PG mints registered backend
  postgres while ab10AuditArm filters on the arm identity postgresql,
  so every PostgreSQL mint was skipped and both inventory legs failed
  with minted 0. Registration now uses the arm identity. The audit
  additionally moves into the first-registered t.Cleanup of each arm:
  LIFO ordering guarantees the fixture drop cleanups have marked the
  registry dropped=true before the registry is read, and a fresh-
  connection zero-survivor census (ab10AuditSurvivors) always runs,
  even after failures. Registration happens after the env-skip
  decision so skipped arms stay skip-clean.

- Zero-statement witness (r4558770211): after/before/executed were
  discarded and n_tup_ret is not a pg_stat_database column, so the
  branch asserted nothing and would then fail with a spurious probe
  error. Replaced with a durable n_xact_commit delta: the paired
  assertion allows +1 for the before-witness read's own commit and
  fails on anything beyond; the pool is opened before sampling so
  assembly never lands in the window; the Arango lane asserts the
  typed refusal alone and its comment now says so.

- CAS writer goroutines (r4558770219): requestJSON calls t.Fatal,
  illegal off the test goroutine. Writers now use ab10AttemptJSON,
  which returns errors into the outcome; the main goroutine fails
  after done.Wait().

- Runner reserve (r4558770214): the conformance budget check ran
  after the lane and reserved up to 390s against the fixed 480s
  deadline, so a real run threw Eight-minute fixture budget exhausted
  after all work had executed. Reserve now precedes the lane with the
  sibling shape (goTestBudgetMs + kill + cleanup margin) and the lane
  uses the shared Go timeout, mirroring generation-load.

Validation: go vet clean; offline parent pass with both arms skipping
named identities; full ./internal/server 6.6s; skipset capture
byte-identical; runner suites 44/44.

* fix(postgres): assemble the capability evidence reader over all three boundaries

Runtime.Catalog is documented as the full catalog store: the value behind the
narrow evidence ports plus the capability-evidence reads that the Explorer
capability resolver consumes. The assembly handed out the inventory-only
Store instead (r.Catalog = inventory). catalog.ReadCapabilityEvidence calls
DiscoverResourceInventory, DiscoverRelationshipObservations, and
DiscoverFieldEnrichment on one reader, so the Builder capability lane of the
full PostgreSQL runtime dereferenced two repositories that were never
injected: GET .../authoring/v2/builder panicked at relationships.go:342 and
the route answered 500 INTERNAL_ERROR while the Arango lane served the same
request. Found by the architecture conformance suite
(arch-backend-10), reproduced at the assembly boundary.

Add catalogstore.NewCapabilityEvidenceStore, which requires all three
boundaries, and assemble Runtime.Catalog with it. Inventory and Relationships
keep their single-boundary stores; nothing else consumed Catalog.

Regression witnesses drive all three discovery methods, and the aggregate,
through the assembled runtime against a live service: field profiles arrive
through the runtime's own write port and the inventory through its rebuild
port, so "available" means the boundary answered. Restoring the inventory-only
assembly reproduces the nil-pointer panic in these tests by name.

* test(server): repair the conformance cells the live PostgreSQL arm exposed

Offline composition proved the suite; the live arm adjudicated the assertions.
Six cell-logic defects, all of them the test asserting something production
never promised:

- Fixtures ran census probes on the maintenance pool, which cannot see the
  fixture database. Add an iso pool per fixture and route probeCount,
  ab10PGRowsDigest, and ab10PGLedgerDigest through it.
- The fence stub treated an empty-but-non-nil authz map as "no stub", so the
  decoy branch never fired. Test len(grants) == 0.
- Loads stamped raw auth paths while the bulk-load boundary normalizes them,
  so the read-scope filter matched nothing. Stamp through
  authscope.NormalizeAuthResourcePath on both arms.
- Arango loads without a Dataset ref take the primary-resource lane, which
  stamps no dataset_generation, so a staged generation leaked into scalar
  reads. Pass explicit publication.NewRef refs.
- Release CAS: the production zero-write no-op compares the active release
  before the expected revision, so "exactly one caller succeeds" was wrong —
  same-candidate drivers legitimately converge. Assert the write count
  instead: same-candidate drivers all converge on one verdict with the
  revision moving by one; two distinct non-active candidates on one expected
  revision give exactly one winner and one typed conflict; three give one
  winner and two conflicts.
- Manifest activation: re-activating the pointed-at generation is the same
  documented no-op, so the wrong-expected-pointer witness needs a candidate
  that is not the pointer. Drive gen-a/gen-b through the fence (refusal
  leaves the pointer untouched, matching pointer moves it, active candidate
  completes idempotently) and restore the served generation for later cells.
- Cancellation: the adapters observe the context at the driver seam, so a
  small buffered result can complete without consulting a mid-visit cancel.
  Assert the two guarantees they do give: an already-cancelled request is
  refused with the arm's own typed context failure and visits nothing, and a
  visitor abort keeps its error identity and stops delivery of the rest.
- The mint ledger billed subtest mints to the parent leg and assumed a single
  invocation. Stamp registrations with a sequence and scope each leg's audit
  to its own name, so -count and -run filters stay honest; the arm-end audit
  keeps the anti-sprawl and leak guarantees.

All 14 cells pass against a live PostgreSQL service, and the fence cell is
stable across eight repeats. The Arango arm's fixes ride on CI.

* test(server): address the Arango census cursor by its real route

The census probes posted to /_api/cursor/database/<db>. On a multi-database
server the path parameter after /_api/cursor/ is the CURSOR ID, so Arango
answered 404 errorNum 1600 "cursor not found" for both the occurrence count
and the stored-payload attribute probe. The database belongs directly after
the route: /_api/cursor/<db>.

* fix(ci): adjudicate the conformance suite outside the 8-minute PG fixture budget

The opt-in PostgreSQL 18 fixture runner enforces an 8-minute internal
deadline under a 540s step and a 10-minute job contract. On CI the seven
store/ingest lanes completed their reserves at ~213s, and the conformance
lane's honest 270s reserve (180s Go timeout + kill + cleanup margin) then
tripped the deadline before the lane could start: "Eight-minute fixture
budget exhausted". The reserve is honest — it must cover a hung child until
timeout and kill — and the lane also drags the runner's first cold compile
of ./internal/server into a budget sized for store/ingest packages. No
reserve tuning fixes a structural overrun.

The lane was a duplicate gate anyway: the conformance suite's adjudication
lane is the dedicated backend-conformance job, which boots both real
services, runs both arms with zero-skip acceptance over the frozen 29
identities, and carries its own 10-minute budget; the Arango real-service
runner additionally registers the ArangoDB arm as a required server-profile
witness. The PG fixture runner returns to its store/ingest contract.

The skip-set capture pin test moves to the Arango runner test, beside the
allowlist whose identities the capture must match byte-for-byte.

* fix(arango): converge same-candidate release CAS races through retry

Arango aborts the loser of a concurrent same-candidate activation with
error 1200 on the ignoreRevs:false pointer update before its snapshot
can ever take the alreadyActive zero-write no-op, so the shared CAS
contract (memory reference + PostgreSQL: same-candidate drivers all
converge) was violated under the race while different-candidate rivals
correctly got the typed conflict. The abort is zero-write, so the
bounded re-run is safe: the fresh transaction re-evaluates every fence
guard, converges via alreadyActive for the same candidate, or surfaces
ErrReleaseActivationConflict for a rival. Cancellation stops the retry
after the first abort. Fake-RowQueryer witnesses cover converge, budget
exhaustion, cancellation, and non-conflict pass-through. Witnessed by
the publicationControlFenceRejectsStaleOwner cell on the Arango arm.

* test(server): oracle dataframe rows by FHIR logical id, not _key

The dataframe _key column is arm-native row identity: the PostgreSQL
lane serves the logical id, the Arango lane a g_<sha256> graph digest.
The literal oracles therefore project an explicit id rootField and
match rows on the logical id, which both arms serve identically; the
paging cell asserts repeat-stability of the arm's own row identity
byte-for-byte plus literal logical-id coverage. The mutation negative
controls keep the oracles non-vacuous.

* style(server): gofmt the conformance suite

The gofmt gate caught drift introduced by hand-editing the decoded-row
struct fields.

* test(server): route census cursors through the production _db path

Both CI attempts against /_api/cursor/<db> and /_api/cursor/database/<db>
answered 404 errorNum 1600 (cursor-not-found): Arango routes the
/_api/cursor/ prefix to the by-id cursor endpoints, which only take the
bare /_api/cursor form for creation. The production profile client
(internal/backends/arango/internal/store/profile_client.go) posts
/_db/<database>/_api/cursor with the same raw-URL pattern, so the
census probes now use exactly that route.

The reopen cell's mint audit also ran on both arms while billing the
postgresql backend, so the Arango leg failed its own ledger. The audit
belongs to the pinned-pre-refactor fixture and moves into the
PostgreSQL path, where the leg-scoped inventory entry lives; the
Arango leg mints nothing and the arm-end audit already forbids
unregistered minting legs.

* test(server): address the Arango census by logical_key and lease by claim verdict

The payload-attribute probe looked the vertex up by FHIR id, but ingress
namespaces every vertex key to g_<sha256> and keeps the FHIR id in
logical_key (generation_identity.go), so DOCUMENT(collection, id) could
only ever miss. The probe now selects project + dataset_generation +
logical_key — the same census the PostgreSQL arm runs against its
logical_id column.

The lease-fence assertions demanded errors where both registries
document refusal-by-verdict: AcquireBundleLease answers (false, nil)
when the lease is held by another (RowsAffected 0 on PostgreSQL, an
emptied UPSERT behind the Arango FILTER), and a foreign release is a
no-op that leaves the fence intact. The cell now asserts the claim
verdicts and keeps the owner renewal as the durable fence-survival
witness after the foreign release.

* test(server): declare the census collection bind at the @@ arity

Arango resolves an @@collection declaration from the @-prefixed bind key
(the production lifecycleCollectionBindVars passes
"@lifecycle_collection"); the rewrite passed the bare key, so the
cursor answered 400 errorNum 1551. The simple @project/@generation/
@logicalKey/@Attribute declarations keep their bare keys.

* test(server): refuse to read a missing census row as an absent attribute

Both payload witnesses conflated row-absent with attribute-absent: the
Arango scan yielded null and the PostgreSQL count went to 0, so the
negative three-state witness could pass on an ingestion gap. Each probe
now returns two verdicts — found and hasAttribute — and fails the cell
when the scoped census (project, dataset_generation, resource type /
collection, logical id) does not find exactly one stored row, matching
the PostgreSQL scoping on both arms. Follow-up on review thread
PRRT_kwDOS-yV5s627ijN; the logical_key addressing and project/generation
threading the thread asked for landed in 8d519ff/66a47657.

* test(arango): re-pin citation lines shifted by the release CAS retry

The F-B13/F-B15 citation guards pin activateReleaseAQL lines by number;
the bounded conflict retry inserted 27 lines, so the explorer-profile
citation check failed (citation drift: release_store.go:178) and aborted
the Arango integration runner before the server profile could re-run the
conformance arm. Re-pinned to the verified current lines (178->205,
192->219, 202->229, 167->223).

Also re-pinned one pre-existing base drift the sweep caught:
bulk/load/service.go:213 -> 217, shifted by the GENERATION_NOT_READY
comment block on base. That table's test is LOOM_TEST_ARANGO_URL-gated
and in no CI profile, so base never noticed.

* docs(arango): re-point the F-B15 prose citation to the moved short-circuit

The failed-on-purpose message and header cite the alreadyActive /
selectedRevision pair by line; the CAS retry shifted it from 158-159 to
209-210. Narrative only (no assertion), but a stale pointer misleads the
next reader of the F-B15 finding.

* ci(pg-fixture): run the capability-evidence witnesses as a never-skipped lane

The two runtime capability-evidence assembly witnesses skip without
LOOM_TEST_POSTGRES_URL, which no lane sets, so after the rebase moved the
production composition to base they proved nothing on a green CI. Add a
capability-evidence-integration phase to scripts/run-postgres-integration.mjs
with an explicit -run filter and both names as anchors, executed under the
job's owned PostgreSQL by checkGoEvents' zero-skip gate: a skipped witness
now fails the run instead of silently passing every lane.

Measured budget: 8.0s wall cold-cache, 0.7s warm for the filtered pair; the
60s Go timeout is ~7.5x the worst measurement and the phase reserves
timeout + 30s kill + 30s cleanup inside the eight-minute deadline. The
witnesses own their isolated database end to end, so the phase administers
nothing, mirroring the generation-load lane.

Evidence: live runner pass (summary.json capabilityEvidenceIntegration,
jsonl zero skips, both witnesses run+pass); runner suites 37/37 including
two new negative tests that prove a skip or a never-run anchor is fatal;
scripts/tests discovery 48/48.

Addresses review thread PRRT_kwDOS-yV5s628TgQ.
…nd lanes (ticket code-comments-20261113-01) (#161)

* chore(comments): remove handwritten comments from dataframe and backend lanes

Ticket code-comments-20261113-01-dataframe-backends, batch
c4b53e23b9d190fe addendum remove-all-code-comments-20261113.

Removes 42,152 handwritten comments from 571 of 805 lane Go files under
internal/dataframe/** and internal/backends/** using an AST-aware lever
(go/parser comment-range removal). Machine law per file: comment-skipping
go/scanner token streams identical pre/post, and position-insensitive AST
structural equality with comments excluded. Only 7 //go:embed compiler
directives (go toolchain, embedding migrations/*.sql) remain, plus 3
comments asserted verbatim by lane acceptance tests
(TestSQL16LawCells x2, TestPublishPartialPointerNeverAdvertisedAgainstArango).

40 .sql migration/fixture files are untouched: their bytes are sha256-
frozen by embedded-migration checksum contracts asserted in lane tests;
stripping was proven safe by token-law + libpg_query parse-tree identity
but reverted rather than falsify the frozen-byte guarantees. Ruling
requested from the operator via the coordinator.

JSON/.query testdata classified as runtime fixture payloads: no comment
grammar; preserved byte-for-byte.

Validation: go build + go vet clean on both trees; full lane sweep
go test -count=1 all 44 packages ok (4,669 tests; 966 environment-gated
service tests skipped by design, exercised in CI); gofmt clean on all
lane files; git diff --check clean; diff restricted to lane .go files;
zero .md changes.

Co-authored-by: AO <ao@localhost>

* revert(comments): restore //nolint:govet directive for isolated-removal split

Per coordinator ruling on code-comments-20261113-01: the single
//nolint:govet removal in this lane is kept in its own commit so a
reviewer can revert it in isolation. This commit restores the line;
the next commit removes it alone. Net head content is unchanged.

* chore(comments): remove //nolint:govet directive (isolated commit)

isolated per coordinator ruling. Removal accepted: the repository has
no Go linter - no .golangci.yml/.yaml, no golangci/staticcheck/revive
step in .github/workflows or Makefile (grep negative evidence recorded
in evidence-code-comments-01.json) - so the directive is not a
semantically required tool directive under the operator policy.
gofmt/go vet pass with and without it.

* fix(comments): re-pin line-number citations and restore //nolint:govet

Comment stripping shifted source lines, breaking line-number citation
pins that are verified verbatim at runtime:

- cross_generation_publish_e2e_test.go: release_store.go 205/219/229
  -> 179/193/203 (caught by TestStaleReceiptPublishDowngradesActive
  GenerationAgainstArango in CI Arango job)
- generation_activation_cas_e2e_test.go: 9 pins remapped
- dangling_binding_e2e_test.go: 5 pins remapped
- release_dangle_reconcile_e2e_test.go: 4 pins remapped

All remaps derived by difflib alignment of base 9534829 vs head lines
and re-validated: every citation that passed at base passes at head;
25 pre-existing base-stale entries left untouched (out of scope).

Restores //nolint:govet byte-for-byte from base on
stage_sequence_test.go (fresh shadow of the entry-render error is
intentional) per coordinator directive audit; the earlier isolated-
removal commits e3386ce/c5e77527 remain in history as ordered.

Directive census (base vs head, all lane files): identical -
1 //nolint + 7 //go: retained both sides; //export and //line base
matches were prose, not directives.

Verified: go build + go vet clean; go test pass for arango explorer,
dataset, publication, and dataframe compiler/render/postgres packages.

* fix(comments): re-pin base-stale citation rows citing lane-stripped files

Review thread r4560137711: dangling_binding_e2e_test.go pins on
internal/dataframe/published/current.go at 208/211/212/213/216 were
decorative - already off at base 9534829, and this PR stripped 6
comment lines from current.go, so the sweep that re-pinned the passing
rows should have corrected these too. PR body claim ('leftover stale
triples are all non-lane files or soft-log checkers') was wrong for
this table.

Re-pinned all base-stale rows whose cited file is stripped by this
lane (reviewer-supplied values verified against head; rrd values from
unique-occurrence + in-function context - all six bundle_store rows are
unique lines inside Reconcile at 1044+):

- dangling_binding: current.go 208->203, 211->206, 212->207, 213->208,
  216->211 (releaseMaterialization loop region)
- release_dangle_reconcile: bundle_store.go 1068-1097 -> 1106/1107/
  1111/1143/1148/1159; current.go 95->94, 99->101, 208->211

Citation universe now: 62 triples = 16 pass untouched + 35 pinned-pass
(21 head-shift remaps + 14 here) + 11 base-stale inventory. Remaining
11 all cite files this PR does not strip (internal/dataset/release.go
x10, internal/explorer/lifecycle/publish.go:89); release.go is stripped
by lane-02 #163 but fails-at-base keying keeps them bucket-3 inventory.

Verified: classify_citations.py 0 newly-drifted, 0 drifted-at-head in
lane-stripped files; gofmt/vet clean; arango publication/explorer/
dataset packages pass.

---------

Co-authored-by: AO <ao@localhost>
… across AQL and PostgreSQL (#175)

Extract the final bounded page collection from ScanCategoriesCompiled's
AQL arm and scanCategoriesPostgreSQL into one private helper taking the
compiled command, declared-column list, and a value decoder. The AQL arm
keeps its overflow witness and index preparation; PostgreSQL keeps the
two-column positional declared contract and decodePostgreSQLCategoryValue,
while AQL uses identity decoding with an empty declared contract.

Add TestExec06PGCategoryPageCollectorDialectParity: the same logical page
yields identical values, presence bits, overflow flag, completeness, and
proof across dialects; overflow caps identically at the bound; malformed
raw JSONB refusal stays PostgreSQL-only.

Fresh-source recheck at tip 80bca9a (post comment-sweep) confirmed the
ticket sites with shifted line numbers only.

Validation: gofmt clean; go vet ./internal/dataframe/execution clean; go
build ./internal/dataframe/... clean; go test ./internal/dataframe/execution
-run 'TestScanCategoriesCompiled|TestExec06PGCategory' -count=1 pass; full
package offline pass (live PG acceptance deferred to quiet-window grant).

Ticket: pg-cleanup-168-execution (batch c4b53e23b9d190fe)
Issue: #168
…efore shared result assembly [pg-cleanup-170-cell-trace] (#177)

Both dialect parsers now decode the traced value and contribution page into a common cellTraceDecodedRow and hand it to one assembleCellTraceResult, which owns status validation, hasMore/omission extraction, NextOffset, and CellTraceResult construction. cellTracePostgreSQLJSONParts and raw-JSON value decoding stay the PostgreSQL adapter; parseCellTraceContributions stays for AQL's native array shape. Invalid status is still rejected before any contribution or value decoding, and all observable error strings are unchanged. Adds TestCellTraceCompiledRejectsInvalidStatusBeforeEvidenceDecoding (AQL and PostgreSQL arms) pinning the precedence and the fail-closed-not-row-absence classification. Row-identity digest, witness matching/limits, cancellation, not-found classification, and the sealed six-column PostgreSQL contract are untouched.

Verification: gofmt/go vet/go build clean; go test -count=1 ./internal/dataframe/execution ok; live PG18 focused run -run 'TestCellTraceCompiled|TestPostgresCellTrace' exit 0 with 28 top-level passes, 0 fails, 0 skips; TestZZPostgresCellTraceZeroLeftoverFixtures pass (coordinator-granted quiet window).
…e exclusion validator (#176)

The AQL and PostgreSQL table-shape exclusion parsers repeated the same
semantic checks and result assembly. Each parser is now a small dialect
decoding front end producing one private normalized evidence value
(presence bool, category value untouched, driver-native category type/
row identity/reason/identity status/omission, decoded source identity
strings), and tableShapeExclusionFromEvidence is the single semantic
validator and result builder. The PostgreSQL raw JSONB strict decoders
are preserved and the category value is never normalized, keeping SQL
NULL distinct from explicit JSON null.

- Error messages, rejection order, and no-partial-success law unchanged.
- The nine PostgreSQL declared columns, pagination, omission-driven
  INCOMPLETE status, cancellation, and unsupported-adapter statuses
  remain owned by TableShapeExclusionsCompiled.
- Added a paired malformed-row table proving the same semantic
  rejections for the AQL-native representation, mirroring the existing
  PostgreSQL-decoded table.

Checks: gofmt clean; go vet clean; go build ok; git diff --check clean;
go test ./internal/dataframe/execution -count=1 ok offline; focused
run TestTableShapeExclusions|TestPostgreSQLTableShapeExclusions ok;
38 paired violation subtests pass. Live PG suite pending quiet window.

Ticket: pg-cleanup-169-execution
Refs: #169
…oundary (#179)

All production SQLSTATE/constraint inspections outside store/errors.go now
route through nil-safe predicates owned by the store package, so bare and
wrapped typed-nil *pgconn.PgError values can no longer panic or be mistaken
for real server replies.

- store: export IsUniqueConstraintViolation, IsForeignKeyConstraintViolation,
  IsUndefinedTable, IsDeadlockDetected over the existing pgErrorFrom
  boundary; add shared 23503/42P01 constants
- store: inventory publish/write, verifyStatementError, readLedger, and
  CommitOutcomeUnknown use the boundary; duplicate local SQLSTATE
  constants removed
- catalog: semantic build/contribution classifiers delegate to the
  boundary; local 23505/42P01 constants removed
- dataset: local isUniqueViolation classifier and constant removed;
  manifest creation uses storepostgres.IsUniqueViolation
- explorer: member-ref, draft-history, explicit-group, interpretation,
  and publish-deadlock classifiers delegate to the boundary; duplicate
  SQLSTATE constants removed
- tests: typed-nil (bare/wrapped/double-wrapped/joined) coverage for the
  new predicates, CommitOutcomeUnknown, verifyStatementError, and
  inventoryWriteError; positive/negative constraint, foreign-key,
  undefined-table, deadlock, ordinary, and wrapped-chain cases; adapter
  typed-nil guards; read-only witness allowlist gains pgErrorFrom only

Public error identities, sentinel joins, redaction, retry decisions, and
ambiguous-commit semantics are unchanged. Verified offline with gofmt,
go vet, go build ./..., and go test of all internal/backends/postgres
packages; live PG18 suites run separately with LOOM_TEST_POSTGRES_URL.

Ticket: pg-cleanup-165-error-boundary (batch c4b53e23b9d190fe)
Issue: #165
… namespace (#178)

* test(pg): scope publication fixture audits to the owned verify_pubvis namespace

auditPublishVisibilityLeftovers compared the complete shared pg_database
set against a process-start baseline, so unrelated suites creating or
removing their own databases during the run failed this audit despite
correct cleanup. Replace the baseline capture and the two hard-coded
sibling-prefix exemptions with the read-pins pattern: retain the
exact-name creation registry check and add left(name, $1) = $2 scans of
pg_database and pg_namespace restricted to this suite's verify_pubvis_*
fixture namespace, with no LIKE patterns and no mutation of foreign
objects.

Add regression controls: a foreign fixture database created, audited
alive, survived, then removed independently; a registered owned database
leak; an unregistered namespace database leak; and a namespace schema
leak, each asserting the audit fails clearly and names the leak.

Refs: #166
Ticket: pg-cleanup-166-fixture-isolation (batch c4b53e23b9d190fe)

* test(pg): close the foreign-fixture pool after its defensive drop

The defensive t.Cleanup drop ran after a deferred pool Close and reported
closed pool on the safety-net path only. Register the pool close as the
first cleanup so LIFO ordering drops the foreign database while the pool
is still open.

Refs: #166
Ticket: pg-cleanup-166-fixture-isolation (batch c4b53e23b9d190fe)
…tion source [pg-cleanup-173-fixture-sanitizer] (#180)

sanitizeSchema had no production callers; all four call sites were
fixture migration-rerun helpers building SET LOCAL search_path
statements. Fixtures now use pgx.Identifier{schema}.Sanitize()
directly, matching existing fixture quoting style. sanitizeTableRef
and all fixture allocation/cleanup behavior are unchanged.

Verification: gofmt clean; go vet clean; go test
./internal/backends/postgres/internal/explorer offline compile pass;
live PG18 suite run recorded in PR evidence.
… [pg-cleanup-167] (#181)

* refactor(pg): give partial catalog adapters capability-specific types

The catalog package represented inventory-only, profile-only, and
relationship-only compositions as the same concrete *Store, so a partial
adapter still satisfied catalog.CapabilityEvidenceReader and failed only
when its missing leg was used.

Split the legs into InventoryAdapter, FieldProfileAdapter, and
RelationshipAdapter, each carrying only its own capability, and reserve
the composed Store for NewFullStore, which requires all three
repositories. Migrate the profile-only control read path, the control
vocabulary wrappers, and the ingest fault-seam wiring to the narrow
adapters and remove the replaced partial constructors/aliases.

Typed ErrStoreLegNotAssembled refusals are kept for zero-value misuse;
the #158 wrong-leg refusal probes become compile/type-contract evidence
that a partial adapter cannot be passed as the complete capability
reader, plus live partial-leg boundary coverage. Public error strings,
sentinels, wire formats, and the full production composition are
unchanged.

Refs #167

* test(pg): correct profile-adapter boundary pin in live capability test

TestNarrowAdaptersAnswerTheirLegAndNeverTouchForeignLegs pinned three
filtered profile reads; DiscoverExistingAuthResourcePaths with
AllGenerations reads through ListDistinctAuthResourcePaths, so the true
filtered count is the enrichment and field-discovery probes alone.
Pin 3 -> 2 with its want string: one expectation, two adjacent lines of
one hunk, test file only, production untouched. Authorized by the
coordinator under ticket pg-cleanup-167-catalog-types; corrected pin is
mutation-proven (a third filtered read in production fails the test).

Refs #167
…02 — cmd, internal, generated (code-comments-20261113-02) (#163)

* chore(comments): strip handwritten comments from cmd/** and paired fhir helpers template

Ticket code-comments-20261113-02-go-application, wave A. Lever: stripgo
(go/scanner token-sequence identity + complete comment-discarded AST
equality per file, negative fixtures green). cmd/generate/fhir_helpers.go.tmpl
is a handwritten embedded asset (zero template actions, nothing in-repo
writes it) byte-identical to generated/fhir/helpers.go; stripped as a pair
with the single Code-generated banner line kept in both to preserve
regenerate==committed fidelity. //go:embed directive retained (tool+purpose
recorded in evidence). Checks: git diff --check, go build ./... pass.

* chore(comments): strip handwritten comments from internal/api/**

Ticket code-comments-20261113-02-go-application, wave B. stripgo law
(token-sequence identity + AST equality) per Go file; SDL lever
(token-stream identity with atomic string/block-string tokens) removed the
18 handwritten # comments in internal/api/graphql/graph/schema/schema.graphqls;
gqlgen-managed fhir_schema.resolvers.go keeps only its tool-emitted banner,
handwritten body comments removed; r20 testdata JSONs attested comment-free
by strict json.load. Checks: git diff --check, go build ./... pass.

* chore(comments): strip handwritten comments from internal/server/**

Ticket code-comments-20261113-02-go-application, wave C (includes
backend_architecture_conformance_test.go released from merged #157 per
coordinator update 211). stripgo law per file; both //go:embed directives
retained (Go tool embed; testdata fixtures as embed.FS); 4 saved-document
testdata JSONs attested comment-free by strict json.load. Checks: git diff
--check, go build ./... pass.

* chore(comments): strip handwritten comments from internal/explorer/**

Ticket code-comments-20261113-02-go-application, wave D. stripgo law
(token-sequence identity + complete AST equality) on all 247 files.
Checks: git diff --check, go build ./... pass.

* chore(comments): strip handwritten comments from remaining internal/** packages

Ticket code-comments-20261113-02-go-application, wave E: ingest, catalog,
fhir, dataset, authscope, acceptance, source, store, ci, projectid,
repositoryseed. stripgo law per file. Checks: git diff --check,
go build ./... pass.

* chore(comments): strip handwritten comments in generated/** handwritten assets

Ticket code-comments-20261113-02-go-application, wave F. generated/loomapi
handwritten files (strict_json.go + package tests) stripped via stripgo;
13 genuinely generated files exempt with banner + emitting-source evidence
(cmd/generate banners, Makefile gqlgen v0.17.94 / oapi-codegen v2.8.0 pins).
Checks: git diff --check, go build ./... pass.

* fix(comments): retain FB20 guard-quoted doc promise in recipe_execution_reader.go

FB20 anti-drift guard (fb20QuotedFacts reader-promise-ids-are-not-credentials
in recipe_execution_reader_authz_e2e_test.go) quotes this doc-comment prose
as a source fact; removal fails the guard and weakening tests is forbidden.
Policy classification: documentation prose whose removal is not safe; kept
with recorded classification and escalated to coordinator. Full affected
suite green.

* chore(comments): adopt gqlgen regeneration output for tool-managed resolver/executor files

Regeneration-oracle proof (coordinator ACK ruling 3): make generate-graphql
(gqlgen v0.17.94, go.mod pin) in scratch revealed these files' comments are
tool-emitted, not handwritten: gqlgen re-adds the 'is the resolver for the
X field' boilerplate and embeds schema.graphqls verbatim in
root_.generated.go's schemaString. Adopted = regen output; regenerate ==
committed for the gqlgen chain. Handwritten RunDataframeRecipe doc in
schema.resolvers.go is gone (replaced by boilerplate); no code changes.
Recorded as tool-managed/regeneration-proven in the lever registry.
go build + resolver suite green.

* fix(comments): retain F-B21 guard-quoted doc promise in internal/catalog/helpers.go

CI Go unit job caught TestPointerNameNulAmbiguityHijacksVisibilityPointerAgainstArango
(pointer_name_nul_ambiguity_e2e_test.go:133-135, F-B21) asserting
internal/catalog/helpers.go contains the quoted doc prose
'catalogIdentityDigest hashes a length-prefixed sequence rather than a'.
Same operator-referral class as FB20 (guard-pinned comments): the guard's
subject is the comment text; removal breaks the guard and weakening tests
is forbidden. Retained under policy 'removal not safe', registered in the
lever GUARD_QUOTED set. Systematic sweep (sweep_guard_quotes.py: every
consumer string literal >= 20 chars across all tracked files, checked for
base-in/current-out substring against each changed file; positive control
reproduces this very hit at head) now shows 0 remaining orphaned quotes.
Test green; guard-quoted keeps: 2.

* fix(verification): re-pin reviewed hashes for comment-only removals [lane-02 code-comments-20261113-02]

Re-pin the 11 stale sha256 entries in verification/builder-interactions/
reviewed-sources.json for internal/explorer/** files whose bytes changed
only by AST-proven handwritten-comment removal (lane 02, code-comments-
20261113-02 addendum remove-all-code-comments-20261113). No other manifest
field touched; baselineCommit stays e736e13.
Coordinator-authorized one-off cross-lane exception (option a); precedent
a4d29f0 (#113) change-author re-pin in own PR.

REVIEW-CONTINUITY CLAIM: reviewed-source SEMANTICS are unchanged. Per file,
go/scanner token sequence identical pre/post and complete structural AST
equality holds (all fields except token.Pos/Doc/Comments); lever wave-D
evidence below. The formal-model review at baseline e736e13 therefore
remains valid; only the content hashes move.

Pre/post table (base-blob sha256 == manifest old, head-blob sha256 == new):
- internal/explorer/lifecycle/construction_category_discovery.go
  old ed788312d414014f5bc767e7184fc0c2962598790054f215385cbe4c88e22b96
  new 4e64a91589cffcf0fab618e287aec24fc31fd73392ca16f8c45b0a31b932f732
- internal/explorer/authoringv2/construction_validation.go
  old 6c1de18539c62d1722ee17080932592b00e67315c1cf2d1e0f4b0def1bc160b6
  new b5f7eb80849ef77a4098d094dd420da397d71b26a78c51c119c11cffc0559f6c
- internal/explorer/authoringv2/construction.go
  old 9f2c9694cf736ab974efaad50b52867482c723dce5a5b579462b346ef8088c8b
  new b6886a966dd65faa9ef77581b2b2f204910a15abd9d1d5fef89406bc208c6b00
- internal/explorer/lifecycle/population_report.go
  old faa544b8fc1d01aef07c5a9482643566e0f15c9fe8733d7aeda4debd5ec5ad5e
  new 41e06e00f9b436dee26deb57c5d396a8ac7cc432051ef63a93aed80d7049fe30
- internal/explorer/lifecycle/population_member_proposal.go
  old 519618cb70b0e3865bb49a88201965ba2930ff6127b9364e54995a0eb58b3a96
  new be6b94ff78d0dc7326973eefe855348dfe317021cc75a2d51ea368fcff2b521e
- internal/explorer/lifecycle/authoring.go
  old 28a40031690bef761a52f6cecffdd5967e5c41fabb49f2727c614995c265da5e
  new 2447e01f4b62e5efbf5e6edc419418e5241f18d099859a3349af25d14284616d
- internal/explorer/service.go
  old 357d8a2bfdded3e6f289a5bfa898d7211ff8cafdd973fd4f4baa9d07d9b0340b
  new 2239c3c7093f390962961d8c45f120c8fbd1afda500a683a1efbc92960666e83
- internal/explorer/lifecycle/construction_proposal.go
  old 09ecdf59c0816b7101b2d80fe60b4b1a467ccb69166412891727d13be2c07aae
  new 425bd54ec28a7d5162371d268d793e415af4fbc63e498ff6aea18cf5e88f5956
- internal/explorer/authoringv2/construction_change.go
  old e77128774088970c204054171e857461c0e820573aeddd1da70cf437509ca82f
  new 0ff459d136a393a7b10f502c592f621762b8e4a5a5302c43052390c093cdf816
- internal/explorer/lifecycle/population.go
  old 467b3170d7a67a946f6274ef47c4e716975a9738d0786b537fb32372eeeb0720
  new 4aa83f5ed13e12b931c878ed60c5ff67ef1ef10f4be7c174324206c5b0b80eb1
- internal/explorer/capability/population_route_choice.go
  old 425b5a511e37af114951be176fac06adba1991cc77a6695ea5e7635b3d3bc56b
  new 7244704d39016bfa1d368a1972f583ac22a3d9c4c1efd548325566b8d3dd3d23

Per-file machine law (lever wave-D evidence, token_seq_equal + structural ast_equal):
- internal/explorer/authoringv2/construction.go: 73/73 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/authoringv2/construction_change.go: 20/20 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/authoringv2/construction_validation.go: 6/6 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/capability/population_route_choice.go: 6/6 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/lifecycle/authoring.go: 7/7 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/lifecycle/construction_category_discovery.go: 8/8 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/lifecycle/construction_proposal.go: 23/23 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/lifecycle/population.go: 3/3 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/lifecycle/population_member_proposal.go: 10/10 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/lifecycle/population_report.go: 3/3 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean
- internal/explorer/service.go: 42/42 comment tokens removed; token_seq_equal=true ast_equal=true gofmt=clean

Local re-run green: --self-test --models-only; --phase generated;
--phase trace-controls; --phase source-proofs shards 1/4-4/4
(java Temurin 21 + ui npm ci provided in-sandbox; CI enforces same).

* test(arango): remap line-citation guards shifted by comment removal

Standing gate (lane-01 precedent): differential line-citation sweep over
consumers of the 386 stripped lane-02 files. 8 positional citations in 3
service-gated guard tests pinned line numbers in files whose comment groups
this PR removed (want-strings intact via token+AST law; only positions
moved). Numbers-only remaps: bulk/load/service.go 206/210/217->202/206/209,
server/explorer_capability.go 177/208/218->162/189/199, graphql/dataframe/
rows.go 27/29->25/27. 27 already-stale-at-base citations left untouched
(listed in lever evidence/line-citation-remaps.md; 214-owned targets,
reported separately). Detector sweep_line_citations.py attributes each
drift by base-vs-head want-match; cross-lane edit authorized by the
standing gate order preceding final head.

* docs(verification): re-pin receipt for 0b143de [lane-02 code-comments-20261113-02]

Machine-generated receipt making the re-pin audit trail Git-resident, per
reviewer request (PR #163 discussion_r4560190853) and coordinator ruling
(re-pin approved; receipt required in Git; no amend of 0b143de, whose body
already carries the 22-value pre/post table + per-file token/AST citations).
Empty commit: touches ZERO paths; history untouched (no amend/rebase/force).

Method: at head 49db7ce, clean tree (git status --short empty), for each of
the 11 re-pinned entries compare sha256(working-tree bytes) vs
sha256(git show HEAD:<file>) vs manifest entry. 11/11 triple-equality PASS:

- internal/explorer/lifecycle/construction_category_discovery.go: live==HEAD-blob==manifest == 4e64a91589cffcf0fab618e287aec24fc31fd73392ca16f8c45b0a31b932f732
- internal/explorer/authoringv2/construction_validation.go: live==HEAD-blob==manifest == b5f7eb80849ef77a4098d094dd420da397d71b26a78c51c119c11cffc0559f6c
- internal/explorer/authoringv2/construction.go: live==HEAD-blob==manifest == b6886a966dd65faa9ef77581b2b2f204910a15abd9d1d5fef89406bc208c6b00
- internal/explorer/lifecycle/population_report.go: live==HEAD-blob==manifest == 41e06e00f9b436dee26deb57c5d396a8ac7cc432051ef63a93aed80d7049fe30
- internal/explorer/lifecycle/population_member_proposal.go: live==HEAD-blob==manifest == be6b94ff78d0dc7326973eefe855348dfe317021cc75a2d51ea368fcff2b521e
- internal/explorer/lifecycle/authoring.go: live==HEAD-blob==manifest == 2447e01f4b62e5efbf5e6edc419418e5241f18d099859a3349af25d14284616d
- internal/explorer/service.go: live==HEAD-blob==manifest == 2239c3c7093f390962961d8c45f120c8fbd1afda500a683a1efbc92960666e83
- internal/explorer/lifecycle/construction_proposal.go: live==HEAD-blob==manifest == 425bd54ec28a7d5162371d268d793e415af4fbc63e498ff6aea18cf5e88f5956
- internal/explorer/authoringv2/construction_change.go: live==HEAD-blob==manifest == 0ff459d136a393a7b10f502c592f621762b8e4a5a5302c43052390c093cdf816
- internal/explorer/lifecycle/population.go: live==HEAD-blob==manifest == 4aa83f5ed13e12b931c878ed60c5ff67ef1ef10f4be7c174324206c5b0b80eb1
- internal/explorer/capability/population_route_choice.go: live==HEAD-blob==manifest == 7244704d39016bfa1d368a1972f583ac22a3d9c4c1efd548325566b8d3dd3d23

Runner context: scripts/verify-builder-formal-core.mjs:101-104 independently
asserts digest(working-tree)==manifest for all 29 pinned files and passes on
this head in CI (Formal models + Source proofs 1/4-4/4 green). Receipt also
posted in-thread (r4560211572). Operator sign-off for the one-off cross-lane
exception tracked by coordinator; ledger-thread left open until recorded.

* docs(verification): extend re-pin to 4 lane-01-sweep-stale reviewed-source hashes [lane-02 code-comments-20261113-02]

Extension of the 0b143de hash-entry-only re-pin, per coordinator extension
order. #161's comment sweep byte-shifted 4 ledger-pinned lane-01 files
without (and while unable to) re-pinning their reviewed-sources.json
entries; base 80bca9a fails scripts/verify-builder-formal-core.mjs:101-104
on them (formal run 43377488759), inherited by hop head ea0e1a5.

Independent recompute of all 29 entries vs head blobs: exactly 4 stale,
all lane-01 byte-shifts; other 25 match; no lane-04/TLA/script entry stale
(no stop condition). Runner digest() == createHash('sha256') over raw
bytes, matching the recompute.

baselineCommit e736e13 preserved (frozen).
Hash values ONLY; zero .go/.sdl changes (machine law unaffected: JSON, no
comments). Post-edit: token-identity convergence 0 would-edit (733 files),
line-citation sweep 0 PR-caused drifts.

pre/post table (path | owner-lane | recorded -> live):
  internal/backends/arango/internal/store/client.go | lane-01 | df49ede78861f0857e20410e4b37369ec3efd4cc38873191c98059d0a25fc4d5 -> 3fd27cc4a69b2425457b7c4855156ae3df95cd10516cfaa3130929c1fc9f46f7
  internal/dataframe/compiler/render/clickhouse/workspace_combine.go | lane-01 | 847ed920a4f05f9979c68c505437187f50e8e495f66011403a7a7ebd0b17958b -> a8474cf46bee7d8892d40632e55d0902a1949d4a2abd120e55337bfa2922e85f
  internal/dataframe/compiler/render/aql/stage_sequence.go | lane-01 | 7a98d58e27b154bda15b81b576b9ab614d8647dd4baf62c53d28b081670d3ea1 -> 73ec97a6c2ae9d805c5c469f7c292c6ff60a805e2c7b1e8fe4a916e34d654d37
  internal/dataframe/compiler/render/aql/calls.go | lane-01 | e8dfff64d403d9b10745623813f7870342874dba3c7c30e3ee3cc7a00369906e -> fb58112ba9c5c5d957b6b2120b1134743ff0dc3275f077d97f99fcebf841fc56

Co-authored-by: AO <ao@local>

* test(arango): strict re-pin of 3 dangling-binding release.go citations [lane-02 code-comments-20261113-02]

Verifier 226 finding (coordinator-confirmed, ordered in-scope): the
danglingCitations rows for internal/dataset/release.go cited 193/210/255
while their want strings sit elsewhere; danglingCheckCitations matches the
want anywhere in the file (weak gate, deferred-class) so the drift stayed
masked. Rows were strict-wrong at plan base 25267d1 too (want at
204/221/271; identical at working base 9534829) - repaired in-scope
because this PR shifted the target file by 121 net lines (122 deletions,
1 insertion, comment removal) and re-pinned the 10 sibling current.go rows
in the same table (49db7ce).

Digits-only diff (digit-stripped old/new bytes byte-identical, cmp);
single file touched; zero .go logic changes.

pre/post (row | file | cited -> verified strict at final head):
  45 | internal/dataset/release.go | 193 -> 185
  46 | internal/dataset/release.go | 210 -> 202
  47 | internal/dataset/release.go | 255 -> 247

Battery at final head (working tree == this commit):
  - full-table strict cited-line receipt: 15/15 citations TrimSpace-equal
    at cited line (unique candidates), 6/6 absent-identifiers still absent
    (lever/evidence/dangling-full-table-strict-receipt.json)
  - token delta vs 6214493: digits-only on this file, zero elsewhere
  - citation validator sweep: 0 PR-caused drifts, 8 pre-existing
    (the 3 rows left the pre-existing inventory 11->8; the remaining 8 are
    release_requirements_e2e_test.go r14Citations, base-stale class,
    out-of-scope per coordinator order - lane-05/operator referral)
  - gofmt 0, go vet 0, go build ./... 0

Co-authored-by: AO <ao@local>

---------

Co-authored-by: AO <ao@local>
…alog reads (#182)

DiscoverFields and DiscoverFieldEnrichment projected a persisted
FieldCatalogDocument row into their neutral results with two
independent 21-field copies, so a future field added to one surface
could silently vanish from the other.

Factor the shared FieldCatalogDocument-to-field-observation projection
into one unexported adapter helper; DiscoverFieldEnrichment appends its
result directly and populatedFieldFromProfileDocument converts it to
catalog.PopulatedField through a struct conversion that only compiles
while the two domain layouts stay identical. Distinct row filtering,
profile-status handling, invalid-type diagnostics, truncation,
coverage, digest inputs, ordering, auth-scope behavior, and SQL/query
counts are unchanged; every projected slice keeps its defensive copy.

New offline projection tests seed an in-memory profile store:
all-field equivalence on both read surfaces with typed posture,
digest, and status; per-copied-slice mutation checks proving results
cannot poison persisted state; and a reflection guard that the two
domain structs remain convertible. Mutation-proven: aliasing one
copied slice, dropping one projected scalar, and drifting one domain
field each fail the battery or the build.

Refs #171
…fig/verification code (#164)

* test(verify-ui): re-anchor pivot keyword-names probes to close-path code anchors

Prepare for the policy-required removal of handwritten workflow comments:
the anti-vacuity probe 'switching intent is the real close path' was anchored
on comment prose scheduled for deletion. Replaced with behavioral code anchors
on the same close path: the row-intent-records selector, the 'pivot editor
closed' unmount-wait message, and an adjacency probe requiring the realClick
of the intent-records control immediately followed by the pivot-editor unmount
wait. The adjacency probe makes any real break of the close path (click
removed, wait removed, or order disturbed) fail the probe, closing the
vacuity gap of the bare selector probe (the selector also occurs on a
non-close path at :592-:593). GREEN on this commit with base comments still
present; scratch RED proofs: click-removed, wait-removed, pair-removed all
fail the structural guard (lane04-evidence.json pivot_reanchor.red_proof).

Coordinator ruling (loom-experiment-2 WAVE-2): own commit + scratch RED proof
+ anchor mapping in evidence.

Coordinated with loom-experiment-2.

* chore(comments): remove all handwritten comments from lane-04 tooling/config/verification code

Operator programme remove-all-code-comments-20261113 (batch c4b53e23b9d190fe),
ticket code-comments-20261113-04-tooling. Pure lexer/AST-guided comment
removal over the lane-04 workset (978 tracked paths), base
feature/postgres-backend @ 9534829: 157 files rewritten, 2,127 comment
tokens removed; 166 files proven comment-free by strict parsers; 254
data/evidence assets inventoried only (coordinator ruling 1); 4 run-*
integration scripts deferred under the #159 one-writer hold. Markdown
byte-identical; no other-lane file touched. This commit contains comment
removals only (the pivot-test re-anchor is its own preceding commit).

Machine law: per-language comment-stripped token/AST equality pre/post
(go/scanner+go/parser+gofmt; acorn tokenize+ESTree; tokenize+ast; shell lexer
+bash -n; YAML lexer+js-yaml equality; TLA+ lexer with nested (* *)+token
equality+residue scan; tomllib; line-rule byte identity). Lever re-verified
all 978 files against saved originals with errors=0.

Directive whitelist (tool + purpose recorded in lane04-evidence.json):
shebangs, //go:build, //go:embed, BuildKit # syntax=, go.mod // indirect
(go command), EXTRACT-START/END:killTree sentinels (node test harness
extraction markers). Generated banner scan across the lane: zero hits.

Checks: git diff --check clean; bash -n all tracked .sh; go build/vet/test
(conformance/compiler, packagepolicy, check-boundaries) pass; gofmt clean;
go mod verify; python unittest scripts/tests 48 OK (package_audit CSV/MD
regeneration reverted as generated side effect); node --test 734/738 with the
4 failures identical to HEAD baseline (Go/browser env absent in container);
make -n parse pass; lever negative fixtures 69/69 incl.
proof-rejects-corruption controls.

Evidence: lane04-evidence.json (per-file inventory, methods, kept directives,
unavailable checks: TLC/docker/browser/CI).

Coordinated with loom-experiment-2 (plan ACK, freeze rulings, wave reports).

* fix(comments): restore ledger-cited model comment blocks in six publication-bundle TLA files

Addresses PR #164 review thread r4560127517 (reviewer, AO native f1ca942d):
the deleted SOURCE SYNC round 26/29 headers, fault-injection/legacy-data
reachability caveat for the AtomicPublish arm, and lease-fenced-producer
reasoning in ReconcileDangleTrust.tla, PointerOrphanLifecycle.tla,
PublishPartialPointer.tla, NullPageCoverage.tla, ReleaseRevisionIdempotence.tla
are cited verbatim as authoritative by reviewed-sources.json (r29 header role,
m-dangle-atomic-current caveat 'see model comment', Round 42 source pins) and
release_dangle_reconcile_e2e_test.go:581,585. Those consumers are ledger and
lane-01 owned, so restoring the models is the only in-lane fix.

BundleCommitLifecycle.tla restored as same-class: its base bytes are the
ledger canonicalProbe expectedMD5 pin (14d341f8...), which the strip broke.

All six files restored byte-for-byte to base 9534829 (git diff vs base
empty; MD5s match ledger-recorded model digests). No other file touched.
Comment-removal machine law unaffected: token identity holds trivially for
restored files (they equal base); remaining 152 stripped files unchanged.

* fix(comments): restore ledger-digest-pinned files byte-identical to base

Addresses PR #164 review thread r4561321245 (ConstructionPrepareLanes.tla
sha256 pin, r65 SELF-RUN live==git show 49d6999==on-disk claim, and the
FHelperGateIgnoresCleared / FSetBranchGateIgnoresCleared /
FSetBranchPersistsUnconsumed / FSharedClearedGate per-fault-constant
semantics including the C1-falsifier non-vacuity argument for
ClearedStaysCleared).

Root cause: the strip broke ledger digest pins that were TRUE at base in
verification/publication-bundle/reviewed-sources.json. The earlier
remediation (a174d4f) checked only the model-map md5 fields and the
builder-interactions files map; it missed the publication-bundle files
map and contentMD5 fields. Full exhaustive sweep of both reviewed-sources
files (273 digest pins) found 10 changed files with base==pin now false.
Ledger is off-limits to this lane and README.md/SKILL.md bind digests to
live-byte re-derivation, so restore (same remedy the reviewer prescribed)
is the only in-lane fix.

Restored byte-for-byte to base 9534829 (git diff vs base empty on all
ten): ConstructionPrepareLanes.tla, ConstructionProjectionOwnership.tla,
ActiveGenerationTrust.tla, GenerationActivationCas.tla,
ReleaseBindingTrust.tla, StartupReconcileWedge.tla,
scripts/lib/formal-projection-replay.mjs,
scripts/verify-ui/contracts/source-projection-contracts.mjs,
scripts/ci/vet.mjs, conformance/compiler/benchmark_test.go.

Post-restore sweep: 17 pins over changed files - 13 true, 4 stale-even-at-
base (pre-existing ledger drift, not introduced here: verify-explorer-
unpivot-row-source.mjs, verify-explorer-row-source-four-state.mjs,
row96-row-source-four-state.test.mjs, generated_semantics_coverage_test.go
sha256 pins already false at base; left stripped). Archived playwright
runtime captures pin historical run bytes (367 already stale at base),
inventory-only data assets per ruling 1.

node --check x3 mjs, go vet conformance/compiler pass. Net changed files
now 142.
…he publication-bundle ledger [ledger-digest-repair] (#183)

* fix(verification): re-pin 10 comment-sweep-broken digest entries in the publication-bundle ledger [ledger-digest-repair]

Re-pins exactly 10 digest values in the top-level "files" map of
verification/publication-bundle/reviewed-sources.json to the current
branch-base bytes (git show e68c7d6:<path>, raw bytes, sha256sum/md5sum).
Hash-entry-only repair per coordinator authority (loom-experiment-2),
precedent a4d29f0; the ledger is otherwise frozen.

Root cause (attribution corrected per coordinator, credited to worker
loom-experiment-213; re-verified independently at this head):
- All 10 re-pinned entries were broken by merged lane-01 comment sweep
  80bca9a (#161, ticket code-comments-20261113-01), which stripped
  handwritten comments from pinned files under internal/dataframe/**
  and internal/backends/** without re-anchoring their ledger pins; the
  reviewed-sources ledger was out-of-lane for that ticket. Machine
  attribution: all 10 stale pinned digests equal the 9534829
  (= 80bca9a^) blobs - every pin was TRUE at 9534829 and first
  diverged at 80bca9a.
- internal/backends/postgres/control/vocabulary_control.go was
  secondarily moved by merged cleanup PR #181 e68c7d6 (legit
  ticket-167 partial-catalog adapter refactor, 11+/7-): pin
  7f883cdb TRUE at 9534829, sweep 80bca9a moved the blob to
  98a804cc (still the value at e8a738d = e68c7d6^), and #181 moved
  it again to 5d41b670. Remedy unchanged: re-derive to the current
  tip blob.
- Count reconciliation: the directive tally "10 sweep + 1 (#181)"
  double-counted vocabulary_control.go. Machine truth: 10 files-map
  entries FALSE-at-base, 9 under internal/dataframe/** plus
  vocabulary_control.go under internal/backends/, one of which
  (vocabulary_control.go) was moved by both commits.

Fields per entry (verified per-entry; each carries exactly one digest
field): md5 for publication/bundle.go, clickhouse/bundle_store_test.go,
clickhouse/reconcile_toctou_test.go, publication/pointer_name_encoding_test.go,
published/nullsort_page_cursor_e2e_test.go, published/page.go,
recipe/publication_identity_nul_http_test.go; sha256 for
clickhouse/bundle_store.go, published/read.go, and
backends/postgres/control/vocabulary_control.go.

Frozen / untouched (byte-preserved):
- baselineCommit unchanged. lastUpdated unchanged (sibling precedent
  a4d29f0 touched only review prose + one hash; no ledger commit has
  ever modified lastUpdated after creation).
- 32 files-map digest records across 31 files that are FALSE at base but
  were already stale before 80bca9a: untouched, inventoried in the PR
  body for lane-05/operator referral.
- 7 files-map stale-path entries (path absent at base): untouched.
- 17 FALSE digest bindings outside the files map (confirmed[] and
  preventedArtifacts[] adjudication forensics, model-map contentMD5 and
  fB22Tier1Md5s, repair_units sibling): untouched point-in-time evidence
  hashes; three of them reference re-pinned paths.
- verification/builder-interactions/reviewed-sources.json untouched
  (lane-02 PR #163 owns its 4-entry extension).

Gates (all green before commit; sweep script retained as PR evidence):
1. Machine recompute of the 10 at base: FALSE -> TRUE.
2. Dual-ledger pre/post sweep: status vectors identical outside the 10;
   builder-interactions ledger vector byte-identical pre/post
   (25 TRUE / 4 FALSE); publication-bundle 68->78 TRUE, 59->49 FALSE.
3. JSON parses; git diff --check clean; diff is exactly 10 single-line
   digest-value edits in one file.
4. scripts/verify-builder-formal-core.mjs reads only
   verification/builder-interactions/reviewed-sources.json (its sole
   ledger reference, line 101); that file is untouched by this diff.

No live PG used. Base: e68c7d6 (feature/postgres-backend tip).
Pre-amend commit (attribution wording fix only, tree byte-identical):
c88299e.
Ticket: ledger-digest-repair (coordinator-directive ledger repair).

* docs(verification): refresh pin/rederived justification records for the re-pinned publication-bundle entries [ledger-digest-repair review]

AO native review of 4011e83 (discussion_r4562259237, thread
PRRT_kwDOS-yV5s63DOE8) required, per the a4d29f0 precedent of refreshing
the justification record together with the hash, that the re-pinned
entries not keep attestations whose equality cannot hold for the new
value. Fixed the flagged entry and the two same-class entries whose
attestations the PR #183 re-pin invalidated:

- internal/dataframe/publication/clickhouse/bundle_store.go (flagged):
  pin d5b5491 -> e68c7d6; rederived re-attested to the actual
  re-derivation (git show e68c7d6 blob == entry sha256 == blob at tip
  4878319), recording the supersession of the d5b5491 pin
  (a5db5f55 -> 1dce5b82) and that comment sweep 80bca9a (#161,
  out-of-lane) moved the bytes.
- internal/dataframe/published/read.go (disclosed extension, same
  class): pin d5b5491 -> e68c7d6; rederived likewise (03ac0cd4 ->
  040f0645, sweep-moved).
- internal/backends/postgres/control/vocabulary_control.go (disclosed
  extension, same class): rederived superseded the runtime-composition
  working-tree attestation (ao/loom-experiment-170 branch, base
  28e32a4, amendment 2); records the canonical attribution chain
  7f883cdb TRUE @9534829d -> sweep 80bca9a 98a804cc -> #181 e68c7d6
  5d41b670.

Method: entry-block-scoped single-line value edits (path-key located);
shared attestation strings elsewhere in the ledger untouched (server.go,
explorer_publication.go, options_schemas_test.go, control/runtime.go,
aliases.go retain their original runtime-composition rederived, verified
present). No digest value, role note, baselineCommit, lastUpdated, or
any other entry changed.

Gates green before commit:
1. Re-derivation machine check: for all three entries,
   sha256(git show e68c7d6:<path>) == entry sha256 ==
   sha256(git show 4878319:<path>); rederived text quotes the verified
   digest; pin field matches (absent for vocabulary_control.go, as
   before).
2. Dual-ledger sweep at agreed base e68c7d6: 163-record status vector
   identical pre/post this fix; the 10 re-pinned entries remain TRUE;
   builder-interactions ledger untouched.
3. JSON parses; canonical json.dumps(indent=2) roundtrip byte-identical
   (ledger discipline); git diff --check clean; diff is exactly 5 lines
   (2 pin + 3 rederived) inside the three entry blocks.

Append-only follow-up commit (amend denied per coordinator protocol);
supersedes nothing; PR head advances 4011e83 -> this commit.

Base: feature/postgres-backend (tip 4878319 post #163). Note reported
to coordinator, not fixed here (inventory, lane-05/operator referral):
37 further files-map pins TRUE at e68c7d6 became FALSE at tip 4878319
via the #163 merge's own source moves (base-move drift, list retained
as evidence).

* docs(verification): supersede stale r58 rerun attestation on pointer_name_encoding_test.go [ledger-digest-repair review wave 2]

AO native review of the re-pin (discussion_r4562259258, thread
PRRT_kwDOS-yV5s63DOFC sibling PRRT_kwDOS-yV5s63DOFL) required:
rerun20261102_r58 attested the current md5 as the round-58 re-derivation
of 8c21eb6-only-commit content with prior pin 76337dbac045, which no
longer describes the pinned value after the PR #183 re-pin.

Fix, in the reviewer-prescribed r62-r65 style (original attestation
preserved, supersession appended, naming this repair and the byte-mover):
r58 attested md5 db3807f2b4a9116dd0c70db6f3eb0b9a (machine-verified TRUE
at 8c21eb6 and at 9534829 = 80bca9a^) was first moved to
49187785c747aaad937bd0f3083fd08a by comment sweep 80bca9a (#161,
out-of-lane, no re-anchor); entry now SELF-RUN live md5 ==
git show e68c7d6:internal/dataframe/publication/pointer_name_encoding_test.go
== blob at feature/postgres-backend tip 4878319.

Proactive sweep of all 10 re-pinned entries (coordinator directive m232i:
fix every now-false attestation in one wave): this is the only remaining
false attestation. The other 7 entries carry only a digest field plus a
behavioral role note (no derivation claim); bundle_store.go, read.go, and
vocabulary_control.go were refreshed in wave 1 (269a6f5, threads
r4562259237 / r4562259244 / r4562259251).

Gates green before commit:
1. Re-derivation machine check: md5(git show e68c7d6:<path>) == entry
   md5 == md5(git show 4878319:<path>); quoted historical digest
   db3807f2 verified at 8c21eb6 and 9534829; supersession names 80bca9a.
2. Dual-vector sweep at agreed base e68c7d6: 163-record status vector
   identical pre/post this edit (zero class flips beyond the 10 re-pins).
3. JSON parses; canonical json.dumps(indent=2) roundtrip byte-identical;
   git diff --check clean; diff is exactly 1 line inside the entry block;
   no digest value, role note, baselineCommit, or lastUpdated changed.

Append-only wave-2 commit atop frozen 4011e83 (history law: no amend,
no force). PR head advances 269a6f5 -> this commit.
…me.Readiness (#185)

The six per-series control.Verify*Schema exports existed solely for
the live server read-only witness; Runtime.Readiness already iterates
every assigned series and dispatches to the same six store-owned
VerifySchema implementations with per-series error wrapping, and the
repository search confirms no caller outside that one test.

Delete the six forwarding exports and their orphaned store imports.
Rewrite TestPostgresRuntimeVerifySchemaIsReadOnly to open a control
runtime with the fixture's assigned schemas and SetupNone, snapshot
ledger, table, column, and index fingerprints for every assigned
schema before a single Runtime.Readiness call, then compare all of
them afterward, so cross-schema mutation cannot hide behind
per-schema snapshots around repeated calls.

Store verification, production readiness behavior, the public
Readiness contract, fixture isolation, and readiness negative cases
are unchanged; no store VerifySchema function is touched.

Refs #172
…-comments-20261113-03-ui) (#162)

* chore(ui-comments): remove handwritten comments from UI ts/tsx (wave 1, c4b53e23)

Machine law: per-file parser token-stream (kind,text) equality pre/post via
gap-trivia comment discovery, using TypeScript 5.9.3 from the repo lockfile.
232 files, 888 handwritten comments removed, 837,484 tokens proven identical,
64 @vitest-environment jsdom test-runner directives kept per operator
tool-directive policy.

Declared checks: git diff --check clean; npm --prefix ui/packages/loom-ui run
build exit 0; run test exit 0 (97 files / 1355 tests, matches pristine
baseline at 9534829).

Tool + 25-fixture negative gate: /tmp/ui-comment-tools/ui-comment-strip.mjs.
Ticket code-comments-20261113-03-ui.

* chore(ui-comments): remove handwritten comments from UI scripts/config (wave 2, c4b53e23)

14 mjs/cjs/mts files; only demo-route.mjs had handwritten comments (25-line
JSDoc block), removed with token-stream equality proof for all 14. The
tailwind .cjs comment-shaped hits were glob strings — preserved (negative
proof: files unchanged).

Regression: node --test demo-route.test.mjs 5/5 pass; demo build (tsc
--noEmit + vite) exit 0.

Ticket code-comments-20261113-03-ui.

* chore(ui-comments): remove handwritten comments from UI css/config/special files (wave 3, c4b53e23)

15 files: loom-ui/src/styles.css had 2 handwritten block comments (removed via
postcss AST-equality-minus-comments proof). The other 14 (2 css/json x8/html/
nginx.conf/.dockerignore/2 Dockerfiles incl. full-text continuation-aware
tokenization) verified comment-free and byte-identical.

Declared checks at complete-lane head: git diff --check clean; npm build exit
0; npm test exit 0 (97 files / 1355 tests = baseline). verify pass: 261/261.

Ticket code-comments-20261113-03-ui.

* fix(verification): re-pin reviewed hashes for comment-only removals [lane-03 code-comments-20261113-03]

Re-pin exactly the 5 reviewed-sources.json entries whose files lost
handwritten comments in this PR (ticket code-comments-20261113-03,
batch c4b53e23b9d190fe, operator addendum remove-all-code-comments-20261113).
Coordinator-authorized scope: these 5 hash entries only; baselineCommit
stays e736e13; no other field touched
(diff is 5 changed lines, 5 insertions / 5 deletions).

Pre-check table (base-blob sha256 == old manifest entry verified against
git show <base>:<file>; head-blob sha256 == new manifest entry, computed
from the working tree at the removal head):

  BuilderWorkspace.tsx                                   fc7dd098c4f6cba4.. -> 3e1691e77e548897..
  authoring/model.ts                                     1a288981f3f63dcb.. -> fd87470cae6d1560..
  authoring/reconcileAcceptance.ts                       679a1b1dcbb4c2d2.. -> e617f1a2cc90db4a..
  constructionOperations/ConstructionReshapeEditor.tsx   8f97c58a5ecbe520.. -> a3f66597ebe7cf9d..
  constructionWorkspace/constructionApplyOwnership.ts    13c34fa493dfe699.. -> e03636a22ef578ee..

Full 64-hex values: ui/packages/loom-ui lane evidence, per-file inventory
in PR #162. Every removal is machine-proven token-stream identical
(comment-only): ts/tsx token counts unchanged, CSS AST-equality-minus-comments,
JSON byte-identity, so the re-pin records content-equivalent blobs, not
new semantics.

Post-re-pin local repro (JVM 21, repo toolchain):
- verify-builder-formal-core source-proofs shards 1-4/4: PASS (0 "Review required")
- verify-builder-formal-core --phase generated: PASS
- --self-test --models-only: PASS
- One transient shard-3 TLC parse failure under 5-concurrent-JVM contention
  (/tmp shared standard-module namespace) passed on immediate rerun and at base.

Line-citation differential sweep over consumers of the 51 stripped files:
94 numeric `file:NNN` citations found, all in builderContractAdapters
sourceRefs metadata; no consumer parses the numbers (written into capture
headers only); pass at base and head. Verdict: no differential breakage.

* fix(inventory): re-anchor UI contract inventory pins for comment-only removals [lane-03 code-comments-20261113-03]

Coordinator option-(a) authorization (loom-experiment-2, ticket
code-comments-20261113-03-ui, batch c4b53e23b9d190fe, addendum
remove-all-code-comments-20261113): re-anchor docs/ui-contract-inventory
pins whose targets are files this PR comment-strips, plus the
scripts/normalize_ui_contract_inventory.py evidence-ref string constants.
Resolves the second reviewer ledger item (thread on ui/packages/loom-ui/src/types.ts,
discussion_r4559979558).

Method: deterministic diff-derived re-anchor tool /tmp/opencode/reanchor-inventory.py
(line maps built from `git diff -U0 9534829..f88754c` per stripped file;
per-mapped-line content proof: old line == new line, or old == new + trailing
comment remainder; no hand-edited refs). 1004 ref rewrites, needs-review: NONE.
Compact manifest + watchedFiles regenerated by the canonical normalizer
(scripts/normalize_ui_contract_inventory.py, rc 0). Diff is line-neutral:
920 insertions == 920 deletions.

Diff guards (ruling requirement: entries only derived from the 51 stripped files):
- paths touched: 4 fragments + ui-supported-affordances.json + normalize script, nothing else
- watchedFiles: 103 entries; 24 drifted, all in the 51-file stripped set; new
  digests == sha256(working tree bytes); 79 non-stripped entries byte-identical; file set unchanged
- fragments/manifest: every changed line's refs compared old->new; zero numeric
  changes to refs targeting files outside the stripped set
- normalize script: 44 changed lines, all evidence-ref string literals
  (91 ref tokens); zero logic changes; comments untouched (line counts equal,
  every changed line is a ref literal)

Witnesses at this working tree (portable Temurin JRE 21.0.13, repo toolchain):
- python3 scripts/verify_ui_contract_inventory.py --source-only: PASS, 57
  affordances, source hashes and file set current, source bindings complete
- full verify_ui_contract_inventory: identical failure to base 9534829
  (pre-existing legacy.table_shape.unpivot coverage gaps; not CI-gated; CI
  runs --source-only in tests.yaml:22 and builder-formal.yml:71)
- python3 -m unittest discover -s scripts/tests: 48 tests OK
- verify-builder-formal-core --self-test --models-only: PASS
- --phase generated: PASS; --phase trace-controls: PASS (single transient
  statechart nondelivery under 3-concurrent-JVM /tmp contention, passed serially)
- --phase source-proofs shards 1/4..4/4: PASS, zero "Review required"

PACKAGE_AUDIT.csv/md regenerated by the python suite were reverted (generated
on demand; exclusion pre-agreed with coordinator).

Baseline note: this commit does not touch verification/builder-interactions/
reviewed-sources.json (its own commit f88754c, 5 entries only, baselineCommit
e736e13 preserved).

---------

Co-authored-by: calypr <dev@calypr.com>
…ge (#186)

Five adapter packages, the catalog package, control config, and the
migration runner each compiled their own copy of the identical
schema-name grammar, so a future bound change could silently drift one
surface away from the others.

Expose one pure predicate, ValidSchemaName, beside the now-single
compiled pattern in the store package, and route all twenty-six
validation sites through it, including the store package's own.
Constructor validation order, package-specific sentinels, and every
error message stay byte-for-byte identical; identifier quoting at SQL
construction sites is untouched, as are the distinct application-name
and migration grammars. The dataframe compiler keeps its two copies:
they sit outside the adapter tree and outside Go internal/ reach.

New store tests pin the acceptance set with a verdict table and an
equivalence proof against the canonical literal, including the
63-character bound; mutation probes over corrupting the helper and
dropping a constructor check each fail the battery.

Refs #174
…d CAS of repository publish (#184)

* feat(pg): activate repository generation through the second publish CAS

Implement explorer.Store.ActivateRepositoryGeneration for the PostgreSQL
backend as the second compare-and-set of the repository publish flow,
replacing the deliberate typed refusal in the server runtime.

The adapter runs one transaction against the control, lane, and
execution schemas: lock the candidate, verify the generation manifest,
the active-generation pointer, the PUBLISHED bundle execution, and the
REPOSITORY management mode, then supersede the prior revision, flip the
candidate READY->ACTIVE, and move the owner pointer. Every guard miss
and zero-row CAS maps to the neutral explorer.ErrDraftConflict;
transport failures stay raw so lifecycle keeps them retryable.

Three deliberate divergences from the Arango adapter, agreed with the
orchestrator: the candidate must be READY (not READY|FAILED), the
generation pointer is verified rather than blind-patched, and a replay
is a no-op commit.

Verification:
- gofmt clean; go vet ./internal/... clean; go build ./... clean
- go test -count=1 green for ./internal/backends/postgres/...,
  ./internal/server/..., ./internal/explorer/...
- live PG18 suites (LOOM_TEST_POSTGRES_URL, isolated verify_pgact_*
  database + schemas, zero skips): 15 composite-guard cases including
  happy flip, idempotent replay, and every guard miss with revision and
  owner snapshots unchanged, plus rollback at all three crash seams and
  the activation-vs-failure single-winner race (5 runs with -race)

Co-Authored-By: qwen3.8-flash-next <noreply@anthropic.com>

* test(pg): prove repository publish HTTP spine and pinned replay law

Coordinator amendment for the activation unit (PR #159 battery spine):

- activation_e2e_test.go: pinned replay law cases per the approval.
  replay-with-orphaned-active-candidate-conflicts proves an ACTIVE
  candidate whose owner pointer moved elsewhere loses the neutral
  sentinel race (never silent success); superseded-candidate-conflicts
  proves SUPERSEDED never re-activates. Replay no-op success stays
  conditional on owner.active_revision_id == candidate, matching
  Arango activation.go:18/31 so a battery retry means
  owner-already-flipped.

- repository_publish_wiring_pg18_test.go: HTTP-level acceptance on
  live PG. The production composition (composePostgreSQLFullRuntime)
  serves POST /api/v1/projects/{p}/generations/{g}/explorer-config
  through the real capability, compile, ClickHouse materialization,
  PublishAuthoring, release-activation, and second-CAS activation
  legs; asserts HTTP 200 activated=true, witnesses the flip in
  explorer_revisions and the owner pointer directly, and replays the
  POST to prove the no-op does not restamp activated_at. Gated on
  both LOOM_TEST_POSTGRES_URL and LOOM_CLICKHOUSE_URL; with both set
  it never skips. A ClickHouse-less diagnostic confirms the spine
  reaches materialization (fails there with
  MATERIALIZATION_FAILED/backend-unavailable), proving capability and
  compile seeding work on the PostgreSQL lane.

- runtime_postgres_live_test.go: mint inventory gains a ClickHouse-
  gated leg class so the zero-leftover audit holds the spine leg to
  the one-database law exactly when ClickHouse is configured, and to
  minting nothing when it is not.

Verification: live PG18 composite-guard suite green with 18 cases
including both new pinned negatives; full pgComp server battery live
green (62.8s) with the audit exemption exercised; gofmt, go vet
./internal/..., go build ./..., and offline suites for
./internal/backends/postgres/..., ./internal/server/...,
./internal/explorer/... all clean; lifecycle classification
contracts untouched and passing.

Co-Authored-By: qwen3.8-flash-next <noreply@anthropic.com>

* test(pg): byte-stabilize the whole ledger through the dangling-prior conflict

Divergence-4 acceptance addition from the coordinator: the
dangling-prior-pointer negative now snapshots owners alongside
revisions, so the strict ErrDraftConflict posture is proven to leave
the full control-plane ledger (revisions + explorer owners, updated_at
excluded) byte-stable through the conflict, matching the composite
guard-case discipline.

Co-Authored-By: qwen3.8-flash-next <noreply@anthropic.com>

* refactor(pg): rebase runtime.go adapter onto the comment-free base law

The merged lane-02 comment sweep (4878319, #163) made
internal/server/runtime.go and the lane's test files comment-free,
conflicting with the activation unit's commented additions there.
Take the base's comment-free runtime.go and reapply the activation
delegation unchanged in shape: the narrow repositoryGenerationActivator
interface, the pgExplorerStore.activate field, the nil-gated
delegation replacing the typed refusal, the runtime.Activate nil gate,
and the compose wiring. Strip the handwritten comments added to
runtime_postgres_live_test.go and
repository_publish_wiring_pg18_test.go so every authored hunk obeys
the sweep law. No behavior change.

Co-Authored-By: qwen3.8-flash-next <noreply@anthropic.com>

* ci(pg): run the repository-publish spine leg over PostgreSQL 18 and ClickHouse

The spine leg needs both live services: real ClickHouse materialization
sits between compile and the second-CAS activation flip, and no local
ClickHouse exists in the worker sandbox by adjudication. Add one job
with both ephemeral job-local services (postgres:18 +
clickhouse/clickhouse-server:25.3, wiring copied from the pg-fixture
and go-clickhouse runners), both env families wired, and run the pgComp
battery whole so the spine leg shares the census, the ClickHouse-gated
mint inventory, and the TestZZ zero-leftover audit.

Silent-skip is a red gate: the log is preserved as an artifact and a
follow-up step requires the spine leg's PASS line and fails on any SKIP
of it, so the acceptance proof is executed evidence, not a green job
that skipped past.

Verification: workflow parses (12 jobs, both services, five env keys);
node --test scripts/lib/verification-inventory.test.mjs and
scripts/ci/list-node-tests.failure.test.mjs 14 pass 0 fail;
test_ui_ci_workflow.py OK; gofmt/vet/build clean; spine leg
by-design-skips without envs offline.

Co-Authored-By: qwen3.8-flash-next <noreply@anthropic.com>

* fix(ci): register the pg repository-publish spine leg in the Arango-lane external-skip registry

The go-arango job's run-arango-integration runner rejects undeclared
skips: TestPostgresRuntimeRepositoryPublishRouteActivatesThroughFinalFlip
requires LOOM_TEST_POSTGRES_URL and LOOM_CLICKHOUSE_URL, never Arango, so
its explicit skip in the Arango-only lane was flagged as
'Unexpected skipped case'. Registered in pgRuntimeComposition following
the pg-runtime-server-composition precedent; the dedicated
pg-repository-publish sibling job asserts its PASS line. Runner
self-test (scripts/run-arango-integration.test.mjs) passes.

* style(ci): strip handwritten comments from the spine-leg registry hunk

Lane-04 comment law applies to newly authored hunks; the registration
entry keeps only its machine-required string, matching the 6a4e7af
precedent. Runner self-test scripts/run-arango-integration.test.mjs
passes (fail 0).

* fix(ci): propagate go test status through tee in the pg-repository-publish gate

The battery step ran the default runner shell (bash -e) with go test
piped into tee, so the step exit status was tee's: a failing or
panicking battery (composition legs, TestZZPgCompZeroLeftoverFixtures
audits) stayed green while the assert step inspected only the spine
PASS/SKIP lines, defeating the silent-skip-is-red intent of the gate.
Now set -euo pipefail before the pipeline, matching the Backend
ownership guard named gates and conformance arms steps in this
workflow. Proven: same false|tee pipeline exits 0 without pipefail and
1 with it under bash -e; workflow YAML reparsed and the rendered step
script inspected.

* test(pg): pin the retry-after-activation-failure outcome on the repository-publish spine

The activation store admits READY candidates only (FAILED revival is
trigger-forbidden by migration 000006), so a lost activation race
permanently pins the content identity: the lifecycle marks the
candidate FAILED on every miss and a retried POST converges onto the
same deterministic revision identity. Arango recovers on retry
(READY-or-FAILED candidate filter); PostgreSQL must be proven to stay
refused, not assumed.

Route-level leg drives the production composition with the
DevRepositoryActivationConflictOnce lever: the conflict-armed deploy
lands 409 PUBLICATION_ACTIVATION_CONFLICT with the revision witnessed
FAILED (failed_at set, lifecycle diagnostics code present, owner
pointer unmoved); two retried POSTs each return 409
GENERATION_ACTIVATION_FAILED on the same revision identity with
byte-stable failed_at, diagnostics, and owner pointer (the failAny CAS
fence excludes FAILED, so re-marking is a typed no-op). The sibling
leg pins the ACTIVE replay arm idempotent: 200 activated, same
revisionId, no activated_at restamp, pointer stable.

The leg is inventoried in the ClickHouse-gated mint census, registered
in the Arango-lane declared-skip set, and gated by a second PASS-line
assertion in the pg-repository-publish job: silent-skip stays red.

* test(pg): arm the release CAS against a live pointer in the retry-pinning leg

The one-shot dev fault is consumed by every activation attempt and
corrupts the CAS input only when the project already has an active
release pointer (pinned by
TestDevRepositoryActivationConflictOnceCannotJumpToLaterRequest). The
leg armed a fresh project, so the armed deploy activated instead of
conflicting (CI run 43417949685, spine job 131860480059: 200 where 409
PUBLICATION_ACTIVATION_CONFLICT was pinned).

The leg now bootstraps a real active release with an unarmed runtime
(first deploy 200 activated, owner pointer witnessed on the bootstrap
revision), closes it, then composes the conflict-armed runtime and
publishes a second generation: the armed deploy loses the release CAS
and is witnessed FAILED with PUBLICATION_ACTIVATION_CONFLICT
diagnostics, failed_at set, and the owner pointer still on the
bootstrap revision. Retries stay 409 GENERATION_ACTIVATION_FAILED on
the pinned identity: the release CAS then advances normally (pointer
revision is read fresh), the deterministic claim replays the FAILED
revision unchanged (ON CONFLICT DO NOTHING + content-digest equality),
and READY-only eligibility refuses it — failed_at, diagnostics, and
owner pointer byte-stable across attempts. The sibling leg pins the
ACTIVE replay arm idempotent.

* refactor(pg): ride the centralized schema-name predicate in the activation store

fd2bfeb (#186) deleted the package-local schemaNamePattern and moved
the guard to pgstore.ValidSchemaName across every postgres adapter.
NewActivationStore validated through the deleted variable, so the
merged tree failed to compile the postgres explorer package, which is
what reddened the six dependent CI jobs at run 43419141395. The merge
hop brought the base tip; this adopts the centralized predicate so the
activation store obeys the same law as its sibling adapters.

* feat(pg): evolve the revision guard for activation-shaped FAILED->ACTIVE revival

Migration 000012 CREATE OR REPLACEs loom_explorer_revision_guard with one
additional arm, following the 000011 precedent: same-named function
replaced whole, trigger dropped and recreated, convergence on rerun.
Migration 000006 stays byte-identical to base (sha256
3f6c44bff72d7837634e8c170f0b97e256e38d35f7c844fad27f4fbda38ecc09, zero
diff against origin/feature/postgres-backend).

The arm admits the FAILED->ACTIVE revival only in the activation shape --
failed_at cleared, activated_at set, diagnostics present, ready_at
unchanged -- so a retried repository publish converges onto the pinned
content identity with a 200-activated revival instead of the permanent
409 the READY-only law forced. Bare resurrections (keeping failed_at,
missing activated_at, nulling diagnostics) are refused with 23514, and
frozen-column smuggling during the transition still dies on the untouched
frozen check. This resolves the first PG-law divergence to Arango parity
under the coordinator option-(a) ruling; the aea0653 retry-pinning
outcome is superseded by that ruling.

Adapter: activation eligibility widens to READY|FAILED and dispatches
FAILED candidates to the new candidateRevive statement; candidateActive
stays READY-only, so the first CAS never touches a FAILED row.

Tests: transition probe renamed to TransitionGuardProbe with five
activation-shape cases (legal revival, sloppy failed_at, missing
activated_at, nulled diagnostics, frozen dataset smuggling); the
non-vacuity suite gains restored-law revival refusals and acceptance; the
composite-guard suite drops candidate-failed (now legal) and gains
revival-witness equality against a fresh activation, replay-no-restamp
after revival, a ready-only-first-CAS pin, and guard-refused revival
byte-stability; the race repins to never-strands. The route leg converts
from stays-pinned to revival-parity: the conflict-armed deploy still
lands 409 with the revision witnessed FAILED and the pointer unmoved,
then retried POSTs return 200 activated=true on the pinned identity with
diagnostics cleared, the pointer flipped, and no restamp on replay.

Ledgers: 000012 pinned by sha256 in the checksum registry, the state-02
pin map, the ownership manifest, and the activation control pins;
fixture counts and the membership convergence list move 11 -> 12; the
retroactive-refusal fixture derives its recorded max from the owner
history. Verified live on PostgreSQL 18.6: full explorer package,
probes, non-vacuity suite, race x5 under -race (30/30), store package,
lifecycle package. The route legs gate in CI behind the dual PASS-line
gate (ClickHouse is not reachable from this window).

Co-authored-by: AO <ao@local>

* test(pg): pin FAILED-prior strictness under the revival law

The revival arm admits a FAILED candidate, so the supersede discipline
must not silently tolerate a FAILED revision behind the owner pointer:
supersedePriorActivationRevision locks the prior and refuses any status
other than ACTIVE with explorer.ErrDraftConflict (000006 law, untouched
by 000012). The new composite-guard case fails the prior through the
production FailRevisionFrom CAS (ACTIVE->FAILED is legal), attempts the
activation, and proves ErrDraftConflict with revisions and owners
byte-stable: reviving the candidate is no bypass of a FAILED prior.

Verified live on PostgreSQL 18.6: composite-guard 20/20 PASS, full
explorer package ok (20.9s, zero skips).

* test(pg): statically pin the candidateRevive statement shape

The audited-statement battery covered every mutating statement of the
first CAS but not the revival statement: the e2e revival leg activates
only FAILED candidates (the row lock serializes the load and the CAS,
so loosening or dropping the status filter cannot be observed
behaviorally), and the ready-only pin probes the READY statement via
raw SQL. The candidateRevive entry mirrors candidateActive: SET status
ACTIVE, activated_at = $2, failed_at NULL, diagnostics = $3,
publication = $4, with WHERE id = $1 AND status = 'FAILED', plus the
one-statement count check.

Non-vacuity proven by mutation: deleting the status filter reddens the
battery (go test ./internal/backends/postgres/internal/explorer,
run TestActivationStatementsCarryTheCompositeGuards); restored green,
gofmt and go vet clean.

---------

Co-authored-by: qwen3.8-flash-next <noreply@anthropic.com>
Co-authored-by: AO <ao@local>
…unblocks #159 paired benchmark) (#188)

* fix(catalog): make shared-write pivot hints arrival-order deterministic across backends

observeObservationCodePivot wrote pivot_column_selector and
pivot_value_selector once per Observation document, and setPivotDefaults
overwrote on every non-empty value, so the stored hint was the value arm
of the last-arrived document. Per-backend arrival order differed, the
FieldEnrichment digest diverged, and every downstream identity
(snapshotToken, capability candidate/node/edge IDs, published workspace
bytes) diverged, aborting the paired-benchmark prepare stage.

The profiler now tracks the observed column/value arm sets
(set-normalized, merge-unioned) and derives the stored selectors at
export as the first arm present per observationValueSelectorFromPayload
precedence. The audit extended the same class: pivot family,
pivot_item_source, pivot_item_resource_type, and pivot_value_selectors
are spec constants per (resourceType, path) and converge under
non-empty-wins, so they keep their behaviour; pivot candidate, pivot
kind, and object-to-codeable_concept kind upgrades now converge
monotonically in ensureStat and Merge, and observer-created stats apply
the default pivot spec so spec slots no longer depend on which document
created the stat.

Validation: four new profiler regression tests (720-permutation
arrival-order, arm-precedence, merge-direction, creation-order) fail at
the pre-fix tip and pass post-fix; go build ./..., go vet, gofmt clean;
go test -count=1 ./internal/... plus ./cmd/... ./conformance/... green
offline; backend-conformance skipset verifier green with the new
identity registered in the capture, allowlist, and CI fail-closed gate.
The new cross-backend candidate-ID/node-ID/edge-ID multiset pin is
adjudicated live by the backend-conformance CI job.

Refs #159 (unblocks paired benchmark prepare stage)

* test(scripts): pin the three-identity skip-set capture expectation

The skip-set capture unit test asserted the two-arm identity list by
literal; the cross-backend parity leg adds a third allowlisted skip
identity, so the expected array now lists all three in sorted order.

* fix(catalog): total-order kind upgrades across plan, stat, and merge paths

kindUpgrade only upgraded from the object kind, so a coding-vs-codeable_concept
conflict for one path was resolved by whichever shard or document arrived
first, and Documents emits the stat kind verbatim into the stored profile
and its FieldDigest. The same first-upgrade-wins guard existed at three
sites: convergePivotEvidence, upgradePivotStat, and addFieldPlan.

kindUpgrade now honors a single upgrade lattice (codeable_concept >
coding > object): upgrades fire only while both sides sit inside the
lattice and the incoming rank strictly exceeds the current rank, so
plan, arrival, and merge directions converge to codeable_concept. Kinds
outside the lattice keep their prior behavior: nothing upgrades into or
out of array, scalar, or string, and addFieldPlan's array short-circuit
is unchanged.

Validation: two new tests (merge both directions; document arrival both
orders) fail pre-fix and pass post-fix against the same source identity;
go test -count=1 ./internal/catalog, consumer packages (graphql,
dataframe/recipe, api/recipe, ingest), and the offline backend
conformance run are green; gofmt/vet/build clean.

A same-class finding surfaced while pinning this: semanticObservationKey
excludes Status while mergeSemanticObservations and addSemanticObservation
are first-writer-wins on the whole observation record, so two same-key
observations with shape-derived statuses (e.g. UNSUPPORTED_VALUE_PROJECTION
vs UNRESOLVED_SYSTEM for a coding-only vs text valueCodeableConcept under
one code) converge to the first arrival. Repro evidence retained at
/tmp/opencode/kind-merge-fail.txt; deferred to a separate unit per
coordination.

Addresses PR review thread PRRT_kwDOS-yV5s63IWlo.

* fix(catalog): monotone pivotKind join at the plan layer mirrors the stat layer

addFieldPlan's pivotCandidate branch assigned existing.PivotKind
unconditionally, a raw last-write-wins shape, while the stat-layer
counterpart convergePivotEvidence resolves the same conflict through
pivotKindRank. Under today's callers the write is a constant (only
classifyObjectShape enters the branch, always pairing pivotCandidate
with pivotKindCodeableConcept; pivotKindObservation never reaches the
plan layer because observeObservationCodePivot writes it directly on
stats), so the assignment is order-independent in the current code.
The rank-join removes the latent last-write-wins: the plan layer now
honors the same total order (observation > codeable_concept), higher
rank wins, equal rank keeps the incumbent, and an empty or unknown
pivotKind can never demote a populated lattice kind.

New unit test merges conflicting same-path candidate plans in both
directions through addFieldPlan and pins observation both ways; it
fails on the pre-fix unconditional assignment and passes post-fix.
Catalog package, consumer packages (graphql, dataframe/recipe,
api/recipe, ingest), the offline backend conformance run, the skipset
verifier (3 identities), gofmt, vet, and build are green.

Addresses the adjacent audit in the recovery order for PR #188.
…re-pin wave for 22 receipt paths (lane-05) (#189)

* feat(gate): repository-wide no-code-comments checker with fixtures and CI step

Adds scripts/check_no_code_comments.py --all-tracked (ticket
code-comments-20261113-05-final-audit): re-enumerates every tracked path via
git ls-tree -r HEAD (git ls-files rejected: empty-index silently reports zero
files in a detached worktree), classifies through language-aware backends in
scripts/lib/no_code_comments_backends.py, and fails on handwritten comments.

Allowlist classes, each with evidence rather than path-shaped trust:
- go compiler/tool directives (go:*, //line, extern, export, #cgo), shebangs,
  shell/py/dockerfile tool directives, gomod // indirect, and JS tool
  directives (@vitest-environment 64 uses, eslint, ts-*, istanbul, __PURE__).
- generator-provenance: 14 generated/ files + 2 gqlgen resolvers bound to
  generator + make regen command AND a required banner regex; a generated-path
  name or forged banner alone never exempts (provenance violation recorded).
- governance-directive: stage_sequence.go D-16a attribution string, asserted
  verbatim by TestSQL16LawCells.
- ledger-bound-pinned: the files-dict keys of both verification
  reviewed-sources.json ledgers (158), zero-diff byte contracts.
- checksum-payload: postgres migration .sql executed through
  pgstore.LoadMigrations/MigrateSchema, which sha256-pins file bytes into the
  migration ledger (store/migrate.go:118, ErrMigrationChecksumMismatch :42,
  ledger INSERT :499); stripping changes hashes = deployed-DB behavior change.
  Bound by path evidence, never bare .sql (coordinator ruling 2026-11-13).
- fixture-payload: the 8 ab05_pre_refactor testdata migration dirs.
Markdown/log/data assets and binaries inventoried; unsupported formats
reported and exit nonzero, never silently excluded (fail-closed classifier).

scripts/tests/test_no_code_comments.py: 29 fixtures incl forged banners,
fake .gen.go, commented-out code/TODO failures, directive/docstring/
string-URL-regex-template passes, markdown exclusion, payload binding by path
evidence, ledger-bound pass, and self-compliance of checker/lib/tests/CI file.
CI: wired as 'No-code-comments gate' in the tests.yaml ui-unit job after
npm ci so the TS scanner resolves ui/node_modules/typescript.

* chore(comments): strip handwritten comments from lane-05 residual code files

Removal wave for ticket code-comments-20261113-05-final-audit against the
lane-04 lever (comment-stripped token/AST sequence identical pre/post, per
language: go/scanner token-stream + go/parser + gofmt; acorn tokenize +
ESTree equality). Evidence: levers-lane05/out/strip-all.json, all seven rows
tokensEqual=true, parseOK=true.

- scripts/run-arango-integration.mjs (207 removed),
  scripts/run-postgres-integration.mjs (206),
  scripts/run-postgres-integration.test.mjs (26),
  scripts/run-arango-integration.test.mjs (10): runner freeze lifted per
  coordinator ruling (2); node --check clean on all four, both own test
  suites pass (7/7, 37/37), importers (check-go-test-events.mjs,
  verification-inventory.mjs, pg-exec-03-skipset-verify.mjs) load, profiles
  registry (10 legs) intact - token identity guarantees the d42e7a5
  spine-leg registry and 710f3bc strip survive untouched.
- internal/catalog/helpers.go (3 doc comments).
- internal/dataframe/compiler/render/postgres/stage_sequence_test.go (2):
  D-16a attribution remains satisfied in this file via the TestSQL16LawCells
  const attribution literal; decorative //nolint:govet removed (no linter
  consumes it anywhere in the repository).
- stage_sequence.go: net-zero (its only comment is the governance-mandated
  D-16a attribution, restored and classified as an enumerated
  governance-directive).

Go: go test -count=1 green for internal/catalog and the render/postgres
package (incl TestSQL16LawCells); go build ./... clean; gofmt clean.

* test(publication): enforce citation-line accuracy in arango dangle gates

WEAK-CITATION hardening (ticket code-comments-20261113-05-final-audit):
danglingCheckCitations (dangling_binding_e2e_test.go:84) and
rrdCheckCitations (release_dangle_reconcile_e2e_test.go:85) accepted a
citation when the want string appeared anywhere in the cited file, so a
comment naming the right string on the wrong line passed the trust check.

Adds shared citationLineMismatch: requires the want string at the cited
line (TrimSpace-equal) and rejects past-EOF and non-positive line numbers;
both e2e citation checks now call it. e2e paths stay gated on
LOOM_TEST_ARANGO_URL as before.

internal/backends/arango/internal/publication/citation_gate_test.go: 8
offline regression fixtures (exact-line accept, whitespace-trim accept,
wrong-line fail - the forgery case, near-miss fail, past-EOF fail,
non-positive-line fail, dangling table strict, rrd table strict); mutation
control confirmed: reverting to the weak any-line scan turns the wrong-line
fixture red.

* fix(ci): arango runner cleanup transport failures record audit status, not run failure

HARNESS-FINDING-ARANGO-CLEANUP-CATCH (coordinator assignment, same wave as
the lane-05 strip, separate commit so the strip token-identity proofs stay
clean). The runArango finally-loop marked the whole run failed whenever a
post-verification database-drop attempt threw a transient transport error,
even though every profile had already passed verification.

Extracts cleanupOwnedDatabases(endpoint, owned, evidence, request = fetch)
(following the ownDatabase injection pattern): thrown transport/timeout
errors now append {database, transportError} to evidence.cleanupAudit with a
[cleanup-audit] console warning and leave the run verdict untouched; an
explicit HTTP response outside ok/404 still hard-fails (environment contract
violation); ok/404 outcomes record as before.

Regression fixtures in run-arango-integration.test.mjs (3 new, 10/10 suite):
transport failure keeps a passed run passed with 2 audit records + warnings;
403 refusal fails the run with the original 'Database cleanup HTTP 403'
record and pinned request shape; 200/404 pass through recorded.

* feat(comments): zero-suppression policy for ledger-pinned files + unresolvable-key inventory

Ledger pinning alone never exempts handwritten comments (C0 ruling): the
ledger-bound-pinned allowlist class is removed; pinned paths are inventoried
('ledger-bound') but comments there are violations like anywhere else. Keys in
either reviewed-sources.json files{} that match no tracked path are inventoried
as 'unresolvable-ledger-key' (visible, never gate-red; deferred hygiene ticket,
per C6). Adds js-tool-directive class entries for EXTRACT-START/END tool
sentinels (consumer: row96-killtree-escalation probe). Fixtures: 35 incl
policy-flip, unresolvable-class, EXTRACT sentinel + lookalike, vitest-env
repo-file checks.

Lane code-comments-20261113-05-final-audit (AO loom-experiment-213).

* chore(comments): unified strip + atomic re-pin wave for 22 receipt-bearing paths (lane05, OPTION A ATOMIC)

Comment-only removal with token/AST-sequence-identical proof per language
(TLA+ lexer + token streams, TS/JS parse, gofmt) across 12 models and 7
code files; 3 UI-family files retain only tool-directive comments
(EXTRACT sentinels, @vitest-environment, eslint-disable).

Atomic scoped re-pin of publication-bundle reviewed-sources.json (coordinator
scope authorization; strictly the md5/sha receipt fields for these wave paths):
23 machine digest fields recomputed TRUE vs post-strip blobs + 2 in-scope
pre-existing-stale rows restored (waveBytesChanged=false recorded), 26
lane05Repin receipt blocks (#183 3040a67 hash-entry-only style), historical
prose never rewritten (sibling Amendment annotations). FINDINGS.md /
OPERATOR_REVIEW_DIGEST.md amendments annotate pre-strip digests; SKILL.md
canonical probe value updated live.

Proofs (artifact lane05-final-audit-census.json):
- canonical probe PASS: disk == git blob == canonicalProbe.expectedMD5
- C5 TLC: all 52 receipt-cited arms determinate and matching receipts
  (witness depths baseline 9 / f2 15 / f3 7; controls complete 14,608,028
  distinct); 3 unreferenced Horizon-8 dotfile ctrls not receipt-cited
  (Horizon-3 twins clean); negative controls 0 false-executions
- C1 builder-formal source-proofs / trace-controls / generated phases exit 0
- gate: scanned 2963, violations 0, unsupported 0
- node --check + consumer suites + go vet/test-compile green post-strip
- pre-existing-drift disclosure: recipe_execution_reader.go pin predates base;
  46 out-of-scope stale rows inventoried, not touched (C6 deferred hygiene)

Refs lane code-comments-20261113-05-final-audit (AO loom-experiment-213).

* chore(comments): remove the 12 prose comments the postgres spine job added to tests.yaml

Gate-completion repair: this lane's CI step fails on head while any handwritten
comment exists; the comments were introduced by #184 after the wave population
was fixed. Comment-only, YAML document-tree equality proven by proof_yaml.mjs
(equal=true); all jobs, steps and ids unchanged. Not a #184 logic edit; job
semantics untouched.

Refs lane code-comments-20261113-05-final-audit (AO loom-experiment-213).

* fix(comments): fail closed when the TypeScript-family scanner cannot resolve

CI caught what the dev environment hid: the python-unit job has no
node_modules, so the typescript module is unresolvable there, and scan()
crashed instead of failing closed. TypeScript-family files (.js/.mjs/.cjs/
.mts/.ts/.tsx/.jsx all scanner-backed) are now inventoried 'unsupported'
(gate-red via the existing unsupported exit rule), never silently passed.
Fixtures: scanner-dependent tests declare their skip via ts_available()
(ToolSentinels, unresolvable-keys repo scan), and a new bare-runnable test
proves the fail-closed routing (unsupported inventory, empty violations,
empty allowed). Self-compliance preserved: fail-closed note is a docstring,
not a hash comment.

Bare mode: 84 OK (11 declared skips). Full mode: 84 OK.

Refs lane code-comments-20261113-05-final-audit (AO loom-experiment-213).

* fix(comments): retain guard-quoted claim anchors CI caught and add fail-closed guard-quoted gate class

CI (PR #189, head 1e52b4e) failed 8 tests in two packages: the FB20
STEP 0 anchor table (recipe_execution_reader_authz_e2e_test.go),
publish_partial_pointer_e2e_test.go, and pointer_name_nul_ambiguity_e2e_test.go
quote doc-comment prose verbatim as claim-source drift anchors; the
lane05 strip wave orphaned those quotes in recipe_execution_reader.go,
bundle_store.go, and internal/catalog/helpers.go.

Retain guard-quoted anchors per lane02 precedent (retain commits
recorded inside 4878319): all three files restored byte-identical to
their 90267c0 base blobs (git hash-object verified). Systematic
orphaned-quote sweeps re-run over the whole branch: forward (deleted
comment lines vs test corpus) and reverse (25+ char test literals
absent from non-test sources at HEAD but present in pre-strip blobs)
show 0 remaining orphaned quotes; the only other hits are path-string
citations against live production files (verified) and duplicated
citation-gate helper code from this branch's own in-test refactor
d566977.

Gate: new allowlist category guard-quoted -- a comment block is
allowed iff some line (marker-stripped, >=25 chars) appears verbatim
in a tracked test-family file (excluding itself); corpus is built
from the same enumeration as the scan and failure to build allows
nothing (fail closed). Seven GuardQuotedAnchors fixtures pin the
semantics: unquoted stays red, sub-threshold quote red, quote outside
test files red, self-quoting test file red, quote removal flips back
to red. scripts/tests suite 91/91.

Adversarial controls re-run against the patched gate: positive
(planted ts comment -> exit 1 VIOLATION) and mutation (typescript
removed -> exit 1, 638 UNSUPPORTED).

Ledger: lane05Repin blocks gain postStrip history + guardQuoteRestore
receipts; bundle_store sha256 net-nil (returns to #183 value
1dce5b82c3...), reader sha256 set to true base-blob value
b00d64740d... matching preExistingDrift. helpers.go has no ledger row.

Verification: go test ok on resolver, clickhouse, catalog, arango
(publication, dataset, root), dataframe/published, dataset, server,
conformance/compiler; gate scanned=2969 violations=0 unsupported=0
with 7 guard-quoted allows.

* fix(comments): batched review wave T1-T3 - restore D-16a attribution, governance-directive gate class, python-unit ts resolution

PR #189 review threads (coordinator triage 2026-11-13, batched one-wave order):

T2 (CONFIRMED FINDING, thread PRRT_kwDOS-yV5s63I8f9): the 5f36dbe strip
removed the file-level D-16a attribution comment from
stage_sequence_test.go, which TestSQL16LawCells exists to protect; the
own-file check was self-satisfying (const literal contains the asserted
text, so strings.Contains(ownSource, attribution) was vacuous). Fix:
(1) attribution line restored byte-identical to 7e081f4 (diff-verified);
(2) law cell now requires the comment-line form '// D-16a attribution
(mandatory, coordinator ruling 2026-11-11): ' + attribution, so the const
alone can no longer satisfy it; go test -run TestSQL16LawCells green.
(3) gate class closed, not just instance: GOVERNANCE_ATTRIBUTION in the
allowlist matches D-<id> attribution + dated coordinator ruling on one
line at ANY path -> category governance-directive (never strip-eligible;
both tokens on one line closes the cross-line forgery). stage_sequence_test.go
registered in GOVERNANCE_DIRECTIVES with tool linkage. 6 GovernanceAttribution
fixtures incl forged-negatives: prose citing a ruling without the D-id token
RED, D-id without dated ruling RED, tokens on separate lines RED,
registered-path pattern scope pinned, repo file scan pinned.
(4) one-off sweep proof (class closure): every non-md tracked line
containing 'coordinator ruling' at 7e081f4 (3 lines, 2 files) present at
wave head; table in artifact c8GovernanceAttributionRepair.
//nolint:govet removal in same file left per coordinator pre-approved class.

T1 (STALE, thread PRRT_kwDOS-yV5s63I8fu): the five python-unit failures
(LedgerBound unresolvable-keys + 4 ToolSentinels, RuntimeError ts scanner
unavailable) were from run 43443590349 at 85ab5ac; ts_available() guards +
fail-closed routing landed at 1e52b4e/bdc036c1. Reviewer's real ask honored
too: scanner now RESOLVABLE in python-unit (Install UI dependencies step
mirroring node-unit + LOOM_TYPESCRIPT_DIR export), so those tests execute in
a CI job instead of skipping everywhere; suite 97/97 with 0 skips under
LOOM_TYPESCRIPT_DIR.

T3 (documentation, thread PRRT_kwDOS-yV5s63I8gD): 18 unresolvable ledger
keys subclass-tagged in artifact c6LedgerHygienePending: 15
A-stale-path-moved-or-renamed (arango relocations under
internal/backends/arango/, deleted postgres/aliases.go) vs 3
B-malformed-non-path-key (two '... [pkg]' labels, one '....go.explorer');
checker already prints the named UNRESOLVABLE-LEDGER-KEY class; non-red
deferral stands per coordinator ruling; hygiene ticket owns the split.

No ledger impact: stage_sequence_test.go has no reviewed-sources.json row.
Gate: scanned=2970 violations=0 unsupported=0.

Refs lane code-comments-20261113-05-final-audit (AO session loom-experiment-213).
…MAX set reducers (#190)

* feat(pg-render): register post-window child routes and set aggregate reducers

The compiler scheduler places the generic SORT/LIMIT window (compiler/output.go)
before the child-route LETs, so post-window TRAVERSAL, SET, and AGGREGATE
operations are legitimate plan shapes the AQL arm renders (render/aql). The
PostgreSQL renderer refused them at the phase guards, 422-ing the #159 paired
benchmark AuthorWorkload output aggregate_sum_age_by_patient.

- acceptPostWindowTraversal: dead child-route traversals (canonical scope block,
  no downstream reader) render nothing, matching the AQL dropped LET; a located
  reader refuses by naming the consuming operation.
- acceptPostWindowSet + aggregateConsumesSetVariable: post-window sets are
  accepted only through registered consumers (reduction, SLICE, SUM/COUNT/MIN/MAX).
- renderSetAggregateExpression: SUM/COUNT/MIN/MAX AGGREGATE RETURN expressions
  render as scalar correlated sublinks on the setReductionSublink model, with
  AQL-parity semantics (collections.go renderAggregate): Value-less COUNT counts
  the per-edge-occurrence item array (no UNIQUE in the AQL LET unless set.Unique,
  which the child-set lowering never sets); COUNT with a Value counts unnested
  non-null slots; SUM uses the registered operand clamp + IEEE double band with
  empty-to-NULL and the NUMERIC_AGGREGATE_NON_NUMERIC guard-barrier raise;
  MIN/MAX order by the ArangoDB value type order (booleans before numbers) over
  ::numeric keys. Every other operation, cardinality, or payload stays
  ErrUnsupportedPostgresPlan behind the canonical AGGREGATE gate text.
- ENDPOINT_LOOKUP is admitted only for aggregate-consumed sets: it is an
  ArangoDB access-path hint and edgeOccurrencePredicates renders the identical
  typed-identity join, per the registered stage_related_occurrence.go
  normalization; the reduction and related-existence surfaces keep the
  fail-closed refusal, so the pg-sql-24 spine witnesses stay verbatim.
- edgeOccurrencePredicates takes a pointer receiver and registers bind
  parameters lazily so validation-only probes leave no orphan parameters.

Validation: internal/dataframe/compiler/render/postgres post_window_test.go
(acceptance, COUNT slot-vs-row, endpoint-lookup consumer gate, dead-LET
equivalence, 8 refusal classes); go test ./internal/... all green; gofmt/vet
clean. Offline witness: the benchmark plan renders to
/tmp/opencode/pg-traversal-probe/pg-aggregate_sum_age_by_patient.sql; paired
benchmark execution is #159's gate.

* test(pg-render): pin deadness near-misses, unrimmed rim, row-count preservation, preview path

Completes the gate-cycle fixture classes for the post-window registration:
- consumer-in-a-later-subplan-block, reducer-referenced, and subplan-sort-key
  deadness near-misses, each refusing with the typed not-dead voice (the consumer
  scan is load-bearing, not just a RETURN-projection check);
- all nine AQL-registered-but-unrimmed aggregate operations refused behind
  validator-legal payloads, with a registered COUNT reducer isolating the gate;
- row-count preservation: the outer FROM/WHERE/ORDER BY tail is byte-identical
  with and without the accepted SET and reducers (window-final soundness);
- preview path pinned: bind-backed LIMIT (limit>0, the preview form; the #159
  benchmark runs limit=0) keeps the window clause and every reducer sublink.

Pre-fix red at 492d3f0: 27 failures, all guard refusals (sets/traversals must
precede the execution window) or aggregate-gate drift; green at head.
gofmt/vet clean; go test ./internal/... green.

* fix(pg-render): aggregate predicate reads the reached target row, not the items alias

Review finding PRRT_kwDOS-yV5s63K-w9: the aggregate predicate fragment rendered
EXISTS over itemAlias."payload" inside (SELECT ...) AS itemAlias, so PostgreSQL
rejected every with-predicate statement at plan analysis (SQLSTATE 42P01,
missing FROM-clause entry). The items alias names the subselect it must be
visible in; the item row inside that subselect is corr.targetAlias, whose
payload column the subselect projects. The predicate now renders over
corr.targetAlias (helper params renamed itemAlias -> baseAlias to say so); the
value slot keeps itemAlias because it lives in the outer CROSS JOIN LATERAL.

Red: TestPostWindowLiveReducersExecuteWithPredicates on live PG18 fails at
pre-fix source with exactly the reviewer's 42P01 error. Green: the same test
passes at fixed source, pinning the per-occurrence grain (p-1: obs-a x2 +
obs-b, predicate-mismatched obs-c/obs-d excluded: SUM 50, MIN 10, MAX 30,
COUNT 3) and the zero-child patient (SUM/MIN/MAX null, COUNT 0). Structure
witness: post_window_test.go now rejects items subselects that reference their
own alias and requires the predicate to read x1."payload".

Live legs: local PostgreSQL 18.1 (zonky portable) via LOOM_TEST_POSTGRES_URL;
full postgres render package green (33s) including the pwin-01 delta audit in
TestMain; unit suites green without the URL. Witness artifact regenerated.

* fix(pg-render): deduplicate items per document, C-collate MIN/MAX keys, refuse endpoint direction mismatch

Review threads PRRT_kwDOS-yV5s63K-xC/-xM/-xO on #190:

xC: the items subselect counted every fhir_edge_occurrence row while the AQL
arm always collapses to one item per reached document — lower/child_sets.go:88
builds every child set with Unique/SortByKey (sets.go:174-177 refuses their
absence) and render/aql/navigation_render.go:294-296 always wraps the item
array in UNIQUE(). Items now carry SELECT DISTINCT over the projected columns,
matching setReductionSublink (sets.go:274); the per-occurrence comment is
corrected; the structural test requires four DISTINCT items subselects and
the blanket DISTINCT prohibition is gone. Live legs flip to AQL parity: two
stored occurrences of obs-a contribute one item (p-1: SUM 40, COUNT 2,
MIN 10, MAX 30) while the edge table witness still shows both rows.

xM: MIN/MAX text ordering keys (stringKey, booleanKey) now carry COLLATE
"C", pinning byte-order ranking against non-C database locales — the shape
already pinned by category_scan.go:287 and group.go:943-954.

xO: the aggregate-consumed ENDPOINT_LOOKUP rewrite now requires
EndpointField/EndpointJoinField to equal the direction-derived pair
(_from/_to outbound, _to/_from inbound; lower/storage_route.go:30-39) before
normalizing to Native, and refuses any direction without a derived contract —
the graph.go:355-357 fail-closed posture for planner-metadata divergence.
Three refusal cases added; undirected plans are caught by plan validation
(ir/navigation.go:11).

Verification: local PostgreSQL 18.1 via LOOM_TEST_POSTGRES_URL, full postgres
render package green (28s) including the live predicate/dedup test and the
pwin-01 delta audit; compiler, AQL render, and execution suites green; gofmt
and vet clean. Witness artifact regenerated (DISTINCT x4, COLLATE "C" x4).

* chore(pg-render): strip handwritten comments for the repository-wide no-code-comments gate

Base moved: 8f65f3c (#189, lane-05) merged the repository-wide
no-code-comments gate into feature/postgres-backend after this branch
diverged at 492d3f0. CI runs the gate from the base at the merge ref,
so all 173 handwritten comment lines this PR introduced under
render/postgres/ now fail the UI job (scripts/check_no_code_comments.py
--all-tracked: violations=173, every one in post_window.go,
post_window_test.go, post_window_live_test.go, sets.go, sets_test.go,
traversal.go, render.go, selectors.go).

Comment-only strip: 173 flagged lines removed (checker text-matched per
path), gofmt-clean after; no code line changed. The parity rationale the
removed comments carried lives in this message, the PR body, and the
review-thread replies, which is the post-#189 home for that content.

Verification: local gate rerun on the eight files reports violations=0;
full render/postgres package green on live PostgreSQL 18.1 (31s,
TestMain delta audits intact); compiler/execution/explorer-compilation
suites green; gofmt/vet/build clean.

* test(pg-render): token-pin the C-collated MIN/MAX keys

Review class T3 (PRRT_kwDOS-yV5s63K-xM) asked for a group.go-style token pin
on the rendered SQL: TestPostWindowAggregateReducersRenderAsCorrelatedSublinks
now requires END COLLATE "C" and censuses exactly four occurrences (two text
keys each in the MIN and MAX sublinks). Red-first: at d8cff54 the renderer
emits zero COLLATE tokens, so the pin fails on the divergent shape; green at
this head. Precedent: group.go:943-954, category_scan.go:287.

* ci(pg-render): execute the post-window live reducer leg in CI

Retained finding (248 delta, coordinator source-confirmed): no CI leg ran
internal/dataframe/compiler/render/postgres with LOOM_TEST_POSTGRES_URL, so
the live family skips offline everywhere and TestPostWindowLiveReducersExecuteWithPredicates
executed only on the worker's local PostgreSQL 18.

Adds the ordered leg to the pg-fixture job (postgres:18 service and URL env
already configured): scoped go test -run TestPostWindowLive over the package
tee-ing to the runner temp log, then a fail-closed assertion mirroring the
repository-publish spine's never-skipped step: PASS token required, SKIP or
absence fails with an ::error annotation.

Scoped -run is deliberate per ruling; the four legacy live files go to the
follow-up tooling ticket, not this PR.

Local receipts: ordered command passes against a freshly recreated loom_test
database (0.07s, pwin-01 delta audit in TestMain intact); workflow parses and
the job's step list shows both new steps; the assertion logic verified
exit-0 on PASS log, exit-1 on SKIP log, exit-1 on absent token;
check_no_code_comments.py on the touched file reports 0 violations; diff is
16 added lines in tests.yaml only.
…(125-row disposition) (#191)

* fix(verification): final pubbundle reviewed-sources re-pin at 8f65f3c

Recompute every derivation-claiming field in
verification/publication-bundle/reviewed-sources.json against the
git show HEAD:<path> blobs and fix all mismatches to true computed
values; expectations were never adjusted to admit stale digests.

- 78 files-map md5/sha256 mismatches re-pinned (incl internal/catalog/
  types.go 6b84be97->418edc97 broken by 4878319, vocabulary_control.go
  5d41b670->06d0597c), 10 stale pin attributions corrected to the first
  commit whose blob actually produced the claimed digest
- 4 model fB22Tier1Md5s entries + reconcileDangleTrust.contentMD5
  re-pinned; canonicalProbe/model canonical scalars verified MATCH
- 15 A-class unresolvable keys dispositioned: 14 repointed across the
  32e8ad3 internal/backends/arango relocation, aliases.go (deleted
  b2da41e) retired under retiredFilesKeys with reason
- 3 B-class malformed keys retired under retiredFilesKeys with
  per-key reason and tracked-counterpart notes
- 19 confirmed/prevented artifact sha256 claims adjudicated against
  snapshot blob, head blob, file history, and a full
  git rev-list --objects --all scan: 9 verified against real blobs
  (evidence attached), 10 matched no object ever committed and were
  replaced with true head values + untraceable-credential receipts
- status_updates[F-B15-ledger-pin] re-pinned to head md5 with the
  prior value's verified-at commit recorded
- scripts/recompute_reviewed_ledger.py: rerunnable row-by-row recompute
  + apply tool (scan classes gated; historical receipts never gated)
- checker test inverted to assert zero unresolvable keys, plus a new
  test that every ledger files key resolves to a tracked HEAD path

Validation: check_no_code_comments --all-tracked exit 0
(unresolvable-ledger-key=0, violations=0); unittest checker harness
50/50; go test -count=1 ./internal/... exit 0 (73 pkgs ok);
conformance/compiler ok; gofmt/vet/build clean; canonical
json.dumps(indent=2, ensure_ascii=False)+newline roundtrip holds.

* fix(verification): repoint receipts for the five prose-string A-class rows

The re-pin tool attached repointFrom receipts only to dict rows; the five
relocated rows whose ledger value was prose (manifest_lifecycle.go,
selections.go, selections_cleanup_e2e_test.go, chartifact catalog.go,
name_latest_binding_e2e_test.go) now carry the same repointFrom/viaCommit
audit as the other nine, prose preserved verbatim under note. Regenerated
from the 8f65f3c baseline with the updated tool; all 169 fixes otherwise
byte-identical. Checker --all-tracked exit 0; checker harness 50/50.

* test(scripts): synthetic-ledger coverage for the unresolvable-key inventory class

The checker's unresolvable-ledger-key inventory reporting had lost its only
live coverage when the pubbundle ledger's malformed keys were dispositioned:
test_unresolvable_ledger_keys_are_inventory_not_red now asserts the repaired
state (empty inventory), so the reporting branch could regress to always-empty
without any test noticing. Add a synthetic-ledger test: stub
ledger_bound_paths with one nonexistent path, scan a clean Go file, assert the
inventory reports exactly that key with its ledger attribution and stays out
of violations. Coordinator ruling 2026-11-13 (loom-experiment-2): push now,
single append-only scripts/tests-only commit; reviewer auto-tracks, verifier
250 re-pins cheaply (ledger + tool blobs unchanged).

Validation: unittest scripts.tests.test_no_code_comments 51/51 OK;
check_no_code_comments --all-tracked exit 0 (violations=0,
unresolvable-ledger-key=0).

* fix(scripts): gate hex-valued model fields in ledger recompute (review #191 r4565972024

The model scan and apply verified only fields NAMED md5/sha256/contentMD5/
expectedMD5, so a hex-valued claim under another name was invisible to the
gate. model.nullPageCoverage.tla holds the md5 of NullPageCoverage.tla
(1372a87cbf2ee82f8366df1d525b9f96) and that file is pinned nowhere else in
the ledger - exactly the class the review comment identified.

Extend both sides through one enumerator (model_section_claims): named
claims now include digest (wiring the previously unused CLAIM_ALGO auto
entry) and tla-when-bare-hex (md5/sha256 by length), with resolve_algo for
auto-length dispatch; scan and apply can no longer diverge on the field
list. Path-valued tla fields are untouched.

Re-derivation: the nullPageCoverage.tla claim is TRUE against the HEAD
blob (scan row: model/nullPageCoverage/tla MATCH, scanned 220->221), so no
ledger value changed and the ledger blob stays byte-identical.
Non-vacuity control: corrupting the field in place to 0*32 yields
GATED-FAIL MISMATCH claimed=0000... computed=1372a87c... with tool exit 1;
ledger restored byte-identical afterward.

Validation: scan exit 0 with the new gated row; comment gate exit 0 on the
tool; ledger git-clean.

* fix(scripts): gate unevidenced artifact digests, stamp superseded quotes, add tool tests (review #191)

Three findings from the adversarial pass on #191:

1. Gating contract (thread r4566...) — the docstring promised artifact
   claims gate, but both check_claim calls passed gated=False, so a
   digest mismatch could only surface as SNAPSHOT-DRIFT (never gated).
   _artifact_claim now gates the @Head row unless the claim verifies
   against its sourceSnapshot blob or a recorded sha256Verification blob
   (_artifact_backed: re-checks file-history-blob/sourceSnapshot-blob
   commits, or membership via object-db-scan). On the live ledger: the
   10 head-repinned artifact digests now gate as MATCH and the 9
   evidence-backed claims stay SNAPSHOT-* report-only; scan exit 0.

2. Superseded attestations (reviewer BBlU) — 48 files rows kept a
   rederived SELF-RUN quote asserting live == git show <old>:<path> ==
   on-disk beside a corrected pin. Checker.stale_quotes re-derives every
   quoted blob and emits report-only SUPERSEDED-PROSE; --apply stamps
   pubbundleRepin.rederivedSuperseded (quotes, cited digests, pinned
   claims, note) so no false quote stands unqualified. Applied: exactly
   48 stamp additions, zero digest-value changes, idempotent on rerun.

3. Test coverage (reviewer BBlI) — new scripts/tests/
   test_recompute_reviewed_ledger.py builds a fixture git repo and
   covers MISMATCH re-pin receipt shape (pre/post/movedAt/ticket),
   SHAPE-ANOMALY and PROSE-VALUE gating, repoint-merge with both keys
   present, plain repoint receipt, prose-str-to-{md5,note} upgrade,
   model hex-tla gating, artifact head gating with and without
   evidence, superseded-quote report/stamp/idempotence, and the
   canonical JSON roundtrip through main() --apply. 9/9 pass.

Also: the repoint-merge branch was silent (no FIX note) — now recorded;
resolved_tracked moved from an id()-keyed global cache (id-reuse hazard)
to a per-instance memo; docstring exit-gate paragraph matches behavior.

Validation: scan exit 0 (221 rows, 0 gated failures, 0 SUPERSEDED-PROSE
after stamping); checker --all-tracked exit 0 (unresolvable=0,
violations=0); scripts/tests full discovery OK; comment gate exit 0 on
both touched scripts; ledger canonical roundtrip byte-exact.

* fix(scripts): make --apply a true byte-noop on converged ledgers (verifier F-2, coordinator ruling)

WAVE ADDENDUM verdict, option (i) chosen: adjudicate_artifact now skips
re-derivation entirely when an artifact row's sha256 claim already
matches the live head (or sourceSnapshot) blob AND its recorded
sha256Verification block re-verifies against its cited blob
(verification_reverifies: git show for sourceSnapshot-blob /
file-history-blob / head-blob, object-index membership for
object-db-scan). Evidence-gated, not unconditional: the stale-block
control test proves an unverifiable block is still rewritten. The
docstring --apply paragraph now states the contract.

Chosen over option (ii) because skip-if-live-true+backed makes drift
impossible to mask while giving strict byte stability; historical
file-history/object-db rows stay on the active repair path and land on
an identical fixed point (deterministic trace derivation).

Proof at this head: python3 scripts/recompute_reviewed_ledger.py --apply
run twice against the committed ledger -> cmp byte-identical both times
(10 live-true rows skip with 'no rewrite', 9 historical rows re-derive
identical traces). Scan unchanged: exit 0, 221 rows.

Fixtures: test_apply_noop_on_converged_artifact_verifications (double
--apply, byte-identical, no 'verified via' rewrite lines) and
test_stale_artifact_verification_is_rewritten (unverifiable block ->
rewritten to sourceSnapshot-blob trace). Tool suite 11/11; scripts/tests
discovery 110 OK; checker --all-tracked exit 0; comment gate exit 0.
Ledger untouched by this commit.
…d phases (#202)

constructionInputsCatalog.list interleaved candidate discovery with the
exact pinned reread and response pagination behind one 217-line body.
Split it into collectConstructionInputCandidates (enumerate published
references, filter by identity/digest/scope/schema, load presentation
metadata once per execution receipt, query-match, sort) and
resolveConstructionInputPage (dedupe page pins, reread exact
materializations under WithExecutionReadPins, revalidate identity and
scope, resolve the current marker, build entries). list keeps the
request/readiness guards, snapshot authorization, cursor page selection
and cursor encoding.

Behavior is unchanged by construction: the bodies moved verbatim via a
checked extraction tool (657 moved-verbatim lines, 11 declared edits,
19 new lines, 0 untraceable). Error classification, first-failure
precedence, skip-if-invalid candidate filtering, fail-closed pinned
reread, side-effect and read ordering (no forbidden metadata read before
scope approval, ListExecutions after draft validation, no pin call on an
empty page), and the empty-page response shape are preserved.

Verification: go test ./internal/server focused construction-inputs
suite 20 matched / 20 passed / 0 skipped; full internal/server package
695 passed / 33 skipped (all live-service gated: PG18, Arango,
ClickHouse) / 0 failed; internal/dataframe/published 59 passed / 2
skipped / 0 failed, read-pin tests 3/3 passed; publication clickhouse
unpinned-page-read e2e 2 matched / 2 skipped (no live services
configured). gofmt and go vet clean; zero handwritten comments; test
expectations untouched.

Issue: #194
…ransaction coordinator (#203)

BatchWriter.WriteBatch now owns only the transaction-wide protocol:
validation, connection acquisition, one transaction and search_path,
ledger replay/claim, invoking present-kind phases in resource-then-edge
order, one ledger finalization, and one commit. The two per-kind
stage/guard/publish sequences move verbatim into writeResourcePhase and
writeEdgePhase, each taking the already-open transaction and returning
committed accounting; a missing probe, guard, hook, or accounting check
can no longer drift silently between the two inline copies, and the
ledger protocol can be reviewed without holding both kind bodies in
working memory.

Behavior is unchanged: same SQL and request ordering, same fault-injection
step names at the same semantic boundaries, same probes, same error types,
first-failure precedence, accounting sides, rollback and commit-unknown
paths. Moved bodies were proved verbatim by a whitespace-normalized diff
against the base (31 lines per kind; only return-form adaptation).

Validation (PostgreSQL 18.6, isolated cluster):
- go test -json ./internal/backends/postgres/internal/store -run TestBatchWriter -count=1: matched 19, passed 19, skipped 0, failed 0
- go test ./internal/backends/postgres/internal/store -count=1: matched 321, passed 321, skipped 0, failed 0
- go test ./internal/ingest -run 'PostgresGenerationLoad|PostgresResourceWriter|PostgresEdgeWriter' -count=1: matched 90, passed 89, skipped 1 (child-process helper by design, driven by its passing parent), failed 0
- git diff --check clean; gofmt/go vet clean; scripts/check_no_code_comments.py violations=0

Refs #197
…operation handlers (#206)

Extract one private handler per construction operation kind from
authoredConstructionOutputsWithCombineInputs (733 lines) into named
apply<Operation>ConstructionStep functions that receive an explicit
constructionStepContext (document, step, stepIndex, prior schema, authored
metadata, source-only projection IDs, compiled output, resolved Combine
inputs, capability snapshot, seeded next metadata, and the shared addOutput
validator) and return the next metadata map or an error. The owner keeps
the shared per-step schema transition: source-projection exclusion set,
prior/priorIDsByName seeding with compiled source-stage merge, nextAuthored
seeding, addOutput validation and error wrapping, step output-schema
validation, clear(authored)/copy-back per-step atomicity, first-failure
precedence, and the unsupported-kind default error.

Behavior is preserved by construction, not by assertion tuning: 569
case-body lines moved line-exact under the only two sanctioned rewrites
(two-tab dedent; single-value error returns gain a nil first value), all
owner-retained regions line-exact, and the function-region string-literal
multiset identical, verified against the base blob by a rerunnable
transformation plus a correspondence checker.

Verification: go test ./internal/server -count=1 gives the identical
test-level result as the base (695 pass, 33 service-gated skips, 0 fail);
focused runs TestAuthoredConstructionOutputs|TestDeriveSourceProjection|
TestExplorerReceipt (9 pass) and the operation-contract regex (28 pass)
match base; TestExplorer.*(Receipt|Reconcile|Construction) matches zero
tests at base and after; gofmt, go vet, scripts/check_no_code_comments.py
and git diff --check clean.

Issue: #193
…es (#204)

canonicalize() mixed fragment folding, exceptional ID rewrites, request
and request-flow construction, capability/constraint/evidence projection,
flow sorting, and disabled-affordance mapping in one 497-line function.
Extract the already-visible phases into private functions
(_fold_fragment_rows, _entry_paths, _build_requests, _request_path,
_build_request_flows, _build_dimensions, _build_constraints,
_disabled_state_record, _build_disabled_states, _availability_for,
_build_affordance, _attach_aliases, _build_disabled_affordances) so each
domain special case sits beside the phase that owns it, and leave
canonicalize as a six-line orchestrator.

Bodies moved verbatim by a rerunnable checked-extraction generator with
exhaustive before/after line accounting. Deliberate edits beyond moves:
drop the aliases copy and a no-op invariants loop, merge two identical
disabled-state literals into one projection, hoist the request_path
closure out of the inner loop, and drop seed_for's unused lifecycle
parameter. Normalization and independent validation stay separate.

Verification: expanded inventory byte-for-byte identical to the pinned
pre-change output (57 affordances, 159 request rows, digest checked via
load_inventory); scripts.tests.test_normalize_ui_contract_inventory and
test_verify_ui_contract_inventory pass 14/14 unchanged with zero skips;
verify_ui_contract_inventory.py --source-only PASS; no-code-comments
checker 0 violations on the changed file; Node reader
scripts/lib/ui-contract-inventory.mjs returns 57 affordances / 159
requests unchanged.

Closes #200
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant