Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
6e10a87
test(naming): define result application semantic contract
seonghobae Sep 2, 2026
6e12edb
refactor(results): isolate semantic application identifiers
seonghobae Sep 2, 2026
4f58319
docs(results): record semantic application boundary
seonghobae Sep 2, 2026
836b902
docs(product): establish technical gap baseline
seonghobae Sep 2, 2026
d2c88e0
docs(architecture): define result application ACL
seonghobae Sep 2, 2026
f55c3d6
docs(changelog): record result naming compatibility
seonghobae Sep 2, 2026
cf4afec
test(results): cover semantic compatibility branches
seonghobae Sep 2, 2026
cefc0c3
test(results): preserve released outcome dataclass shape
seonghobae Sep 2, 2026
b58c11f
fix(results): preserve public outcome compatibility
seonghobae Sep 2, 2026
e054066
docs(results): preserve dataclass compatibility boundary
seonghobae Sep 2, 2026
341d7c1
docs(architecture): preserve released outcome shape
seonghobae Sep 2, 2026
28d2fe4
docs(changelog): clarify outcome compatibility
seonghobae Sep 2, 2026
3a830e1
test(results): preserve public error keyword compatibility
seonghobae Sep 2, 2026
f4de3a2
fix(results): preserve public error keyword compatibility
seonghobae Sep 2, 2026
49ee6ac
chore(stack): compose semantic naming with result authority
seonghobae Sep 2, 2026
2c4164d
chore(stack): restack semantic docs on UTF-8 authority fix
seonghobae Sep 2, 2026
69520a8
chore(stack): restack semantic docs on integer budget fix
seonghobae Sep 2, 2026
6d1bf44
chore(results): restack docs after integer budget repair
seonghobae Sep 2, 2026
520a3e8
merge updated #277 into semantic documentation child
seonghobae Sep 3, 2026
1f65afb
merge updated #277 test repair into documentation child
seonghobae Sep 7, 2026
f343c36
merge restacked #277 into semantic documentation child
seonghobae Sep 7, 2026
a3874e2
merge current #277 coverage repair into documentation child
seonghobae Sep 7, 2026
9b0cc39
docs(gaps): converge current Result Application evidence
seonghobae Sep 7, 2026
4fc0a57
merge current #277 integer-budget evidence into documentation child
seonghobae Sep 7, 2026
9e0165a
docs: refresh canonical product gap authority
seonghobae Sep 11, 2026
aaf8bc8
docs(gaps): separate evidence authority scopes
seonghobae Sep 11, 2026
13774da
docs(gaps): refresh central integration authority
seonghobae Sep 12, 2026
c25e593
docs(gaps): refresh central prerequisite and release authority
seonghobae Sep 13, 2026
e2f8d37
docs(gaps): distinguish current Noema owners
seonghobae Sep 13, 2026
452a567
docs(gaps): record protected-main diagnostic privacy gap
seonghobae Sep 13, 2026
79b7347
docs(gaps): refresh diagnostic privacy lineage
seonghobae Sep 13, 2026
9b49ac3
docs(gaps): refresh Noema relation repair state
seonghobae Sep 13, 2026
2985486
docs(gap): refresh central review and release owners
seonghobae Sep 13, 2026
2b49268
docs(gap): record current central acceptance blockers
seonghobae Sep 13, 2026
1609e02
docs(gap): refresh live central and release prerequisites
seonghobae Sep 13, 2026
14a5fb1
docs(gaps): refresh central gates and database wait seam
seonghobae Sep 13, 2026
509f0b8
docs: stabilize central acceptance authority
seonghobae Sep 13, 2026
c6205ee
docs(gaps): reconcile central prerequisite heads
seonghobae Sep 14, 2026
ca13a28
docs(gap): reconcile central prerequisite heads
seonghobae Sep 14, 2026
b70d571
docs(gap): make central owner topology durable
seonghobae Sep 14, 2026
8b8737d
docs(product): keep gap baseline durable
seonghobae Sep 15, 2026
9c9cd7e
docs(product): add licensing and recovery buyer gaps
seonghobae Sep 15, 2026
ec91141
docs(recovery): document bounded PITR target observation
seonghobae Sep 15, 2026
d6d7bba
docs(product): record provider-port convergence gap
seonghobae Sep 15, 2026
aa24911
docs(batch): doctor provider-neutral port convergence
seonghobae Sep 15, 2026
9c4666f
docs(gap): mark checkpoint repair exact-head green
seonghobae Sep 15, 2026
66cb316
docs(changelog): restore physical PITR profile release note
seonghobae Sep 16, 2026
cc52c43
docs(product): record provider retention authority gap
seonghobae Sep 17, 2026
8baa512
docs(product): record content-bearing tenant isolation gap
seonghobae Sep 17, 2026
6e2d23b
docs(product): record async credential concurrency gap
seonghobae Sep 17, 2026
4811a74
docs(product): record governance succession buyer gap
seonghobae Sep 17, 2026
cba2423
docs(product): record FinOps usage completeness buyer gap
seonghobae Sep 17, 2026
4f211dc
docs(product): refresh integrated workflow and CO release authority
seonghobae Sep 17, 2026
dac2803
docs(product): restore baseline paragraph separation
seonghobae Sep 17, 2026
c638922
docs(product): refresh CO release and FinOps gap authority
seonghobae Sep 17, 2026
a1d8a0a
docs(product): refresh central integration owner map
seonghobae Sep 18, 2026
2aa369d
docs(acquisition): add support lifecycle evidence gap
seonghobae Sep 19, 2026
04aff47
docs(security): correct protected secret-encryption authority
seonghobae Sep 19, 2026
a0877d2
docs(gaps): track permanent live PostgreSQL acceptance
seonghobae Sep 19, 2026
dceb13f
docs(recovery): bind PITR observer edge semantics
seonghobae Sep 19, 2026
4be995a
docs(architecture): bound reconciliation scheduling authority
seonghobae Sep 19, 2026
d41b61c
docs(gap): record package version authority
seonghobae Sep 19, 2026
1396570
docs(product): record compatibility and deprecation buyer gap
seonghobae Sep 19, 2026
aaa5fd4
docs(product): record release manifest validation gap
seonghobae Sep 19, 2026
056025a
docs(architecture): bound health diagnostic disclosure
seonghobae Sep 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 80 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@
## Deployment boundary

