Composition activation contract¶
The base coordinator provides complete parent source, physical-admission and
occurrence contracts. Public composition activation and actual worker execution
remain unavailable until protected backend adapters and worker fencing are
installed and verified. No production factory or new cache-sync CLI option is
provided by this base change. The existing default returns
DPONE_COMPOSITION_ADMISSION_UNAVAILABLE.
This page describes the implemented integration boundary and the required follow-up acceptance. See composition operations for artifact delivery, and the approved specification for the full execution scope. A successful source read, plan, fake-adapter test, cache install or launcher prepare does not certify SQL execution.
The separate ClickHouse snapshot component defines strict whole-snapshot intents and one-time EXCHANGE/recovery policy. Concrete ClickHouse gate, catalog, storage and worker qualification remain required before that component can participate in actual parent execution.
The internal scoped owner original describes complete retained reads and helper effects while preserving the activation request and attempt write projection. Its pure comparisons do not enable this coordinator or the current SQL store to admit scoped execution.
Concrete SQL Server persistence¶
dpone.adapters.composition_mssql_store.MssqlCompositionActivationStore
implements the occurrence store with real DB-API SQL statements. It accepts an
injected factory for independent connections, an externally pinned
expected_service_id, and an optional control_schema. It retains the complete
MSSQL and ClickHouse resource closure in one protected SQL control database.
ClickHouse rows in that ledger do not themselves prove ClickHouse permissions or
writer exclusion.
The platform installs the SQL from
dpone.adapters.composition_mssql_schema.render_composition_mssql_schema()
explicitly, then provisions and protects the authority and domain records.
Reapplying the initial DDL fails rather than adopting existing tables. Runtime
operations never create, repair or enroll their own authority. Each transaction
requires schema version 2, the externally pinned service UUID and the complete
eight-table catalog: original columns, keys, constraints, triggers and metadata
visibility. Legacy writable table names reject admission. See the
shared SQL storage reference for generated
CHECK provenance and initial installation. The protected backend must separately
verify database continuity, role permissions, exclusive enrollment and installed
writer gates. The schema-v2 component result
records all 50 SQL cases at the named source commit; complete worker
qualification remains pending.
The store uses one short transaction-owned application lock in the control database to serialize ledger changes. It also observes the actual SQL transaction identity at read, callback and commit boundaries; closing and reopening a transaction with the same lock does not preserve the original observation. This lock is not a writer-session fence. Requests retain canonical UTF-8 bytes and their original catalog observations. Each mutation closes its transaction connection and independently rereads the exact request, state, complete guard partition and epochs. A lost commit acknowledgement permits only exact reconciliation; it never triggers a blind mutation replay. An unavailable or changed readback requires operator recovery.
Before retirement, the store reads all durable attempts, their complete epoch
partitions and the immutable issued-principal journal. Resolved attempts require
the exact protected CLOSED_GATES, QUIESCENCE and OUTCOME proof triplet. Each
proof binds attempt, parent request, guard-epoch subject, backend service and
issued principal identities. OUTCOME also binds its terminal state; a caller
cannot promote a protected failed outcome to success. Unknown or running attempts
retain ownership. A proof document's shape or caller-supplied digest grants no
authority: trusted backend producers must create the actual observations and
protected records.
An unowned domain is not sufficient for successor admission. The store scans every owner and operation original independently of partition rows and current domain pointers. It validates complete original partitions before comparing guard intersection and reopening the relevant prior terminal-proof closure. Missing partitions, missing proof bytes and terminal-state tampering reject reservation before any epoch is advanced.
Offline adapter tests use explicit DB-API doubles. The separate synthetic SQL component runner exercises real control transactions; neither is the full current/provider/native/generated/ordinary execution campaign. Public activation remains unavailable until the complete protected backend and worker path is installed and verified.
SQL Server attempt and connection gates¶
MssqlCompositionAttemptStore in dpone.adapters.composition_mssql_attempts
accepts the same connection factory, pinned service UUID and control schema.
admit_once(attempt) persists all selected epochs before credential issuance.
read_exact(attempt) audits durable state and does not authorize another executor.
Admission checks the complete protected proof triplet of relevant previous
terminal attempts; three nonempty receipt digests are insufficient.
finalize(attempt, state=..., outcome_evidence_sha256=...) selects a protected
OUTCOME proof for a RUNNING attempt. The argument names the proof digest; its
inner evidence_sha256 names the actual producer's outcome evidence. Completion
requires matching closed-gate and quiescence proofs for every issued principal,
including other backends. A SQL gate cannot supply business-outcome evidence.
The explicit reconcile_unknown(...) operation accepts a newly protected success
or failure proof only for an audited COMMIT_UNKNOWN attempt. It issues no
credentials and cannot change an already successful or failed attempt.
MssqlCompositionLoginGate in dpone.adapters.composition_mssql_login_gate
additionally requires the exact control_database. issue_once(attempt) first
commits a unique login SID/name to the protected journal, then creates its bounded
target users and verifies READY on another connection. Only that invocation
receives the memory-only password. A replay cannot reset, enable or recreate the
principal. Driver tracing must be disabled on these injected connections.
close(attempt) irreversibly closes the reconnect gate and verifies the exact
disabled SID before persisting closure evidence. prove_quiescence(attempt)
requires server-visible absence of that original SID's sessions and transactions.
Missing or uncertain principal state remains blocking. Process exit, gate table
presence and login disablement alone are insufficient quiescence evidence.
The platform separately installs
render_composition_mssql_login_gate(control_database=...) from
dpone.adapters.composition_mssql_gate_schema. Execute its GO batches preserving
the trigger definition bytes. Provision the disabled gate reader, its minimum
catalog/DMV grants and the protected control-table read permission as documented
by the renderer. Enroll newly isolated target databases with their actual
database identity, managed schemas and exact bounded writer role. Runtime checks
the installed trigger definitions and permissions; it does not provision them.
For this initial cell the trusted controller must own each dedicated target
database, the bounded role must be owned by dbo, and managed objects must use
inherited or dbo ownership. Read-only principals may not acquire writer authority
through object or role ownership.
The controller's exact dbo principal may retain its membership in the fixed
db_owner role. This exception requires principal ID 1 and the original
controller SID; it does not admit any other db_owner member.
The catalog policy reports fixed login_database_policy_* refusal reasons for
role/object ownership, unsupported objects, unmanaged scope, assemblies,
authentication, ambient grants and memberships. These declared policy failures
are distinct from control_operation_unknown, which indicates an unavailable or
uncertain driver operation. A diagnostic reason never relaxes the predicate.
LOGON synchronization and DMV visibility still require real tests on the pinned
SQL Server version before worker activation is enabled.
The gate-reader permission probe restores the controller before it emits its result set. A driver that reads only the first row must not leave subsequent ledger or login operations running under the reader's restricted identity.
Disposable SQL component check¶
The Composition SQL Server component GitHub workflow uses a clean candidate
checkout, Linux x86-64, Docker and Microsoft ODBC Driver 18. Its equivalent command
on an explicitly approved disposable runner is:
uv sync --locked --extra mssql
uv run python tools/composition_mssql_synthetic.py \
--profile gate \
--output-dir "$RUNNER_TEMP/composition-mssql-gate-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
The output must be a new directory outside the checkout. The runner creates its
own pinned SQL Server container, random loopback port and synthetic database;
it does not accept an existing service. It retains only sanitized summary.json
and junit.xml, recording exact source, image, driver and server identity. All
expected cases must execute without skips. A cleanup failure changes the result
to FAIL. No raw driver diagnostics or credentials belong in these artifacts.
The workflow runs four independent profiles, each in its own fresh container:
| Profile | Required cases | Evidence scope |
|---|---|---|
store (default) |
7 | Real ledger DDL, whole-parent transactions, conflicts, lost acknowledgements and retirement |
gate |
16 | Real issued credentials, target permissions and continuity, monotonic LOGON closure, races, in-flight transactions and explicit unknown recovery |
trust |
9 | Real append-only nonproduction trust, original bytes, revision races, schema integrity, lock/acknowledgement failures and bounded provisioner permissions |
registration |
18 | Exact grant originals and complete membership, historical trust, replay and concurrency, rollback/unknown acknowledgements, catalog/session enforcement and restricted-login permissions |
The gate profile uses the actual closed-gate and quiescence producers. Its
test-only outcome producer binds observed SQL and independent reconciliation;
it does not qualify the future native/transfer worker outcome producer. The
runner rejects a missing, skipped, duplicate or foreign case, including results
from the other profile. JUnit retains bounded numeric SQL error identifiers and
fixed domain reasons for failure diagnosis; raw driver messages stay suppressed.
The trust profile uses inert public policy documents as storage fixtures. It
does not verify actual grant signatures, consume grants or authorize workers.
Its provisioner case verifies database permissions through an impersonated
database user; it does not qualify a separately authenticated network login.
Select it with --profile trust in the same disposable command.
The registration profile also uses inert unsigned storage fixtures. It requires
the real 8 MiB bundle boundary, complete membership and historical-original audits,
and explicit lost-acknowledgement recovery. Its restricted-login case uses actual
server/database tokens. The runner creates an exact two-byte public integer file
inside that new container; administrator SQL must independently read/hash it and
successfully import it before a restricted principal's bulk-import refusal can
serve as permission evidence. A missing file or unsupported operation is a failure,
not a verified denial. Use --profile registration to select this inventory.
Default non-live collection skips all profiles without opening a connection.
This component's ClickHouse rows are synthetic ledger metadata. Route
qualification and complete worker execution remain separate observations;
a component PASS must not be reported as their certification. LOGON conclusions
require a green gate result on the exact source and pinned server version;
the store profile supplies no such evidence.
Required downstream matrix¶
| Workload | Required route | Base contract | Actual parent execution |
|---|---|---|---|
| Native dbt | Verified SQL Server execution-pack.v2 | Full native workflow/model/helper ownership | UNVERIFIED; protected SQL login gate and worker integration pending |
| Native-generated transfer | MSSQL to ClickHouse full_refresh | Separate producer-aware classifier; positive cumulative max_source_bytes required | UNVERIFIED; protected CH gate, Atomic publication and canonical route evidence pending |
| Ordinary transfer | PostgreSQL to MSSQL full_refresh | Explicit external target_atomic state; table extraction only | UNVERIFIED; parent fence inside the actual target transaction pending |
| Other cells, including ordinary MSSQL to ClickHouse | Not in this initial matrix | Rejected | Unsupported |
The required downstream spans SQL Server and ClickHouse. A SQL Server-only coordinator or synthetic pass does not satisfy this matrix. The same named execution cell cannot make an ordinary declaration eligible for the native-only ClickHouse route.
Exact Python boundaries¶
Read a complete parent with the production source verifier:
from pathlib import Path
from dpone.app.release_composition import build_composition_source_reader
sources = build_composition_source_reader().read_sources(
Path("synthetic/composed"),
expected_release_id=expected_parent_release_id,
)
The returned CompositionSourceSnapshot retains the native child identity,
ordinary inventory identity, every final workload pin, complete relation writes,
and bounded original transfer manifests. Native-generated transfers are included.
The reader revalidates the entire producer closure before returning. Ordinary
archives retain support for declared SQL files and generated runtime manifests.
Their delivery acceptance is separate from the narrower execution matrix.
State-bearing ordinary MSSQL packs use
AirflowCompactPackBuilder.build(..., outlet_binding="logical"); the verifier
reconstructs the same projection. Aliases gain physical authority only from later
verified deployment bindings, never from the logical outlet.
dpone.manifest.composition_execution_plan.plan_composition_execution(sources)
classifies the complete workload union. Native-generated declarations retain
runtime, quality, gitops, sink.mode, source/target options and their byte
budget. They are not stripped into an ordinary-manifest shape. The protected
backend must subsequently validate all option effects, physical design, state,
permissions, enrollment and writer-session capabilities.
Application integrators construct
dpone.services.composition_activation_coordinator.CompositionActivationCoordinator
with keyword capabilities inputs, preparation and stores.
CompositionActivationPreparation(physical=...) uses
CompositionPhysicalAdmissionService(backend=...) to merge aliases before
physical observation. The ports document the protected transaction and session
requirements; in-memory or filesystem-only implementations do not meet them.
The coordinator exposes:
prepare(*, projection_root, activation_id, environment, release_id, deployment_id, previous_deployment_id);activate(prepared, *, projection_root);require_active(...)with the same coordinates asprepare;begin_retirement(active, *, projection_root);finalize_retirement(retiring, *, projection_root).
The additive materializer parameter is
DeploymentCacheMaterializer(..., composition_activation_coordinator=coordinator).
It is separate from the existing native-only workspace_activation capability.
A native receipt, untyped result, missing constituent, stale request or changed
fencing epoch cannot acknowledge parent activation. Production deployment
composition must supply all protected capabilities before using this parameter.
Identity and physical collision algorithm¶
- Verify original native and ordinary sources, final transport, parent identity, selected native trios and exact source-to-workload membership.
- Bind the activation to the sealed deployment/runtime context and a UUIDv4 occurrence. Classify every workload; reject an unavailable cell before any reservation or predecessor drain.
- Resolve every binding to its protected service incarnation and physical collision domain. Aliases, credentials, hostnames and engine versions are not physical identities.
- Group all writes by the resulting domain. Ask the backend for one complete catalog/collation comparison per group, including native intermediate, backup and helper relations and all modeled transfer effects. Query-local equivalence IDs from separate alias queries are not comparable.
- Reject missing/duplicate slots or any equivalent write coordinates. Persist the immutable request containing full workload/write membership, stable resources and the original observation digest.
- On later phases, reread the immutable request and reverify source, runtime and stable physical bindings. Legitimate table create/modify timestamps must not change the original request identity.
dpone.contracts.composition_control is the explicit contract boundary for
application services and ports. It only reexports cohesive DTOs/policies; it
performs no I/O, backend selection or policy registration.
Lifecycle and failure semantics¶
stateDiagram-v2
[*] --> PREPARED: complete admission / protected reservation
PREPARED --> ACTIVE: current CAS commit / exact acknowledgement
ACTIVE --> RETIRING: close new attempt admission
RETIRING --> RETIRED: closed gates / quiescence / resolved outcomes
The store must reserve all guards without expiration, close predecessor admission, prove its attempts quiescent with resolved outcomes, and transfer exact epochs under protected control transactions. Cross-service data writes remain separate transactions. Drain-first handover does not promise zero downtime.
The cache validates a typed PREPARED receipt before switching current and the
same full request/epochs in ACTIVE afterward. A failed post-pointer acknowledgement
returns DPONE_COMPOSITION_ACTIVATION_COMMIT_UNKNOWN with
state_may_have_changed: true and recovery_required: true. Retain sealed inputs,
original request and control evidence. Old pointer bytes alone do not prove the
old occurrence remains executable after a protected ownership transfer.
CompositionAttemptIdentity binds the parent activation request, constituent,
workload pack, verified plan, actual DAG run/task/try/map coordinates and complete
applicable guard epochs. Protected admission must evaluate the entire ledger in
the same transaction as reservation. The pure policy rejects RUNNING replay,
stale or missing epochs, retired parents and overlapping RUNNING or COMMIT_UNKNOWN
attempts across native and ordinary workloads.
A terminal receipt requires independent closed-gate, server-quiescence and durable outcome evidence. A closed gate or exited process does not resolve an unknown SQL commit. No TTL may release its resource ownership. These policy checks still need to be connected to actual worker sessions and target transactions.
Downstream CI and recovery acceptance¶
The required isolated synthetic campaign is:
verified native + ordinary producer outputs
-> complete parent -> deployment -> current ACTIVE
-> provider loads every expected DAG -> explicit DAG triggers
-> actual native dbt SQL -> generated MSSQL-to-ClickHouse transfer
-> actual ordinary PostgreSQL-to-MSSQL transfer
-> independent row/schema/state/evidence reconciliation
Native DAG ordering does not establish cross-constituent dependencies. With
schedule: null, trigger the relevant DAGs explicitly. Do not handcraft runtime
plans or rewrite producer/receipt identities.
The campaign must retain exact source commit, environment versions, parent and child identities, activation, all workload/run/attempt IDs and complete observed results. It must reconcile Decimal/numeric precision and scale, GUID, NULL, vanished rows, empty full snapshots and measured cumulative source bytes. Source stream bytes are distinct from post-transcode HTTP bytes.
Required faults include physical aliases/collation collisions, unsupported cells, stale CAS/context/epochs, replayed RUNNING attempts, lost gate issuance ACK, credential reconnection races, current commit without ACTIVE ACK, committed SQL without evidence, delayed ClickHouse staging INSERTs and uncertain EXCHANGE. ClickHouse recovery must compare persisted before/after UUID identities: blindly retrying EXCHANGE can exchange the tables back. Close and drain stage writers before exposing that UUID as the target. Deployment rollback does not undo SQL.
Current acceptance gaps are explicit:
- Protected SQL Server enrollment, one-time login issuance, LOGON closure barrier, DMV quiescence and actual dbt/ordinary worker credential injection.
- ClickHouse physical enrollment, per-attempt writer closure, staged snapshot publication with atomic EXCHANGE and durable recovery intent.
- Genuine route qualification and the separately approved nonproduction authority family for the synthetic campaign. Existing production/native-v2 requirements retain their meaning; local synthetic receipts cannot be relabeled as production.
- The public authority-aware app factory/CLI and complete current/provider/SQL reconciliation run. Local ARM64 Docker is not the vendor-supported SQL Server container cell; use an isolated Linux x86-64 runner for that proof.
The base contracts are reviewable independently. These gaps remain requirements for completing the feature and declaring downstream readiness.