diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b4bbb9a..aa643117 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added + - `BE-03-CLOSEOUT-01`: correct the materially stale active Publisher Services programme and dependency state left after the `BE-03` implementation merged. Active controls now record `BE-03` as `CLOSED - INACTIVE FOUNDATION`, and stop asserting that `BE-03` is unmerged, a draft, in review, awaiting independent review or merge authorization, `NOT AUTHORIZED`, or that `feature/publisher-services/be-03` must not exist. The `BE-03` dependency is recorded as satisfied for `BE-04`, `MIG-01`, `APP-01` and `APP-02` **without** any of them becoming ready: `BE-04` remains `BLOCKED` and `NOT STARTED` with no `distribution_job`, `distribution_job_target` or `distribution_job_attempt` relation, no automatic back-catalogue job creation and no dissemination in existence; `MIG-01` remains `CRITICAL` and blocked by its audit, backfill and production prerequisites; `APP-01`'s satisfied backend-contract dependency is scoped to its configuration-only surface while its app-readiness controls, exact-SHA contract pinning and own approved specification still gate it and its job-aware elements still require `BE-04`; and `APP-02` remains blocked on `BE-04` and `APP-01`. Corrects the `BE-03` specification's own lifecycle-boundary prose without altering any approved requirement, invariant, architecture, API contract, authorization matrix, migration decision, acceptance criterion or test obligation, and adds the bounded `BE-03-CLOSEOUT-01` implementation report. **Documentation and control records only: no runtime, schema, migration, API, generated contract, client artifact or workflow change.** Under `ADR-0005` no active control correction in this change copies GitHub lifecycle metadata — a review, approval or merge-authorization identifier, a merge commit SHA, a merge timestamp or a draft/ready state — merely to restate terminal review, authorization or merge state; the exact SHAs this change records as the authorized implementation base and as preflight/ancestry evidence are execution evidence the repository's own controls require, not post-merge lifecycle transcription. GitHub remains the terminal lifecycle authority, the self-resolving authority-condition construction of the `BE-03`/`BE-04`/`APP-01` phase-boundary decision is preserved as written, and historical implementation-time evidence — including every migration-path reference recorded at an exact implementation head and later renamed by PR [811](https://github.com/thoth-pub/thoth/pull/811) — is preserved unchanged. Deployment, environment and production migration execution, package commercial backfill, assignment creation/backfill, durable job creation, dissemination, distribution activation, `OBSERVE`/`ENFORCE`, workflow changes or dispatch and production access all remain **NOT AUTHORIZED**, and PR [799](https://github.com/thoth-pub/thoth/pull/799), issue [765](https://github.com/thoth-pub/thoth/issues/765) and issue [766](https://github.com/thoth-pub/thoth/issues/766) are untouched - `BE-03-CLOSEOUT-01-SPEC`: propose the bounded post-merge control-correction specification for `BE-03-CLOSEOUT-01` (`docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md`). Records the classified stale-state analysis of the active Publisher Services and shared engineering-control surface after the `BE-03` merge, and specifies the correction that must follow: `BE-03` recorded as `CLOSED - INACTIVE FOUNDATION`; the `BE-03` dependency recorded as satisfied for `BE-04`, `MIG-01`, `APP-01` and `APP-02` **without** any of them becoming ready — `BE-04` remains unspecified and unauthorized with no durable job, target, attempt or automatic onboarding behaviour in existence, `MIG-01` remains `CRITICAL` and blocked by its production audit/backfill prerequisites, `APP-01`'s satisfied backend-contract dependency is scoped to its configuration-only surface while its app-readiness controls, exact-SHA contract pinning and own specification still gate it and its job-aware elements still require `BE-04`, and `APP-02` remains blocked on `BE-04` and `APP-01`. Classifies every statement as `ACTIVE STALE STATE - CORRECT`, `HISTORICAL RECORD - PRESERVE`, `CURRENT AND CORRECT - PRESERVE` or `OUT OF SCOPE - PRESERVE`, forbidding global find/replace. Under `ADR-0005`, forbids any commit that merely transcribes a review, approval or merge-authorization identifier, PR [809](https://github.com/thoth-pub/thoth/pull/809)'s merge SHA or its merge timestamp, and preserves historical implementation-time evidence — including every migration-path reference recorded at an exact implementation head, which the later PR [811](https://github.com/thoth-pub/thoth/pull/811) forward-integration renamed (`BE-02` `20260812_v1.7.0` -> `20260811_v1.7.0`; `BE-03` `20260813_v1.7.0` -> `20260812_v1.7.0`, content and relative apply order preserved). Preserves the `ADR-0005` authority-condition construction of the `BE-03`/`BE-04`/`APP-01` phase-boundary programme decision rather than replacing it with a literal status token, correcting only the references outside that self-resolving construction. **Specification and control records only - no runtime, Cargo, GraphQL, schema, migration, workflow or infrastructure change, no closeout correction performed, and no implementation branch created.** The `BE-03-CLOSEOUT-01` implementation remains **NOT AUTHORIZED** pending explicit CTO authorization against a freshly verified base; `BE-04`, `MIG-01`, `APP-01`, `APP-02`, deployment, environment and production migration execution, package commercial backfill, assignment creation/backfill, durable job creation, dissemination, distribution activation, `OBSERVE`/`ENFORCE`, workflow dispatch, production access and PR [799](https://github.com/thoth-pub/thoth/pull/799) all remain outside scope and unauthorized - `BE-03`: implement the approved bounded **protected publisher service configuration** as an inactive additive foundation. Adds the canonical optimistic-concurrency token `publisher.service_configuration_updated_at` (`timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL`, strictly increasing per publisher through `GREATEST(CURRENT_TIMESTAMP, previous + interval '1 microsecond')`), the closed two-value `publisher_service_configuration_source` type (`SUPERUSER_API`, `MIGRATION_BACKFILL`; no `OTHER`, no `UNKNOWN`, no `Default`) and the append-only `publisher_service_configuration_history` audit table (`actor text NOT NULL` with a named non-whitespace check constraint `CHECK (actor ~ '[^[:space:]]')`, enforcing that an audit actor contains at least one non-whitespace character, `ON DELETE CASCADE` foreign key, and a deterministic `(publisher_id, created_at DESC, id DESC)` composite index), with `thoth-api/src/schema.rs` updated manually and atomically in the same PR under `ADR-0003` Architecture A. Introduces **exactly one authoritative production write path** — the service-configuration write coordinator — which owns every committed write of package, enabled-platform desired state, configuration version token and audit history in one transaction on one connection under an explicit caller-supplied source/actor context, taking the publisher row lock first, rejecting a stale `expectedUpdatedAt` before any validation or lifecycle call, pre-validating the whole normalized desired platform set, applying platform state only through `BE-02`'s lifecycle primitives, committing the package and the token together in **exactly one** publisher `UPDATE` written directly (so no `publisher_history` row is written, and the shared `AFTER UPDATE` work-freshness cascade runs once per committed change whatever its shape, while a true no-op or stale request issues zero publisher `UPDATE`s), and writing exactly one audit row per committed change with bounded three-key canonical before/after state. Refactors `BE-02`'s lifecycle additively into connection-scoped `enable_on`/`disable_on` primitives that return a `#[must_use]` `Changed`/`Unchanged` outcome and validate `is_assignable()` themselves before any write, leaving the pool-level `enable`/`disable` signatures, semantics, early non-assignable check and existing tests unchanged and keeping exactly one linked-platform algorithm in the repository — so a membership-equal but split OAPEN/DOAB pair is **repaired**, bumping the token and writing one audit row, while a fully normalized request is a true no-op that writes nothing. Adds the protected `PublisherServiceConfiguration` type exposing the publisher, `subscriptionPackage`, `effectiveCapabilities`, `enabledDistributionPlatforms` and the version token; effective capabilities are **derived on read** from the canonical package through `BE-01`'s code-owned `ThothPackage::capabilities()` in that slice's order and persisted nowhere, so no package/capability inconsistency is representable and a package change updates them automatically. Adds the owner-and-superuser `publisherServiceConfiguration` query under a least-privilege per-publisher check (superuser, or exactly `PUBLISHER_USER` for that publisher's organisation, with **no role inheritance**: `PUBLISHER_ADMIN`, `WORK_LIFECYCLE` and `CDN_WRITE` without `PUBLISHER_USER` are denied, and a `NULL` `zitadel_id` fails closed for every non-superuser), the superuser-only `publisherServiceConfigurations` staff report and `publisherServiceConfigurationCount` with `[Uuid!] = []`, `[ThothPackage!] = []` and `[DistributionPlatform!] = []` filters, `AND` semantics for `enabledPlatforms`, a mandatory `publisher_id ASC` tie-breaker and a bounded two-statement page (one publisher page plus one `DISTINCT ON` latest-change lookup, with assignments resolved through `BE-02`'s existing request-local `ADR-0007` loader and **no second loader**), and the superuser-only `replacePublisherServiceConfiguration` mutation. Adds exactly one new error variant, `ThothError::StalePublisherServiceConfiguration`, and exactly one new `into_field_error` arm, `STALE_SERVICE_CONFIGURATION`, disclosing no SQL, column name or current token; every other error family keeps its merged mapping. `ThothPackage` and `PublisherCapability` become SDL-reachable for the first time, exclusively through the protected type: neither is on the public `Publisher`, and no package or capability value is anonymously readable. **Accepted and measured consequence:** because the token is a `publisher` column, every committed change — including a platform-only change and a linked-state repair — also moves `publisher.updated_at` and refreshes `work.updated_at_with_relations` for every work of that publisher through the existing `AFTER UPDATE` trigger's single set-based statement (never a per-work application loop), invalidating that publisher's cached export records; a stale request, a true no-op and a rolled-back transaction move none of the three values, and another publisher's works are never touched. **Inactive foundation only: the migration creates zero audit rows and changes no package or assignment; no distribution job, job target, job attempt or fabricated job status exists; no dissemination, upload or feed is produced; no capability state is persisted; no production migration, deployment, environment migration, backfill or distribution activation is performed; mutation-guard mode is unchanged; and no `BE-04`, `MIG-01`, `APP-01`, `APP-02` or PR [799](https://github.com/thoth-pub/thoth/pull/799) work is included.** - `BE-03-SPEC`: propose the complete bounded implementation specification for `BE-03` - **protected service configuration** (`docs/engineering/ai-delivery/tasks/BE-03.md`). Settles the full contract for the protected `PublisherServiceConfiguration` type — which, per `ADR-0001` section 4.4, exposes the current package, the **effective capability codes** and the enabled distribution platforms — the owner-and-superuser `publisherServiceConfiguration` query with its complete deny/allow matrix resolved through the existing ZITADEL publisher-role model (no new ownership table, no new role), the superuser-only paginated and deterministically ordered `publisherServiceConfigurations` staff report with publisher/package/enabled-platform filters declared in the merged repository shape (`[Uuid!] = []`, `[ThothPackage!] = []`, `[DistributionPlatform!] = []`), and the superuser-only `replacePublisherServiceConfiguration` mutation executing in exactly one transaction with a documented deterministic lock order matching `BE-02`. Effective capabilities are **derived on read** from the canonical `subscription_package` through `BE-01`'s code-owned `ThothPackage::capabilities()`, in that mapping's canonical order, and are **persisted nowhere** — no capability column, table, override or cache, no second mapping, and no capability input — so no package/capability inconsistency is representable and a package change updates them automatically; they are protected by the same single read decision as the rest of the type and must not appear on the public `Publisher`. States the protected read as a **least-privilege per-publisher check** — superuser, or exactly `PUBLISHER_USER` for the target publisher's organisation — with **no role inheritance**, so `PUBLISHER_ADMIN`, `WORK_LIFECYCLE` or `CDN_WRITE` without `PUBLISHER_USER` are denied and commercial package visibility is not widened by an unrelated scoped capability. Fixes one authoritative internal **service-configuration write coordinator** owning every committed write of package, enabled-platform desired state, canonical configuration version and configuration audit history in one caller-owned transaction under an explicit source/actor context, with `BE-02`'s pool-level `enable`/`disable` retained unchanged but reclassified as lower-level domain/compatibility functions barred from new production configuration call sites, and required call-site and bypass-search evidence. Selects a **dedicated `publisher.service_configuration_updated_at` concurrency token** with a strict per-publisher monotonicity rule, recording why `publisher.updated_at` and a computed multi-timestamp maximum were rejected, and documenting the accepted consequences that follow from the token being a `publisher` column: `public.publisher` carries **two** existing `UPDATE` triggers, so every committed configuration change — including a platform-only change or a linked-state repair — moves the public `Publisher.updatedAt` through `set_updated_at` **and** refreshes `work.updatedAtWithRelations` for every work of that publisher through its imprints through the existing `AFTER UPDATE` `set_work_updated_at_with_relations`, while a stale request, a true no-op and a rolled-back transaction move none of the three values and no other publisher's works are ever touched. The work-freshness value is a **public downstream signal** that invalidates that publisher's cached export records, so a platform-only change and a linked-state repair newly cause a cascade merged `BE-02` does not cause; the committed transaction therefore writes one publisher row plus bounded configuration/audit rows plus N related work rows through **one set-based trigger statement, never a per-work application loop**, with row-lock footprint and transaction duration growing with catalogue size while the publisher lock is held, and `BE-04` inherits this with the same transaction boundary. The token stays on `publisher` because a separate version table — whose genuine benefit for platform-only persistence is recorded honestly — would not avoid the same cascade for canonical package changes while `BE-01`'s `subscription_package` remains on `publisher`, and eliminating it fully would mean wider changes to approved `BE-01` storage or shared publisher trigger semantics; acceptance is therefore **evidence-conditional**, requiring six-case evidence against a real disposable PostgreSQL database with at least two imprints, at least two target works and a control work of another publisher, plus a catalogue-scale write-amplification and lock-footprint measurement recorded without production extrapolation, and a new stop condition requiring `BLOCKED` and a separate architecture escalation — never a silent trigger or storage change — if that evidence is bad. This freshness cascade is **not** distribution activation: no distribution job, upload, feed or dissemination is created. `Publisher.updatedAt` is explicitly **not** the configuration concurrency token, the protected values themselves stay behind the single read decision (timing correlation is acknowledged rather than denied), and the token's addition to the `Publisher` struct may surface as an additional key in future `publisher_history.data` snapshots; specifies the additive `publisher_service_configuration_history` audit table with an explicit `actor text NOT NULL` column (non-blank check constraint; following the repository's established account-FK-free actor representation but deliberately not named `user_id`, because `source` fixes the actor's provenance) and a closed two-value `source` type whose `SUPERUSER_API`/`MIGRATION_BACKFILL` actor contract is defined now, binding a future `MIG-01` to the same coordinator, the same token update and the same audit invariants while creating no job; plus bounded canonical before/after state that exposes no credential, endpoint, activation identifier or unrelated publisher metadata; requires reuse of `BE-02`'s linked OAPEN/DOAB normalization and non-assignable `JISC_NBK` behaviour through an additive connection-scoped refactor rather than a second implementation, with the primitives reporting whether they changed persisted state so that a **membership-equal but split OAPEN/DOAB pair is repaired rather than skipped** — a repair being a committed change that bumps the token and writes exactly one audit row — and with the connection-scoped enable primitive required to check `is_assignable()` **itself** before any write, as defence in depth alongside the retained pool-level early check and the coordinator's whole-set pre-validation; and requires reuse of `BE-02`'s existing request-local `ADR-0007` assignment DataLoader rather than a second equivalent loader. Raises one **programme-decision candidate** for CTO approval, under a durable `ADR-0005` authority condition rather than a mutable status word — it becomes an approved programme decision when the exact specification content carrying it receives explicit CTO specification approval **and** that content is reachable from `develop`, with no separate lifecycle-status commit required: `BE-03` owns desired configuration only and creates no `distribution_job`, `distribution_job_target` or `distribution_job_attempt` row, no placeholder job and no fabricated job status, with `BE-04` later extending the same transaction boundary; the decision additionally reconciles `APP-01`, whose configuration scope BE-03 satisfies but whose durable job, attempt, failure and pending-onboarding elements require `BE-04`. **Specification and control records only - no runtime, Cargo, GraphQL, schema, migration, workflow or infrastructure change, no implementation, and no implementation branch created.** `BE-03` implementation remains **NOT AUTHORIZED** and `feature/publisher-services/be-03` must not exist; `BE-04`, `MIG-01`, `APP-01`, `APP-02`, deployment, environment and production migration, assignment backfill, distribution activation, `OBSERVE`/`ENFORCE` and PR [799](https://github.com/thoth-pub/thoth/pull/799) all remain outside scope and unauthorized diff --git a/docs/engineering/ai-delivery/implementation-reports/BE-03-CLOSEOUT-01-implementation-report.md b/docs/engineering/ai-delivery/implementation-reports/BE-03-CLOSEOUT-01-implementation-report.md new file mode 100644 index 00000000..e5f54f31 --- /dev/null +++ b/docs/engineering/ai-delivery/implementation-reports/BE-03-CLOSEOUT-01-implementation-report.md @@ -0,0 +1,996 @@ +# BE-03-CLOSEOUT-01 Implementation Report + +## 1. Repository state + +Repository: `thoth-pub/thoth` +Workflow: STANDARD +Base branch: `develop` +Base commit: `b51bcc0905ac17fc0c142b2002b11fec711331a3` +PR target: `develop` +Programme integration branch: None +Task branch: `feature/publisher-services/be-03-closeout` +Head commit: recorded in the pull request; this report is written at the branch +head that carries it +Pull request: draft pull request against `develop`; live state is the GitHub +pull-request record +Expected branch deletion after merge: YES +Final programme PR required: NO +Implementing model: Claude Opus 5 +Reasoning level: Extra High / xhigh + +### 1.1 Exact authorized base + +The CTO authorized implementation against exact `develop` head: + +```text +b51bcc0905ac17fc0c142b2002b11fec711331a3 +``` + +### 1.2 Preflight, performed before branch creation and before any edit + +```text +origin/develop = b51bcc0905ac17fc0c142b2002b11fec711331a3 MATCH +b51bcc09 parents = a4585a8d89166577da5ce6f46ce51ddb134b3f7e (first) + d952a83206ad846c7a01f70c29fe694bc8cd5561 (spec content) +b51bcc09 identity = merge commit of PR #812 +PR #812 = MERGED, base develop, + head feature/publisher-services/be-03-closeout-spec, + mergeCommit b51bcc09 +BE-03-CLOSEOUT-01.md at base = present; blob 2f23caf076ba963bc38b24d3c8b8f5a5e9261429, + byte-identical to the blob at d952a832 +PR #809 = MERGED, base develop, + mergeCommit 3ba4452c316399d80cd8d85e7d5e1bd05e252664 +PR #809 ancestry = 3ba4452c is an ancestor of b51bcc09 (verified with + git merge-base --is-ancestor) +BE-03 implementation at base = thoth-api/migrations/20260812_v1.7.0/{up,down}.sql present +Local branch feature/publisher-services/be-03-closeout = does not exist +Remote branch feature/publisher-services/be-03-closeout = does not exist +Open BE-03-CLOSEOUT-01 implementation PR = none + (open PRs: #799, #752, #744, #742, #668) +Committed competing closeout implementation record = none +Working tree = clean +``` + +`origin/develop` matched the authorized SHA exactly, so no intervening-commit +inspection was required. The pre-existing branch +`feature/publisher-services/be-03-closeout-spec` is the merged specification +branch, not a competing implementation branch. + +Repository instructions read before any edit: root +[`AGENTS.md`](../../../../AGENTS.md), +[`docs/engineering/AGENTS.md`](../../AGENTS.md), the approved specification +[`BE-03-CLOSEOUT-01`](../tasks/BE-03-CLOSEOUT-01.md) and +[ADR-0005](../../decisions/ADR-0005-terminal-merge-evidence.md). No more +specific `AGENTS.md` applies: the diff touches no workspace member and no +workflow directory. + +Branch creation: + +```bash +git switch -c feature/publisher-services/be-03-closeout b51bcc0905ac17fc0c142b2002b11fec711331a3 +``` + +## 2. Scope confirmation + +Approved specification: +[`BE-03-CLOSEOUT-01`](../tasks/BE-03-CLOSEOUT-01.md) + +Implemented objective: correct the materially incorrect active Publisher +Services programme and dependency state left behind after the BE-03 +implementation merged, so that active controls durably record BE-03 as +`CLOSED - INACTIVE FOUNDATION` and record each downstream dependency +accurately — satisfied where the merge satisfied it, and still blocked +everywhere else. + +Out-of-scope changes made: NONE. Every changed path is one of the paths the +specification lists in its section 3. No additional documentation path was +required. + +## 3. Commits + +- `docs(publisher-services): reconcile BE-03 post-merge state` - the bounded + commit carrying this closeout. +- `docs(publisher-services): clarify closeout evidence record` - additive + review-remediation commit. It corrects the overly absolute ADR-0005 evidence + wording in the CHANGELOG entry and in sections 5 and 15 of this report so that + prohibited lifecycle transcription is distinguished from the exact-base and + ancestry SHAs the controls require as execution evidence; records the exact + reproducible relative-link verification command and its fresh result in + section 9 in place of a prose description; and clarifies section 5.1. It + changes no classification, no other file and no scope. The earlier commit was + not amended, rebased or force-pushed. +- `docs(publisher-services): clarify closeout acceptance evidence` - additive + control-clarification commit. It applies the explicit CTO clarification of one + overbroad acceptance criterion in this task's own approved specification + (`BE-03-CLOSEOUT-01.md` section 9) and records that clarification here. It + touches those two files only. It changes no architecture, no runtime scope, no + BE-03/BE-04/APP-01 boundary, no ADR-0005 text, no migration policy, no + classification and no other file, and it neither implements nor authorizes any + further work. See section 5.3. The two earlier commits were not amended, + rebased or force-pushed. + +The current branch head is recorded in the pull request. This report records the +commit sequence; the head SHA, review state and merge state are terminal GitHub +evidence under ADR-0005 and are not transcribed here. + +## 4. Files changed + +- `docs/publisher-services/task-status.md` + - reason: the active programme tracker recorded BE-03 as + `IMPLEMENTATION IN REVIEW` with a `(draft)` PR cell, an acceptance cell + reading `IMPLEMENTATION DELIVERED, NOT MERGED`, a `Last updated` note and + next-actions 10, 11 and 12 describing BE-03 as unmerged and awaiting fresh + review and CTO merge authorization, and listed BE-03 as an unsatisfied + blocking dependency of BE-04, MIG-01, APP-01 and APP-02. + - behavioural effect: none. BE-03 is now recorded as `CLOSED` with acceptance + `CLOSED - INACTIVE FOUNDATION`; BE-04, MIG-01, APP-01 and APP-02 record the + BE-03 dependency as satisfied while retaining every remaining blocker and + their `BLOCKED` / `NOT STARTED` status; the transient review-lifecycle + narrative is replaced by durable prose that points at the pull-request + record under ADR-0005. + +- `docs/publisher-services/README.md` + - reason: the header status line and the section 5 decision block asserted + `BE-03 IMPLEMENTATION NOT AUTHORIZED`; gating reason 1 repeated it; the + closing paragraph said an approved specification does not "unlock `BE-03`". + - behavioural effect: none. The decision block now records BE-03 as a closed + inactive foundation and states the downstream position for BE-04, MIG-01, + APP-01 and APP-02 explicitly, together with the expanded + `NOT AUTHORIZED` list. + +- `docs/publisher-services/rollout-plan.md` + - reason: the BE-02 implementation state block ended with "`BE-03` + implementation is `NOT AUTHORIZED`", and section 2.2 bound "the later + `BE-03`" in the future tense with a future-tense item 1. + - behavioural effect: none. A `BE-03 implementation state` block records the + merged inactive foundation on the same terms as the BE-02 block; section + 2.2 now binds APP-01 and states that the reserved control binds against + BE-03's reviewed implementation head. The control's substance is unchanged. + +- `docs/publisher-services/decisions.md` + - reason: the section 3a APP-01 reconciliation asserted in the present tense + that APP-01 "remains blocked on BE-03 exposing the approved protected + API", which the BE-03 merge falsified; the `Last updated` line needed to + reflect this change. + - behavioural effect: none. See section 5.2 for the explicit control ruling + and its application. The self-resolving ADR-0005 authority-condition + construction is preserved verbatim. + +- `docs/engineering/ai-delivery/tasks/BE-03.md` + - reason: the approved BE-03 specification carried `Status: DRAFT`, a header + implementation-authorization block reading "**separate and absent** ... The + branch `feature/publisher-services/be-03` must not exist", and a section 23 + lifecycle boundary asserting "BE-03 implementation status is + `NOT AUTHORIZED`". + - behavioural effect: none. Only the three lifecycle-boundary sites the + specification authorizes are changed. No requirement, invariant, + architecture, API contract, authorization matrix, migration decision, + acceptance criterion, test obligation, operational consequence or BE-04 + transaction seam is altered. + +- `docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md` + - reason: this task's own durable specification decision state was `DRAFT` + and its section 18 approval record was empty, both of which the + specification's CTO approval and merge through PR #812 falsified. + - behavioural effect: none. `Status: APPROVED`; section 18 records the + durable implementation authorization and the exact authorized base. The + header rule "Implementation authorization: **separate.**" is retained + unchanged as a durable rule. + - reason (second, later edit): one section 9 acceptance criterion was + overbroad and, read literally, forbade the exact-base and preflight/ancestry + evidence the same specification and root `AGENTS.md` require. The CTO + explicitly clarified it. See section 5.3. + - behavioural effect: none. One checklist item in section 9 is replaced by the + CTO-approved purpose-qualified wording. Section 18's authorized-base + evidence, the historical background, Annex A, the authority condition, + scope, non-goals and architecture are all unchanged. + +- `docs/engineering/ai-delivery/implementation-reports/BE-03-CLOSEOUT-01-implementation-report.md` + - reason: required by the specification section 14 and root `AGENTS.md` + section 14. + - behavioural effect: none; new evidence record. + +- `CHANGELOG.md` + - reason: root `AGENTS.md` section 13 requires an entry under + `## [Unreleased]`. + - behavioural effect: none. One entry added as the first item under the + existing `### Added` heading. No heading was created or duplicated. + +## 5. Implementation decisions + +Decisions made within the approved design: + +1. **Durable rather than transient prose throughout.** Every corrected sentence + was re-read against the ADR-0005 section 6 test and stays truthful before + review, after review, before merge and after merge. No corrected sentence + says "awaiting review", "pending merge", "draft PR" or "merge authorization + outstanding" as current programme state. This closeout therefore does not + create the need for another closeout when it merges. +2. **No lifecycle metadata transcribed into active control state.** No active + control correction in this change exists to copy an independent review + identifier, a CTO approval identifier, a merge-authorization identifier, a + merge commit SHA, a merge timestamp, a draft/ready state or equivalent + GitHub lifecycle metadata merely to restate terminal review, authorization + or merge state — the transcription ADR-0005 section 4.1 items 6 and 10 + prohibit. Where the previous prose narrated the BE-03 review history (the + earlier BLOCKED exact-head review and the authorized bounded remediation), + that narrative was removed from the active tracker rather than updated, + because ADR-0005 section 5 makes the GitHub pull-request record the + authority for it. Pointers to PR #808 and PR #809 are retained; they are + references, not transcriptions. + + This is distinct from the exact SHAs this change legitimately records. + `BE-03-CLOSEOUT-01.md` section 18 records + `b51bcc0905ac17fc0c142b2002b11fec711331a3` as the exact CTO-authorized + implementation base, and section 1.2 above records that SHA, its identity as + the merge commit of specification PR #812, and PR #809's merge commit + `3ba4452c316399d80cd8d85e7d5e1bd05e252664` as ancestry evidence. Those are + execution evidence required by root `AGENTS.md` to prove implementation + authorization, preflight and repository ancestry — not post-merge lifecycle + transcription — and ADR-0005 does not forbid them. The distinction is + purpose, not SHA-shaped text: recording the base a change was authorized + against proves the change is in scope; copying a merge SHA to announce that + something merged is what the ADR prohibits. +3. **`BE-03.md` corrections confined to the three authorized sites.** The + `Status` line uses the house form established by `ADR-01.md` + (`APPROVED AND REPOSITORY-AUTHORITATIVE - ...`) rather than a bare + `APPROVED`, so the line records both the specification's durable decision + state and the inactive-foundation delivery boundary in one place. +4. **`rollout-plan.md` gains a `BE-03 implementation state` block** modelled on + the existing BE-02 block rather than an inline clause, so the inactive + foundation and the satisfied-but-not-ready downstream position are stated + once, coherently, in the document that owns rollout state. The block is + deliberately undated: BE-03's merge date is transient GitHub evidence. +5. **`README.md` decision block expanded per downstream task.** The block + previously carried a single BE-03 line. It now states BE-04, MIG-01, APP-01 + and APP-02 positions explicitly, because a bare "BE-03 CLOSED" would leave a + reader to infer the downstream consequence, which is exactly the inference + the specification forbids. +6. **Two `Last updated` metadata lines refreshed** (`task-status.md` line 7 and + `decisions.md` line 4). Both were accurate at the authorized base and became + inaccurate as a direct consequence of this change; refreshing them follows + the BE-02-CLOSEOUT-01 precedent. + +Deviations from the specification: NONE. There is no implementation deviation +from the CTO-approved specification as clarified. One acceptance criterion's +wording was itself corrected under explicit CTO control before final approval, +because as originally written it was overbroad; the implementation was not +changed to match it and did not need to be. That correction is a +task-specification clarification, not an implementation deviation and not an +architecture amendment. See section 5.3. + +Scope deviations on touched paths: NONE. The changed set is exactly the +specification's expected set. `platform-inventory.md`, `acceptance-matrix.md`, +`master-issue.md` and `control-gaps.md` were searched and left untouched, as +expected. + +### 5.1 Two additional BE-03 source-state hits found by the fresh search + +These are the two **stale-state findings** the fresh classified search from the +authorized base discovered that the authoring-time Annex A does not record. +They are not the only edits Annex A does not enumerate: the implementation +authorization itself explicitly requires updating the closeout task record's own +`Status` line and its section 18 approval block after specification approval and +implementation authorization. Those task-record updates are directly mandated by +the authorization and are reported in section 4; they are not stale-state +findings and are not classified as such. Neither is the later CTO clarification +of one section 9 acceptance criterion, which is an approved specification +correction recorded in section 5.3. The two items below are the additional BE-03 +source-state assertions found by the search. + +Both fall inside an already-expected touched path and inside the approved +scope; neither required a new path. + +1. `task-status.md` next-action 6: "BE-03 later exposes the protected + package/capability contract under its own approval gates" — a future-tense + BE-03 lifecycle assertion about something that has now happened. Classified + `ACTIVE STALE STATE - CORRECT` and corrected to the past tense, retaining the + "under its own approval gates" qualifier and adding "as a merged but equally + inactive foundation". +2. `task-status.md` next-action 9: "BE-03 later exposes the protected service + configuration under its own approval gates" — same class, same correction. + +Annex A did not record either, which is why the specification requires the +search to be repeated rather than applied from the annex. + +### 5.2 `decisions.md` section 3a - classification and CTO control ruling + +The authoring-time Annex A classifies `decisions.md` section 3a +`CURRENT AND CORRECT - PRESERVE` "in its entirety", while the normative +specification section 2 and its `ACTIVE STALE STATE` list identify one +present-tense sentence inside the same section as stale. The CTO resolved this +wording collision explicitly, and the normative sections control over the +informative annex. + +**Ruling applied.** The self-resolving ADR-0005 authority-condition +construction is preserved as written, including: + +- `Decision state: PROPOSED IN THIS SPECIFICATION CANDIDATE` (line 247, + unchanged); +- the two-part authority condition (lines 251-256, unchanged); +- the rule that once both parts hold it is an `APPROVED PROGRAMME DECISION` + "without requiring a separate lifecycle-status edit to this file" (lines + 258-261, unchanged); +- the explanation of why a literal mutable `APPROVED` token is not required + (lines 263-269, unchanged); +- the deliberate "This decision candidate **refines and, in that narrow + respect, supersedes**..." phrasing that belongs to that construction (line + 336, unchanged). + +`PROPOSED` was **not** mechanically replaced with `APPROVED`, and no +architecture was rewritten. + +**Corrected.** One sentence only, in the APP-01 reconciliation: + +```text +before: ... and remains blocked on BE-03 exposing the approved protected API, + app readiness controls, the exact-SHA schema pinning control and its + own approved bounded specification. + +after: ... Its dependency on BE-03 exposing the approved protected API is + satisfied for the configuration-only surface enumerated below, BE-03 + having merged that surface; APP-01 itself remains blocked on app + readiness controls, the exact-SHA schema pinning control and its own + approved bounded specification, and its job-aware elements remain + dependent on BE-04 as set out below. +``` + +Classification: `ACTIVE STALE STATE - CORRECT`. + +Applying the ruling required **no** change to the BE-03/BE-04/APP-01 +architecture. The enumerated configuration-only scope (items 1-6 immediately +below the corrected sentence), the four BE-04-dependent elements, the APP-02 +dependency on both BE-03 and BE-04, and the consequences list are all unchanged +and continue to say exactly what they said. The stop condition "if applying this +ruling would require changing the BE-03/BE-04/APP-01 architecture, STOP BLOCKED" +therefore did not fire. + +### 5.3 Section 9 acceptance criterion - CTO control clarification + +The third commit in section 3 applies an explicit CTO clarification to this +task's own approved specification. It is a control clarification only. + +**The defect.** Section 9 of +[`BE-03-CLOSEOUT-01`](../tasks/BE-03-CLOSEOUT-01.md) carried the acceptance +criterion: + +```text +- [ ] no review, approval or merge identifier, merge SHA or merge timestamp is + newly transcribed into a repository file; +``` + +Read literally, that criterion is overbroad. It forbids any newly recorded +review, approval or merge identifier, merge SHA or merge timestamp regardless of +why it is recorded, and so forbids evidence the same repository controls +require. It conflicted with: + +1. this task's own non-goal 2, which is purpose-qualified: it prohibits copying + review, approval and merge-authorization identifiers, PR #809's merge commit + SHA, the merged timestamp or the bare statement "the PR is now merged" into + repository files *merely to transcribe them*; +2. [ADR-0005](../../decisions/ADR-0005-terminal-merge-evidence.md), which + prohibits lifecycle-transcription churn by purpose rather than by textual + shape, and whose section 8 distinguishes a required post-merge correction + from a commit existing merely to record that a pull request merged; +3. the repository requirement to record the exact implementation base and the + preflight and ancestry evidence proving the change was authorized against it + — root [`AGENTS.md`](../../../../AGENTS.md) section 14 requires the exact + base commit in this report, carried in sections 1.1 and 1.2; +4. section 18 of this same specification — already authorized and merged — which + records `b51bcc0905ac17fc0c142b2002b11fec711331a3` as the exact authorized + implementation base. + +Taken literally, the criterion made the document carrying it fail its own test. + +**The ruling.** The CTO explicitly clarified the criterion. The clarified, +CTO-approved wording now in section 9 is: + +```text +- [ ] no active control correction copies a review, approval or + merge-authorization identifier, merge SHA, merge timestamp, draft/ready + state or equivalent GitHub lifecycle metadata merely to restate terminal + review, authorization or merge state; exact SHAs recorded as the + authorized implementation base or as required preflight/ancestry evidence + are permitted execution evidence under repository controls; +``` + +The wording is the CTO's verbatim, including its line breaks. Only the terminal +punctuation is rendered as `;` rather than `.`, so the item matches the +surrounding checklist, whose items are semicolon-separated. No other acceptance +criterion, and no other part of the task record, was touched. + +**What the clarification does not do.** It changes no architecture, no runtime +scope, no BE-03/BE-04/APP-01 boundary and no implementation scope. It does not +alter ADR-0005, migration policy, any other task's recorded status, any +authorization path or any migration. It authorizes no downstream task, no +deployment and no production activity. It is not an architecture amendment. + +**Effect on the implementation.** None. The implementation already drew exactly +the distinction the clarified criterion states — see section 5 item 2 and the +section 15 confirmations, both written before this clarification. The corrected +criterion now matches ADR-0005 and the implementation's already-correct evidence +distinction rather than contradicting both. No control correction in any of the +three commits was changed in order to satisfy the clarification. + +**Three distinct things, kept separate.** This report does not conflate: + +- **approved task-specification clarification** — the CTO-approved correction to + the wording of this task's own acceptance criteria, recorded in this section. + It changes what the task's acceptance test says, not what the implementation + did; +- **implementation remediation** — the additive corrections to repository files + carried by the second and third commits in section 3, made under review and + control feedback without amending, rebasing, squashing or force-pushing + earlier history; +- **GitHub terminal lifecycle evidence** — independent review decisions, CTO + merge authorization, draft/ready state, the merge itself, its SHA and its + timestamp. Under ADR-0005 these live in the GitHub pull-request record and are + deliberately absent from every repository file in this diff. + +## 6. Database and migration effects + +Migration added: NO + +No migration, schema, catalog or data change of any kind. +`thoth-api/src/schema.rs` and `thoth-api/migrations/` are untouched, as proved +by the negative path check in section 9. + +## 7. API and compatibility effects + +GraphQL/API changes: none. +Generated schema/client updates: none; `thoth-client/assets/schema.graphql` is +byte-identical to the base. +Backwards compatibility: unaffected. +Deprecations: none. +Cross-repository dependencies: none created. The reserved BE-03/APP-01 exact-SHA +schema-pinning control continues to bind against BE-03's reviewed implementation +head, not against this task's head; section 2.2 of `rollout-plan.md` now says so +explicitly. This task produces no new contract for a downstream repository to +pin. + +## 8. Authorization and security + +Authorization paths changed: none. +Roles/scopes involved: none. `thoth-api/src/policy.rs` and every authorization +test are untouched. +Negative authorization tests: not applicable; no authorization code is in this +diff. +Secret or personal-data handling: none. No credential, token, endpoint, bucket +or account identity is introduced into the diff. +Security limitations: none introduced. + +## 9. Tests and checks + +Root `AGENTS.md` section 8 prescribes the documentation-only evidence set and +reserves the full workspace gate for Rust/domain changes. No file under any +workspace member is modified, so the workspace gate has no changed input and was +not run. + +### Formatting + +Command: + +```text +git diff --check +``` + +Result: + +```text +no output; no whitespace error +``` + +### Path containment + +Command: + +```text +git diff --name-only b51bcc0905ac17fc0c142b2002b11fec711331a3..HEAD +``` + +Result: + +```text +CHANGELOG.md +docs/engineering/ai-delivery/implementation-reports/BE-03-CLOSEOUT-01-implementation-report.md +docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md +docs/engineering/ai-delivery/tasks/BE-03.md +docs/publisher-services/README.md +docs/publisher-services/decisions.md +docs/publisher-services/rollout-plan.md +docs/publisher-services/task-status.md +``` + +Every path matches `^docs/` or is exactly `CHANGELOG.md`. + +### Negative runtime-path proof + +Command: + +```text +git diff --name-only b51bcc0905ac17fc0c142b2002b11fec711331a3..HEAD \ + | grep -E '^(thoth-api|thoth-api-server|thoth-client|thoth-errors|thoth-export-server|\.github|Cargo\.)' +``` + +Result: + +```text +no output +``` + +No runtime, migration, schema, GraphQL, generated client, workflow or Cargo file +changed. + +### Unit tests + +Not applicable: documentation-only change, no workspace member modified. + +### Integration/database tests + +Not applicable: no migration, schema or database-backed code is touched. + +### Lint/static analysis + +Not applicable to the changed paths. + +### Documentation link verification + +Every relative markdown link target in the changed files is resolved against the +filesystem. Absolute (`http:`, `https:`, `mailto:`) targets and same-document +anchors are not filesystem-resolvable and are excluded from the count. + +Command, run from the repository root: + +```bash +python3 - <<'PY' +import re, subprocess, os +base = "b51bcc0905ac17fc0c142b2002b11fec711331a3" +files = subprocess.run(["git", "diff", "--name-only", base + "..HEAD"], + capture_output=True, text=True, check=True).stdout.split() +link = re.compile(r'\[[^\]]*\]\(([^)\s]+)\)') +checked = broken = 0 +for f in files: + for t in link.findall(open(f, encoding="utf-8").read()): + if re.match(r'^(https?:|mailto:|#)', t): + continue + checked += 1 + tgt = os.path.normpath(os.path.join(os.path.dirname(f), t.split('#')[0])) + if not os.path.exists(tgt): + broken += 1 + print("BROKEN", f, "->", t) +print("files:", len(files), " relative links checked:", checked, " broken:", broken) +PY +``` + +Result: + +```text +files: 8 relative links checked: 100 broken: 0 +``` + +Run after every repository-file edit in this task, including the remediation +edits recorded in section 3. + +## 10. Manual verification + +Environment: local checkout of `feature/publisher-services/be-03-closeout` at +the branch head, created from `b51bcc0905ac17fc0c142b2002b11fec711331a3`. + +Steps: the classified search was performed from the authorized base with +`git grep -n 'BE-03' -- docs/ CHANGELOG.md` (27 files), every hit was read in +context, and the search was re-run after the edits. + +### 10.1 Complete fresh classified stale-state findings + +#### `ACTIVE STALE STATE - CORRECT` + +- `docs/publisher-services/task-status.md` line 7 — `Last updated` note + describing BE-03 as delivered as a draft pull request with the new exact head + "awaiting a fresh independent review". Corrected. +- `docs/publisher-services/task-status.md` BE-03 row — status + `IMPLEMENTATION IN REVIEW`; blocking-dependency cell listing a fresh + independent review and CTO merge authorization as remaining gates; PR cell + `(draft)`; acceptance cell `IMPLEMENTATION DELIVERED, NOT MERGED`. Corrected + to `CLOSED` / `CLOSED - INACTIVE FOUNDATION`. +- `docs/publisher-services/task-status.md` BE-04 row — BE-03 listed as an + unsatisfied blocking dependency. Corrected to satisfied, with BE-04 retained + as `BLOCKED` / `NOT STARTED` and the explicit statement that no + `distribution_job`, `distribution_job_target`, `distribution_job_attempt`, + automatic back-catalogue job creation or dissemination exists. +- `docs/publisher-services/task-status.md` MIG-01 row — same, corrected to + satisfied with MIG-01 retained as `CRITICAL` / `BLOCKED` and its audit, + backfill, dry-run and CG-13 prerequisites retained. +- `docs/publisher-services/task-status.md` APP-01 row — BE-03 listed as an + unsatisfied blocking dependency, and "the candidate phase boundary". + Corrected: the backend-contract dependency is satisfied for the + configuration-only scope, APP-01 remains `BLOCKED` by its other controls, the + job-aware elements remain BE-04-dependent, and the boundary is referred to as + approved. +- `docs/publisher-services/task-status.md` APP-02 row — BE-03 listed as an + unsatisfied blocking dependency. Corrected to satisfied-only, with APP-02 + retained as blocked on BE-04 and APP-01 and an explicit statement that this + does not make it ready. +- `docs/publisher-services/task-status.md` next-action 6 — future-tense "BE-03 + later exposes the protected package/capability contract". Fresh finding, not + in Annex A; corrected. +- `docs/publisher-services/task-status.md` next-action 9 — future-tense "BE-03 + later exposes the protected service configuration". Fresh finding, not in + Annex A; corrected. +- `docs/publisher-services/task-status.md` next-action 10 — "delivered ... as a + **draft** pull request", the exact-head review narrative, "BE-03 is **not + merged**", the fresh-review requirement, "explicit CTO merge authorization + remains outstanding", and "programme-decision candidate". Corrected to durable + prose. +- `docs/publisher-services/task-status.md` next-action 11 — "APP-01 remains + blocked pending BE-03" and "the candidate phase boundary". Corrected. +- `docs/publisher-services/task-status.md` next-action 12 — "the separately + authorized, delivered-but-unmerged BE-03 implementation". Corrected, and the + unauthorized-action list extended to name package commercial backfill, durable + job creation, dissemination and workflow change/dispatch explicitly. +- `docs/publisher-services/README.md` line 3 header status — did not record + BE-03. Corrected. +- `docs/publisher-services/README.md` section 5 decision block — `BE-03 + DEPENDENCIES ON BE-01 AND BE-02 SATISFIED; BE-03 IMPLEMENTATION NOT + AUTHORIZED`. Corrected, and the per-downstream position added. +- `docs/publisher-services/README.md` gating reason 1 — "`BE-03` implementation + remains `NOT AUTHORIZED` pending its own approved bounded specification and + separate explicit authorization". Corrected. +- `docs/publisher-services/README.md` closing paragraph — an approved + specification does not "unlock `BE-03`". Corrected by removing `BE-03` from + the list only. +- `docs/publisher-services/rollout-plan.md` BE-02 implementation state block — + "`BE-03` implementation is `NOT AUTHORIZED`". Corrected, and a `BE-03 + implementation state` block added. +- `docs/publisher-services/rollout-plan.md` section 2.2 — "It binds the later + `BE-03` and `APP-01` tasks" and item 1's future-tense "`BE-03` produces an + exact generated GraphQL SDL at its reviewed head". Corrected without changing + the control's substance. +- `docs/publisher-services/decisions.md` section 3a APP-01 reconciliation — the + present-tense APP-01 dependency assertion. Corrected under the CTO control + ruling; see section 5.2. +- `docs/engineering/ai-delivery/tasks/BE-03.md` line 3 — `Status: DRAFT`. + Corrected. +- `docs/engineering/ai-delivery/tasks/BE-03.md` header + implementation-authorization block — "**separate and absent** ... must not + exist until the CTO separately and explicitly authorizes implementation". + Corrected. +- `docs/engineering/ai-delivery/tasks/BE-03.md` section 23 — "BE-03 + implementation status is `NOT AUTHORIZED`. The branch + `feature/publisher-services/be-03` must not exist...". Corrected. +- `docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md` line 3 — + `Status: DRAFT`, falsified by this specification's own CTO approval and merge + through PR #812. Corrected to `APPROVED`. +- `docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md` section 18 — empty + approval record. Completed with the durable implementation authorization. + +#### `HISTORICAL RECORD - PRESERVE` + +- `docs/engineering/ai-delivery/implementation-reports/BE-03-implementation-report.md` + in its entirety (30 BE-03 references), including its base and head commits, + exact test commands, CI record and every reference to + `thoth-api/migrations/20260813_v1.7.0` and to `20260812_v1.7.0` as BE-02's + migration. Untouched. +- `docs/engineering/ai-delivery/implementation-reports/BE-03-SPEC-implementation-report.md` + (111 references) — untouched. +- `docs/engineering/ai-delivery/implementation-reports/BE-03-CLOSEOUT-01-SPEC-implementation-report.md` + (43 references) — the specification task's own exact-head record. Untouched. +- `docs/engineering/ai-delivery/implementation-reports/BE-02-implementation-report.md`, + `BE-02-CLOSEOUT-01-implementation-report.md`, `BE-02-SPEC-implementation-report.md`, + `BE-01-implementation-report.md`, `BE-01-SPEC-implementation-report.md`, + `ADR-01-SPEC-implementation-report.md`, + `ADR-0002-APPROVE-implementation-report.md`, + `P0-01-CLOSEOUT-implementation-report.md`, + `P0-01-FINALIZE-implementation-report.md` — untouched. +- `docs/engineering/ai-delivery/tasks/BE-02-CLOSEOUT-01.md` lines 32, 74, 100 + and 252 — the completed BE-02 closeout's own scope, non-goals and merge-order + record, correct as written for that task. Untouched. +- `docs/engineering/ai-delivery/tasks/ADR-01-CLOSEOUT-01.md` line 183 — that + task's non-goal. Untouched. +- `docs/publisher-services/adr-01-evidence-matrix.md` line 256 — "future + BE-02/BE-03 implementation; not yet implemented at the inspected commits", an + ADR-01 evidence record explicitly bound to the commits it inspected. + Untouched. +- `CHANGELOG.md`'s existing `BE-03` entry from PR #809, `BE-03-SPEC` entry from + PR #808 and `BE-03-CLOSEOUT-01-SPEC` entry from PR #812 — append-only records + of what each pull request contained when written, including the + `BE-03-SPEC` entry's closing "`BE-03` implementation remains **NOT + AUTHORIZED** and `feature/publisher-services/be-03` must not exist". Preserved, + on the same basis BE-02-CLOSEOUT-01 used for the equivalent PR #805 entry. +- `docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md` sections 1, 2, 3, 9, + 10 and Annex A — this specification's own approved record of the pre-correction + state it exists to correct, including every quotation of the stale wording. + These are the approved specification's own content and its acceptance + criteria; rewriting them would rewrite the approved specification and + invalidate its own tests. Preserved. The only changes to this file are + `Status`, section 18, and the single section 9 acceptance criterion the CTO + explicitly clarified — the last being an approved specification clarification + recorded in section 5.3, not a stale-state reclassification of anything in + this list. + +#### `CURRENT AND CORRECT - PRESERVE` + +- `docs/publisher-services/decisions.md` section 3a authority-condition + construction — `Decision state:` line, the two-part condition, the + self-resolution rule, the rationale against a mutable `APPROVED` token, and + the "decision candidate" phrasing belonging to it. Preserved verbatim; see + section 5.2. +- `docs/publisher-services/decisions.md` section 3a tension, proposed + resolution, transaction-boundary note, configuration-only scope list, + BE-04-dependent list, consequences and boundary-of-decision paragraphs — the + architecture itself. Untouched. +- `docs/publisher-services/decisions.md` operational invariants 3 and 7 — + backfill creates no back-catalogue jobs; automatic job creation is initially + inactive. Untouched. +- `docs/publisher-services/README.md` section 5 item 6 — protected package and + effective-capability reads and the dedicated superuser package mutation + remain BE-03 scope. Untouched. +- `docs/publisher-services/rollout-plan.md` dependency graph and the structural + statement "`BE-03` depends on both `BE-01` and `BE-02`". Untouched. +- `docs/publisher-services/rollout-plan.md` control "`thoth-app` must not begin + `APP-01` implementation until `BE-03` exposes the approved protected API" — a + durable rule whose condition is now satisfied; its wording stays truthful. + Untouched. +- `docs/publisher-services/rollout-plan.md` Stage 1-5 deliverables, controls, + exit evidence and rollback — rules and plan, not status claims. Untouched. +- `docs/publisher-services/adr-01-evidence-matrix.md` line 192 — the unpinned + `codegen.ts` observation confirming the reserved BE-03/APP-01 contract + control's concern; still true. Untouched. +- `docs/publisher-services/platform-inventory.md` — jobs are BE-04 scope and + automatic job creation is inactive; no BE-03 reference at this base. + Untouched. +- `docs/engineering/repository-map/control-gaps.md` CG-13 activation block, + including `BE-02 runtime: NOT AUTHORIZED`; CG-13 remains `OPEN`. No BE-03 + reference at this base. Untouched. +- `docs/engineering/ai-delivery/tasks/BE-03.md` section 24 approval boundary — + a statement about what specification approval does not authorize, still true. + Untouched. +- `docs/engineering/decisions/ADR-0001-publisher-package-capability-model.md` + line 334 — an architectural affected-task reference, not a lifecycle claim. + Untouched. + +#### `OUT OF SCOPE - PRESERVE` + +- `docs/publisher-services/acceptance-matrix.md` lines 14-20 — maps requirements + to owning tasks, evidence and activation gate; carries no BE-03 lifecycle + status claim. Untouched, as the specification expected. +- `docs/publisher-services/master-issue.md` — no BE-03 statement. Untouched. +- `docs/engineering/ai-delivery/tasks/BE-01.md` (9 references), + `BE-02.md` (5), `ADR-01.md` (11) — other tasks' approved specifications. Their + BE-03 references are structural task-decomposition and scope-boundary + statements ("BE-03 later owns the protected mutation", "`BE-03` depends on + both `BE-01` and `BE-02`", "the dedicated protected read and superuser + mutation belong to BE-03") rather than BE-03 lifecycle status claims. + Amending another task's approved specification is outside this task's scope + and is forbidden by its non-goal 9. Untouched. +- `docs/engineering/ai-delivery/tasks/THOTH-GQL-BATCH-01.md` line 1636 — the + acceptance criterion asserting that `BE-02` remains unimplemented with no + `DistributionPlatform` enum. A different programme's `DRAFT`, + `NOT AUTHORIZED` specification, and a scope-containment test on that task's + own future diff. Its premise is outdated; correcting it belongs to that task + and programme. Untouched, per the explicit instruction not to repair it here. +- `docs/publisher-services/README.md` section 5 item 7 — "no + `DistributionPlatform` enum exists in code". Materially false, but a BE-02 + assertion, not a BE-03 one. See section 13. Untouched. +- issue [#765](https://github.com/thoth-pub/thoth/issues/765), issue + [#766](https://github.com/thoth-pub/thoth/issues/766) and PR + [#799](https://github.com/thoth-pub/thoth/pull/799) — explicitly untouched. + +### 10.2 Migration-path classification + +Current repository migration names after PR #811, used by any new prose in this +change: + +```text +BE-02 current: thoth-api/migrations/20260811_v1.7.0/ +BE-03 current: thoth-api/migrations/20260812_v1.7.0/ +v1.6.3 chapter hotfix: thoth-api/migrations/20260813_v1.6.3/ +``` + +Historical implementation-head names, preserved wherever they appear: + +```text +BE-02 implementation head: 20260812_v1.7.0 +BE-03 implementation head: 20260813_v1.7.0 +``` + +Classification: every old-path reference in this repository lives in the BE-02, +BE-02-CLOSEOUT-01, BE-03, BE-03-SPEC and BE-03-CLOSEOUT-01-SPEC implementation +reports. Each is `HISTORICAL RECORD - PRESERVE`: correct at the exact head it +describes. None was rewritten. The BE-03 implementation report's rollout note +"Migration sequence: `20260813_v1.7.0` applies after `20260812_v1.7.0`" is +preserved: it was true as written and the ordering it asserts still holds under +the renamed directories. + +**Active path-related control debt: none found.** No active Publisher Services +or shared engineering-control document makes a present-tense operational +assertion about the BE-03 migration path. The finding matches Annex A's. No +migration was renamed or modified, no migration ordering was changed, and PR +#811 was not reviewed, reverted or repaired. + +This closeout's own new prose does not name a migration directory at all, so the +"use `thoth-api/migrations/20260812_v1.7.0/`" rule had no occasion to apply +outside this report. + +### 10.3 Historical implementation reports untouched + +Confirmed by the path containment result in section 9: no path under +`docs/engineering/ai-delivery/implementation-reports/` appears in the diff other +than this new report. The BE-02, BE-02-CLOSEOUT-01, BE-03, BE-03-SPEC and +BE-03-CLOSEOUT-01-SPEC implementation reports and all of their migration-path +references are byte-identical to the base. + +### 10.4 Post-edit classified re-run + +Command: + +```text +git grep -n 'BE-03' -- docs/ CHANGELOG.md +git grep -n -iE 'BE-03[^.]{0,80}(not merged|unmerged|NOT AUTHORIZED|awaiting|in review|must not exist|draft)' \ + -- docs/publisher-services/ docs/engineering/ai-delivery/tasks/ docs/engineering/repository-map/ docs/engineering/decisions/ +``` + +Result: every surviving hit of the stale-language pattern is inside +`docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md`, in that +specification's own background, scope, acceptance criteria, manual-verification +commands and Annex A — that is, its approved record of the state it exists to +correct. No hit remains in `task-status.md`, `README.md`, `rollout-plan.md`, +`decisions.md`, `BE-03.md`, `control-gaps.md` or any other active control +document. + +Observed result against each required assertion: + +- no active control says BE-03 is unmerged — confirmed; +- no active control says the BE-03 implementation is awaiting authorization, + review or merge — confirmed; +- no active control says BE-03 is an unsatisfied dependency where the merge + satisfied it — confirmed; +- BE-04 remains `BLOCKED` / `NOT STARTED`, unspecified and unauthorized, with no + durable job, target, attempt, automatic onboarding or dissemination + represented as existing — confirmed + (`git grep -n 'BE-04\|distribution_job' -- docs/publisher-services/`); +- MIG-01 remains `CRITICAL` / `BLOCKED` with its audit, backfill, dry-run and + CG-13 prerequisites — confirmed; +- APP-01 remains `BLOCKED` by BR-APP-01 or an explicit CTO exception, the CG-11 + CI closure work, exact-SHA contract pinning and its own approved + specification — confirmed; +- APP-01 job-aware state remains BE-04-dependent — confirmed in `task-status.md`, + `README.md` and `decisions.md`; +- APP-02 remains blocked on BE-04 and APP-01 and is not represented as ready — + confirmed; +- production, environment, migration-execution, backfill, job-creation, + dissemination, activation, `OBSERVE`/`ENFORCE`, workflow and production-access + actions remain `NOT AUTHORIZED` — confirmed + (`git grep -n 'NOT AUTHORIZED' -- docs/publisher-services/ docs/engineering/repository-map/control-gaps.md`); +- `decisions.md` authority-condition construction intact — confirmed by + inspecting the two-hunk diff for that file; +- historical implementation reports and their migration paths untouched — + confirmed; +- PR #799 untouched and not represented as a Publisher Services dependency — + confirmed (`git grep -n '799' -- docs/`: every hit is a pre-existing non-goal + or exclusion statement, none changed by this diff). + +### 10.5 Durability re-read + +Each corrected paragraph was re-read against the ADR-0005 section 6 test. No +corrected sentence depends on this pull request's own review, authorization or +merge state, so merging this closeout does not falsify any sentence it writes +and does not create the need for a further closeout. + +### 10.6 Changelog + +One entry added as the first item under the existing `## [Unreleased]` / +`### Added` headings. Verified: exactly one `## [Unreleased]` heading and +exactly one `### Added` heading in that section; no heading created or +duplicated. + +Evidence link: the pull-request diff and check record. + +## 11. CI + +CI status: PENDING at the time of writing. GitHub is the live authority; the +result is the pull request's check record. The change is expected to classify as +documentation-only. Actual results will be reported rather than assumed. + +## 12. Rollout and rollback + +Initial state after merge: repository documentation only; no runtime, +deployment, migration, backfill, activation or production effect. +Activation required: none; this task activates nothing. +Feature flag/configuration: none. +Migration sequence: not applicable; no migration is added, renamed or modified. +Rollback/disable procedure: ordinary revert of the documentation pull request +under normal review. +Monitoring required: none. + +## 13. Known limitations and deferred work + +- **Residual BE-02 control debt, deliberately not fixed here.** + `docs/publisher-services/README.md` section 5 item 7 states "It is a decision + record, not an implemented enum; no `DistributionPlatform` enum exists in + code." This is materially false — BE-02 merged the 17-value enum through PR + #805 — but it is a BE-02 assertion, not a BE-03 one. BE-02-CLOSEOUT-01's + acceptance criterion targeted exactly this class of statement and corrected + the `platform-inventory.md` and `control-gaps.md` instances; this README + instance survived. Recorded as deferred control debt for its own bounded task. + Recommended owner: CTO, as a bounded BE-02 residual-debt correction. +- **Different-programme stale premise, deliberately not fixed here.** + `docs/engineering/ai-delivery/tasks/THOTH-GQL-BATCH-01.md` line 1636 carries an + acceptance criterion premised on BE-02 being unimplemented. It belongs to a + different programme's `DRAFT`, `NOT AUTHORIZED` specification. Recommended + owner: that task and programme. +- **Adjacent observation, not actioned.** PR #811 placed the v1.6.3 hotfix + migration at `thoth-api/migrations/20260813_v1.6.3/`, which sorts after the + v1.7.0 publisher-services migrations at `20260811_v1.7.0` and + `20260812_v1.7.0`. That is PR #811's business, is out of scope here, and does + not affect the BE-02-then-BE-03 apply order. Recorded for the CTO only. +- **Identical overbroad acceptance wording elsewhere, deliberately not edited.** + `docs/engineering/ai-delivery/tasks/BE-02-CLOSEOUT-01.md` carries the same + acceptance criterion that section 5.3 records the CTO as having clarified for + this task. BE-02-CLOSEOUT-01 is a completed task record outside this task's + authorized file set, and the clarification authorization is bounded to the two + files listed against the third commit in section 3. It was therefore not + edited. Recorded so the observation is not lost. Recommended owner: CTO, if + the same clarification is to be applied there. +- **`BE-02.md` header.** The BE-02 specification header still reads + "Implementation authorization: separate and absent" although BE-02 has merged. + It is a BE-02 record, outside this task's scope, and is noted only so the + observation is not lost. + +## 14. Unresolved issues + +NONE. + +No repository authority conflict was found about what BE-03's merge satisfies. +The one wording collision inside the approved specification — Annex A's +"section 3a in its entirety" versus the normative sections' identification of +the APP-01 dependency sentence as stale — was resolved by explicit CTO control +ruling and is recorded in full in section 5.2. + +## 15. Agent self-assessment + +This agent implemented the change and does not approve it. The pull request +remains draft pending fresh independent exact-head review and separate CTO merge +authorization. + +Confirmations: + +- no runtime, schema, migration, GraphQL, generated-contract, client-artifact, + Cargo, workflow, deployment or environment change occurred (section 9 negative + path proof); +- issues #765 and #766 and PR #799 were untouched; no GitHub issue or pull + request other than this task's own draft PR was created or modified; +- BE-04, MIG-01, APP-01 and APP-02 were not started, specified or authorized, + and each retains its recorded blockers; +- no production or environment action occurred: no deployment, no migration + execution, no backfill, no assignment or job creation, no dissemination, no + activation, no `OBSERVE`/`ENFORCE` transition, no workflow dispatch and no + production access or credential use; +- no active control correction in this change copies a review, approval or + merge-authorization identifier, a merge commit SHA, a merge timestamp or a + draft/ready state merely to restate terminal review, authorization or merge + state. The exact SHAs recorded here and in `BE-03-CLOSEOUT-01.md` section 18 + — the authorized implementation base and the preflight/ancestry evidence in + section 1.2 — are execution evidence required by repository controls, not + post-merge lifecycle transcription (section 5 item 2). + +Suggested review focus: + +1. **The `decisions.md` section 3a ruling application** (section 5.2). Confirm + the self-resolving authority-condition construction is intact and that the + single corrected sentence changes dependency state only, not architecture. +2. **Durability of every corrected sentence.** Confirm no sentence written here + becomes false when this pull request merges. +3. **The two fresh findings in section 5.1** that Annex A did not record, and + whether the classified search missed any comparable future-tense assertion. +4. **Downstream containment.** Confirm that satisfying the BE-03 dependency did + not make BE-04, MIG-01, APP-01 or APP-02 read as ready anywhere. +5. **`BE-03.md` blast radius.** Confirm only the three authorized + lifecycle-boundary sites changed and that no requirement, invariant, + acceptance criterion, test obligation or BE-04 transaction seam moved. +6. **The section 9 acceptance clarification** (section 5.3). Confirm that the + CTO-approved wording replaced exactly one checklist item, that the + surrounding acceptance criteria, section 18's authorized-base evidence, + Annex A, the authority condition, scope, non-goals and architecture are + unchanged, and that no repository file in this diff now carries a lifecycle + identifier, merge SHA, merge timestamp or draft/ready state recorded merely + to restate terminal review, authorization or merge state. diff --git a/docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md b/docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md index 2f23caf0..fbb97c03 100644 --- a/docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md +++ b/docs/engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md @@ -1,6 +1,6 @@ # BE-03-CLOSEOUT-01 - Post-merge control correction for BE-03 -Status: DRAFT +Status: APPROVED Programme: Publisher Services and Distribution Configuration Repository: `thoth-pub/thoth` Workflow: STANDARD @@ -383,8 +383,12 @@ touches no environment or production configuration. dependency; - [ ] `docs/publisher-services/decisions.md` section 3a retains its authority-condition construction unchanged; -- [ ] no review, approval or merge identifier, merge SHA or merge timestamp is - newly transcribed into a repository file; +- [ ] no active control correction copies a review, approval or + merge-authorization identifier, merge SHA, merge timestamp, draft/ready + state or equivalent GitHub lifecycle metadata merely to restate terminal + review, authorization or merge state; exact SHAs recorded as the + authorized implementation base or as required preflight/ancestry evidence + are permitted execution evidence under repository controls; - [ ] no migration-path reference in any implementation report is rewritten, and any new prose naming the current BE-03 migration uses `thoth-api/migrations/20260812_v1.7.0/`; @@ -588,9 +592,16 @@ correction of materially stale active BE-03 programme state. ## 18. Approval -Approved for implementation by: -Date: -Notes: +Approved for implementation by: Javi, CTO +Date: 2026-08-14 +Notes: implementation was explicitly authorized against exact `develop` base +`b51bcc0905ac17fc0c142b2002b11fec711331a3`, the merge commit of this +specification's own pull request +[#812](https://github.com/thoth-pub/thoth/pull/812). Authorization is limited to +the documentation and control correction specified here — correcting materially +stale active BE-03 programme state. It authorizes no runtime, schema, migration, +GraphQL, generated contract, workflow, deployment, environment or production +action, and it starts, specifies or authorizes no other task. Record only the durable implementation authorization here. Independent review decisions, CTO merge authorization and the merge itself are terminal GitHub diff --git a/docs/engineering/ai-delivery/tasks/BE-03.md b/docs/engineering/ai-delivery/tasks/BE-03.md index 25f9f491..8eb6cae4 100644 --- a/docs/engineering/ai-delivery/tasks/BE-03.md +++ b/docs/engineering/ai-delivery/tasks/BE-03.md @@ -1,6 +1,7 @@ # BE-03 - Protected service configuration -Status: DRAFT +Status: APPROVED AND REPOSITORY-AUTHORITATIVE - BE-03 IMPLEMENTATION DELIVERED +AS AN INACTIVE FOUNDATION Programme: Publisher Services and Distribution Configuration Repository: `thoth-pub/thoth` Workflow: STANDARD @@ -27,11 +28,11 @@ content is reachable from the repository's authoritative integration branch (`develop`). Live review, authorization and merge evidence is the GitHub pull-request record and is not copied here. -Implementation authorization: **separate and absent.** This document specifies -BE-03; it does not authorize it. The branch `feature/publisher-services/be-03` -must not exist until the CTO separately and explicitly authorizes -implementation against a freshly verified exact `develop` head. Section 23 -defines the lifecycle boundary and section 24 the approval boundary. +Implementation authorization: **separate.** This document specifies BE-03; it +does not authorize it. Implementation required, and received, explicit CTO +authorization against a freshly verified exact `develop` head, separately from +this specification's own approval. Section 23 defines the lifecycle boundary and +section 24 the approval boundary. Specification authoring base: `bcb6ce3081abb14467798b372fcc3e6af9da1c6a` (the merge commit of BE-02 implementation PR @@ -2707,15 +2708,22 @@ Review reasoning level: Extra High / xhigh ## 23. Lifecycle boundary This document is a specification. Its presence on `develop` makes BE-03's -requirements repository-authoritative; it does not create the implementation -branch, authorize an implementation edit, or activate anything. - -BE-03 implementation status is `NOT AUTHORIZED`. The branch -`feature/publisher-services/be-03` must not exist until separate explicit CTO -authorization from a freshly verified base. - -Live review, authorization and merge evidence for the pull request carrying this -content is the GitHub pull-request record and is not copied here (ADR-0005). +requirements repository-authoritative; it did not by itself create the +implementation branch, authorize an implementation edit, or activate anything. +Implementation was separately and explicitly authorized by the CTO from a +freshly verified base, as this boundary requires. + +The BE-03 repository implementation has been delivered as an **inactive +foundation**. Its merge authorized repository integration only. It did not +authorize deployment, environment migration execution, production migration +execution, package commercial backfill, distribution assignment creation or +backfill, durable job creation, dissemination, distribution activation, any +`OBSERVE`/`ENFORCE` transition, workflow change or dispatch, or production +access; each remains separately gated and unauthorized. + +Live review, authorization and merge evidence for the pull requests carrying +this specification and its implementation is the GitHub pull-request record and +is not copied here (ADR-0005). ## 24. Approval boundary diff --git a/docs/publisher-services/README.md b/docs/publisher-services/README.md index fce67b8e..d0c5f757 100644 --- a/docs/publisher-services/README.md +++ b/docs/publisher-services/README.md @@ -1,6 +1,6 @@ # Publisher Services and Distribution Configuration -Status: CONTROL FOUNDATION CLOSED; BE-01 CLOSED; ADR-01-SPEC-AMEND-01 MERGED (PR #781, MERGE COMMIT a511e01c); CORRECTED ADR-01 SPECIFICATION REPOSITORY-AUTHORITATIVE; ADR-01 MERGED - COMPLETE (PR #783, MERGE COMMIT 299b0eff); ADR-0004 AND FINAL PLATFORM INVENTORY APPROVED AND REPOSITORY-AUTHORITATIVE; CG-07 RESOLVED; BE-02 CLOSED - INACTIVE FOUNDATION MERGED THROUGH PR #805; DEPLOYMENT, MIGRATION EXECUTION, BACKFILL AND DISTRIBUTION ACTIVATION NOT AUTHORIZED; ALL OTHER IMPLEMENTATION GATED +Status: CONTROL FOUNDATION CLOSED; BE-01 CLOSED; ADR-01-SPEC-AMEND-01 MERGED (PR #781, MERGE COMMIT a511e01c); CORRECTED ADR-01 SPECIFICATION REPOSITORY-AUTHORITATIVE; ADR-01 MERGED - COMPLETE (PR #783, MERGE COMMIT 299b0eff); ADR-0004 AND FINAL PLATFORM INVENTORY APPROVED AND REPOSITORY-AUTHORITATIVE; CG-07 RESOLVED; BE-02 CLOSED - INACTIVE FOUNDATION MERGED THROUGH PR #805; BE-03 CLOSED - INACTIVE FOUNDATION MERGED THROUGH PR #809; DEPLOYMENT, MIGRATION EXECUTION, BACKFILL, DURABLE JOB CREATION, DISSEMINATION AND DISTRIBUTION ACTIVATION NOT AUTHORIZED; ALL OTHER IMPLEMENTATION GATED Programme owner: CTO Primary coordinating repository: `thoth-pub/thoth` Related repositories: @@ -91,10 +91,17 @@ ADR-0004 APPROVED AND REPOSITORY-AUTHORITATIVE FINAL DISTRIBUTION-PLATFORM INVENTORY APPROVED AND REPOSITORY-AUTHORITATIVE CG-07 RESOLVED BE-02 CLOSED (INACTIVE FOUNDATION MERGED THROUGH PR #805) -BE-03 DEPENDENCIES ON BE-01 AND BE-02 SATISFIED; BE-03 IMPLEMENTATION NOT -AUTHORIZED -DEPLOYMENT, ENVIRONMENT AND PRODUCTION MIGRATION EXECUTION, ASSIGNMENT -CREATION/BACKFILL AND DISTRIBUTION ACTIVATION NOT AUTHORIZED +BE-03 CLOSED (INACTIVE FOUNDATION MERGED THROUGH PR #809) +BE-04 BE-03 DEPENDENCY SATISFIED; BE-04 STILL BLOCKED AND NOT STARTED +MIG-01 BE-03 DEPENDENCY SATISFIED; MIG-01 STILL CRITICAL AND BLOCKED +APP-01 BE-03 BACKEND CONTRACT SATISFIED FOR ITS CONFIGURATION-ONLY SCOPE; +APP-01 STILL BLOCKED BY ITS OTHER CONTROLS; ITS JOB-AWARE ELEMENTS STILL +REQUIRE BE-04 +APP-02 BE-03 DEPENDENCY SATISFIED ONLY; APP-02 STILL BLOCKED ON BE-04 AND +APP-01 +DEPLOYMENT, ENVIRONMENT AND PRODUCTION MIGRATION EXECUTION, PACKAGE +COMMERCIAL BACKFILL, ASSIGNMENT CREATION/BACKFILL, DURABLE JOB CREATION, +DISSEMINATION AND DISTRIBUTION ACTIVATION NOT AUTHORIZED CG-11 UNCHANGED; CG-13 OPEN / UNCHANGED ALL OTHER IMPLEMENTATION REMAINS GATED ``` @@ -231,9 +238,15 @@ Reasons all other implementation remains gated: not authorize deployment, environment or production migration execution, assignment creation or backfill, distribution activation, `OBSERVE`/`ENFORCE` or production access, each of which remains separately - gated. `BE-03`'s `BE-01` and `BE-02` dependencies are therefore satisfied, - and `BE-03` implementation remains `NOT AUTHORIZED` pending its own - approved bounded specification and separate explicit authorization. + gated. `BE-03` is `CLOSED` on the same terms: its bounded implementation + merged through [PR #809](https://github.com/thoth-pub/thoth/pull/809) as an + inactive additive foundation under its own approved bounded specification + and separate explicit implementation authorization. That merge satisfies the + `BE-03` dependency of `BE-04`, `MIG-01`, `APP-01` and `APP-02` without + making any of them ready, and authorizes no deployment, environment or + production migration execution, package commercial backfill, assignment + creation or backfill, durable job creation, dissemination or distribution + activation. 2. Every task still requires its own approved bounded specification, its applicable dependencies, and separate explicit authorization before any implementation branch or edit. @@ -248,8 +261,7 @@ Reasons all other implementation remains gated: Discovery, review, documentation, and read-only orientation may continue. An approved specification makes a task's requirements repository-authoritative; it does not create the implementation branch, authorize an implementation edit, or -unlock `BE-03`, `BE-04`, `APP-01`, OAI-PMH, release, deployment or production -work. +unlock `BE-04`, `APP-01`, OAI-PMH, release, deployment or production work. ## 6. Files diff --git a/docs/publisher-services/decisions.md b/docs/publisher-services/decisions.md index 57f901b9..b4bdbf37 100644 --- a/docs/publisher-services/decisions.md +++ b/docs/publisher-services/decisions.md @@ -1,7 +1,7 @@ # Publisher Services Decision Summary Status: ACTIVE SUMMARY -Last updated: 2026-08-12 (BE-02 closed as an inactive merged foundation; BE-03/BE-04/APP-01 phase boundary raised as a specification candidate under a durable authority condition, including the APP-01 reconciliation) +Last updated: 2026-08-14 (BE-02 and BE-03 closed as inactive merged foundations; the BE-03/BE-04/APP-01 phase boundary's authority condition is satisfied and the decision is approved under its own self-resolving construction, including the APP-01 reconciliation) Owner: CTO This file summarizes decisions. The approved technical design and approved ADRs remain authoritative. @@ -336,9 +336,12 @@ measured and evidenced under This decision candidate **refines and, in that narrow respect, supersedes** the earlier APP-01 wording that assigned superuser back-catalogue-status inspection to a BE-03-only dependency. Nothing else in the approved APP-01 record is -changed: APP-01 remains a `thoth-app` task, remains MEDIUM risk, and remains -blocked on BE-03 exposing the approved protected API, app readiness controls, the -exact-SHA schema pinning control and its own approved bounded specification. +changed: APP-01 remains a `thoth-app` task and remains MEDIUM risk. Its +dependency on BE-03 exposing the approved protected API is **satisfied** for the +configuration-only surface enumerated below, BE-03 having merged that surface; +APP-01 itself remains **blocked** on app readiness controls, the exact-SHA +schema pinning control and its own approved bounded specification, and its +job-aware elements remain dependent on BE-04 as set out below. Scope available from **BE-03 alone** — the BE-03-dependent part of APP-01: diff --git a/docs/publisher-services/rollout-plan.md b/docs/publisher-services/rollout-plan.md index 6cf07328..5066094b 100644 --- a/docs/publisher-services/rollout-plan.md +++ b/docs/publisher-services/rollout-plan.md @@ -119,7 +119,28 @@ BE-02 implementation state (2026-08-12): integration only; deployment, environment and production migration execution, assignment creation or backfill, distribution activation and `OBSERVE`/`ENFORCE` remain separately gated and unauthorized. `BE-03`'s - `BE-02` dependency is satisfied; `BE-03` implementation is `NOT AUTHORIZED`. + `BE-02` dependency is satisfied. + +BE-03 implementation state: + +- `BE-03` is `CLOSED`. The bounded implementation was delivered under its own + approved specification (PR [#808](https://github.com/thoth-pub/thoth/pull/808)) + and separate explicit implementation authorization, and merged into `develop` + through implementation PR + [#809](https://github.com/thoth-pub/thoth/pull/809) as an inactive additive + foundation: the canonical optimistic-concurrency configuration token, the + closed two-value configuration-source type, the append-only configuration + audit table, the single canonical service-configuration write coordinator, + the protected owner-and-superuser read, the superuser-only staff report and + replace mutation, and effective package capability exposure derived from + BE-01's code-owned capability mapping. The migration creates zero audit rows + and changes no package and no assignment. Merge authorized repository + integration only; deployment, environment and production migration execution, + package commercial backfill, assignment creation or backfill, durable job + creation, dissemination, distribution activation and `OBSERVE`/`ENFORCE` + remain separately gated and unauthorized. The `BE-03` dependency of `BE-04`, + `MIG-01`, `APP-01` and `APP-02` is satisfied; none of those tasks becomes + ready, and each retains its remaining blockers. Outstanding evidence: @@ -191,10 +212,13 @@ Controls: ### 2.2 Reserved BE-03/APP-01 GraphQL contract control -Reserved and documented, not implemented. It binds the later `BE-03` and -`APP-01` tasks. +Reserved and documented, not implemented. `BE-03` has merged, so this control +now binds the later `APP-01` task. -1. `BE-03` produces an exact generated GraphQL SDL at its reviewed head. +1. `BE-03` produced an exact generated GraphQL SDL at its reviewed + implementation head, merged through PR + [#809](https://github.com/thoth-pub/thoth/pull/809). This control binds + against that head, not against any later documentation change. 2. `APP-01` records the exact `BE-03` commit SHA. 3. `APP-01` code generation consumes a schema artifact pinned to that SHA, or a preview API proven to expose that exact schema. diff --git a/docs/publisher-services/task-status.md b/docs/publisher-services/task-status.md index 4f0aac90..6b2d7efa 100644 --- a/docs/publisher-services/task-status.md +++ b/docs/publisher-services/task-status.md @@ -4,7 +4,7 @@ Status: ACTIVE TRACKER Programme owner: CTO Master issue: [#765](https://github.com/thoth-pub/thoth/issues/765) Approved design: [private Google Doc](https://docs.google.com/document/d/1kr2Ft0Y4pxgcXGyFAKs_wfFx4I0jlxEvaceswE5Dus8/edit), Drive revision `3` -Last updated: 2026-08-13 (BE-03 specification repository-authoritative on `develop`; BE-03 implementation delivered as a draft pull request, independently reviewed at its previous exact head with a BLOCKED decision, CTO-authorized bounded remediation delivered, and the new exact head awaiting a fresh independent review) +Last updated: 2026-08-14 (BE-03 closed as an inactive merged foundation; the BE-03 dependency recorded as satisfied for BE-04, MIG-01, APP-01 and APP-02 without any of them becoming ready) ## 1. Control rule @@ -25,11 +25,11 @@ No task moves to `READY` without an approved specification, architecture depende | LIC-02 Enforce supported licences | `thoth` | HIGH | BLOCKED | `develop` / `develop` | LIC-01 release; production licence audit plan | #765 | TBD | NOT STARTED | | [BE-01 Publisher package model](../engineering/ai-delivery/tasks/BE-01.md) | `thoth` | HIGH | CLOSED | `develop` at `37b802776ae6853affe19d90156f3c1e0654ebe3` (PR #778 merge commit, verified before any edit) / `develop` | None remaining for BE-01 itself: the separately authorized bounded implementation was delivered on `feature/publisher-services/be-01` under ADR-0003 Architecture A and merged into `develop` through implementation PR [#779](https://github.com/thoth-pub/thoth/pull/779) after fresh independent exact-head review and explicit CTO merge authorization, as required for every HIGH-risk merge. Production migration/release execution remains separately gated by open CG-13, and the MIG-01 commercial backfill remains a separately approved CRITICAL task. | [#765](https://github.com/thoth-pub/thoth/issues/765) | Specification [#774](https://github.com/thoth-pub/thoth/pull/774); implementation [#779](https://github.com/thoth-pub/thoth/pull/779) | CLOSED - INACTIVE FOUNDATION - all publishers `OASIS`; no consumer, package API, mutation, UI, distribution, OAI or Metrics behaviour activated; retained-foundation operational rollback applies; evidence in the [BE-01 implementation report](../engineering/ai-delivery/implementation-reports/BE-01-implementation-report.md) and the immutable exact-head comments on PR #779 | | [BE-02 Distribution platform model](../engineering/ai-delivery/tasks/BE-02.md) | `thoth` | HIGH | CLOSED | `develop` at `1c752a522f7048963efde00b50565379d7c14b4d` (PR #788 merge commit, verified before any edit) / `develop` | None remaining for BE-02 itself: ADR-01/the final inventory is satisfied through PR #783, ADR-0007 through PR #800, and the request-local non-cached DataLoader foundation through PR #802 (`8dcf031d`). The reconciled BE-02 specification was independently reviewed, CTO-approved and merged through PR #788, making it repository-authoritative at `1c752a52`; the CTO then separately authorized implementation against that exact `develop` SHA, and the bounded implementation was delivered on `feature/publisher-services/be-02` and merged into `develop` through implementation PR [#805](https://github.com/thoth-pub/thoth/pull/805) after fresh independent exact-head review and explicit CTO merge authorization, as required for every HIGH-risk merge. Deployment, environment migration execution, production migration, assignment creation/backfill and distribution activation remain separately gated and unauthorized. | #765 | Specification [#788](https://github.com/thoth-pub/thoth/pull/788); implementation [#805](https://github.com/thoth-pub/thoth/pull/805) | CLOSED - INACTIVE FOUNDATION - the 17-value `DistributionPlatform` enum, the `publisher_distribution_platform` migration and repository-authoritative `schema.rs`, the assignment lifecycle, linked OAPEN/DOAB normalization, four additive public GraphQL read surfaces and the first production ADR-0007 DataLoader adoption are merged, with evidence in the [BE-02 implementation report](../engineering/ai-delivery/implementation-reports/BE-02-implementation-report.md) and the immutable exact-head comments on PR #805. The migration creates zero assignment rows, no distribution behaviour is activated, and merge is not deployment, migration execution, backfill or activation authorization | -| [BE-03 Protected service configuration](../engineering/ai-delivery/tasks/BE-03.md) | `thoth` | HIGH | IMPLEMENTATION IN REVIEW | `develop` at `3b6b3a31f9358011f0c998015dfd0c2508380e83` (specification PR #808 merge commit, verified before any edit) / `develop` | BE-01 (CLOSED, satisfied); BE-02 (CLOSED, satisfied). The specification at [`tasks/BE-03.md`](../engineering/ai-delivery/tasks/BE-03.md) is repository-authoritative: its exact CTO-approved content merged into `develop` through PR [#808](https://github.com/thoth-pub/thoth/pull/808) as `3b6b3a31`, which also satisfies the authority condition of the [BE-03/BE-04/APP-01 phase-boundary programme decision](decisions.md) with no separate lifecycle-status edit required. The CTO then separately authorized implementation against that exact `develop` SHA, and the bounded implementation was delivered on `feature/publisher-services/be-03`. An independent HIGH-risk implementation review of the previous exact head `1315057983d389d1ef6b85bc4e69b81eda53aa79` returned BLOCKED on five findings; the CTO resolved the single blocking authority conflict (the actor check-constraint contradiction) and authorized bounded corrections, now delivered on the same branch. Remaining for BE-03 itself: a fresh independent implementation review of the **new** exact head, and explicit CTO merge authorization, as required for every HIGH-risk merge. Deployment, environment migration execution, production migration, assignment creation/backfill and distribution activation remain separately gated and unauthorized. | #765 | Specification [#808](https://github.com/thoth-pub/thoth/pull/808); implementation [#809](https://github.com/thoth-pub/thoth/pull/809) (draft) | IMPLEMENTATION DELIVERED, NOT MERGED - the additive migration (configuration token, closed audit-source type, append-only audit table), repository-authoritative `schema.rs`, the single service-configuration write coordinator, the protected owner-and-superuser read, the superuser-only staff report and replace mutation, derived effective capabilities and the connection-scoped `BE-02` lifecycle refactor are implemented with evidence in the [BE-03 implementation report](../engineering/ai-delivery/implementation-reports/BE-03-implementation-report.md). The migration creates zero audit rows and changes no package or assignment; no distribution job, dissemination or activation exists; and no environment or production migration has been executed | -| BE-04 Durable distribution jobs | `thoth` | HIGH | BLOCKED | `develop` / `develop` | BE-02 (CLOSED, satisfied); BE-03 | #765 | TBD | NOT STARTED | -| MIG-01 Audit/production backfill | `thoth` + operations | CRITICAL | BLOCKED | dedicated task branch -> `develop`; separately approved production run | BE-01 and BE-02 (CLOSED, satisfied); BE-03; licence audit; dry run | #765 | TBD | NOT STARTED | -| APP-01 Service configuration UI | `thoth-app` | MEDIUM | BLOCKED | current `dev` / `dev` pending BR-APP-01 or exception | BE-03 exposing the approved protected API; app readiness controls (BR-APP-01 or explicit CTO exception; the separately specified CG-11 CI closure task); generated API contract pinned to the exact BE-03 commit SHA per the reserved contract control; own approved bounded specification. Scope boundary: under the candidate [BE-03/BE-04/APP-01 phase boundary](decisions.md), BE-03 alone supports only APP-01's configuration scope — own-publisher reads of package, effective capability codes and enabled platforms; superuser read/edit; capability-driven UI affordances; backend-driven linked-platform behaviour; optimistic-concurrency handling; and server-normalized state. APP-01 elements rendering durable back-catalogue job status, attempt state, failure state or pending-onboarding state additionally depend on BE-04 and must not be planned against BE-03 alone | #765 | TBD | NOT STARTED | -| APP-02 Staff subscription report | `thoth-app` | MEDIUM | BLOCKED | current `dev` / `dev` pending BR-APP-01 or exception | BE-03; BE-04; APP-01 | #765 | TBD | NOT STARTED | +| [BE-03 Protected service configuration](../engineering/ai-delivery/tasks/BE-03.md) | `thoth` | HIGH | CLOSED | `develop` at `3b6b3a31f9358011f0c998015dfd0c2508380e83` (specification PR #808 merge commit, verified before any edit) / `develop` | None remaining for BE-03 itself: BE-01 (CLOSED, satisfied) and BE-02 (CLOSED, satisfied). The specification at [`tasks/BE-03.md`](../engineering/ai-delivery/tasks/BE-03.md) is repository-authoritative: its exact CTO-approved content merged into `develop` through PR [#808](https://github.com/thoth-pub/thoth/pull/808) as `3b6b3a31`, which also satisfies the authority condition of the [BE-03/BE-04/APP-01 phase-boundary programme decision](decisions.md) with no separate lifecycle-status edit required. The CTO then separately authorized implementation against that exact `develop` SHA, and the bounded implementation was delivered on `feature/publisher-services/be-03` and merged into `develop` through implementation PR [#809](https://github.com/thoth-pub/thoth/pull/809) after fresh independent exact-head review and explicit CTO merge authorization, as required for every HIGH-risk merge. Post-merge control reconciliation is delivered by [BE-03-CLOSEOUT-01](../engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md). Deployment, environment migration execution, production migration, package commercial backfill, assignment creation/backfill, durable job creation, dissemination and distribution activation remain separately gated and unauthorized. | #765 | Specification [#808](https://github.com/thoth-pub/thoth/pull/808); implementation [#809](https://github.com/thoth-pub/thoth/pull/809) | CLOSED - INACTIVE FOUNDATION - the additive migration (configuration token, closed audit-source type, append-only audit table), repository-authoritative `schema.rs`, the single service-configuration write coordinator, the protected owner-and-superuser read, the superuser-only staff report and replace mutation, derived effective capabilities and the connection-scoped `BE-02` lifecycle refactor are merged, with evidence in the [BE-03 implementation report](../engineering/ai-delivery/implementation-reports/BE-03-implementation-report.md) and the immutable exact-head comments on PR #809. The migration creates zero audit rows and changes no package or assignment; no distribution job, dissemination or activation exists; and merge authorized repository integration only, not deployment, environment or production migration execution, backfill or activation | +| BE-04 Durable distribution jobs | `thoth` | HIGH | BLOCKED | `develop` / `develop` | BE-02 (CLOSED, satisfied); BE-03 (CLOSED, satisfied). BE-04 itself remains unspecified and unauthorized: it requires its own approved bounded specification and separate explicit implementation authorization. BE-03's merge created no `distribution_job`, `distribution_job_target` or `distribution_job_attempt` relation, no automatic back-catalogue job creation and no dissemination; the BE-03 write coordinator is the seam BE-04 will later extend, not a partial BE-04 implementation | #765 | TBD | NOT STARTED | +| MIG-01 Audit/production backfill | `thoth` + operations | CRITICAL | BLOCKED | dedicated task branch -> `develop`; separately approved production run | BE-01, BE-02 and BE-03 (CLOSED, satisfied); licence audit; dry run; the production audit and backfill controls recorded in [`rollout-plan.md`](rollout-plan.md) and open [CG-13](../engineering/repository-map/control-gaps.md). No package commercial backfill and no production migration execution is authorized | #765 | TBD | NOT STARTED | +| APP-01 Service configuration UI | `thoth-app` | MEDIUM | BLOCKED | current `dev` / `dev` pending BR-APP-01 or exception | BE-03 backend contract (CLOSED, satisfied for APP-01's configuration-only scope: the approved protected API is merged and available). APP-01 itself remains BLOCKED by its other controls: app readiness (BR-APP-01 or explicit CTO exception; the separately specified CG-11 CI closure task); a generated API contract pinned to the exact BE-03 commit SHA per the reserved contract control; and its own approved bounded specification. Scope boundary: under the approved [BE-03/BE-04/APP-01 phase boundary](decisions.md), BE-03 alone supports only APP-01's configuration scope — own-publisher reads of package, effective capability codes and enabled platforms; superuser read/edit; capability-driven UI affordances; backend-driven linked-platform behaviour; optimistic-concurrency handling; and server-normalized state. APP-01 elements rendering durable back-catalogue job status, attempt state, failure state or pending-onboarding state additionally depend on BE-04 and must not be planned against BE-03 alone | #765 | TBD | NOT STARTED | +| APP-02 Staff subscription report | `thoth-app` | MEDIUM | BLOCKED | current `dev` / `dev` pending BR-APP-01 or exception | BE-03 (CLOSED, satisfied); BE-04; APP-01. Its satisfied BE-03 dependency does not make APP-02 ready: it remains blocked on BE-04 and APP-01 | #765 | TBD | NOT STARTED | | APP-03 API-backed licence options | `thoth-app` | MEDIUM | BLOCKED | current `dev` / `dev` pending BR-APP-01 or exception | LIC-02 | #765 | TBD | NOT STARTED | | DIS-01 API discovery/comparison | `thoth-dissemination` | HIGH | BLOCKED | `develop` / `develop` | BE-02 (CLOSED, satisfied); MIG-01; BR-DIS-01 or exception | #765 | TBD | NOT STARTED | | DIS-02 Back-catalogue worker | `thoth-dissemination` | CRITICAL | BLOCKED | `develop` / `develop` | BE-04; DIS-01 clean comparison; production controls | #765 | TBD | NOT STARTED | @@ -114,9 +114,10 @@ Each branch starts from the repository's verified development branch and targets delivery-workflow state lives only in that PR's metadata and comments. 6. The merged BE-01 foundation is inactive and closed: every publisher stores `OASIS`, and no consumer, package API, mutation, UI, distribution, OAI or - Metrics behaviour is activated. BE-03 later exposes the protected - package/capability contract under its own approval gates, and the MIG-01 - commercial backfill remains a separately approved CRITICAL task. + Metrics behaviour is activated. BE-03 has since exposed the protected + package/capability contract under its own approval gates, as a merged but + equally inactive foundation, and the MIG-01 commercial backfill remains a + separately approved CRITICAL task. 7. Production migration execution and release for BE-01 remain separately gated by open CG-13; nothing in BE-01 authorizes production action. 8. BE-02 is `CLOSED`. Its dependencies were all satisfied — ADR-01/the final @@ -142,7 +143,7 @@ Each branch starts from the repository's verified development branch and targets 9. The merged BE-02 foundation is inactive and closed: the migration creates zero assignment rows, no publisher has an enabled distribution-platform assignment created by it, and no distribution consumer, job, dissemination - or activation exists. BE-03 later exposes the protected service + or activation exists. BE-03 has since exposed the protected service configuration under its own approval gates. Merge authorized repository integration only; deployment, environment migration execution, production migration, assignment creation or backfill and distribution activation @@ -157,25 +158,22 @@ Each branch starts from the repository's verified development branch and targets approved programme decision with no further status edit required. The CTO separately authorized implementation against that exact freshly verified `develop` head, and the bounded implementation was delivered on - `feature/publisher-services/be-03` as a **draft** pull request following + `feature/publisher-services/be-03` and merged into `develop` through + implementation PR + [#809](https://github.com/thoth-pub/thoth/pull/809) following ADR-0003 Architecture A (direct `thoth-api/src/schema.rs` edit in the same bounded PR as the migration, models, GraphQL contract and tests). Evidence is recorded in the [BE-03 implementation report](../engineering/ai-delivery/implementation-reports/BE-03-implementation-report.md); live review, authorization and merge evidence lives only in that pull - request's record under ADR-0005 and is not restated here. An independent - HIGH-risk implementation review of the previous exact head returned - **BLOCKED** on five findings, one of which was an authority conflict between - the approved specification's exact actor DDL and its own acceptance-test - wording; the CTO resolved that conflict and authorized bounded corrections, - which have been delivered on the same branch without rebase or history - rewrite. BE-03 is **not merged**: the resulting new exact head requires a - **fresh** independent review — the earlier review applies only to the head it - examined — and explicit CTO merge authorization remains outstanding. Merge - would authorize repository integration only — deployment, environment - migration execution, production migration, assignment creation or backfill - and distribution activation remain separately gated and unauthorized. The - specification carried one programme-decision candidate — the + request's record under ADR-0005 and is not restated here. BE-03 is `CLOSED` + as an inactive foundation: merge authorized repository integration only — + deployment, environment migration execution, production migration, package + commercial backfill, assignment creation or backfill, durable job creation, + dissemination and distribution activation remain separately gated and + unauthorized. Post-merge control reconciliation is delivered by + [BE-03-CLOSEOUT-01](../engineering/ai-delivery/tasks/BE-03-CLOSEOUT-01.md). + The specification carried one programme decision — the [BE-03/BE-04/APP-01 phase boundary](decisions.md), under which BE-03 owns desired configuration only and creates no durable job, no placeholder job and no fabricated job status, and under which APP-01's job-aware elements depend @@ -189,22 +187,25 @@ Each branch starts from the repository's verified development branch and targets production writer, and it implements the protected-read authorization as a least-privilege per-publisher `PUBLISHER_USER` (or superuser) check with no role inheritance, covering package and capability codes alike. -11. APP-01 remains blocked pending BE-03, app readiness controls (BR-APP-01 or - an explicit CTO exception, and the separately specified CG-11 CI closure), - the exact BE-03 SHA/schema-pinning contract control, and its own approved - bounded specification. Under the candidate phase boundary, only APP-01's - configuration scope is satisfiable from BE-03 — including reads of effective - capability codes; durable back-catalogue job status, attempt state, failure - state and pending-onboarding state require BE-04. +11. APP-01's BE-03 backend-contract dependency is satisfied for its + configuration-only scope: the approved protected API is merged and + available. APP-01 itself remains blocked by its other controls — app + readiness (BR-APP-01 or an explicit CTO exception, and the separately + specified CG-11 CI closure), the exact BE-03 SHA/schema-pinning contract + control, and its own approved bounded specification. Under the approved + phase boundary, only APP-01's configuration scope is satisfiable from + BE-03 — including reads of effective capability codes; durable + back-catalogue job status, attempt state, failure state and + pending-onboarding state require BE-04. 12. Beyond the delivered and merged documentation-only ADR-01 implementation, ADR-01-CLOSEOUT-01 control reconciliation, the shared DataLoader - foundation, the merged inactive BE-02 foundation and the separately - authorized, delivered-but-unmerged BE-03 implementation, no BE-04, + foundation and the merged inactive BE-02 and BE-03 foundations, no BE-04, MIG-01, APP-01, APP-02, OAI-PMH, deployment, release, environment or - production migration, assignment creation or backfill, distribution - activation, `OBSERVE`/`ENFORCE` transition or PR #799 action is - authorized; all licence, migration, app, dissemination and operational - tasks remain blocked under their recorded dependencies. Repository - authority, specification work and BE-03 implementation authorization do + production migration, package commercial backfill, assignment creation or + backfill, durable job creation, dissemination, distribution activation, + `OBSERVE`/`ENFORCE` transition, workflow change or manual dispatch, or PR + #799 action is authorized; all licence, migration, app, dissemination and + operational tasks remain blocked under their recorded dependencies. + Repository authority, specification work and a merged implementation do not authorize runtime change, credential use, workflow dispatch or production access.