`pg-llm-batch` remains independently deployable and embeddable. PostgreSQL owns
configuration, encrypted secrets, token counting, JSONL payloads, and durable
configuration, secret storage, token counting, JSONL payloads, and durable
provider lifecycle state. Provider HTTP behavior remains behind
`BatchAPIClient`, while host services may inject credential, observation-order,
and lifecycle-persistence seams without changing provider semantics.

Protected `SecretStore` does **not** make encryption-at-rest mandatory. A supplied
Fernet key encrypts stored values; without one, the current compatibility path
base64-obfuscates values unless the caller explicitly sets
`require_encryption=True`. Mandatory Fernet policy, migration of historical
unencrypted rows, key rotation/recovery, and external key-custody evidence remain
the buyer/security gap tracked by #121 and the active config/secret source owner.
Do not describe the protected product as encryption-required until that contract
is normally integrated and released.

## Durable lifecycle tenancy

`DurableBatchAPIClient` is the backward-compatible standalone facade.
Expand Down Expand Up @@ -55,6 +64,56 @@ Rollback to the former two-column key is unsafe until an operator proves that no
The packaged schema and Docker initialization schema are maintained as exact
mirrors and must be reapplied successfully more than once.

## Reconciliation orchestration boundary

Protected `main` contains bounded reconciliation primitives, not a package-owned
automatic worker. `reconcile_batch_candidates()` executes one finite
scheduler-independent provider pass. Its protected contract explicitly leaves
candidate discovery, scheduling, tenant authorization, and any cross-process
lease to the host. Durable candidate discovery, PostgreSQL advisory single-flight,
and caller-owned result/checkpoint application are separate primitives; their
presence must not be described as an autonomous reconciliation service.

Issue #102 remains the buyer/operability gap for composing those primitives into
a bounded automatic loop with crash/restart recovery, durable terminal-work
retirement, content-free operator evidence, and realistic high-cardinality
acceptance. A future loop must preserve minimal PostgreSQL transactions: reserve
or read the minimum durable state, commit or roll back before provider/model
network work or retry backoff, and open a new bounded transaction only for the
next durable transition. Session-advisory coordination remains transient and
must not be represented as a durable lease or as distributed exactly-once
delivery.

The active reconciliation source slices remain separately owned by their
canonical PRs/issues, including candidate validation, bounded database result
materialization, sweep evidence, and Result Application. This documentation
records the protected capability boundary only; it does not transfer their
runtime/test authority into #324 or authorize a competing scheduler branch.

## Diagnostic disclosure boundary

`check_health()` is an operator-facing diagnostic report, not a public-safe
serialization contract. Protected `main` currently preserves backend `detail`
values and maps a database failure to `detail=str(exc)`, so that internal report
can contain lower-layer PostgreSQL diagnostics. The HTTP `/healthz` path does
not expose that report directly: `serve_healthz()` passes it through
`public_health_report()`, which emits only the fixed required component names and
boolean readiness states.

The standalone `health` CLI currently prints the unprojected `check_health()`
report. Its output must therefore be treated as operator-only and must not be
represented as safe for untrusted logs, tenant-visible telemetry, public HTTP,
or other user-facing surfaces. Issue #203 owns the remaining runtime hardening:
the CLI needs a bounded content-free projection or equally strict coded
diagnostic contract while preserving readiness exit semantics and useful
operator failure classification. DSNs, credentials, certificate/private-key
material, SQL text, provider content, arbitrary exception strings, and backend
connection diagnostics must not become public diagnostic evidence.

This section records the protected capability boundary only. It does not move
`health.py` or CLI runtime/test authority into #324; source work for #203 still
requires the invocation-scoped writer/path census before mutation.

## Logical restore execution

`restore_postgres_logical_backup()` is a bounded direct-SQL restore seam. The
Expand All @@ -70,6 +129,26 @@ Post-restore metadata mismatch is fail-closed and must be treated as unsafe
because the SQL transaction may already have committed. This seam does not
complete isolated schema/RLS/PITR acceptance.

## Result application boundary

Checkpointed result application is a package-owned domain service. Internally,
its ubiquitous language is `transaction_cursor`, `checkpointed_record`,
`record_effect`, `record_applied`, and `result_checkpoint`. The released
`apply_checkpointed_result_in_transaction(cursor, checkpoint_store,
consumer_name, item, apply_record)` keyword signature and the public
`ResultApplicationOutcome(applied, checkpoint)` dataclass field/introspection
shape remain compatibility adapters because renaming them would be a released
source/serialization break. The adapter immediately translates to/from a
private semantic outcome model. Additive `.record_applied` and
`.result_checkpoint` properties expose the semantic vocabulary without changing
historical `dataclasses.fields` or `dataclasses.asdict` output.

The service preserves the same transaction and replay invariants: the local
record effect and checkpoint save occur under the caller-owned transaction,
exact replay skips the effect, checkpoint regression fails closed, and the
scoped cursor is revoked when synchronous effect execution ends. This naming
boundary changes no provider protocol or database schema.

## Modular interoperability

CWL hosts such as `contextual-orchestrator` and `naruon` supply tenant context
Expand Down
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Bounded read-only PostgreSQL PITR target-configuration observation on a caller-owned already-connected isolated recovery target. The observer first snapshots the exact reviewed `PostgresPitrRecoveryTarget`; wrong-type authority or a target mutated out of that reviewed contract fails before cursor acquisition or database I/O. It reads exactly eight recovery-target settings plus `pg_is_in_recovery()`, uses bounded result materialization, and fails closed on malformed, duplicate, oversized, pending-restart, inactive-recovery, or mismatched evidence. When a reviewed `name` or `immediate` target intentionally has no inclusion edge, the effective `recovery_target_inclusive` setting must remain PostgreSQL 18's default `on`; time/XID/LSN targets retain their explicit reviewed inclusion edge. Returned provenance is content-free. The observer does not write recovery configuration, create `recovery.signal`, supply `restore_command`, prove WAL/archive/timeline completeness or target attainment, promote recovery, prove application readiness, or establish achieved RPO/RTO or DR capability.
- Caller-owned physical/WAL/PITR recovery profile binder
(`bind_postgres_physical_recovery_profile()` /
`parse_postgres_physical_recovery_profile()`). The seam records method,
recovery-target kind, continuous-WAL necessity, isolated-target readiness,
and optional RPO/RTO objectives without executing backup or restore.
`wal_archive_required=False` means no continuous archive, not the absence of
backup-internal WAL. `pitr` plus `immediate` is a consistent-state stop, not
replay-to-end-of-archive. Lone-surrogate profile text fails as
`PostgresPhysicalRecoveryError`.
- Bounded `restore_postgres_logical_backup()` executor that runs one
shell-free `pg_restore --single-transaction --exit-on-error` against a
caller-owned private archive descriptor. Callers must pass exact-boolean
Expand Down Expand Up @@ -135,6 +145,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Replaced generic package-owned Result Application implementation names with
`application_phase`, `record_applied`, `result_checkpoint`,
`transaction_cursor`, `checkpointed_record`, and `record_effect`. The released
`apply_checkpointed_result_in_transaction(cursor, ..., item, apply_record)`
keyword signature and public `ResultApplicationOutcome(applied, checkpoint)`
dataclass field/introspection/`asdict` shape remain unchanged at an explicit
compatibility boundary; additive `.record_applied` and `.result_checkpoint`
reads expose semantic vocabulary while provider wire contracts and PostgreSQL
persistence remain unchanged.
- Bound repository CI checkouts to the exact pull-request source head and verify
the checked-out commit before tests, coverage, packaging, or container gates.
- Migrated package licensing to PEP 639 with an SPDX `Apache-2.0` expression,
Expand All @@ -148,4 +167,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Initial standalone and embeddable PostgreSQL LLM batch engine extraction.
- Initial standalone and embeddable PostgreSQL LLM batch engine extraction.
66 changes: 66 additions & 0 deletions docs/doctoring/batch-inference-port-convergence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# BatchInferencePort convergence doctoring

## Purpose

`pg-llm-batch` owns durable asynchronous batch lifecycle, token/size accounting, tenant-scoped persistence, checkpoint/result application, and the provider-neutral `BatchInferencePort` boundary. `contextual-orchestrator` owns provider/model discovery, routing/fallback, credential discovery and concrete LLM execution authority. This note prevents a structural Python `Protocol` or a renamed direct HTTP client from being mistaken for that completed authority split.

This is a doctoring/evidence surface. Mutable branch heads below are dated candidate evidence only and must be refreshed before integration or release decisions.

## Current evidence snapshot — 2026-09-16

Protected `main` remains on the pre-convergence implementation and does not establish a released Contextual-Orchestrator-backed batch adapter.

Draft #319 at `7b1864028d952c233abf1318e8b8b0c3351c5b65` already contains `pg_llm_batch/batch_inference_port.py` and `tests/test_batch_inference_port.py`. The candidate `BatchInferencePort` exposes upload, create, status, cancel, result-download and file-delete lifecycle operations. Its tests prove that the shipped `BatchAPIClient` and a non-HTTP adapter can satisfy the protocol while discovery/routing methods remain outside the port.

That is useful candidate evidence, but it is not the end state required by #318:

- `BatchAPIClient` remains a conforming implementation and still owns direct OpenAI-compatible `/files` + `/batches` HTTP behavior on its active source lineage;
- `create_batch_job` still accepts a host-selected `endpoint` string, so the candidate protocol alone does not prove semantic operation identity is separated from provider wire routing;
- the protocol deliberately permits an arbitrary host adapter and therefore does not itself bind execution to a versioned immutable `contextual-orchestrator` API/client/schema;
- a mutable #319 head is neither protected product truth nor immutable dependency identity.

Draft #317 remains the active `batch_api_client.py` writer for #301/#302/#347. Issue #201 owns first-class endpoint preparation/accounting. Issue #318 owns the released-contract/ACL convergence. Canonical product documentation remains separated across #229 and #324. No parallel source writer should be created while those paths overlap.

## Required authority split

The final boundary must make the following ownership executable rather than descriptive:

| Concern | Canonical owner |
| --- | --- |
| PostgreSQL durable lifecycle, tenant/RLS, token/size accounting, idempotency, checkpoint/result application | `pg-llm-batch` |
| Provider/model discovery and selection | `contextual-orchestrator` |
| Provider credentials/key discovery | `contextual-orchestrator` |
| Routing, fallback and provider-specific execution semantics | `contextual-orchestrator` |
| Versioned batch lifecycle ACL consumed by pg | pg-owned adapter over an immutable released CO API/client/schema |
| Provider wire identifiers returned as evidence | adapter boundary only; never pg domain authority by themselves |

No implementation may copy CO source, query another service database, pin a mutable CO branch, hard-code provider/model/group authority, or treat a protected source SHA as a released contract.

## RED-to-GREEN acceptance

Before replacing or restricting direct-provider authority, the serialized owner must establish realistic REDs for all of these conditions and then make the minimum causal repair:

1. **Released-contract admission.** A pg adapter must reject missing, mutable, incompatible or unverifiable CO contract identity and admit only an explicitly supported immutable released API/client/schema identity.
2. **No hidden provider authority.** Durable pg lifecycle callers must not need provider/model/group/key discovery. Provider wire endpoints or route selection must not become hidden authority merely because they are passed through a `Protocol` method.
3. **Primitive authority before transport.** The #347 invariant survives migration: behavior-bearing caller identifiers are rejected before URL formatting, credential resolution, transport preparation, comparison, logging, persistence or evidence retention.
4. **Usage honesty.** Measured, estimated and unavailable usage remain distinguishable. Unknown usage or unknown price is never coerced to zero or an authoritative complete measured total; zero usage remains distinct from unknown price.
5. **Lifecycle semantics.** Submit/status/cancel/result retrieval preserve idempotency, bounded response handling and provider-neutral lifecycle state without inventing unsupported provider behavior.
6. **Termination semantics.** User cancellation, provider terminal state and any administrator policy timeout remain distinguishable. Reasoning, streaming or tool execution is not terminated merely because elapsed time crossed an arbitrary default.
7. **Database transaction boundary.** Remote inference, provider queue wait, retry backoff and long CPU/GPU/tokenization work occur outside avoidable explicit PostgreSQL transactions and locks. Transactions cover only the minimal durable aggregate transition before or after external work.
8. **Standalone compatibility is explicit.** If a direct provider adapter is retained for standalone use, it is a deliberately bounded compatibility adapter with the same security/accounting invariants. It is not silently treated as the production CO-backed authority.

GREEN requires exact-head repository tests plus the then-live security/SAST/review gates. A predecessor GREEN does not transfer after source/base movement.

## Migration order

Use the existing serialized owners rather than creating a sibling implementation:

1. settle #317/#347 and the overlapping endpoint/accounting writers with their own RED→repair→exact-head evidence;
2. repeat #316's open-PR and no-PR path census for `batch_inference_port.py`, `batch_api_client.py`, endpoint preparation/accounting, package exports and tests;
3. obtain an eligible immutable CO release from the current CO release owner and verify API/client/schema identity, SBOM/provenance/reproducibility and rollback evidence;
4. author the pg ACL REDs against that released boundary, then implement the minimum adapter/port repair without source copying or cross-service SQL;
5. ordinary/non-force reconcile descendants, reacquire exact-final-head evidence, converge #229/#324 documentation, and only then promote an immutable pg release and consumer canary.

## Release claim boundary

A protocol class, branch-local test, protected commit, successful Release Acceptance workflow, package build or documentation statement is not an immutable release. Completion requires a normally integrated protected exact head and verified version/CHANGELOG/tag/package/SBOM/provenance/reproducibility/rollback artifacts. The consuming pg release must bind to the eligible immutable CO contract it actually uses.
Loading
Loading