From 5a428b7cf3f90af26cf60f2ccd1a2b49887b4275 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Wed, 15 Jul 2026 16:38:31 +0100 Subject: [PATCH 01/22] Plan contribution and compensation boundary --- .../ARTIFACT_STORAGE_HANDOFF.md | 40 + .../AUTHORIZATION_HANDOFF.md | 87 + .../CHUNK_MAP.md | 100 + .../CONFORMANCE_MATRIX.md | 30 + .../DECISIONS.md | 114 + .../DISCOVERY.md | 161 + .../INTENT.md | 86 + .../JOINT_RELEASE_HANDOFF.md | 102 + .../PLAN.md | 298 ++ .../RISKS.md | 21 + .../RUNTIME_VERIFICATION.md | 48 + .../SOURCE_MANIFEST.md | 67 + .../STATUS.md | 52 + ...-CON-001-01-canonical-contract-adoption.md | 141 + ...S-CON-001-02A-shared-outbox-persistence.md | 43 + ...WS-CON-001-02B-shared-outbox-dispatcher.md | 70 + ...-02C-shared-lifecycle-audit-participant.md | 43 + ...CON-001-03A-adapter-binding-persistence.md | 43 + ...001-03B-compensation-policy-persistence.md | 42 + ...-001-03C-contribution-award-persistence.md | 42 + ...03D-delivery-receipt-status-persistence.md | 47 + ...-001-04A-hidden-adapter-binding-service.md | 45 + ...-04B-hidden-compensation-policy-service.md | 45 + ...policy-semantic-cutover-and-task-freeze.md | 126 + ...-payment-policy-physical-schema-removal.md | 48 + ...001-06-review-lease-compensation-freeze.md | 87 + ...c-review-contribution-award-participant.md | 111 + ...-001-08A-outbound-compensation-delivery.md | 88 + ...ON-001-08B-inbound-fulfillment-callback.md | 64 + ...-CON-001-08R-bound-service-rate-control.md | 44 + ...CON-001-09A-contribution-evidence-write.md | 45 + ...B-authorized-contribution-evidence-read.md | 43 + ...01-10A-contribution-award-product-reads.md | 45 + ...1-10B-operations-reconciliation-rebuild.md | 56 + .../WS-CON-001-11-hidden-release-readiness.md | 88 + ...PLAN-contribution-compensation-planning.md | 82 + ...S-CON-001-PLAN-internal-review-evidence.md | 138 + ...compensation-boundary-specification(2).pdf | Bin 0 -> 283397 bytes ...and-compensation-boundary-specification.md | 3161 +++++++++++++++++ 39 files changed, 5993 insertions(+) create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md create mode 100644 docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf create mode 100644 docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md new file mode 100644 index 00000000..78ec7fc4 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md @@ -0,0 +1,40 @@ +# Artifact Storage Handoff: WS-ART-001-CON-EVIDENCE + +## Ownership and gate + +This is a proposed ART-owned prerequisite before CON-09A. ART owns the chunk, +raw ArtifactStore composition, prepared-byte admission, provider I/O, +verification, ArtifactBinding/receipt persistence, retry recovery, and provider +conformance. CON owns only the deterministic contribution-evidence schema, +projection status, canonical owner facts, and disclosure guards. + +## Required typed capabilities + +- `ContributionEvidenceWritePort.write(request)` accepts contribution/project/ + schema identity, media type, expected digest, stable idempotency identity, and + bounded deterministic bytes or byte source. It returns bounded verified + ArtifactBinding/receipt data and never a provider reference. +- `ContributionEvidenceReadPort.read(request)` accepts a Workstream + ArtifactBinding id and already-authorized contribution context. It verifies + binding/digest and returns bounded bytes or a stream, never provider authority. +- `ArtifactOperatorRecoveryPort.retry_verification(request)` remains the only + operator recovery entry. Only exhausted `provider_unavailable` verification + jobs are eligible; one recovery attempt creates a new retry job, leaves the + exhausted source job unchanged, and exact replay returns the same attempt and + retry-job ids. + +## Authorization dependency + +AUTH registers `artifact.contribution_evidence.binding.create` mapped to the +existing `artifact.binding.create` PermissionId. ART provisions the fixed +service actor and activates exact contribution/project/role/schema/digest facts. +Public reads continue to use `contribution.read_self` or +`contribution.read_project`; there is no `artifact.retrieve` action. + +## Provider and proof boundary + +LocalStorage is focused dev/test, MinIO is local/CI S3-protocol proof, AWS S3 is +production, and R2/Flow Node are deferred. Contract tests must reject raw store +or provider imports in CON, raw provider-reference disclosure, changed bytes +under one idempotency identity, cross-owner/project binding, and recovery rows +or executor leases owned by CON. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md new file mode 100644 index 00000000..9789d6c9 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -0,0 +1,87 @@ +# Authorization Handoff: WS-CON-001 + +## Status and ownership + +Every ActionId below is **proposed and currently absent**. AUTH-07A commit +`3ab25cf` merged to trusted `main` through `e9d72a1`; the canonical catalogue +now contains 74 PermissionIds and 50 planned non-WS-CON ActionIds. Its additive +permission is `review.queue.override`. Neither proposed WS-CON service-only +PermissionId is registered, and none of the proposed WS-CON ActionIds is in the +merged closed enum. + +AUTH owns ActionId/ActionOwner registration, PermissionId registration, +typed/PostgreSQL parity, grants, service ActorProfiles and exact service-action +assignments, and kernel behavior. The feature owner below owns canonical +resource composition, lifecycle guards, transaction-time revalidation, +behavioral proof, and activation after AUTH registration merges. WS-CON must not +edit AUTH persistence, catalogue, grant, or kernel files. + +## Proposed closed handoff + +`T` means authority must be revalidated in the same caller transaction after +the relevant canonical rows are locked. `Q` means request-scoped authorization +is sufficient because the operation is read-only, but resource facts still come +from canonical rows. + +| Proposed ActionId | PermissionId | Target | Candidate principal | Canonical facts/mandatory guards | Revalidation | Registry / activation owner | +|---|---|---|---|---|---:|---| +| `contribution.read_self` | existing `contribution.read_self` | ContributionRecord | human contributor | contribution, project, contributor; caller is exact contributor; minimal self disclosure | Q | AUTH / CON-09B; reused by CON-10A | +| `contribution.read_project` | existing `contribution.read_project` | Project contribution collection | Project Manager, Finance Authority, Operator/Audit as separately eligible | exact project role/operational scope; pre-filtered pagination and concealment; Reviewer is self-only and gains no project-wide history | Q | AUTH / CON-09B; reused by CON-10A | +| `compensation.policy.read` | existing `compensation.policy.manage` | CompensationPolicyVersion | Finance Authority candidate only | exact project; version belongs to project; no provider secret or service route data | Q | AUTH / CON-04B | +| `compensation.policy.create_draft` | existing `compensation.policy.manage` | Project compensation policy collection | Finance Authority candidate | exact project; setup state; referenced bindings belong to project/instrument | T | AUTH / CON-04B | +| `compensation.policy.update_draft` | existing `compensation.policy.manage` | draft CompensationPolicyVersion | Finance Authority candidate | same project; draft only; optimistic version and immutable published fields | T | AUTH / CON-04B | +| `compensation.policy.publish` | existing `compensation.policy.manage` | draft CompensationPolicyVersion | Finance Authority candidate | project selector, version, all referenced bindings active; closed rules; no contradictory guide handoff | T | AUTH / CON-04B | +| `compensation.policy.retire` | existing `compensation.policy.manage` | published CompensationPolicyVersion | Finance Authority candidate | same project; preserve frozen work; no selector corruption | T | AUTH / CON-04B | +| `compensation.adapter_binding.read` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | exact project; redact route identity as required; never expose credentials | Q | AUTH / CON-04A | +| `compensation.adapter_binding.create` | existing `compensation.adapter_binding.manage` | Project adapter-binding collection | Finance Authority candidate | project, instrument, adapter capability, canonical active service actor and non-secret route identity | T | AUTH / CON-04A | +| `compensation.adapter_binding.suspend` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | project/binding state; block new freezes/delivery, preserve existing callback obligations | T | AUTH / CON-04A | +| `compensation.adapter_binding.resume` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | actor/link/action assignment and adapter capability are active; no silent backlog mutation | T | AUTH / CON-04A | +| `compensation.adapter_binding.retire` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | no active-policy reference, unfinished frozen assignment/lease, or unfulfilled award; after retirement only exact replay of a previously accepted receipt remains | T | AUTH / CON-10B | +| `compensation.award.read_self` | existing `contribution.read_self` | CompensationAward | human beneficiary | award/project/beneficiary; exact subject match; safe status only | Q | AUTH / CON-10A | +| `compensation.award.read_project` | existing `compensation.award.read` | Project award collection | Finance Authority, Operator/Audit as separately eligible | exact project/ops scope; pre-filtered pagination; no provider refs | Q | AUTH / CON-10A | +| `compensation.delivery.reconcile` | existing `compensation.delivery.reconcile` | CompensationDelivery | Finance Authority or reason-bound Operator candidate | exact project/delivery; immutable event/payload/binding/idempotency identity; distinct finance/operator guards | T | AUTH / CON-10B | +| `compensation.status.read` | existing `operations.status.read` | Compensation operations projection | Operator candidate | bounded operational scope; redacted failure class; no beneficiary/provider secret | Q | AUTH / CON-10B | +| `compensation.reconcile.run` | existing `operations.reconcile.run` | Compensation reconciliation request | reason-bound Operator candidate | bounded project/range; durable request only; immutable truth comparison; never repair canonical awards/receipts; async execution is a shared-outbox handler under fixed dispatch authority | T | AUTH / CON-10B | +| `contribution.projection.rebuild` | existing `operations.projection.rebuild` | Contribution projection rebuild request | reason-bound Operator candidate | bounded project/version; durable request only; rebuild projection only; immutable truth unchanged; async execution is a shared-outbox handler under fixed dispatch authority | T | AUTH / CON-10B | +| `audit.read` | existing `audit.read` | WS-CON audit projection | Audit/Operator candidate | exact project/ops scope; redaction and pagination; append-only truth | Q | AUTH / CON-10B | +| `audit.export` | existing `audit.export` | bounded WS-CON audit export | Audit candidate | exact scope, purpose, maximum range, redaction, export evidence | T | AUTH / CON-10B | +| `compensation.fulfillment.report` | **new service-only `compensation.fulfillment.report`** | frozen CompensationAdapterBinding + Award | exact bound service ActorProfile only | actor/link/action assignment active; route identity, award, project, instrument, frozen binding and receipt state all match | T | AUTH / CON-08B | +| `outbox.dispatch` | **new service-only `outbox.dispatch`** | claimed shared OutboxEvent | fixed `workstream.outbox.dispatcher` ActorProfile only | current claim/lease/generation; immutable event, payload and idempotency identity; handler side effects occur only under this claimed command | T | AUTH + shared outbox / CON-02B prerequisite; consumed by CON-08A | +| `artifact.contribution_evidence.binding.create` | existing `artifact.binding.create` | ContributionRecord evidence role | fixed ART/CON worker service actor | exact contribution/project/role/schema/digest; ART admission/verification receipt; no raw provider ref | T | AUTH + ART / ART prerequisite then CON-09A | + +## Adapter service-identity invariant + +Each CompensationAdapterBinding persists an `adapter_actor_id` referencing a +canonical service ActorProfile, project, instrument, adapter capability, and a +non-secret route identity. AUTH creates the exact +`compensation.fulfillment.report` service-action assignment. Human +AdminRoleGrant or ProjectRoleGrant records can never satisfy this action, and +WS-CON never fabricates such grants. + +Under the canonical lock order a callback revalidates actor state, identity-link +state, exact service-action assignment, route identity, award, project, +instrument, frozen binding, binding state, and delivery/receipt state. Controls +are rate-limited and idempotent per actor plus binding, not by shared IP alone. + +- Active binding: new freeze, delivery, and valid callback are eligible. +- Suspended binding: no new freeze or delivery; a valid callback for an award + already frozen/issued to that binding may still fulfill it. +- Retirement is denied while an active policy references the binding or any + unfinished frozen assignment/lease or unfulfilled award depends on it. + Retired binding: no new freeze, delivery, or receipt; only byte-for-byte exact + replay of a receipt already accepted before retirement is acknowledged. +- Callback before local acknowledgement creates the terminal receipt/status and + suppresses later delivery without regressing state or changing identities. + +Actor suspension/revocation and identity-link revocation always deny; these are +distinct from adapter-binding suspension. + +## Shared-outbox and ART prerequisites + +CON-08A is an outbox handler, not an independently authorized compensation +command. The shared-outbox owner must register and provision `outbox.dispatch` +for the fixed dispatcher before CON-08A activates; human +`operations.outbox.retry` authority can request recovery but can never execute +delivery. CON-09A similarly consumes a narrow ART-owned capability after ART +registers `artifact.contribution_evidence.binding.create`; CON never receives a +raw storage port or an artifact-recovery execution authority. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md new file mode 100644 index 00000000..670d94d8 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -0,0 +1,100 @@ +# Chunk Map: WS-CON-001 Contribution Record And Compensation Boundary + +## Rule + +One chunk maps to one reviewable PR. No runtime chunk starts until its exact +AUTH, ART, REV, outbox, migration, and human gates are satisfied on current +trusted `main`. Every runtime chunk uses the fresh isolated PostgreSQL runner +and same-invocation coverage evidence defined in `PLAN.md`. + +## Chunks + +| Chunk | Title | Risk | Gate | Status | +|---|---|---:|---|---| +| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Internally reviewed; human approval pending | +| `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Plan/human decisions approved | Proposed | +| `WS-CON-001-02A` | Shared Transactional Outbox Persistence | L1 | 01; event ownership approved | Proposed | +| `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; worker/operations contract and AUTH `outbox.dispatch` registration approved | Proposed | +| `WS-CON-001-02C` | Shared Lifecycle Audit Participant | L1 | 02B; existing AuditEvent contract refreshed | Proposed | +| `WS-CON-001-03A` | Compensation Adapter-Binding Persistence | L1 | 02C; migration head refreshed | Proposed | +| `WS-CON-001-03B` | Compensation Policy Persistence | L1 | 03A; legacy-data rule | Proposed | +| `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; merged REV-03 and REV-04 exact FK targets | Proposed | +| `WS-CON-001-03D` | Delivery, Receipt, And Status Persistence | L1 | 03C | Proposed | +| `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; AUTH registrations/kernel merged | Proposed | +| `WS-CON-001-04B` | Hidden Compensation-Policy Service | L1 | 03B,04A; AUTH registrations/kernel merged | Proposed | +| `WS-CON-001-05A` | PaymentPolicy Semantic Consumer Cutover And Task Freeze | L1 | 04B; merged REV-02 exact `Submission.task_assignment_id` lineage; D2 approved; legacy rule; AUTH task-claim cutover | Proposed | +| `WS-CON-001-05B` | PaymentPolicy Physical Schema Removal | L1 | 05A; zero-consumer scan; removal migration approval | Proposed | +| `WS-CON-001-06` | Review-Lease Freeze Capability | L1 | REV-03 schema; 05B; exact caller facts stable | Proposed | +| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D; REV-09B; shared audit/outbox | Proposed | +| `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07; 02B; ADR 0014 adapter foundation; joint lifecycle-fence port contract | Proposed | +| `WS-CON-001-08R` | Bound-Service Callback Rate Control | L1 | 08A; shared API-control contract | Proposed | +| `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; AUTH callback permission/service assignment; joint callback-fence port contract | Proposed | +| `WS-CON-001-09A` | Contribution Evidence Projection Write | L1 | 07; named `WS-ART-001-CON-EVIDENCE` capability/action prerequisite | Proposed | +| `WS-CON-001-09B` | Authorized Contribution Evidence Read | L1 | 09A; disclosure schema; AUTH read actions | Proposed | +| `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B,09B; AUTH read actions | Proposed | +| `WS-CON-001-10B` | Operations, Reconciliation, Rebuild, And Fulfillment Drain Observation | L1 | 10A; AUTH ops/audit actions; shared-outbox observation capability | Proposed | +| `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10B; REV-10 integration; AUTH/ART/outbox readiness; required CON-owned dispatch/callback fence hooks and drain port | Proposed | + +## Dependency order + +```text +PLAN -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D -> 04A -> 04B -> 05A -> 05B -> 06 -> 07 -> 08A -> 08R -> 08B -> 09A -> 09B -> 10A -> 10B -> 11 +``` + +Cross-initiative ownership and merge gates: + +```text +CON-03B policy persistence -> REV-03 lease persistence (REV owns lease FK) +REV-02 exact Submission.task_assignment_id lineage -> CON-05A semantic cutover/freeze -> CON-05B physical removal -> new task claims under compensation policy only +CON-02C shared audit participant -> REV-04 review-chain persistence +REV-03 lease persistence + CON-05B -> CON-06 capability +CON-06 -> REV-06 claim injection/integrated freeze proof +REV-04 exact Review target -> CON-03C foreign keys +REV-09B + CON-07 participant -> REV-10 sole review-composition integration +CON-08A/B,09A/B,10A/B + REV-12 + AUTH/ART/outbox -> CON-11 hidden readiness +CON-08A/08B/10B/11 required CON-owned dispatch/callback fence ports and fulfillment-drain observation + CON-11 hidden manifest + REV-12 -> REV-12A hidden joint release-control composition -> REV-13 sole route activation and joint live drill +``` + +## Chunk boundaries + +- 01 reconciles specifications/ADR and owns only the exact fail-closed scanner + classification required by its byte-preserving archival rename; 05A + atomically removes all PaymentPolicy semantic consumers and freezes the + replacement policy on task claim; 05B physically drops the unreachable + model/table/columns/constraints. +- 02A owns generic persistence/append; 02B alone owns the feature-neutral + dispatcher, handler registry, retry/dead-letter/replay, operations, and typed + read-only drain observation. +- 02C extends the existing shared AuditEvent repository/service with one typed + caller-transaction lifecycle participant; it owns no review/CON semantics. +- 03A/03B split binding and policy schema; 03C/03D split canonical economic + truth from delivery/receipt/projection schema. +- 04A/04B split hidden binding and policy services; routes remain unregistered. +- 05A owns the cross-module semantic cutover because the old locked fields span + project, task, submission and checker contracts; 05B is schema cleanup only. +- 06 exposes only a CON-owned capability; REV-06 owns review claim wiring. +- 07 creates the database-local participant; REV-10 owns review wiring. +- 08A is an outbox feature handler and owns its narrow mandatory dispatch-fence + consumer port; REV-12A may supply the durable implementation only through + joint composition and may not edit the CON handler. 08R extends the shared + closed rate-control scopes; 08B owns the separately authenticated callback + and its narrow mandatory callback-fence consumer port. +- 09A writes evidence projections through ART; 09B owns safe reads. +- 10A owns product reads; 10B owns operations/reconciliation/rebuild plus the + read-only fulfillment-drain observation port over CON and shared-outbox state. +- 11 proves hidden readiness, including both required fence injection seams and + the drain-observation port, and produces the exact dependency manifest. It + registers no production routes. REV-12A owns hidden release-control + composition; REV-13 remains the sole joint activation owner. + +## Required reviewer tracks + +Every chunk: senior engineering, QA/test, security/auth, product/ops, +architecture, docs, and reuse/dedup. Runtime/test chunks add test-delta. Add CI +integrity for workflow, scripts, dependency, package, test configuration, or +coverage changes. + +## Stop condition + +Planning ends after required plan review and human discussion. Do not start 01 +or any runtime chunk automatically. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md new file mode 100644 index 00000000..7b7b41fc --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -0,0 +1,30 @@ +# Conformance Matrix: WS-CON-001 + +## Rule + +This matrix is the traceability index for the reconciled active contract. Chunk +01 expands every retained candidate requirement into an exact row. Runtime +chunks replace proposed case names with collected pytest node IDs and retained +metadata at `.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/evidence/--isolated-tests.json` +plus live-evidence paths before activation. Failed attempts remain immutable; +the matrix records the one accepted attempt ID/path. Archival candidate text is +evidence, not executable authority. + +| Requirement family | Owner | Minimum executable cases before owner completes | Final live evidence owner | +|---|---|---|---| +| Contribution identity and review lineage | CON-03C/07 + REV-10 | one completed-review contribution per valid Review; accept adds one accepted-submission contribution; second revision review creates a distinct reviewer contribution; automated checker outcomes create none; at-most-one DB constraints and mandatory-participant at-least-one proof | REV-13 | +| Policy publication and freezing | CON-04B/05/06 + REV-06 | absent/incomplete setup denies; unpaid is explicit; retired frozen version remains valid for started work; later activation changes new assignments/leases only; publish versus both claims in both lock orders | REV-13 | +| Binding lifecycle | CON-04A/08A/08B/10B | suspended blocks new freeze/delivery but accepts valid existing-work callback; retirement denies dependencies then permits exact accepted-receipt replay only; actor/link revocation denies; project/instrument mismatch denies | REV-13 | +| Immutable award evaluation | CON-03C/07 | at most one money plus one points award; exact decimals; accept/needs_revision/reject rules; replay stable; changed facts fail; no PaymentPolicy fallback | REV-13 | +| Outbox and delivery | CON-02A/02B/03D/08A + REV-12A | immutable event/payload/binding/idempotency identity; stale claim fencing; durable in-flight generation; retry/dead-letter/replay; reconciliation preserves original identity; provider I/O occurs outside every database transaction/lifecycle fence; dispatch-versus-admission fencing in both orders | REV-13 | +| Callback and fulfillment | CON-08B + REV-12A | callback before acknowledgement suppresses later delivery; duplicate exact receipt idempotent; changed receipt conflicts; per-actor/binding limits; suspended/retired matrices; callback allowed through delivery drain and denied after disable; callback-versus-disable in both orders; no human authority | REV-13 | +| Evidence artifact | CON-09A/09B | deterministic versioned schema; self/project disclosure matrix; no reviewer-private, provider, credential, external-receipt or unnecessary actor data; newer-schema rebuild retains prior immutable bundle; LocalStorage/MinIO capability conformance | REV-13 | +| Product reads | CON-10A | self/project role matrix, cross-project concealment, stable pagination, money/points/status separation, no provider refs | REV-13 | +| Operations and audit | CON-10B + REV-12A | Finance versus Operator reconciliation and PM/contributor denials; bounded rebuild; immutable truth unchanged; audit read/export scope and redaction; same-session drain observation never reports false zero or exposes repositories | REV-13 | +| Atomic review integration | CON-07 + REV-10 | allowed exact `review.decision` evidence matches actor/action/resource/project/request/correlation; denied/stale/mismatched evidence rejected; every injected failure rolls back review/task/contribution/award/audit/outbox together | REV-13 | +| Public contract | CON-11 readiness + REV-12A control + REV-13 activation | hidden routes absent before release; `/api/v1` only; dependency/fence/drain manifest exact; startup/preflight fail closed; no partial surface; deterministic shutdown/reactivation phase matrix | REV-13 | + +The completed matrix must cover every normative invariant adopted into +`docs/spec_contribution_compensation.md`, including all candidate cases that are +retained after reconciliation. “All mismatch cases” is not an acceptable test +reference. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md new file mode 100644 index 00000000..c93e9851 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -0,0 +1,114 @@ +# Decisions: WS-CON-001 Contribution Record And Compensation Boundary + +## D1 - Preserve Reference Generations; Reconcile Active Contract + +**Status:** recommended; human approval required. + +Preserve supplied PDFs as immutable source generations. Treat the Markdown as +an explicitly editable reconciled working transcription derived from the +generation-2 PDF, record its current hash after every reviewed reconciliation, +and never claim it is byte-identical to the PDF. CON-01 creates +`docs/spec_contribution_compensation.md` plus an ADR as the active normative +repository contract. + +Rejected: silently replacing a PDF generation, claiming the reconciled +Markdown is archival, or treating a candidate as executable merely because it +says “locked.” + +## D2 - One Executable Compensation Authority + +**Status:** approved by the human on 2026-07-15. + +`CompensationPolicyVersion` supersedes and completely replaces `PaymentPolicy`. +The `PaymentPolicy` model/table, project-guide request/response fields, +repository/service methods, task/submission/checker locked-version fields, +copied amount/currency/payout fields, constraints, imports, tests, active docs, +templates, diagrams and operations language are removed. No compatibility +alias, dormant historical model, dual write/read, automatic conversion, or +fallback is retained. + +CON-05A atomically cuts every semantic consumer to the replacement: project +guide activation stops requiring PaymentPolicy, Finance-published +CompensationPolicyVersion becomes the only task-claim economic prerequisite, +and TaskAssignment freezes it. Old columns/table may remain physically present +but are unreachable and write-blocked only until CON-05B drops them. CON-05B +owns physical schema/model removal and a zero-consumer scanner. Ambiguous legacy +rows fail migration; the exact reset-versus-classified-backfill rule remains a +separate human gate before CON-05A. + +Rejected: advisory retention, historical quote APIs, dual execution, silent +unpaid behavior, or rewriting legacy values into compensation terms by guess. + +## D3 - Existing Submission Is The Versioned Identity + +**Status:** accepted by repository evidence and parallel WS-REV plan. + +Use `backend/app/modules/tasks/models.py::Submission` and its `version`/ +`supersedes_submission_id` chain. WS-CON creates no `SubmissionVersion` table. + +## D4 - ActionIds Do Not Replace PermissionIds + +**Status:** separation accepted; all WS-CON actions and service permissions are +proposed dependencies requiring human approval and AUTH registration. + +WS-CON declares granular proposed ActionIds mapped to existing stable +PermissionIds when semantically safe. AUTH owns registration, audit migration, +grants/service actors, and kernel behavior; the named feature chunk owns +resource composition, behavioral proof, and activation after registration. +Shared outbox dispatch and the external fulfillment callback require the +proposed service-only PermissionIds `outbox.dispatch` and +`compensation.fulfillment.report`; neither can borrow human authority. CON-08A +is a handler of the claimed shared-outbox command, not a separately authorized +delivery command. Keeping dispatch separate from human reconciliation or retry +authority prevents a Finance or Operator grant from authorizing an external +side effect. + +No WS-CON code edits the AUTH catalogue. `AUTHORIZATION_HANDOFF.md` is the exact +proposal, and every mapping is re-read from merged trusted `main` before its +implementation chunk. + +## D5 - Derived Contribution/Award Writes Are Review Participants + +**Status:** accepted by the parallel WS-REV plan and candidate invariant. + +The authorized `review.decision` transaction invokes mandatory task and WS-CON +participants using the same `AsyncSession`. Contribution/award creation has no +separate human API and no invented `materialize` permission. The participant +flushes but does not commit. + +## D6 - Artifact Ownership Follows ADR 0013/0014 + +**Status:** accepted repository decision. + +WS-CON owns the deterministic contribution evidence schema and projection +status. ART owns prepared-byte admission, raw provider operations, verification, +content/binding/receipt persistence, and recovery through a narrow typed +capability. LocalStorage is development/focused-test only; MinIO proves the +S3-compatible protocol locally/in CI; AWS S3 is v0.1 production. Flow Node and +R2 are deferred. + +## D7 - Shared Outbox Is A Prerequisite + +**Status:** recommended; human approval required with the chunk sequence. + +One generic shared outbox owns delivery state and retry/dead-letter mechanics. +Review and WS-CON append events through a caller-transaction participant. No +review-private or compensation-private outbox is allowed. + +## D8 - Coherent Public Activation + +**Status:** recommended; human approval required. + +Policy, contribution, award, callback, evidence, read, and review lifecycle +routes remain behind unregistered production composition until AUTH, ART, REV, +outbox, audit, migrations, operations, and live preflight are complete. The +final chunk activates one coherent `/api/v1` surface and no `/v1` alias. + +## D9 - No Provider Payment Or Points Ledger In Workstream + +**Status:** accepted from the human scope and candidate boundary. + +Workstream persists awards, exact outbound instructions, adapter delivery +evidence, immutable fulfillment receipts, and rebuildable status. External +adapters own payment requests/attempts, approvals, provider reconciliation, +beneficiary accounts, balances, and project-points ledger entries. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md new file mode 100644 index 00000000..a6e6b76e --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -0,0 +1,161 @@ +# Discovery: WS-CON-001 Contribution Record And Compensation Boundary + +Discovery was read-only for application code. No contribution or compensation +runtime implementation was performed. + +## Current behavior + +- `backend/app/api/router.py` exposes the current backend only under + `/api/v1` (plus the unversioned health compatibility route). +- `backend/app/modules/tasks/models.py::Submission` is already the immutable, + version-numbered submission record. There is no separate `SubmissionVersion` + table and WS-CON must not create one. +- `TaskService.claim_task` creates `TaskAssignment` but freezes no compensation + policy. The parallel WS-REV plan will create `ReviewLease`; no review models + exist on current `main`. +- `WorkstreamTask` and `Submission` lock guide-bound `PaymentPolicy` versions. + The task also copies `base_amount`, `currency`, and `payout_type`. No runtime + `ContributionRecord`, `PaymentRecord`, `CompensationPolicy`, award, receipt, + fulfillment, or reputation model exists. +- Durable checker execution advances a locked Submission through the automatic + gate to `review_pending`. The review/revision lifecycle is planned in the + sibling `workstream-rev-001` worktree and remains unimplemented. +- Current task/project services still contain explicitly temporary legacy role + checks. WS-AUTH owns their cutover; WS-CON must not reproduce or repair them. +- The shared `AuditEvent` ledger and caller-owned `AsyncSession` are the + transaction foundation. There is no shared transactional-outbox module yet. +- Current artifact runtime is the pre-v2 foundation. Accepted ADR 0013 and + `docs/spec_artifact_storage_service.md` define the target: only + `ArtifactStorageOrchestrator` receives `ArtifactStore`; product modules use + narrow typed capability ports. +- Trusted `main` now includes ADR 0014's generic typed + `ExternalServiceAdapterFactory[TAdapter]` foundation. It does not supply a + contribution-evidence capability or compensation provider adapter; those + remain separately gated, explicit composition-root registrations. + +## Reconciled working source and supplied generation-2 PDF + +The working tree contains an editable reconciled Markdown transcription derived +from the supplied generation-2 PDF, plus that immutable PDF companion: + +| File | SHA-256 | Observation | +|---|---|---| +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md` | `cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640` | Editable reconciled working transcription derived from the revised PDF; not canonically adopted | +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf` | `ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457` | Revised archival companion; text extracts successfully; not a reproducible Markdown build contract | + +The original tracked PDF is currently deleted in the user's working tree but +remains the immutable first archival generation at SHA-256 +`34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1`. +`docs/reference_specs/README.md` and `SHA256SUMS` require that original to remain +unchanged. The revised candidate should therefore be retained as a second +generation rather than replacing the first. + +## Reconciliation findings + +| Finding | Evidence | Required correction in active contract | +|---|---|---| +| Wrong public prefix | Candidate section 18 uses `/v1`; router and ADR 0012 use `/api/v1`. | Use `/api/v1` only; no alias. | +| ActionId/PermissionId conflation | Candidate calls granular `compensation.policy.*` values permissions and says broad IDs were removed. Merged AUTH-07A preserves 74 approved PermissionIds and separately registers 50 planned ActionIds. | Publish an exact proposed ActionId -> PermissionId handoff. Never call an ActionId a permission or a merely planned identifier active. | +| Wrong Review action | Candidate uses `review.decision.record`; merged AUTH-07A and WS-REV use planned ActionId `review.decision` mapped to PermissionId `review.decision`. | Consume `review.decision` only after its AUTH/REV activation gate. | +| Invented WS-AUTH source | Candidate names `WS-AUTH-001-A`, which is not a canonical repository artifact. | Cite merged `docs/spec_authorization_service.md`, ADR 0012, and the closed catalogue. | +| Invented artifact permissions | Candidate uses `artifact.recovery.request`, `artifact.recovery.execute`, and `artifact.retrieve`. AUTH explicitly rejected the first; none is a registered PermissionId. | Use `artifact.verification_job.retry` through `ArtifactOperatorRecoveryPort`; require ART-owned typed storage/read capabilities and approved action mappings. | +| Wrong artifact port | Candidate injects `ArtifactStorePort` with store/projection/retain/retrieve methods. ADR 0013's target `ArtifactStore` has only provider-byte behavior and cannot enter product services. | WS-CON consumes narrow ART capability ports. Only ART orchestration receives the raw store. | +| Wrong providers | Candidate requires Local Storage/Flow Node parity. ADR 0013 locks LocalStorage for dev/focused tests, MinIO for local/CI S3 proof, AWS S3 for v0.1 production, and defers Flow Node/R2. | Test LocalStorage and MinIO; AWS deployment proof gates production; Flow Node remains future. | +| Wrong retention/search claims | Candidate assumes retain/pin and semantic indexing APIs that ADR 0013 deliberately excludes from v0.1 `ArtifactStore`. | Use ART's immutable completed-byte retention policy and typed lifecycle records; omit semantic indexing/search from WS-CON v0.1. | +| Duplicate submission model language | Candidate defines `SubmissionVersion` as if separate. | Treat existing `Submission` as the versioned identity and use `submission_id` in repository schemas. | +| Payment model collision | Active docs/model use guide-bound `PaymentPolicy`, a future mutable `PaymentRecord`, adjustments, and voidable contributions; candidate introduces immutable policies/awards/receipts and prohibits adjustments/voiding. | D2 approves `CompensationPolicyVersion` as the sole authority and complete PaymentPolicy removal; CON-01 records the ADR, 05A/05B perform the cutover, and only the legacy-row rule remains open. | +| Outbox assumed but absent | Candidate requires atomic outbox effects; repository has no shared outbox. WS-REV also blocks on it. | Land a shared caller-transaction outbox foundation before review-chain and contribution integration. | +| Direct system-action invention | Candidate adds `contribution.materialize`, `compensation.award.materialize`, and `outbox.dispatch` as if already registered permissions. | Derived contribution/award creation is a required participant of authorized `review.decision`. Shared outbox owns the proposed service-only dispatch action; CON adds no feature-local bypass action. | + +## Relevant files/modules + +| Path | Purpose | Notes | +|---|---|---| +| `backend/app/api/router.py` | API composition | Canonical `/api/v1`; future routes stay unregistered until coherent cutover. | +| `backend/app/modules/tasks/models.py` | Task, assignment, versioned Submission, shared audit | Must gain exact assignment compensation freeze; Submission remains canonical version identity. | +| `backend/app/modules/tasks/service.py` | Claim, submission, task lifecycle | WS-CON may integrate only through task-owned participants; auth cutover stays WS-AUTH-owned. | +| `backend/app/modules/projects/models.py` | Project and guide-bound `PaymentPolicy` | Approved for complete semantic removal in CON-05A and physical removal in CON-05B; the legacy-row rebuild/classification rule remains a human gate. | +| `backend/app/modules/projects/service.py` | Guide activation and policy locking | Must not become a second compensation-policy engine. | +| `backend/app/modules/authorization/*` | Current authority idempotency/audit foundation | WS-CON imports only the future public service/types, never repositories or grants. | +| `backend/app/modules/authorization/catalogue.py` from AUTH-07A `3ab25cf`, merged through `e9d72a1` | Canonical merged closed catalogue | 74 PermissionIds and 50 planned ActionIds; the additive permission is `review.queue.override`, not either proposed WS-CON service permission. All WS-CON ActionIds remain absent/proposed. | +| sibling `workstream-rev-001/.../` working delta atop `3e09e99` | Content-reviewed, uncommitted parallel review integration amendment | The branch has integrated trusted `main` `e9d72a1`; its delta defines hidden composition, lock order, contribution participant gates, PaymentPolicy removal dependencies, WS-CON-11 preflight, REV-12A hidden release control, and joint REV-13 activation. Required content tracks pass, but its handler-claim wording must be repaired to preserve CON-02B ownership. It cannot be consumed until the exact repaired snapshot is committed, commit-freshness reviewed, refreshed against trusted main, and merged. | +| `backend/app/modules/artifacts/*` | Current artifact metadata/orchestration foundation | Target v2 is still being delivered by WS-ART; WS-CON cannot import provider internals. | +| `backend/app/interfaces/artifacts.py` | Current v1 raw provider port | Not a WS-CON dependency; it is being clean-cut to ADR 0013 v2. | +| `docs/spec_artifact_storage_service.md` | Canonical target artifact contract | Owns narrow product capability ports, recovery, verification, quotas, and provider policy. | +| `docs/spec_authorization_service.md` | Canonical target authorization contract | Preserves broad PermissionIds; ActionIds are separate. | +| `docs/architecture_data_model.md` | Existing contribution/payment target | Conflicts with supplied candidate and needs ADR-backed reconciliation. | +| `docs/operations_payment_reputation.md` | Existing manual payment/reputation workflow | Needs coordinated update only after architecture adoption. | +| `backend/alembic/versions/*` | Current schema through merged AUTH-07A migration `0021_authorization_action_evidence.py` | Every runtime chunk must refresh the next migration number from trusted `main`; no WS-CON contract pre-reserves `0022`. | + +## Current tests + +| Test path | What it covers | Gaps relevant to WS-CON | +|---|---|---| +| `backend/tests/test_tasks.py` | Task policy locks, assignment uniqueness, immutable Submission versions, checker admission, concurrency | No compensation freeze, review effects, contribution, or award tests. | +| `backend/tests/test_projects.py` | Guide/policy activation including `PaymentPolicy` | No CompensationPolicy lifecycle or Finance Authority behavior. | +| `backend/tests/test_authorization.py` | Authority foundations plus merged closed catalogue/audit parity | The deny-by-default kernel, grants, service actors, and feature action activation remain later AUTH-owned work. | +| `backend/tests/test_audit.py` | Typed append-only authority evidence | No contribution/compensation lifecycle audit contract. | +| `backend/tests/test_artifacts.py` | Current artifact port, local adapter, content/binding/receipt foundation | Target v2, S3/MinIO, typed contribution projection capability, and evidence reads are not merged. | +| `backend/tests/test_checkers.py` | Durable checker run and `allow_review` routing | Stops before Review persistence. | +| `backend/tests/test_alembic.py` | Migration upgrade/downgrade guards | No outbox, review, or WS-CON schema. | +| `backend/tests/test_api_contract_e2e.py` | Current API contract drill | No review/contribution/compensation routes or events. | + +## Dependencies/integrations + +- WS-AUTH: executable kernel, grants, service actors, exact WS-CON ActionId + registrations/mappings, immutable `AuthorizationDecision`, and final bypass + removal. WS-CON does not edit those owned surfaces. +- WS-REV: `Review`, `ReviewLease`, findings/resolutions, decision idempotency, + task effects, hidden composition, and final public review cutover. +- WS-ART: v2 store, LocalStorage/MinIO conformance, AWS proof, narrow system- + generated projection/read/bind capabilities, verification recovery, and + artifact action activation. +- Shared outbox: caller-transaction append, stable event identity, post-commit + publication, at-least-once dispatch, delivery attempts, dead-letter, replay, + and idempotent consumer contract. +- PostgreSQL: exact decimals, composite project ownership, uniqueness, row + locking, immutable history, and atomic cross-domain commit. +- Celery/Redis: post-commit dispatch/projection/reconciliation execution only; + correctness must remain PostgreSQL-backed. +- External compensation adapters: typed ADR 0014 capability, deterministic test + adapter for proof, no provider-specific runtime integration in WS-CON. + +## Risks discovered + +| Risk | Why it matters | Suggested handling | +|---|---|---| +| Dual payment truth | `PaymentPolicy`/future `PaymentRecord` and new compensation versions/awards can disagree. | ADR-backed sole execution authority and clean documentation/schema cutover. | +| Permission replacement | Treating ActionIds as replacement permissions would break merged audit/grants. | Exact mapping table; AUTH-owned additive registration; typed manifest tests. | +| Circular REV/CON dependency | Leases need policy FKs; claims need freeze; decisions need contribution participant. | Explicit interleaving gates in chunk map. | +| Cross-domain deadlock/partial commit | Review, authority, tasks, artifacts, CON, audit, and outbox share one transaction. | One canonical lock order, caller-owned session, fault injection, real Postgres concurrency tests. | +| Economic overreach | Payment-provider or points-ledger logic could leak into Workstream. | Typed outbound instruction/receipt boundary and architecture import tests. | +| Artifact bypass | Direct store injection could bypass quotas, verification, binding, and audit. | ART-owned typed capability only; static import/composition tests. | +| Premature public surface | Partial routes would create authorization or lifecycle gaps. | Hidden internal composition until final coherent activation. | +| Legacy/pre-production rows | Existing PaymentPolicy/tasks/assignments cannot be safely guessed into new frozen terms. | Human-approved rebuild/classification/backfill rule before migration. | +| Event/schema drift | The candidate names many events without a shared outbox registry. | Freeze envelope/ownership in the outbox chunk before persistence consumers. | +| Scope size | The candidate is a multi-initiative system, not one PR. | PR-sized L1 chunks with hard stop after each merge. | + +## Unknowns/questions for human + +| Question | Why it matters | Needed before chunk? | +|---|---|---| +| Preserve both candidate generations and reconcile into active spec? | Maintains archival provenance and follows repository precedent. | Before 01. | +| May pre-production payment/task rows be rebuilt, or must they be classified/backfilled? | Determines migration safety and atomic claim cutover. | Before 05. | +| Approve two new service-only PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`? | Human outbox recovery/reconciliation authority must not execute async side effects; no existing permission safely names the external adapter callback entitlement. | Before shared-outbox prerequisite/08A. | +| Does the ART initiative add the contribution evidence capability, or should it be a separate ART-owned prerequisite chunk? | WS-CON cannot own raw storage orchestration. | Before 10. | + +## Existing conventions to preserve + +- One caller-owned async SQLAlchemy session and explicit commit boundary. +- Router -> service -> repository separation with stable structured errors. +- `/api/v1`, no short-prefix alias. +- Existing `Submission` is the versioned submission identity. +- Canonical review decisions only: `accept`, `needs_revision`, `reject`. +- ActionId and PermissionId are distinct closed types. +- Authorization resource facts come from canonical rows, never request JSON. +- Provider-neutral external adapters follow ADR 0014 with explicit composition. +- Only ART orchestration receives raw `ArtifactStore`. +- AWS S3 production, MinIO local/CI protocol proof, LocalStorage focused + development/tests; Flow Node and R2 deferred. +- New/materially changed backend subsystems stay at or above 90 percent while + repository coverage stays at or above 78 percent. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md new file mode 100644 index 00000000..5f453a73 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md @@ -0,0 +1,86 @@ +# Intent: WS-CON-001 Contribution Record And Compensation Boundary + +## Human-level goal + +Implement an evidence-backed contribution and compensation boundary that joins +the canonical human Review transaction without taking ownership of +authentication, authorization, provider payment execution, a points ledger, or +reputation scoring. + +The supplied revised WS-CON Markdown/PDF pair is an input to reconcile, not an +authority to accept blindly. The active contract must conform to the repository, +the live WS-AUTH action/permission catalogue, the parallel WS-REV plan, and the +accepted artifact-storage and external-adapter decisions. + +## Why now + +The backend currently stops at `review_pending`. The parallel review initiative +needs real compensation-policy persistence before ReviewLease creation, a +transaction participant that freezes compensation terms, and an atomic +contribution/award participant before it can expose review decisions. + +## Success state + +- Every valid Review records one immutable reviewer contribution. +- `accept` additionally records one immutable submitter contribution; the other + canonical decisions do not. +- Contributions and awards use compensation terms frozen before the work. +- Review, task/assignment effects, contributions, awards, audit, and shared + outbox events commit or roll back together. +- Money and project-points awards remain project-scoped obligations. Provider + payment attempts, balances, point ledgers, and settlement stay outside + Workstream. +- Fulfillment delivery, acknowledgement, callback receipts, and rebuildable + status projections are distinct. +- Contribution evidence is produced after commit through an ART-owned typed + capability and Workstream `ArtifactBinding`, never through a raw artifact + provider in contribution code. +- Every public or service operation consumes the merged WS-AUTH + `AuthorizationService.require(ActionId, typed ResourceContext)` boundary. +- Public APIs use `/api/v1` only. + +## Non-goals + +- Workstream-owned login, sessions, passwords, or token-role authority. +- AUTH catalogue/kernel/grant/service-actor implementation in this initiative. +- Provider-specific payment SDKs, payment attempts, payout batching, settlement, + beneficiary onboarding, balances, point ledgers, credits, or blockchain work. +- Reputation scores, aggregates, adjudication, reversals, or contribution + mutation. +- A second artifact store, direct `ArtifactStore` injection into contribution + services, Flow Node, R2, semantic-search authority, or public provider refs. +- Frontend work before backend contracts and guards are proven. + +## Business/product/engineering context + +Workstream must certify useful human work independently from whether an external +provider has paid or credited it. Reviewer work is itself a contribution for +every valid completed review. This creates a durable economic and reputation +input while preserving the separation between human judgment, contribution +recognition, compensation authorization, external fulfillment, and future +reputation policy. + +## Human judgment required + +1. Approve the recommended active-contract model: preserve both supplied + reference generations byte-for-byte and create a separately reconciled + `docs/spec_contribution_compensation.md`, instead of editing archival input. +2. **Approved 2026-07-15:** remove `PaymentPolicy` completely because + `CompensationPolicyVersion` supersedes it. The removal must migrate every + project/task/submission/checker/schema/API/doc consumer, preserve no fallback + alias, and leave CompensationPolicyVersion as the only economic policy. +3. Approve the additive WS-AUTH dependency: granular WS-CON ActionIds map to + existing broad PermissionIds wherever safe, while the exact bound adapter + shared outbox dispatch and inbound callbacks require two new service-only + PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`, + owned and implemented by WS-AUTH. The shared-outbox owner activates dispatch; + CON-08A only consumes the claimed command. +4. Approve the cross-initiative sequence, including REV-13 as the sole joint + production-route activation/live-drill owner after AUTH, ART, REV, shared + outbox, and WS-CON participants are mandatory and proven. + +## Initial risk class + +L0 for architecture direction and contract adoption. Each approved runtime +chunk is L1 because it touches payment, permissions, lifecycle, audit, schema, +and cross-domain transactions. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md new file mode 100644 index 00000000..39527e74 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -0,0 +1,102 @@ +# Joint Release Handoff: WS-CON-001 To WS-REV-001-13 + +## Incorporation status + +The inspected sibling working delta atop `3e09e99` has incorporated +contribution/compensation router registration, the WS-CON-11 preflight +manifest, the complete joint live matrix, PaymentPolicy removal dependencies, +the active generated/document companions, and a new REV-12A hidden +release-control chunk. The delta also corrects REV-12A to consume the CON-owned +dispatch and callback fences plus fulfillment-drain observation through +composition instead of editing CON product files or importing CON/outbox +repositories. Its required content-review tracks pass, but the snapshot remains +uncommitted and lacks commit-bound freshness evidence as recorded in +`SOURCE_MANIFEST.md`; it is working discovery evidence, not a dependency. +The current REV-12A draft still says the CON handler claims the shared-outbox +event; before review/merge it must instead accept the dispatcher's already- +claimed command and return a typed outcome, leaving every outbox transition to +CON-02B's shared dispatcher. +WS-CON does not edit the parallel worktree. The WS-REV owner must commit the +exact content-reviewed delta, run commit-bound freshness review, and merge +before CON-11, REV-12A, or REV-13 can activate. Until the later implementation +gates land, both initiatives remain hidden. + +## Required REV-13 allowed-file additions + +```text +backend/app/api/router.py for one joint review/contribution/compensation registration +backend/app/modules/reviews/router.py +backend/app/modules/contributions/router.py +backend/app/modules/compensation/router.py +backend/tests/test_api_contract_e2e.py +backend/tests/test_authorization.py +backend/tests/test_reviews.py +backend/tests/test_contributions.py +backend/tests/test_compensation.py +README.md +docs/product_brief.md +docs/product_principles.md +docs/principles.md +docs/architecture_data_model.md +docs/operations_payment_reputation.md +docs/operations_operator_workflow.md +docs/operations_project_operating_manual.md +docs/template_project_guide.md +docs/template_task.md +docs/architecture_brief/workstream_architecture_brief.md +docs/architecture_brief/workstream_architecture_brief.pdf +docs/architecture_brief/task_lifecycle_sequence.puml +docs/architecture_brief/images/task_lifecycle_sequence.png +docs/architecture_brief/images/future_identity_payment_reputation.png +docs/architecture_brief/images/workstream_v01_container.png +docs/diagrams/task_lifecycle_sequence.md +docs/diagrams/workstream_v01_container.md +docs/diagrams/workstream_v01_container.puml +docs/diagrams/rendered/workstream_v01_container.svg +docs/diagrams/future_identity_payment_reputation.md +docs/diagrams/future_identity_payment_reputation.puml +docs/diagrams/rendered/future_identity_payment_reputation.svg +``` + +This is a seed list, not a closed substitute for discovery. REV-13 must replace +it with CON-01's exact generated active-document/companion inventory and may add +or remove paths only from that evidence. It must include every active/template/ +operations/generated file containing an affected claim. Archival inputs, +historical reviews, and generated loop memory remain excluded. + +## Required joint activation criteria + +- Register review, contribution, compensation policy/binding, contribution/ + award/evidence reads, fulfillment callback, and bounded operations routers in + the same PR under `/api/v1`; no `/v1` alias and no partial prior surface. +- Consume CON-11's exact merged-SHA/migration/action/service-assignment/ART/ + outbox/worker/handler/fence manifest and fail startup/preflight on any + mismatch. +- Use REV-12A only for hidden persisted joint lifecycle control and explicit + composition. Consume the required CON-owned `FulfillmentDispatchFence`, + `FulfillmentCallbackFence`, and `FulfillmentLifecycleDrainObservationPort`; + do not edit CON delivery/callback/outbox policy or import CON/outbox + repositories from REV. +- Preserve CON-02B as sole outbox claim/retry/finalization owner. REV-12A may + fence the CON handler and observe drain state, but neither REV nor the handler + claims or directly transitions the shared OutboxEvent. +- Prove the complete `CONFORMANCE_MATRIX.md` plus REV matrix with collected node + IDs and retained live evidence, including policy/binding setup, task/review + freezes, accept/needs_revision/reject, second revision review, money+points, + explicit unpaid, delivery/callback ordering, suspended/retired binding, + evidence privacy/rebuild, Finance-versus-Operator operations, denials, atomic + rollback, storage/adapter outage, replay and reconciliation. +- Update all active sources/generated companions in the same release so no + mutable PaymentRecord, accept-only/voidable contribution, automatic + reputation, executable PaymentPolicy or stale prefix claim remains. +- Preserve the one-sheet roadmap rule if the roadmap is touched; do not change + archival reference bytes. + +## Ownership + +WS-REV-001-12A owns only the hidden joint release-control foundation and typed +composition; WS-REV-001-13 remains the sole production activation/live-drill +PR. This file does not authorize WS-CON to edit the sibling plan or start REV +work. The incorporated sibling contract must be preserved through rebase, +receive any required delta review, and merge before an implementation chunk may +consume it. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md new file mode 100644 index 00000000..08b2d261 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -0,0 +1,298 @@ +# Plan: WS-CON-001 Contribution Record And Compensation Boundary + +## Proposed approach + +Reconcile the supplied candidate into an active repository contract first, then +deliver the backend through small hidden-composition chunks. Land the shared +outbox and compensation policy ownership before Review persistence needs them; +interleave the remaining WS-CON participants with WS-REV at explicit gates; +activate public contribution/compensation APIs only after AUTH, ART, REV, and +outbox dependencies are mandatory and proven. + +## Design chosen + +### Canonical records + +- `ContributionRecord` is immutable and recognizes one exact contributor unit: + `completed_review` for every valid Review and `accepted_submission` only for + `accept`. +- Existing `Submission` is the versioned submission identity. Contribution + fields use `submission_id`, not a new `SubmissionVersion` table. +- `CompensationPolicyVersion` is the sole executable economic authority for new + assignments/leases. Rules match only contribution type and create at most one + money plus one project-points award. +- `CompensationAward` is immutable. Adapter delivery/acknowledgement and + immutable fulfillment receipts are separate; a rebuildable status projection + supports reads. +- `PaymentPolicy` is removed completely. `CompensationPolicyVersion` is the + only economic policy in persistence, APIs, task/review freezes, checker + context and active documentation; no alias or fallback survives. +- Provider payment attempts, balances, payout batches, points ledgers, and + settlement remain external. + +### Authorization dependency + +WS-CON never reads grants, roles, or AUTH repositories. Every protected command +or query declares one ActionId and consumes a request-scoped, caller-session- +bound `AuthorizationService`. + +Every WS-CON ActionId is currently absent and proposed. AUTH-07A is merged on +trusted `main` through `e9d72a1`; its closed catalogue contains 74 PermissionIds +and 50 planned non-WS-CON ActionIds. The exact handoff is in +`AUTHORIZATION_HANDOFF.md`. It enumerates each proposed action separately, +its existing or proposed PermissionId, canonical target, candidate principal +class, typed resource facts and guards, transaction revalidation requirement, +registry owner, resource-context owner, and activation owner. + +WS-AUTH owns identifier/owner-enum registration, typed/PostgreSQL parity, +service ActorProfile/action-assignment construction, grant semantics, and +kernel behavior. The feature chunk named in the handoff owns resource +composition, lifecycle guards, behavioral proof, and activation only after the +AUTH registration prerequisite is merged. WS-CON never edits AUTH-owned files. + +Derived contribution/award writes are mandatory participants of the already +authorized `review.decision` transaction. They are not separately callable +human/service commands and do not invent `contribution.materialize` or +`compensation.award.materialize` permissions. Shared outbox dispatch likewise +belongs to the outbox subsystem, not WS-CON. + +### Review composition + +`ContributionCompensationDecisionParticipant` accepts the caller's +`AsyncSession`, exact Review/lease/assignment/Submission facts, originating +AuthorizationDecision reference, and canonical request/correlation IDs. It +flushes contributions, awards, projections, audit, and outbox events but never +commits. WS-REV owns the decision and final commit. No optional/no-op production +participant exists. + +Policy lookup/freezing uses separate narrow participants: + +- task-owned assignment claim calls a WS-CON policy-freeze participant; +- review-owned lease claim calls the same policy lookup contract with a distinct + lease freeze operation; +- both lock the Project active compensation selector and copy exactly one + published version ID. + +`ReviewLease` schema and review-claim wiring remain wholly WS-REV-owned: +REV-03 adds the immutable policy-version FK/field, CON-06 supplies only the +narrow compensation lookup/freeze participant against caller-supplied canonical +facts, and REV-06 injects it and proves integrated claim behavior. Likewise, +CON-07 supplies the decision participant; REV-10 alone wires it into review +composition and proves end-to-end atomicity. + +### Canonical lock and revalidation order + +The active contract extends, and may not replace, WS-REV's accepted order: + +1. AUTH-owned current actor/identity/grant/control rows in AUTH internal order; +2. the operation idempotency row; +3. for lifecycle-controlled commands, the shared lifecycle advisory fence and + captured phase snapshot; this is held through the database transaction but + never through remote I/O; +4. for an already-claimed outbox handler command only, read-only validation of + the immutable event/claim generation through the outbox-owned capability; + the handler acquires no OutboxEvent row lock and performs no outbox state + transition; +5. `Project`; +6. active/candidate ProjectGuide, GuideSourceSnapshot, submission-artifact, + effective, checker, review, revision and legacy payment-policy rows in the + existing REV order; then the active compensation selector, + CompensationPolicyVersion and referenced CompensationAdapterBinding rows; +7. WorkstreamTask, TaskAssignment, Submission, CheckerRun, + RevisionContextPreparation, ReviewQueueEntry, ReviewLease, + ReviewReconciliationFinding and prior Review/finding rows in REV order; +8. stabilized ArtifactBinding/Replica facts without remote provider I/O; +9. ContributionRecord, CompensationAward, delivery, receipt and projection rows + in WS-CON order; +10. append-only audit and shared-outbox rows after all state locks. + +Multiple same-type rows are locked by ascending primary key/UUID. Operations +skip absent classes but never reorder shared classes. + +No feature may reverse this order. Publish, retire, binding suspend/resume/ +retire, assignment claim, review claim, delivery, callback, reconciliation, and +projection rebuild revalidate authority after acquiring their relevant locks. +Freezing requires a published version whose referenced bindings are active. +Suspension blocks new freezes and new delivery but does not erase already-frozen +obligations; exact callback/replay behavior is state-matrix controlled. Real +PostgreSQL tests cover publish/suspend versus both claim types and suspend/ +retire versus dispatch/callback in both lock permutations. + +The dispatcher claim is a separate, previously committed CON-02B transaction. +It releases its session and every database lock before invoking a feature +handler. The handler starts a new caller transaction, acquires the lifecycle +fence/phase, validates the supplied claim generation through the typed outbox +capability without locking or mutating the OutboxEvent, and only then locks CON +rows. It commits durable pre-I/O state and releases the transaction/fence before +remote I/O. Only the dispatcher later applies the handler's typed outcome to +outbox retry/finalization state. + +### Artifact evidence + +The Review transaction creates only a pending contribution-evidence projection +row and a shared-outbox wake-up event. After commit, a worker loads canonical +PostgreSQL records, produces deterministic canonical JSON, and hands prepared +bytes plus exact contribution facts to an ART-owned typed capability. ART owns +admission, raw provider I/O, verification, content/binding/receipt records, and +recovery. WS-CON stores only its projection state and verified Workstream +binding reference. + +LocalStorage and MinIO exercise the same product capability contract. AWS S3 +deployment proof gates production. Flow Node, R2, semantic search, provider +retain/pin APIs, and raw provider refs are excluded. + +### Shared outbox + +Land one generic PostgreSQL outbox before contribution integration. CON-02A +owns persistence/caller-transaction append. CON-02B owns the feature-neutral +Celery dispatcher, claim fencing, stable task IDs, retry/dead-letter/replay, +retention, operational recovery, a single explicit handler registry, and the +read-only same-session `OutboxDrainObservationPort` plus +`OutboxClaimValidationPort`. Feature handlers own deterministic delivery +semantics, never dispatch infrastructure or repository queries. + +## Alternatives considered + +### Edit the supplied reference pair in place + +Rejected because reference inputs are provenance evidence, the original PDF is +already checksum-bound, and the revised PDF is not a declared reproducible +Markdown build. Preserve generations and create an active reconciled spec. + +### Replace broad PermissionIds with granular strings + +Rejected because the merged AUTH contract preserves 74 stable PermissionIds +and separately stages 50 planned ActionIds. Granular action names do not replace +permissions. + +### Reuse `PaymentPolicy` directly as the award policy + +Rejected because it is guide-version-bound, submitter-oriented, and cannot +represent reviewer compensation, explicit unpaid rules, points, bindings, or +immutable publication lifecycle without becoming a second incompatible model. + +### Retain `PaymentPolicy` as advisory or historical context + +Rejected by the human. CompensationPolicyVersion supersedes it. A two-step +expand/contract removal keeps the semantic cutover atomic in CON-05A and drops +the unreachable physical schema in CON-05B; neither step exposes a fallback. + +### Call ArtifactStore from contribution workers + +Rejected by ADR 0013/0014 because it bypasses ART admission, verification, +binding, receipts, recovery, and composition ownership. + +### Implement ContributionRecordRequested first + +Rejected because the approved REV/CON seam is direct atomic participation in +the Review transaction. A temporary event would create a partial-history risk. + +### Publish partial APIs early + +Rejected because action activation, policy freeze, callback service identity, +review atomicity, and artifact capabilities must fail closed as one coherent +backend contract. + +## Boundaries preserved + +- Auth/session: external tokens are verified by existing issuer adapters; + WS-AUTH alone owns product authorization and service actors. +- Permission/policy: WS-CON supplies resource facts/guards but never edits + grants or implements an authorization kernel. +- Payment/execution: Workstream records awards/instructions/receipts; external + adapters own provider attempts, approvals, balances, and ledgers. +- Persistence/data: PostgreSQL owns canonical contribution/award/receipt truth; + provider bytes are never canonical product state. +- Presentation/API: `/api/v1`; deterministic concealment and pagination; no + provider refs, tokens, or credentials. +- CI/deployment: no threshold weakening; no new production provider or + dependency without explicit approval. + +## Rollout/migration strategy + +1. Adopt the ADR-backed active contract while preserving both archival + generations. The same chunk adds only the exact renamed generation-2 + Markdown path to the stale-authorization scanner's reviewed history map, + with near-miss/new-document fail-closed regression proof; the active spec + remains scanned. Its gate test repairs the existing cross-scanner set + comparison by subtracting only this authorization-only path and proves the + artifact scanner already excludes it through the reference-spec prefix; the + artifact scanner itself is unchanged. +2. Merge outbox persistence then its feature-neutral dispatcher; add split, + inactive binding/policy/contribution/award/delivery/receipt persistence. +3. Merge required AUTH ActionId/PermissionId registrations and exact service + action assignments in the AUTH initiative; merge required ART capabilities + in ART. Feature chunks then activate only their own registered actions with + resource composers and behavioral proof. +4. Activate hidden binding/policy services. CON-05A atomically removes every + PaymentPolicy semantic consumer and enables only task claims that freeze a + CompensationPolicyVersion, only after merged REV-02 establishes the exact + `Submission.task_assignment_id` lineage. CON-05B drops the unreachable old + model/table/columns/constraints after a zero-consumer scan. +5. Interleave with WS-REV: policy schema before REV lease schema; lease freeze + before claims; atomic participant after revision/decision persistence. +6. Add delivery/callback, evidence projection, reads, and operations behind + unregistered production routes. +7. Finish WS-CON hidden readiness and an exact dependency manifest. WS-REV-13 + is the sole production router activation and joint live-drill owner for the + review/contribution/compensation release. Before it, REV-12A may own hidden + persisted joint release control and inject its implementation through the + required CON-owned dispatch/callback fence ports while consuming the + read-only fulfillment-drain observation port; it may not edit CON product + files or import CON/outbox repositories. + The content-reviewed sibling working delta atop `3e09e99` currently matches + this boundary except for the recorded shared-outbox claim-wording repair. The + exact repaired snapshot must become a branch-reachable commit, pass + commit-bound freshness review, preserve the boundary through refresh, and + merge before it is a consumable dependency. Do not change archival sources. + +At every chunk activation, rebase discovery on trusted `main`, refresh exact +migration numbers and dependency symbols, and stop if an expected port/action +is absent or materially changed. + +## Verification strategy + +- Ruff and focused unit/service tests for every chunk. +- Every runtime chunk uses `scripts/run_isolated_tests.py` with one unique, + attempt-specific metadata JSON retained under the initiative evidence + directory and same-invocation `pytest --cov=app --cov-fail-under=78`; stale + `.coverage` output is never evidence. Focused reports from that invocation + prove each new/materially changed subsystem is at least 90 percent. +- Fresh isolated real-PostgreSQL tests cover migrations, constraints, + transaction rollback, idempotency, and both concurrency permutations. +- New/materially changed module coverage at or above 90 percent; same-run + repository coverage at or above 78 percent. +- OpenAPI action inventory requires one ActionId per protected surface and + proves hidden routes remain absent before final activation. +- Static architecture tests reject AUTH persistence imports, local role checks, + provider-specific compensation adapters, concrete-adapter imports or + construction outside the explicit composition root, raw ArtifactStore + injection, provider refs, and duplicate outbox implementations. The + deterministic conformance adapter is allowed only through the shared typed + factory and explicit composition. +- Contract tests prove proposed ActionId -> PermissionId parity with the merged AUTH + catalogue and stable event payload/digest identity. +- LocalStorage and MinIO evidence-capability conformance; AWS deployment proof + remains owned by ART. +- Final live drill covers paid accept, needs revision, reject, unpaid policy, + frozen-version change, money+points, acknowledgement vs fulfillment, + failure-then-fulfillment, replay, adapter outage, storage outage, recovery, + authorization denials, atomic rollback, and reconciliation. +- `CONFORMANCE_MATRIX.md` maps every adopted candidate invariant to an owning + chunk, executable case, final live case, and retained evidence; activation + replaces proposed names with collected test node IDs. +- Stale wording scan, Markdown links, reference checksums, `git diff --check`, + and one-sheet roadmap checks when sheets are present. + +## Review strategy + +Planning and every specification/runtime chunk require senior engineering, +QA/test, security/auth, product/ops, architecture, docs, and reuse/dedup. +Runtime/test chunks add test-delta. Outbox/worker/script/config/CI changes add CI +integrity. Critical/High findings block; Medium findings require human decision. + +## Sequencing + +See `CHUNK_MAP.md`. Only one WS-CON chunk is active at a time. Cross-initiative +gates do not authorize another initiative's work and no successor starts +without a new explicit human instruction. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md new file mode 100644 index 00000000..50152ce8 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -0,0 +1,21 @@ +# Risks: WS-CON-001 Contribution Record And Compensation Boundary + +| Risk | Severity | Mitigation | Owner | Status | +|---|---|---|---|---| +| Candidate spec replaces canonical API/permission/storage rules | Critical | Preserve as input; reconcile into active spec with ADR precedence and exact scans. | WS-CON-001-01 | Open | +| Dual `PaymentPolicy` and `CompensationPolicyVersion` truth | Critical | D2 approved complete removal; 05A cuts all consumers atomically and 05B drops schema under a zero-consumer scanner. | WS-CON-001-05A/B | Direction resolved; implementation open | +| Existing rows lack safe frozen compensation refs | High | CON-05A classifies/drains or approved-backfills; migration fails on ambiguity and never guesses conversion. | Human / WS-CON-001-05A | Legacy rule decision needed | +| Bound adapter callback lacks a safe current service permission | Critical | AUTH-owned additive service-only PermissionId/action, fixed actor, exact binding guards. | WS-AUTH | Open | +| Shared outbox dispatcher borrows human retry/reconciliation authority | Critical | Add service-only `outbox.dispatch`, fixed dispatcher assignment, and claimed-command generation guards in CON-02B; CON-08A is only a handler. | WS-AUTH / WS-CON-001-02B | Open | +| Review/CON circular dependency | High | Interleaved gates: policy schema -> lease schema -> freeze -> claims -> participant -> integration. | WS-CON / WS-REV | Mitigated in plan | +| Partial Review/contribution/economic commit | Critical | Caller-owned session, shared lock order, DB constraints, fault injection, exact replay. | WS-CON-001-07 / WS-REV | Open | +| Direct provider call bypasses ART controls | Critical | Named `WS-ART-001-CON-EVIDENCE` capability prerequisite; import/composition tests reject raw store/provider access. | WS-ART / WS-CON-001-09A | Open | +| Outbox duplication or loss | High | 02A owns truth/append; 02B alone owns dispatch/retry/replay with stable identities. | WS-CON-001-02A/B | Open | +| Human role or token claims leak into feature authorization | Critical | Central AUTH service only; no grant queries/local role checks; deny/race tests. | WS-AUTH / all WS-CON | Open | +| Provider payment logic leaks into Workstream | High | Typed instruction/ack/receipt contract; provider attempts/balances/ledger prohibited. | WS-CON-001-08A/B | Open | +| Fulfilled state regresses or duplicates | High | Immutable receipts, unique fulfilled row, row locks, exact callback idempotency. | WS-CON-001-08B | Open | +| Lifecycle disable races adapter I/O or authenticated callback | Critical | CON-owned mandatory dispatch/callback fence ports, durable pre-I/O in-flight state, same-session drain observations, REV-12A exclusive transition lock, and both-order PostgreSQL tests. | WS-CON-001-03D/08A/08B/10B/11 + WS-REV-001-12A | Open | +| Artifact outage changes contribution truth | High | Projection is post-commit/rebuildable; canonical records never depend on provider availability. | WS-CON-001-09A | Open | +| Sensitive financial/provider/token data leaks | Critical | Bounded schemas, redaction, no human-token forwarding, no provider refs in APIs/events. | Security review | Open | +| Public routes expose partial system | High | CON-11 proves hidden readiness; REV-13 alone registers the joint surface. | WS-CON-001-11 / WS-REV-001-13 | Open | +| Initiative becomes unreviewable | High | One PR-sized chunk, circuit-breaker, explicit stop after each. | Primary agent / human | Mitigated in plan | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md new file mode 100644 index 00000000..80aefb56 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md @@ -0,0 +1,48 @@ +# Runtime Verification Contract: WS-CON-001 + +Every runtime chunk executes this template exactly after replacing +`` and `` with its row. It then runs one separate focused +report command for every concrete subsystem pattern in that row. The initial +erase, isolated PostgreSQL run, repository threshold, and all focused reports +are one evidence run; a pre-existing `.coverage` file is never accepted. + +```bash +ATTEMPT_ID="${ATTEMPT_ID:-$(date -u +%Y%m%dT%H%M%SZ)-$$}" +EVIDENCE_JSON="$(pwd)/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/evidence/-${ATTEMPT_ID}-isolated-tests.json" +mkdir -p "$(dirname "$EVIDENCE_JSON")" +test ! -e "$EVIDENCE_JSON" +(cd backend && .venv/bin/python -m coverage erase) +(cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$EVIDENCE_JSON" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78) +(cd backend && .venv/bin/python -m coverage report --include='' --fail-under=90) +(cd backend && .venv/bin/ruff check ) +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +git diff --check +``` + +| Chunk | Separate focused subsystem reports (one `coverage report` per entry) | `` | +|---|---|---| +| CON-02A | `app/modules/outbox/*` | `app/modules/outbox app/db/models.py tests/test_outbox.py alembic/versions/.py` | +| CON-02B | `app/modules/outbox/*`; `app/workers/outbox.py` | `app/modules/outbox app/workers/outbox.py app/workers/celery_app.py app/core/config.py tests/test_outbox.py tests/test_config.py` | +| CON-02C | `app/modules/audit/*` | `app/modules/audit tests/test_audit.py` | +| CON-03A | `app/modules/compensation/*` | `app/modules/compensation app/db/models.py tests/test_compensation.py alembic/versions/.py` | +| CON-03B | `app/modules/compensation/*` | `app/modules/compensation app/modules/projects/models.py app/db/models.py tests/test_compensation.py tests/test_projects.py alembic/versions/.py` | +| CON-03C | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation app/db/models.py tests/test_contributions.py tests/test_compensation.py alembic/versions/.py` | +| CON-03D | `app/modules/compensation/*` | `app/modules/compensation app/db/models.py tests/test_compensation.py alembic/versions/.py` | +| CON-04A | `app/modules/compensation/*` | `app/modules/compensation app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-04B | `app/modules/compensation/*` | `app/modules/compensation app/modules/projects/repository.py app/composition/compensation.py tests/test_compensation.py tests/test_projects.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-05A | `app/modules/compensation/*`; `app/modules/projects/*`; `app/modules/tasks/*`; `app/modules/checkers/*` | `app/modules/compensation app/modules/projects app/modules/tasks app/modules/checkers app/db/models.py tests/test_compensation.py tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_authorization.py tests/test_alembic.py tests/test_api_contract_e2e.py alembic/versions/.py` | +| CON-05B | `app/modules/projects/models.py`; `app/modules/tasks/models.py`; `app/modules/checkers/models.py`; `app/db/models.py` | `app/modules/projects/models.py app/modules/tasks/models.py app/modules/checkers/models.py app/db/models.py tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_alembic.py alembic/versions/.py` | +| CON-06 | `app/modules/compensation/*` | `app/modules/compensation tests/test_compensation.py tests/test_authorization.py` | +| CON-07 | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py` | +| CON-08A | `app/modules/compensation/*`; `app/workers/compensation.py`; `app/interfaces/compensation.py`; `app/adapters/compensation/*` | `app/interfaces/compensation.py app/adapters/compensation app/modules/compensation app/modules/outbox/handlers.py app/workers/compensation.py app/workers/celery_app.py app/composition/compensation.py tests/test_compensation.py tests/test_outbox.py tests/test_external_service_adapters.py` | +| CON-08R | `app/modules/api_controls/*`; `app/api/deps/api_controls.py`; `app/core/config.py` | `app/modules/api_controls app/api/deps/api_controls.py app/core/config.py tests/test_api_rate_controls.py tests/test_config.py tests/test_alembic.py alembic/versions/.py` | +| CON-08B | `app/modules/compensation/*` | `app/modules/compensation app/api/internal_compensation.py app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-09A | `app/modules/contributions/*`; `app/workers/contribution_evidence.py` | `app/modules/contributions app/modules/outbox/handlers.py app/workers/contribution_evidence.py app/workers/celery_app.py tests/test_contributions.py tests/test_artifacts.py tests/test_outbox.py` | +| CON-09B | `app/modules/contributions/*` | `app/modules/contributions app/api/internal_contributions.py app/composition/contributions.py tests/test_contributions.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-10A | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation app/api/internal_contributions.py app/api/internal_compensation.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-10B | `app/modules/contributions/*`; `app/modules/compensation/*`; `app/modules/audit/*` | `app/modules/contributions app/modules/compensation app/modules/audit app/api/internal_operations.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py tests/test_audit.py` | +| CON-11 | `app/modules/contributions/*`; `app/modules/compensation/*`; `app/modules/outbox/*`; `app/modules/audit/*`; `app/modules/api_controls/*`; `app/api/deps/api_controls.py`; `app/core/config.py`; `app/modules/projects/*`; `app/modules/tasks/*`; `app/modules/checkers/*`; `app/interfaces/compensation.py`; `app/adapters/compensation/*`; `app/workers/outbox.py`; `app/workers/compensation.py`; `app/workers/contribution_evidence.py`; `app/composition/contributions.py`; `app/composition/compensation.py`; `app/composition/outbox.py`; `app/api/internal_contributions.py`; `app/api/internal_compensation.py`; `app/api/internal_operations.py` | `app/composition/contributions.py app/composition/compensation.py app/composition/outbox.py tests/test_api_contract_e2e.py tests/test_authorization.py tests/test_contributions.py tests/test_compensation.py tests/test_outbox.py tests/test_audit.py` | + +If a named path differs after prerequisite merges, the chunk stops and its +contract is re-reviewed; it may not silently broaden a glob or skip the target. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md new file mode 100644 index 00000000..8ec5d151 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -0,0 +1,67 @@ +# Source Manifest: WS-CON-001 Contribution Record And Compensation Boundary + +## Primary revised inputs under review + +| File | SHA-256 | Status | +|---|---|---| +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md` | `cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640` | Editable reconciled working transcription derived from generation-2 PDF; not archival and not canonically adopted | +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf` | `ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457` | Revised archival companion; text extracted and structurally inspected; not a reproducible Markdown build contract | + +## Original immutable input + +| File | SHA-256 | Status | +|---|---|---| +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf` | `34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1` | First archival generation supplied 2026-07-11; currently deleted in the pre-existing user worktree and not modified/restored by this audit | + +## Normative repository constraints + +- `AGENTS.md` +- `README.md` +- `docs/architecture_lockdown.md` +- `docs/decision_0005_postgres_is_the_record_database.md` +- `docs/decision_0007_async_first_execution.md` +- `docs/decision_0009_review_decisions_are_canonical.md` +- `docs/decision_0010_revision_context_rebase.md` +- `docs/decision_0012_workstream_authorization_service.md` +- `docs/decision_0013_immutable_artifact_storage_boundary.md` +- `docs/decision_0014_external_service_adapter_convention.md` +- `docs/spec_authorization_service.md` +- `docs/spec_artifact_storage_service.md` +- `.agent-loop/policies/*` + +## Parallel dependency sources inspected + +- trusted authorization worktree and `origin/main` at + `e9d72a16d95e704f2af514a97d37623940854d95`, which merges AUTH-07A through + PR #126 +- merged AUTH-07A catalogue implementation `3ab25cf`, now canonical on trusted + `main` with 74 PermissionIds, 50 planned ActionIds, and no WS-CON ActionIds or + service-only delivery/fulfillment permissions +- `/home/abiorh/flow/workstream-auth-001-07/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/` +- active sibling REV worktree `/home/abiorh/flow/workstream-rev-001/`, observed + at branch-reachable head `3e09e994d500cd45916b449d7bc4f13b7623cdcc` + on `2026-07-15T17:48:19+01:00`, plus an uncommitted initiative delta. The + branch head integrates trusted `main` `e9d72a1`. The + delta introduces REV-12A hidden joint release control, preserves REV-13 as + sole production activation, consumes the proposed CON-owned dispatch and + callback fences plus fulfillment-drain observation only through composition, + and retains the complete PaymentPolicy removal/CON-11 gates. All required + content-review tracks pass in the sibling evidence, but the reviewed snapshot + and reference changes remain dirty. No dependency SHA is claimed. The exact + reviewed delta must become a branch-reachable commit, pass commit-bound + freshness review, refresh against trusted main, and merge before it is + consumable. The sibling's revised reference Markdown/PDF remain separate + worktree-only discovery inputs alongside pre-existing original-reference + deletions. +- trusted `main` at `e9d72a16d95e704f2af514a97d37623940854d95`, including the + merged ADR 0014 `ExternalServiceAdapterFactory[TAdapter]` foundation from PR + #127 and the AUTH-07A catalogue/audit foundation from PR #126. + +These sibling worktrees are discovery evidence, not dependencies by path. Every +implementation chunk consumes only contracts merged into trusted `main`. + +## Adoption note + +The revised pair contains valuable domain invariants but is not the repository's +active runtime contract. Chunk 01 will preserve both source generations and +write the reconciled active specification/ADR after explicit human approval. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md new file mode 100644 index 00000000..70e0c703 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -0,0 +1,52 @@ +# Status: WS-CON-001 Contribution Record And Compensation Boundary + +## Current status + +Planning amendment under internal review. Application code is unchanged. The supplied revised Markdown/PDF, +original archival PDF, current backend, active docs, parallel WS-AUTH +authorization catalogue, and parallel WS-REV plan have been mapped. + +The candidate cannot be canonically adopted as written because it conflicts +with `/api/v1`, the ActionId/PermissionId model, artifact-storage ownership and +providers, existing versioned `Submission`, and active payment architecture. + +## Active chunk + +`WS-CON-001-PLAN` only. The human approved complete PaymentPolicy removal on +2026-07-15; the resulting plan amendment requires reviewer closure. No +implementation is active. + +## Chunk status + +| Chunk | Status | Branch | PR | Notes | +|---|---|---|---:|---| +| `WS-CON-001-PLAN` | D2 removal amendment review pending | `codex/ws-con-001-plan` | - | Prior review predates the approved removal direction. | +| `WS-CON-001-01` | Proposed | - | - | No runtime work. | +| `WS-CON-001-02A` through `11` | Proposed | - | - | Each requires separate explicit start; REV-13 owns final activation. | + +## Blockers + +| Blocker | Owner | Next action | +|---|---|---| +| Active-contract/archive handling approval | Human | Approve D1. | +| PaymentPolicy/CompensationPolicy authority relationship | Human | D2 approved: complete removal; only legacy reset/backfill rule remains. | +| Exact WS-CON action registrations plus callback and shared-outbox service permissions | WS-AUTH + human | Approve dependency proposal; implement only in AUTH-owned chunk. | +| Contribution evidence typed capability | WS-ART + human | Create and approve the named `WS-ART-001-CON-EVIDENCE` prerequisite before CON-09A. | +| ReviewLease/Review contracts | WS-REV | Merge owning persistence/behavior chunks at declared gates. | +| Shared outbox | WS-CON-001-02A/B after approval | Land persistence and dispatcher before asynchronous integration. | +| Current REV-13 scope omits the joint CON surface/docs/drill | WS-REV owner + human | Incorporate and review `JOINT_RELEASE_HANDOFF.md`; both surfaces stay hidden until then. | +| Exact-head evidence gate requires a committed candidate | Primary agent after human publication direction | Do not claim PR readiness; commit only when authorized, rerun reviewers, and require the gate to pass. | + +## Follow-ups + +| Item | Source | Priority | +|---|---|---:| +| Re-read AUTH-07A/07B and later merged catalogue at each activation. | Parallel worktree | P1 | +| Re-read REV contracts at CON-03C/06/07 activation. | Parallel worktree | P1 | +| Re-read ART v2/capability ports before CON-09A. | ADR 0013/spec | P1 | +| Decide pre-production row rebuild vs classified backfill. | Migration risk | P1 | + +## Stop condition + +Do not edit runtime code or start `WS-CON-001-01` from this planning turn. +Present the plan, risks, and human decisions, then wait for explicit approval. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md new file mode 100644 index 00000000..58b88402 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -0,0 +1,141 @@ +# Chunk Contract: WS-CON-001-01 - Canonical Contract Adoption And Architecture Decision + +## Parent initiative + +`WS-CON-001` - Contribution Record And Compensation Boundary + +## Goal + +Preserve both WS-CON archival generations and adopt one ADR-backed active +repository specification reconciled with AUTH, ART, REV, `/api/v1`, existing +Submission identity, and payment-policy reality. + +## Why this chunk exists + +The revised candidate contains correct domain intent and incorrect executable +contracts. Runtime chunks need one active source of truth before schema work. + +## Approved plan reference + +- `../INTENT.md` +- `../PLAN.md` +- `../CHUNK_MAP.md` + +## Risk class + +L0 architecture direction executed as an L1 specification chunk; SLA P1. + +## Allowed files + +```text +docs/reference_specs/README.md +docs/reference_specs/SHA256SUMS +docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf +docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md only for a byte-preserving rename +docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).md +docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf +docs/spec_contribution_compensation.md +docs/decision_0015_contribution_compensation_boundary.md +README.md only for one active-spec link/precedence note +scripts/check_stale_authorization_docs.py only for the exact generation-2 + archival Markdown classification +scripts/test_agent_gates.py only for the exact archival-classification + fail-closed regression and the existing cross-scanner history-set assertion +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-01.json +``` + +The original and second-generation reference bytes are allowed only for +restoration/filename normalization that preserves their recorded hashes; their +contents are not editable. + +## Not allowed + +```text +backend runtime, migrations, backend tests, workflows, dependencies +AUTH/ART/REV owned specifications or catalogues +permission/action activation +roadmap or broad operational-doc rewrite +``` + +## Acceptance criteria + +- [ ] Original PDF is restored at exact hash `34c433...66c1`. +- [ ] Revised candidate pair has distinct generation-2 names and exact recorded + hashes; the original eight checksum entries remain unchanged and additive + generation-2 provenance/checksums describe the pair without calling it + executable. The current Markdown path may only be deleted as one side of a + byte-preserving Git rename. +- [ ] Only after the byte-preserving rename and hash proof, the exact renamed + path + `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).md` + is added to `HISTORICAL_PATHS` with an explicit immutable/reconciled archival + candidate rationale. The active `docs/spec_contribution_compensation.md` + remains scanned; the deleted unsuffixed working path is not allowlisted; and + arbitrary new documents or near-miss sibling filenames continue to fail + closed under gate regression tests. +- [ ] The existing authorization/artifact historical-set regression subtracts + only that named authorization-only path before comparing exact sets, then + separately proves the artifact scanner already classifies the renamed path as + historical through its `docs/reference_specs/` prefix. Do not edit the + artifact scanner or duplicate this path in its exact-path set. +- [ ] ADR 0015 resolves immutable contribution/award/receipt meaning, + PaymentPolicy versus CompensationPolicyVersion authority, external + fulfillment, shared outbox, review atomicity, and artifact ownership. +- [ ] ADR/spec defines the exact project setup handoff: Project Manager records + guide/business terms; Finance Authority creates a canonical adapter binding + and publishes the executable policy; new assignment/lease fails with stable + remediation when setup is absent, suspended, retired, contradictory, or + incomplete. Missing setup is never silently unpaid. +- [ ] ADR adopts complete PaymentPolicy removal: CON-05A atomically removes all + semantic consumers while cutting task claims to the frozen replacement; + CON-05B physically removes dead schema after the zero-consumer and approved + legacy-data gates pass. No advisory runtime/API fallback survives. +- [ ] Active spec uses `/api/v1`, existing `Submission`, AWS/MinIO/LocalStorage + roles, typed ART capabilities, and exact ActionId -> PermissionId language. +- [ ] Active spec contains no `WS-AUTH-001-A`, `review.decision.record`, + `artifact.recovery.request`, `artifact.recovery.execute`, `artifact.retrieve`, + `ArtifactStorePort`, production Flow Node/R2, or broad-permission removal. +- [ ] Active spec declares AUTH/ART/REV/outbox prerequisites and no local auth + implementation. +- [ ] Required specification reviewers pass. +- [ ] `CONFORMANCE_MATRIX.md` maps every retained normative invariant to its + owning chunk, concrete behavioral case, and final evidence owner; no blanket + or unowned requirement remains. +- [ ] Every README-linked active document and generated companion containing + mutable PaymentRecord, accept-only/voidable contribution, automatic + reputation, or PaymentPolicy execution language is inventoried in the + conformance matrix. The scan also covers active templates and operations docs + even when not README-linked, and emits the exact REV-13 allowed-file inventory. + Historical review/reference evidence stays untouched. + +## Verification commands + +```bash +sha256sum -c docs/reference_specs/SHA256SUMS +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +python3 scripts/test_agent_gates.py +python3 -m py_compile scripts/check_stale_authorization_docs.py scripts/test_agent_gates.py +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +rg -n '(^|[^[:alnum:]_/])/v1|WS-AUTH-001-A|review\.decision\.record|artifact\.recovery\.(request|execute)|artifact\.retrieve|ArtifactStorePort|production Flow Node' docs/spec_contribution_compensation.md +git diff --check +``` + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +reuse/dedup, test-delta, and CI integrity. + +## Human review focus + +ADR load-bearing decisions, archive provenance, the exact and fail-closed +historical-path classification, sole compensation authority, +ActionId/PermissionId mapping, and strict ownership exclusions. + +## Stop conditions + +Stop if active adoption requires editing archival bytes, implementing AUTH/ART +behavior, or choosing a legacy-data migration not approved by the human. +Stop after merge/memory; do not start 02 automatically. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md new file mode 100644 index 00000000..f3a81b75 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md @@ -0,0 +1,43 @@ +# Chunk Contract: WS-CON-001-02A - Shared Transactional Outbox Persistence + +## Goal and risk + +Land feature-neutral PostgreSQL outbox truth and caller-transaction append only. +L1 infrastructure/audit/data risk. + +## Allowed files + +```text +backend/app/modules/outbox/{__init__,models,schemas,repository,service}.py +backend/app/db/models.py +backend/alembic/versions/_shared_transactional_outbox.py +backend/tests/{test_outbox,test_alembic}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-02A.json +``` + +## Not allowed + +```text +Celery/dispatcher/handler/route changes +review, contribution, compensation, AUTH, ART, task or project behavior +new JSON canonicalizer, idempotency framework, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Immutable event identity/type/version/project/correlation/causation, + canonical payload/digest, idempotency key and occurrence time are separate + from mutable delivery state. +- [ ] Reuse `app.core.hashing.canonical_json_hash` and the existing + reserve/lock/complete idempotency shape; no second canonicalizer/framework. +- [ ] Caller AsyncSession append flushes but never commits/publishes; changed + payload under one identity conflicts; PostgreSQL proves duplicate races. +- [ ] No Celery, handler, broker, review, or compensation behavior is added. + +## Verification and reviewers + +Execute the exact CON-02A expansion in `../RUNTIME_VERIFICATION.md`. +Same-run outbox coverage is at least 90 percent. Baseline plus architecture, +security/auth, product/ops, docs, reuse/dedup, test-delta, and CI integrity. +Stop before dispatcher behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md new file mode 100644 index 00000000..41d1162a --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md @@ -0,0 +1,70 @@ +# Chunk Contract: WS-CON-001-02B - Shared Outbox Dispatcher And Recovery + +## Goal and risk + +Implement the one feature-neutral outbox dispatcher and operational recovery. +L1 worker/operations/infrastructure risk. + +## Allowed files + +```text +backend/app/modules/outbox/{models,schemas,repository,service,ports,dispatcher,handlers}.py +backend/app/workers/celery_app.py +backend/app/workers/outbox.py +backend/app/core/config.py only bounded dispatcher settings +backend/tests/test_outbox.py +backend/tests/test_config.py only dispatcher-setting coverage +docs/operations_outbox.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-02B.json +``` + +## Not allowed + +```text +backend/app/workers/async_runner.py or task_settings.py rewrites +feature callback/adapter, review or compensation behavior +second dispatcher/handler registry/async bridge/session factory/idempotency framework +dependency, workflow, test or coverage weakening +``` + +## Acceptance criteria + +- [ ] One explicit handler registry, stable Celery task IDs, fenced claim, + attempt, retry schedule, dead-letter, replay, retention and bounded recovery + preserve immutable event identity. +- [ ] The shared dispatcher alone mutates outbox claim, lease/generation, + retry/dead-letter and finalization state. Feature handlers receive an already + claimed immutable command and return a typed success/retry/terminal outcome; + they never claim or directly transition the OutboxEvent. +- [ ] Claim reservation commits and releases its session and every row/database + lock before handler invocation. The immutable handler command carries exact + event/claim generation, but no live ORM row or caller session. +- [ ] A read-only same-session `OutboxClaimValidationPort` lets a handler verify + that exact generation after acquiring its lifecycle fence and before locking + feature rows. It never locks or mutates OutboxEvent state and exposes no + repository; the dispatcher revalidates again when applying the typed outcome. +- [ ] Reuse `run_async_task`, current fresh-engine/session-disposal worker + pattern, existing Celery include list and `sync_task_settings`; no second async + bridge, session factory, handler registry, scheduler, or idempotency framework. +- [ ] Crash-before/after handler, stale completion, duplicate task, retry + exhaustion and reason-bound replay are real-PostgreSQL tested. +- [ ] A feature-neutral same-session `OutboxDrainObservationPort` reports + bounded counts by exact registered event type/handler and closed delivery + states, including pending, claimed, retryable and handler-in-flight work. It + is read-only, never commits or invokes a handler, and exposes neither the + repository nor mutable outbox rows. +- [ ] Observation races claim, stale-claim recovery, retry, dead-letter and + finalization in both orders without false zero. Feature modules may compose + the port with their own canonical state but may not extend its status model or + query outbox persistence directly. +- [ ] Handler invocation occurs after commit; no feature event semantics or + compensation adapter is implemented here. + +## Verification and reviewers + +Execute the exact CON-02B expansion in `../RUNTIME_VERIFICATION.md`. Same-run +changed-subsystem coverage is at +least 90 percent. All baseline tracks plus architecture, security/auth, +product/ops, docs, reuse/dedup, test-delta and CI integrity. Stop before feature +handlers. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md new file mode 100644 index 00000000..3807f328 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md @@ -0,0 +1,43 @@ +# Chunk Contract: WS-CON-001-02C - Shared Lifecycle Audit Participant + +## Goal and risk + +Extend the existing shared AuditEvent repository/service with one typed +caller-transaction lifecycle participant required by REV and CON. L1 audit/ +cross-domain-transaction risk. + +## Allowed files + +```text +backend/app/modules/audit/{schemas,repository,service}.py +backend/tests/test_audit.py +docs/architecture_data_model.md only exact shared-audit ownership note +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-02C.json +``` + +## Not allowed + +```text +AuditEvent schema/migration rewrite +review, contribution, compensation, task, AUTH or outbox event semantics +commit ownership, route, worker, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Typed `LifecycleAuditParticipant` accepts caller AsyncSession and bounded + canonical event input, reuses AuditRepository, flushes, and never commits. +- [ ] It preserves append-only AuditEvent identity and rejects credentials, + tokens, provider refs, unbounded payloads and caller-supplied authority facts. +- [ ] Caller rollback removes audit with all other transaction effects; exact + replay/idempotency ownership is explicit and no second audit ledger appears. +- [ ] REV-04 and CON-07 may depend on the merged interface without importing + feature services; this chunk implements no feature-specific event. + +## Verification and reviewers + +Execute CON-02C in `../RUNTIME_VERIFICATION.md`; changed audit code is at least +90 percent. Senior engineering, QA/test, security/auth, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop after the +feature-neutral participant. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md new file mode 100644 index 00000000..da475230 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md @@ -0,0 +1,43 @@ +# Chunk Contract: WS-CON-001-03A - Compensation Adapter-Binding Persistence + +## Goal and risk + +Persist immutable binding identity/lifecycle without adapter behavior. L1 +payment/auth/data risk. + +## Allowed files + +```text +backend/app/modules/compensation/{__init__,models,schemas,repository}.py +backend/app/db/models.py +backend/alembic/versions/_compensation_adapter_bindings.py +backend/tests/{test_compensation,test_alembic}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-03A.json +``` + +## Not allowed + +```text +AUTH actor/grant/action-assignment edits +adapter, route, worker, policy, award, receipt or delivery behavior +credentials, secrets, raw provider refs, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Binding stores project, instrument, typed capability, canonical + `adapter_actor_id`, non-secret route identity, state/version and immutable + lifecycle timestamps; credentials/provider refs are impossible. +- [ ] Composite constraints preserve project/instrument ownership and valid + active/suspended/retired transitions. +- [ ] Schema supports the callback guard but creates no ActorProfile, grant, + action assignment, adapter, route, or delivery behavior. +- [ ] Upgrade/downgrade and duplicate/state races use isolated PostgreSQL. + +## Verification and reviewers + +Execute the exact CON-03A expansion in `../RUNTIME_VERIFICATION.md`; changed +compensation code is at least 90 percent. Senior engineering, QA/test, +security/auth, product/ops, architecture, docs, reuse/dedup and test-delta are +required. Stop after schema. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md new file mode 100644 index 00000000..619562de --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md @@ -0,0 +1,42 @@ +# Chunk Contract: WS-CON-001-03B - Compensation Policy Persistence + +## Goal and risk + +Persist draft/published/retired policy versions and Project active selector +without commands. L1 payment/data risk. + +## Allowed files + +```text +backend/app/modules/compensation/{models,schemas,repository}.py +backend/app/modules/projects/models.py only active compensation selector +backend/app/db/models.py +backend/alembic/versions/_compensation_policy_versions.py +backend/tests/{test_compensation,test_projects,test_alembic}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-03B.json +``` + +## Not allowed + +```text +service, route, claim, award, adapter, AUTH or ART behavior +PaymentPolicy fallback or historical-row rewrite +public API, worker, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Exact decimals/currency/points, explicit unpaid, contribution matching, + binding IDs, provenance and immutable publication lifecycle are constrained; + at most one money plus one points award exists per rule. +- [ ] Active selector references one same-project published version; published + content is immutable; missing policy has no fallback. +- [ ] Legacy classification follows D2/CON-05 and rewrites no history. +- [ ] Upgrade/downgrade and selector/version races use isolated PostgreSQL. + +## Verification and reviewers + +Execute CON-03B in `../RUNTIME_VERIFICATION.md`; changed subsystems are at least +90 percent. Senior engineering, QA/test, security/auth, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop after schema. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md new file mode 100644 index 00000000..7b575a79 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md @@ -0,0 +1,42 @@ +# Chunk Contract: WS-CON-001-03C - Contribution And Award Persistence + +## Goal and risk + +Persist immutable contribution/award truth against merged REV-03/REV-04 exact +targets. L1 history/payment risk. + +## Allowed files + +```text +backend/app/modules/contributions/{__init__,models,schemas,repository}.py +backend/app/modules/compensation/{models,schemas,repository}.py +backend/app/db/models.py +backend/alembic/versions/_contribution_award_truth.py +backend/tests/{test_contributions,test_compensation,test_alembic}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-03C.json +``` + +## Not allowed + +```text +review model/service/composition edits +service, route, worker, receipt, artifact, reputation or PaymentRecord behavior +mutable/void/delete/adjust path, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Existing Submission is the version identity; exact project/review/lease/ + assignment/contributor lineage and immutable digests are constrained. +- [ ] DB enforces immutability/at-most-one but does not require a contribution + child for staged Review writes. +- [ ] At-least-one per valid Review is deferred to CON-07 + REV-10 + preflight. +- [ ] No mutable/void/delete/adjust path or PaymentRecord/reputation schema. + +## Verification and reviewers + +Execute CON-03C in `../RUNTIME_VERIFICATION.md`; changed subsystems are at least +90 percent. Senior engineering, QA/test, security/auth, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop if exact +REV-03/REV-04 targets are not merged. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md new file mode 100644 index 00000000..81870d12 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md @@ -0,0 +1,47 @@ +# Chunk Contract: WS-CON-001-03D - Delivery, Receipt, And Status Persistence + +## Goal and risk + +Persist outbound identity, acknowledgement, immutable fulfillment receipts and +rebuildable status separately. L1 payment/audit risk. + +## Allowed files + +```text +backend/app/modules/compensation/{models,schemas,repository}.py +backend/app/db/models.py +backend/alembic/versions/_compensation_delivery_receipts.py +backend/tests/{test_compensation,test_alembic}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-03D.json +``` + +## Not allowed + +```text +worker, callback, adapter, router or reconciliation behavior +provider request/attempt/balance, points ledger or settlement data +AUTH/ART edit, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Immutable award/event/payload/binding/idempotency identities are retained; + acknowledgement is not fulfillment; receipts are append-only and terminal. +- [ ] Delivery state durably represents fenced pre-I/O `in_flight` ownership, + the originating dispatcher claim generation, retryable recovery and callback + suppression without storing a provider payment attempt. Crash recovery cannot + erase or guess whether remote I/O may have started. +- [ ] Status is rebuildable and cannot overwrite award/receipt truth. +- [ ] Callback-before-ack, duplicate exact receipt and changed receipt are + representable without provider-attempt/balance/ledger data. +- [ ] State constraints permit failed then fulfilled, prohibit any transition + away from fulfilled, prohibit partial fulfillment, and preserve every failed + receipt without allowing it to mutate award quantity or truth. +- [ ] Upgrade/downgrade and receipt/delivery races use isolated PostgreSQL. + +## Verification and reviewers + +Execute CON-03D in `../RUNTIME_VERIFICATION.md`; changed compensation code is at +least 90 percent. Senior engineering, QA/test, security/auth, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop after schema. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md new file mode 100644 index 00000000..8d3a8c76 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md @@ -0,0 +1,45 @@ +# Chunk Contract: WS-CON-001-04A - Hidden Adapter-Binding Service + +## Goal and risk + +Implement authorized binding create/read/suspend/resume commands behind +unregistered composition. Retirement stays planned until dependency rows exist. +L1 payment/auth risk. + +## Allowed files + +```text +backend/app/modules/compensation/{schemas,repository,service}.py +backend/app/composition/compensation.py +backend/tests/{test_compensation,test_authorization,test_api_contract_e2e}.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-04A.json +``` + +## Not allowed + +```text +production router registration, policy commands, delivery or callback +AUTH catalogue/grant/kernel/service-actor edits +concrete adapter, provider secret/ref, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Proposed actions follow AUTHORIZATION_HANDOFF after AUTH registration. +- [ ] Create validates canonical active service ActorProfile, exact AUTH-owned + action assignment and non-secret route identity. +- [ ] Mutations follow PLAN locks and transaction-revalidate authority; own-state + concurrent suspend/resume is deterministic. +- [ ] Retire remains registered/planned but non-executable; any attempt fails + closed with stable not-active behavior. CON-10B activates dependency-aware + retirement after assignment/lease/award/delivery rows exist. +- [ ] Claims/delivery/callback races remain owned by 05/06/08A/08B/REV-13. +- [ ] Production OpenAPI remains unchanged. + +## Verification and reviewers + +Execute CON-04A in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/auth, product/ops, architecture, +docs, reuse/dedup and test-delta are required. Stop after hidden behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md new file mode 100644 index 00000000..bf1d1976 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md @@ -0,0 +1,45 @@ +# Chunk Contract: WS-CON-001-04B - Hidden Compensation-Policy Service + +## Goal and risk + +Implement authorized draft/read/update/publish/retire behavior behind +unregistered composition. L1 payment/auth risk. + +## Allowed files + +```text +backend/app/modules/compensation/{schemas,repository,service}.py +backend/app/modules/projects/repository.py only active-selector locking +backend/app/composition/compensation.py +backend/tests/{test_compensation,test_projects,test_authorization,test_api_contract_e2e}.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-04B.json +``` + +## Not allowed + +```text +production router registration, task/review claim integration or awards +AUTH catalogue/grant/kernel edits, adapter/provider calls +PaymentPolicy fallback, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] Proposed actions follow AUTHORIZATION_HANDOFF; read maps to + `compensation.policy.manage`, never broad `project.read`. +- [ ] Publish locks project/selector/version/bindings, revalidates authority, + validates closed rules/active bindings, and atomically changes selector with + audit/outbox. +- [ ] Explicit unpaid is valid; absent/incomplete/contradictory setup is stable + remediation failure; removed PaymentPolicy never executes or acts as fallback. +- [ ] Own-state concurrent draft/publish/retire/selector/binding changes are + deterministic. Claim races remain 05/06; delivery/callback races remain 08. +- [ ] Production OpenAPI remains unchanged. + +## Verification and reviewers + +Execute CON-04B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/auth, product/ops, architecture, +docs, reuse/dedup and test-delta are required. Stop after hidden behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md new file mode 100644 index 00000000..669095c6 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md @@ -0,0 +1,126 @@ +# Chunk Contract: WS-CON-001-05A - PaymentPolicy Semantic Consumer Cutover And Task Freeze + +## Parent initiative + +`WS-CON-001` - Contribution Record And Compensation Boundary + +## Goal + +Atomically remove PaymentPolicy from every runtime/API semantic consumer, +classify existing rows, and freeze the active published compensation version on +every successful new TaskAssignment. Physical schema removal belongs to 05B. + +## Why this chunk exists + +Submitter compensation must be known before work begins and must not drift when +the project changes policy later. + +## Approved plan reference + +- `../INTENT.md` +- `../PLAN.md` +- `../CHUNK_MAP.md` + +## Risk class + +L1 payment/task lifecycle/authorization; SLA P1. + +## Allowed files + +```text +backend/app/modules/compensation/ports.py +backend/app/modules/compensation/service.py +backend/app/modules/projects/{schemas,repository,service}.py only PaymentPolicy consumer removal +backend/app/modules/tasks/models.py +backend/app/modules/tasks/schemas.py only PaymentPolicy consumer removal/frozen-version API semantics +backend/app/modules/tasks/repository.py only exact cutover locking/classification +backend/app/modules/tasks/service.py only task-owned participant integration +backend/app/modules/checkers/{schemas,repository,service,runner}.py only PaymentPolicy consumer removal +backend/alembic/versions/_task_assignment_compensation_freeze.py +backend/app/db/models.py +backend/tests/test_compensation.py +backend/tests/test_projects.py +backend/tests/test_tasks.py +backend/tests/test_checkers.py +backend/tests/test_authorization.py only action/transaction proof +backend/tests/test_alembic.py +backend/tests/test_api_contract_e2e.py +docs/spec_contribution_compensation.md +docs/architecture_data_model.md only removed/canonical authority reconciliation +docs/operations_payment_reputation.md only setup/cutover operations +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-05A.json +``` + +## Not allowed + +```text +task claim permission/grant/kernel implementation +ReviewLease or Review behavior +contribution/award creation +public compensation routes +PaymentPolicy physical table/model/column removal, fallback, automatic conversion, or historical row rewrite +provider/artifact calls +review behavior or unrelated checker behavior +``` + +## Acceptance criteria + +- [ ] TaskAssignment has non-null immutable + `submitter_compensation_policy_version_id` for all new claims. +- [ ] Merged REV-02 has established exact non-null + `Submission.task_assignment_id` lineage and its accepted task-owned creation + contract; 05A preserves that lineage and introduces no parallel submission + ownership field. +- [ ] No runtime service, API schema/OpenAPI path, setup gate, task claim, + checker, review, or award consumer treats PaymentPolicy as current business + or economic authority; Finance publication is the only authority. CON-01 owns + the active specification inventory and REV-13 owns final joint release docs. +- [ ] A zero-consumer scanner proves the remaining PaymentPolicy model/table is + unreachable compatibility residue pending 05B, not an executable fallback. +- [ ] Existing task-claim ActionId/authority is allowed and revalidated before + assignment/freeze commit; WS-CON introduces no local role checks. +- [ ] Claim follows the PLAN lock order, locks every referenced binding by UUID, + revalidates task-claim authority after relevant locks, and copies one + published same-project version whose bindings are active. +- [ ] Missing/suspended/invalid policy fails with stable compensation error and + creates no assignment/task/audit/outbox partial state. +- [ ] Concurrent publish vs claim freezes one committed old or new version, + never a mixture and without deadlock in either permutation. +- [ ] Binding suspend/retire versus claim is proved in both permutations: new + work never freezes an inactive binding while already-frozen work is retained. +- [ ] Later policy change never updates the assignment. +- [ ] Legacy rows follow the approved migration classification and cannot enter + new Review decisions without a valid frozen ref. +- [ ] Deployment either drains all pre-cutover active assignments or executes + the explicitly approved deterministic rebuild; migration fails on ambiguity. + There is no intermediate deployment that changes economic meaning while + allowing unfrozen claims. +- [ ] Downgrade requires task claims and review intake disabled and refuses when + post-cutover assignments exist; rollback never silently drops a frozen ref. +- [ ] Changed subsystems remain >=90 percent; global floor remains >=78 percent. + +## Verification commands + +Execute the exact CON-05A expansion in `../RUNTIME_VERIFICATION.md`; same-run +changed compensation code is at least 90 percent and repository coverage at +least 78 percent. + +## Required reviewers + +Baseline plus architecture, security/auth, product/ops, docs, reuse/dedup, and +test-delta. + +## Human review focus + +Atomic semantic-consumer/claim cutover, exact freeze timing, auth/lock order, +policy/binding races, legacy drain/rebuild, rollback, and no PaymentPolicy +fallback. + +## Stop conditions + +Stop if merged REV-02 does not expose its exact reviewed +`Submission.task_assignment_id` lineage, AUTH task-claim cutover is incomplete, +TaskService cannot accept the participant within the listed files, or the lock +order conflicts with merged REV/ART/AUTH. Any future composition path requires +contract amendment and a new internal review before implementation. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md new file mode 100644 index 00000000..a1a1dea5 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md @@ -0,0 +1,48 @@ +# Chunk Contract: WS-CON-001-05B - PaymentPolicy Physical Schema Removal + +## Goal and risk + +Delete the now-unreachable PaymentPolicy model, table, columns, constraints, +and compatibility code after 05A proves there are zero semantic consumers. L1 +migration and historical-data risk. + +## Allowed files + +```text +backend/app/modules/projects/{models,schemas,repository,service}.py only dead PaymentPolicy removal +backend/app/modules/tasks/{models,schemas,repository,service}.py only dead references +backend/app/modules/checkers/{models,schemas,repository,service,runner}.py only dead references +backend/app/db/models.py +backend/alembic/versions/_remove_payment_policy.py +backend/tests/{test_projects,test_tasks,test_checkers,test_alembic,test_api_contract_e2e}.py +docs/{architecture_data_model,operations_payment_reputation,spec_contribution_compensation}.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-05B.json +``` + +## Not allowed + +```text +new compensation behavior, policy conversion or inferred backfill +ReviewLease/Review/contribution/award behavior +AUTH, ART, provider, frontend, dependency or CI changes +``` + +## Acceptance criteria + +- [ ] Exact zero-consumer scan from 05A still passes on current trusted main. +- [ ] Approved legacy classification drains, resets, or deterministically + migrates every row; ambiguous economic meaning fails migration and never + guesses a CompensationPolicyVersion. +- [ ] PaymentPolicy model/table/columns/FKs/indexes and API/OpenAPI references + are absent after upgrade; active compensation/frozen references remain valid. +- [ ] Downgrade is explicitly data-loss aware, requires intake disabled, and + never recreates PaymentPolicy as executable authority. +- [ ] PostgreSQL upgrade/downgrade and fresh-install schema tests pass; changed + code remains at least 90 percent and repository coverage at least 78 percent. + +## Verification and reviewers + +Execute CON-05B in `../RUNTIME_VERIFICATION.md`. Senior engineering, QA/test, +security/auth, product/ops, architecture, docs, reuse/dedup, test-delta and CI +integrity are required. Stop before CON-06. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md new file mode 100644 index 00000000..81065d87 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md @@ -0,0 +1,87 @@ +# Chunk Contract: WS-CON-001-06 - ReviewLease Compensation Freeze Participant + +## Parent initiative + +`WS-CON-001` - Contribution Record And Compensation Boundary + +## Goal + +Deliver and independently prove the narrow WS-CON compensation lookup/freeze +participant that REV-06 will invoke with canonical caller-supplied project and +binding facts inside the review-claim transaction. + +## Why this chunk exists + +Reviewer compensation must be fixed before review work begins and cannot depend +on the later decision outcome or current policy at decision time. + +## Approved plan reference + +- `../INTENT.md` +- `../PLAN.md` +- `../CHUNK_MAP.md` + +## Risk class + +L1 payment/review lifecycle/authorization; SLA P1. + +## Allowed files + +```text +backend/app/modules/compensation/ports.py +backend/app/modules/compensation/service.py +backend/tests/test_compensation.py +backend/tests/test_authorization.py only action/transaction proof +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-06.json +``` + +## Not allowed + +```text +review claim/queue/lease policy invention +review models, migrations, services, routes, or composition +AUTH catalogue/grants/kernel changes +review decision or contribution/award creation +task assignment freeze changes +provider/artifact/adapter calls +``` + +## Acceptance criteria + +- [ ] Port accepts caller AsyncSession plus canonical project/claim facts, + follows PLAN lock order, locks referenced bindings by UUID, returns one + published same-project version, flushes nothing outside its ownership, and + never commits. +- [ ] Missing/inactive/invalid policy or binding returns stable typed failure + with no WS-CON/audit/outbox partial state. +- [ ] Contract explicitly requires REV-03's immutable non-null ReviewLease FK + and REV-06's `review.claim` revalidation, injection, lease write, audit/outbox, + release/expiry behavior, and integrated tests; CON-06 implements none of them. +- [ ] Policy publish vs claim concurrency freezes one committed version and + passes both lock permutations without deadlock. +- [ ] Binding suspend/retire versus lookup is covered in both permutations. +- [ ] Reviewer award behavior is not implemented here. +- [ ] Changed modules remain >=90 percent; global floor stays >=78 percent. + +## Verification commands + +Execute the exact CON-06 expansion in `../RUNTIME_VERIFICATION.md`; the same run +proves changed compensation code at least 90 percent. + +## Required reviewers + +Baseline plus architecture, security/auth, product/ops, docs, reuse/dedup, and +test-delta. + +## Human review focus + +Exact lease freeze timing, REV ownership, review.claim authority, no +decision-dependent rate, lock ordering, and no contribution on incomplete lease. + +## Stop conditions + +Stop if REV-03's exact caller facts/FK contract is not merged or if any review +schema, claim wiring, or composition edit would move into WS-CON. REV-06, not +this chunk, owns integrated claim behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md new file mode 100644 index 00000000..52733828 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md @@ -0,0 +1,111 @@ +# Chunk Contract: WS-CON-001-07 - Atomic Review Contribution And Award Participant + +## Parent initiative + +`WS-CON-001` - Contribution Record And Compensation Boundary + +## Goal + +Implement the mandatory database-local participant that creates reviewer and +accept-only submitter contributions, deterministic awards, pending evidence +projections, audit, and outbox events in the caller-owned Review transaction. + +## Why this chunk exists + +Contribution recognition must never lag behind or disagree with a committed +human Review, and no external system can participate in that atomic commit. + +## Approved plan reference + +- `../INTENT.md` +- `../PLAN.md` +- `../CHUNK_MAP.md` + +## Risk class + +L1 payment/canonical judgment/cross-domain transaction; SLA P1. + +## Allowed files + +```text +backend/app/modules/contributions/schemas.py +backend/app/modules/contributions/repository.py +backend/app/modules/contributions/service.py +backend/app/modules/compensation/repository.py +backend/app/modules/compensation/service.py +backend/app/modules/compensation/ports.py +backend/tests/test_contributions.py +backend/tests/test_compensation.py +backend/tests/test_authorization.py only decision-causation evidence proof +backend/tests/test_outbox.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-07.json +``` + +## Not allowed + +```text +Review decision/transition policy in contribution code +review service, model, route, or composition wiring +public route registration +ContributionRecordRequested compatibility event +AUTH catalogue/grants/kernel edits or new materialize permissions +external adapter, broker, or artifact provider calls +mutable/delete/void/adjust contribution/award path +reputation scoring +``` + +## Acceptance criteria + +- [ ] Every committed Review creates exactly one reviewer + `completed_review`; `accept` additionally creates one submitter + `accepted_submission`; needs_revision/reject create none for submitter. +- [ ] Existing Submission/assignment/lease/Review/project/contributor chains and + immutable artifact digest are exact and DB-validated. +- [ ] Reviewer awards use lease-frozen version and are decision-neutral; + submitter awards use assignment-frozen version; explicit unpaid creates none. +- [ ] Participant uses caller AsyncSession, flushes, never commits, and retains + originating `review.decision` AuthorizationDecision as causation. +- [ ] Participant accepts only a typed allowed `review.decision` whose actor, + action, Review/lease/Submission/project resource, request, and correlation + facts match the locked caller transaction; denied, stale, unrelated, or + mismatched evidence is rejected. REV-10 owns final transaction-time authority + revalidation and mandatory injection. +- [ ] Each contribution creates one pending evidence projection and one stable + projection request event in the same transaction. +- [ ] Versioned `ContributionRecorded`, `CompensationAwardCreated`, + `CompensationFulfillmentRequested`, and + `ContributionEvidenceProjectionRequested` use the shared outbox with + deterministic IDs/digests and no sensitive/provider data. These exact tokens + are feature-owned; the generic outbox never aliases them. +- [ ] Direct participant fault injection proves its contribution/award/audit/ + outbox writes roll back with the caller transaction. REV-10 owns cross-domain + Review/task/lease rollback and hidden-composition proof. +- [ ] Exact replay returns one logical set; changed/concurrent replay conflicts + cleanly; no optional/no-op production participant exists. +- [ ] Claims/releases/expiry/revocation/admin closure/artifact failure create no + contribution or award. +- [ ] No production composition or OpenAPI changes; new/changed modules >=90 + percent and global floor >=78 percent. + +## Verification commands + +Execute the exact CON-07 expansion in `../RUNTIME_VERIFICATION.md`; the same run +proves each changed subsystem at least 90 percent. + +## Required reviewers + +Baseline plus architecture, security/auth, product/ops, docs, reuse/dedup, and +test-delta. + +## Human review focus + +Creation matrix, exact frozen sources, no current-policy lookup, atomic rollback, +decision causation, replay/concurrency, and the explicit REV-10 integration +handoff. + +## Stop conditions + +Stop if REV decision/revision schemas are not stable, shared audit/outbox cannot +join caller transaction, or any external call is required before commit. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md new file mode 100644 index 00000000..16fced58 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md @@ -0,0 +1,88 @@ +# Chunk Contract: WS-CON-001-08A - Outbound Compensation Delivery Handler + +## Goal and risk + +Consume versioned `CompensationFulfillmentRequested` through one typed ADR-0014 +adapter and record acknowledgement. L1 payment/integration/worker risk. + +## Allowed files + +```text +backend/app/interfaces/compensation.py +backend/app/adapters/compensation/__init__.py +backend/app/adapters/compensation/deterministic.py +backend/app/modules/compensation/ports.py +backend/app/modules/compensation/{schemas,repository,service,delivery_handler}.py +backend/app/modules/outbox/handlers.py only explicit handler registration +backend/app/workers/compensation.py +backend/app/workers/celery_app.py only include registration +backend/app/composition/compensation.py only explicit ExternalServiceAdapterFactory registration +backend/tests/{test_compensation,test_outbox,test_external_service_adapters}.py +docs/operations_payment_reputation.md only delivery operations +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-08A.json +``` + +## Not allowed + +```text +inbound router/callback, AUTH catalogue/grant/kernel edit +production provider-specific SDK, payment attempt/balance/ledger/settlement +dispatcher/async bridge/session/idempotency duplication, dependency/CI weakening +joint lifecycle-control persistence/phase policy or REV-owned implementation +optional/no-op/fallback dispatch fence or REV edits to CON product files +``` + +## Acceptance criteria + +- [ ] Reuse shared dispatcher/hashing/idempotency/worker/session/task-settings; + preserve event/payload/binding/idempotency identity. +- [ ] Execute only as a handler of a currently claimed `outbox.dispatch` + command assigned to the fixed shared-outbox dispatcher. CON defines no + feature-local delivery-dispatch action, and human retry/reconciliation + authority cannot execute the side effect. +- [ ] Lock/revalidate frozen binding/award/delivery; active permits delivery, + suspended/retired blocks it, terminal callback status suppresses it. +- [ ] The shared dispatcher supplies an already-claimed immutable event and + exact claim generation only after its claim transaction releases every + database lock/session. In a new transaction, the handler acquires the injected + lifecycle fence, revalidates the generation through the outbox-owned + `OutboxClaimValidationPort` without locking/mutating OutboxEvent, then locks + CON rows and persists durable `in_flight` delivery state. +- [ ] The handler commits and releases its transaction and advisory fence before + adapter I/O. It finalizes CON delivery state in a new fenced transaction and + returns a typed success/retry/terminal outcome; only the dispatcher mutates + outbox claim/retry/finalization state. +- [ ] Timeout/crash/duplicate/out-of-order/ack retry never fabricates + fulfillment; binding-vs-dispatch races cover both orders. +- [ ] Instrumentation proves no provider I/O executes while a database + transaction, lifecycle advisory fence, or OutboxEvent row lock is held. Crash + recovery uses the durable claim/in-flight generation and never guesses + provider outcome. +- [ ] The delivery handler requires a narrow CON-owned + `FulfillmentDispatchFence` consumer port after the dispatcher's committed + claim handoff and before claim validation/CON row locks or any adapter call. + Construction or handler registration without an injected fence fails closed; + there is no optional/no-op/fallback production fence. +- [ ] CON owns the handler and port. REV-12A may inject its durable joint + lifecycle-control implementation only through explicit composition; it may + not edit `compensation/delivery_handler.py` or CON outbox handler policy. +- [ ] On a denied/lost release-control race, the handler performs no adapter I/O + or award/delivery identity mutation and returns the exact typed retry outcome; + the dispatcher alone returns its claimed event to retryable state. + Deterministic CON test doubles prove required-port construction failure plus + allow/deny behavior. REV-12A owns integrated independent-session proof of both + shared/exclusive advisory-lock orderings after consuming the merged CON-11 + hook manifest; REV-13 repeats the behavior in the joint live drill. +- [ ] Deterministic adapter conforms to the typed capability and registers only + through the shared `ExternalServiceAdapterFactory[CompensationDeliveryAdapter]` + in explicit FastAPI/Celery composition; no fallback constructor, service + locator, runtime discovery, compatibility alias, or second factory path. +- [ ] Reconciliation preserves exact original identities; no duplicate worker + bridge, registry, canonicalizer, or idempotency implementation. + +## Verification and reviewers + +Execute CON-08A in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/auth, product/ops, architecture, +docs, reuse/dedup, test-delta and CI integrity are required. Stop before callback. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md new file mode 100644 index 00000000..67bc8880 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -0,0 +1,64 @@ +# Chunk Contract: WS-CON-001-08B - Inbound Fulfillment Callback + +## Goal and risk + +Accept immutable reports from the exact service actor bound to the frozen +adapter binding, behind an unregistered route. L1 external-auth/payment risk. + +## Allowed files + +```text +backend/app/modules/compensation/{schemas,repository,service,ports,callback}.py +backend/app/api/internal_compensation.py +backend/app/composition/compensation.py +backend/tests/{test_compensation,test_authorization,test_api_contract_e2e}.py +docs/operations_payment_reputation.md only callback operations +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-08B.json +``` + +## Not allowed + +```text +production router registration or human authority +AUTH catalogue/grant/kernel/service-assignment edits +outbound adapter/dispatcher, provider secret/ref, dependency/CI weakening +REV-owned lifecycle-control persistence/phase policy or implementation +optional/no-op/fallback callback fence or REV edits to CON callback policy +``` + +## Acceptance criteria + +- [ ] AUTH callback PermissionId/ActionId/parity/exact assignment is merged; + human AdminRoleGrant/ProjectRoleGrant never satisfies it. +- [ ] Locks revalidate actor/link/assignment/route/award/project/instrument/ + binding/state; durable rate control is per actor+binding. +- [ ] After signature verification and AUTH/idempotency locking, callback + handling requires a narrow CON-owned `FulfillmentCallbackFence`, captures the + allowed lifecycle phase before any compensation-domain row, and holds the + shared transaction fence through idempotent receipt commit. Missing injection + fails closed; there is no optional/no-op/fallback production fence. +- [ ] The callback fence allows authenticated callbacks through + `delivery_draining` and denies them after `disabled`. Deterministic CON test + doubles prove allow/deny semantics; REV-12A owns integrated callback-versus- + disable independent-session tests in both lock orderings, and REV-13 repeats + the behavior in the joint live drill. +- [ ] CON owns callback verification, receipt/idempotency policy, and the + callback-fence consumer port. REV-12A may inject its durable implementation + only through explicit composition and may not edit CON callback policy. +- [ ] Suspended accepts valid already-issued work; retired accepts only exact + previously accepted receipt replay; actor/link revocation always denies. +- [ ] Callback-before-ack suppresses delivery; replay is idempotent; changed + receipt conflicts; callback-vs-delivery/retire races cover both orders. +- [ ] Callback-before-ack derives `acknowledged_by_adapter`; a late dispatcher + acknowledgement is idempotent and cannot regress fulfillment or delivery. +- [ ] Behavior tests prove failed then fulfilled is allowed, fulfilled then + failed/changed-fulfilled is denied, and partial fulfillment is rejected. +- [ ] Production OpenAPI remains unchanged and secrets/refs are never stored. + +## Verification and reviewers + +Execute CON-08B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/privacy, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop before public +registration. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md new file mode 100644 index 00000000..db6f2388 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md @@ -0,0 +1,44 @@ +# Chunk Contract: WS-CON-001-08R - Bound-Service Callback Rate Control + +## Goal and risk + +Extend the shared closed API-control service with one durable actor+binding +callback scope before the external fulfillment route exists. L1 abuse-control/ +availability/data risk. + +## Allowed files + +```text +backend/app/modules/api_controls/{models,repository,service}.py +backend/app/api/deps/api_controls.py +backend/app/core/config.py +backend/alembic/versions/_compensation_callback_rate_scope.py +backend/tests/{test_api_rate_controls,test_config,test_alembic}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-08R.json +``` + +## Not allowed + +```text +AUTH catalogue/grant/kernel/service-actor edits +callback route/receipt/award/binding behavior +in-memory/shared-IP-only limiter, new rate-control framework, dependency/CI weakening +``` + +## Acceptance criteria + +- [ ] Closed scope adds only `compensation_fulfillment_report`; key digest is + derived from canonical service actor + binding and stores neither raw secret + nor provider credential/reference. +- [ ] Bounded configuration, PostgreSQL atomic window accounting, fail-closed + storage errors and deterministic retry-after behavior reuse RateControlService. +- [ ] Actor A cannot exhaust actor B; binding A cannot bypass binding B; exact + boundary/concurrency/upgrade/downgrade behavior is tested. +- [ ] No callback or authorization decision is implemented in this chunk. + +## Verification and reviewers + +Execute CON-08R in `../RUNTIME_VERIFICATION.md`; changed api-controls code is at +least 90 percent. Senior engineering, QA/test, security/auth, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop before callback. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md new file mode 100644 index 00000000..65323531 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md @@ -0,0 +1,45 @@ +# Chunk Contract: WS-CON-001-09A - Contribution Evidence Projection Write + +## Goal and risk + +Build minimal deterministic evidence and bind it through an ART-owned typed +capability. L1 artifact/privacy/worker risk. + +## Allowed files + +```text +backend/app/modules/contributions/{schemas,repository,evidence}.py +backend/app/modules/outbox/handlers.py only evidence-handler registration +backend/app/workers/contribution_evidence.py +backend/app/workers/celery_app.py only include registration +backend/tests/{test_contributions,test_artifacts,test_outbox}.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-09A.json +``` + +## Not allowed + +```text +raw ArtifactStore/provider ref, ART implementation edit +read route, semantic search, retain/pin or provider recovery invention +duplicate canonicalizer/worker/session/idempotency, dependency/CI weakening +``` + +## Acceptance criteria + +- [ ] Versioned minimal schema/disclosure matrix excludes reviewer-private, + compensation/provider, credential, external-receipt and unnecessary actor data. +- [ ] Versioned `ContributionEvidenceProjectionRequested` reuses shared hashing, + outbox, worker, idempotency and session utilities; replay is byte-stable. +- [ ] ART owns admission/I/O/verification/binding/receipt/recovery; WS-CON stores + only projection state and verified binding reference. +- [ ] LocalStorage/MinIO capability conformance passes; new-schema rebuild + retains prior immutable bundles. + +## Verification and reviewers + +Execute CON-09A in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/privacy, product/ops, +architecture, docs, reuse/dedup, test-delta and CI integrity are required. Stop +if ART capability/action is not merged. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md new file mode 100644 index 00000000..70ec4822 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -0,0 +1,43 @@ +# Chunk Contract: WS-CON-001-09B - Authorized Contribution Evidence Read + +## Goal and risk + +Expose safe self/project evidence reads behind unregistered routes through ART's +typed read capability. L1 auth/privacy risk. + +## Allowed files + +```text +backend/app/modules/contributions/{schemas,repository,service}.py +backend/app/api/internal_contributions.py +backend/app/composition/contributions.py +backend/tests/{test_contributions,test_authorization,test_api_contract_e2e}.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-09B.json +``` + +## Not allowed + +```text +write projection, raw ArtifactStore/provider ref, AUTH/ART implementation edit +production router registration or broad artifact disclosure +dependency, test, coverage or CI weakening +``` + +## Acceptance criteria + +- [ ] Exact proposed actions/canonical facts, pre-filter pagination and + cross-project concealment are required. +- [ ] Matrix proves self, Project Manager, Finance, Operator/Audit views and + Reviewer project-wide denial/self-only behavior without private/provider data. +- [ ] ART result matches immutable projection identity; evidence failure never + changes ContributionRecord truth. +- [ ] All role/project denial cases map to CONFORMANCE_MATRIX; OpenAPI is hidden. + +## Verification and reviewers + +Execute CON-09B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/privacy, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop before public +registration. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md new file mode 100644 index 00000000..386d0608 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md @@ -0,0 +1,45 @@ +# Chunk Contract: WS-CON-001-10A - Contribution And Award Product Reads + +## Goal and risk + +Implement authorized self/project contribution and award reads behind +unregistered routes. L1 auth/privacy/product risk. + +## Allowed files + +```text +backend/app/modules/contributions/{schemas,repository,service}.py +backend/app/modules/compensation/{schemas,repository,service}.py +backend/app/api/internal_contributions.py +backend/app/api/internal_compensation.py +backend/app/composition/{contributions,compensation}.py +backend/tests/{test_contributions,test_compensation,test_authorization,test_api_contract_e2e}.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-10A.json +``` + +## Not allowed + +```text +operations mutation/rebuild/reconciliation, AUTH edit +provider/evidence bytes/ref, balance/ledger, production registration +dependency, test, coverage or CI weakening +``` + +## Acceptance criteria + +- [ ] Exact proposed actions/canonical facts, stable pre-filter pagination and + cross-project concealment are enforced. +- [ ] Self, Finance/project/Operator/Audit disclosure is separated; Reviewer is + self-only absent a later approved assigned-review action. +- [ ] Contribution, money, points, delivery acknowledgement and fulfillment + remain distinct; no provider/balance/ledger data appears. +- [ ] Query races never mutate truth; all matrix cases run; OpenAPI stays hidden. + +## Verification and reviewers + +Execute CON-10A in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/privacy, product/ops, +architecture, docs, reuse/dedup and test-delta are required. Stop before public +registration. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md new file mode 100644 index 00000000..c6eab0b4 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -0,0 +1,56 @@ +# Chunk Contract: WS-CON-001-10B - Operations, Reconciliation, And Rebuild + +## Goal and risk + +Implement bounded status/audit reads, reconciliation and projection rebuild +without repairing immutable truth. L1 operations/auth/data risk. + +## Allowed files + +```text +backend/app/modules/contributions/{schemas,repository,service}.py +backend/app/modules/compensation/{schemas,repository,service,ports}.py +backend/app/modules/audit/{schemas,repository,service}.py only bounded WS-CON query/export capability +backend/app/api/internal_operations.py +backend/app/composition/{contributions,compensation}.py +backend/tests/{test_contributions,test_compensation,test_authorization,test_outbox,test_audit}.py +docs/operations_payment_reputation.md only WS-CON operations +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-10B.json +``` + +## Not allowed + +```text +production router registration, canonical award/receipt repair, AUTH edit +provider settlement/attempt/balance/ledger or second dispatcher +dependency, test, coverage or CI weakening +``` + +## Acceptance criteria + +- [ ] Ops/audit actions follow handoff and revalidate after locks. +- [ ] Finance project and reason-bound Operator reconciliation use distinct + guards; Project Manager/contributor denials are explicit. +- [ ] Reconcile preserves original identities; rebuild changes projection only; + bounded range/reason/audit/idempotency is durable. +- [ ] Audit read/export purpose/scope/redaction/max range is proved without + provider or sensitive failure leakage; OpenAPI remains hidden. +- [ ] Dependency-aware binding retirement now activates: it locks policy, + assignment, lease, award, delivery and receipt dependencies, denies any + active/unfinished/unfulfilled reference, races all dependency changes in both + orders, and afterward permits only exact accepted-receipt replay. +- [ ] A same-session read-only `FulfillmentLifecycleDrainObservationPort` + reports pending/claimed/retryable fulfillment outbox events, durable + in-flight dispatch, and nonterminal delivery/callback obligations using the + shared-outbox capability rather than importing its repository. It never + commits, repairs state, calls a provider, or widens Operator authority. +- [ ] Observation is transactionally stable, bounded and fail-closed; tests + cover concurrent claim/retry/callback/finalization and prove no false zero + while work can still perform remote I/O or accept a terminal receipt. + +## Verification and reviewers + +Execute CON-10B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Senior engineering, QA/test, security/auth, product/ops, architecture, +docs, reuse/dedup and test-delta are required. Stop before public registration. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md new file mode 100644 index 00000000..51ee8450 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -0,0 +1,88 @@ +# Chunk Contract: WS-CON-001-11 - Hidden Release Readiness And Dependency Manifest + +## Goal and risk + +Prove the complete WS-CON subsystem is coherent while still hidden, emit an +exact dependency/action/schema/test/fence manifest, hand hidden joint +release-control composition to WS-REV-12A, and hand sole production activation +to WS-REV-13. L1 release/auth/payment risk. + +## Allowed files + +```text +backend/app/composition/contributions.py +backend/app/composition/compensation.py +backend/app/composition/outbox.py +backend/tests/test_api_contract_e2e.py +backend/tests/test_authorization.py +backend/tests/test_contributions.py +backend/tests/test_compensation.py +backend/tests/test_outbox.py +docs/spec_contribution_compensation.md +docs/internal_reviews/WS-CON-001-hidden-release-readiness.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-11.json +``` + +## Not allowed + +```text +production router registration or /v1 alias +review service/composition ownership +REV-owned lifecycle-control persistence, phase policy, or fence implementation +AUTH/ART catalogue, kernel, grant, provider, or storage edits +active public API/operations claims before REV-13 activation +archival reference edits +``` + +## Acceptance criteria + +- [ ] Startup/preflight fails closed unless exact migrations, AUTH action + definitions/owners/availability/service assignments, ART capabilities, outbox + dispatcher, REV-10 integration and provider readiness are present. +- [ ] Hidden integration proves `/api/v1` target paths are absent from production + OpenAPI before release and no partial direct construction path exists. +- [ ] `CONFORMANCE_MATRIX.md` has collected node IDs/evidence for every adopted + invariant; isolated full-suite metadata proves repository >=78 percent and + every changed subsystem >=90 percent from the same run. +- [ ] Dependency manifest names exact merged SHAs/schema symbols/action mappings, + migration heads, stable Celery task IDs, handler registry entries and live + preconditions consumed by REV-13. +- [ ] Manifest names the exact CON-owned `FulfillmentDispatchFence` and + `FulfillmentCallbackFence` port symbols, handler constructor/injection seams, + registry bindings, `OutboxClaimValidationPort`, committed claim handoff, + phase/command mappings, denied retry/callback transitions, and proof that + production construction fails closed without the REV-12A implementation. + REV-12A consumes both seams through composition and does not edit CON product + files. +- [ ] Manifest names the exact same-session + `FulfillmentLifecycleDrainObservationPort`, shared-outbox observation + capability, pending/claimed/retryable/in-flight/nonterminal count semantics, + and zero-obligation proof consumed by REV-12A. Lifecycle control receives no + CON or outbox repository. +- [ ] CON-01 inventory covers every active README-linked source/generated + companion with stale mutable PaymentRecord, accept-only/voidable contribution, + automatic reputation, PaymentPolicy execution or `/v1` wording. REV-13 owns + the atomic active-doc/API/live-drill update; archival/history remains untouched. +- [ ] Joint drill script/evidence contract covers every conformance family but + is not represented as executed until REV-13's sole activation PR. + +## Verification commands + +Execute the exact CON-11 expansion in `../RUNTIME_VERIFICATION.md`, then: + +```bash +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +git diff --check +``` + +## Review and stop + +All internal reviewer tracks, including CI integrity and test-delta, are +required. Stop after the reviewed hidden-readiness manifest. Do not register a +route, implement lifecycle-control policy, perform the production drill, edit +WS-REV, or start REV-12A/13. Only the human may direct the WS-REV owner to +consume this gate. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md new file mode 100644 index 00000000..c5c84921 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md @@ -0,0 +1,82 @@ +# Chunk Contract: WS-CON-001-PLAN - Contribution And Compensation Planning + +## Parent initiative + +`WS-CON-001` - Contribution Record And Compensation Boundary + +## Goal + +Reconcile the supplied WS-CON pair with current code and parallel AUTH/REV +contracts, then produce a human-reviewable initiative plan without implementing +runtime behavior. + +## Why this chunk exists + +The candidate spans architecture, permissions, payment, artifacts, lifecycle, +workers, APIs, and migrations and contains conflicts with accepted repository +decisions. Implementation cannot safely begin from the candidate alone. + +## Approved plan reference + +This chunk creates the parent `INTENT.md`, `DISCOVERY.md`, `PLAN.md`, and +`CHUNK_MAP.md`; no prior implementation plan exists. + +## Risk class + +L0 architecture/payment/authorization direction; P1 planning priority. + +## Allowed files + +```text +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +``` + +## Not allowed + +```text +backend application, migrations, tests, workflows, dependencies +AUTH/ART/REV sibling worktree edits +reference-spec byte edits or archival replacement +active runtime documentation adoption +``` + +## Acceptance criteria + +- [x] Candidate Markdown/PDF and original PDF are inventoried by hash/status. +- [x] Current code, tests, docs, AUTH catalogue, REV plan, and ART contract are + cited concretely. +- [x] ActionIds and PermissionIds are separated and incorrect candidate IDs are + rejected. +- [x] `/api/v1`, Submission identity, provider, artifact capability, payment + model, outbox, and review integration conflicts are explicit. +- [x] Required initiative artifacts and bounded chunk contracts exist. +- [x] First implementation/spec chunk remains proposed until human approval. +- [x] Required plan reviewers complete and all valid findings are resolved or + recorded for human decision. + +## Verification commands + +```bash +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +git diff --check +sha256sum docs/reference_specs/* +``` + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +and reuse/dedup. CI integrity and test-delta are N/A because this chunk changes +only planning Markdown and no CI/tests. + +## Human review focus + +Review unresolved D1/D4/D7/D8, confirm accepted D3/D5/D6/D9 and approved D2, +and assess D2's unresolved legacy-row handling rule, exact authorization +dependencies, artifact boundary, cross-initiative gates, and whether every +runtime chunk is independently reviewable. + +## Stop conditions + +Stop after presenting the reviewed plan. Do not start `WS-CON-001-01` without +explicit human approval. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md new file mode 100644 index 00000000..c95cb35a --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -0,0 +1,138 @@ +# Internal Review Evidence: WS-CON-001-PLAN + +## 2026-07-15 End-to-End Reference Reconciliation Addendum + +The supplied generation-2 Markdown was audited against AUTH head `3ab25cf`, +canonical ART/REV decisions, ADR 0014, the shared-outbox plan, and current +PaymentPolicy consumers. Final internal delta reviews passed: + +| Track | Result | Closed findings | +|---|---|---| +| security/auth + senior engineering | PASS | Exact ActionId/PermissionId handoff, request-scoped AUTH boundary, service-only callback/outbox authority, human/request versus dispatcher execution, bounded callback data, split award routes | +| product/ops + QA/test | PASS | 05A/05B executable removal scope, contribution/evidence disclosure, delivery retry and callback transitions, conformance traceability | +| architecture + docs | PASS | ART typed capabilities/recovery/provider matrix, centralized adapter factory, shared outbox ownership, source provenance/hash, stale-prefix and Markdown-link checks | + +The reconciled Markdown remains a non-normative working transcription. CON-01 +still owns creation and review of the active specification/ADR; no runtime chunk +is activated by this addendum. + +## Chunk + +`WS-CON-001-PLAN` - Contribution And Compensation Planning + +open sub-agent sessions: none + +valid findings addressed: yes + +## Reviewed Revision + +Reviewed code SHA: f5995518a0d1723be5600d4bb306d99d3ba077a7 + +Reviewed planning-tree SHA-256: `367a43d2913276b1b700f9d55ae30ff812d8478c520bf338035c3b8671048f43` + +Reviewed at: 2026-07-15T14:24:59Z + +Reviewer run IDs: senior-engineering/architecture/reuse=`/root/plan_arch_senior`; +QA/test/product/ops/docs=`/root/plan_qa_product_docs`; +security/auth/privacy=`/root/plan_security_auth` + +The planning-tree digest excludes this post-review evidence file. After the +reviewed digest, only this evidence and initiative status/chunk-status fields +changed. + +## Reviewer Results + +| Reviewer | Result | Blocking findings | Notes | +|---|---:|---|---| +| senior engineering | PASS AFTER FIXES | None | Cross-initiative ownership, PR sizing, reusable infrastructure, and executable contracts repaired. | +| QA/test | PASS AFTER FIXES | None | Traceability, isolated PostgreSQL evidence, separate subsystem coverage, retained attempts, and release handoff repaired. | +| security/auth | PASS AFTER FIXES | None | Proposed action/resource contracts, service actor, binding states, rate controls, retirement and privacy repaired. | +| product/ops | SUPERSEDED | Re-review required | This row predates approved complete PaymentPolicy removal and the end-to-end reference reconciliation. | +| architecture | PASS AFTER FIXES | None | REV ownership, sole activation, outbox/audit/factory boundaries and ART/AUTH ownership are coherent. | +| CI integrity | N/A - with approved reason | None | Planning Markdown only; no workflow, script, dependency, test, or coverage gate changed. | +| docs | PASS AFTER FIXES | None | Archive provenance, active-doc inventory and generated-companion release ownership are explicit. | +| reuse/dedup | PASS AFTER FIXES | None | Shared hashing, idempotency, workers, rate control, audit, outbox, typed factory and existing Submission are reused. | +| test delta | N/A - with approved reason | None | No runtime test file changed; runtime contracts prohibit weakening and require same-run evidence. | + +## Valid Findings Addressed + +- Removed all REV-owned ReviewLease schema/claim/composition work from WS-CON; + REV-03/06/10 retain their exact ownership. +- Made REV-13 the sole joint production activation/live-drill owner and added an + exact evidence-driven release handoff without editing the sibling worktree. +- Split shared outbox truth from its dispatcher, added a shared lifecycle-audit + participant owner, and kept feature handlers separate. +- Reconciled trusted-main 73 PermissionIds versus unmerged AUTH-07A 74/50 state; + every WS-CON ActionId remains proposed with exact target/principal/facts/ + guard/revalidation/registry/resource/activation ownership. +- Added canonical service ActorProfile binding, exact callback assignment, + actor/link/binding state distinctions, per actor+binding rate control, and + dependency-safe deferred retirement. +- Extended the accepted REV lock order and assigned every cross-feature race to + a chunk where both sides exist. +- Superseded the advisory PaymentPolicy direction with complete semantic and + physical removal plus TaskAssignment compensation freeze + one atomic cutover with drain/rebuild/downgrade rules. +- Split persistence, services, delivery, callback, evidence, reads, operations, + and release readiness into explicit contracts with exact allowed/not-allowed + paths and reviewer requirements. +- Added deterministic ADR-0014 compensation adapter/factory composition and + prohibited provider-specific/fallback/service-locator construction. +- Added exact versioned event names and a conformance matrix for retained source + invariants, role/privacy cases, races, failures, replays and live evidence. +- Added a normative runtime proof that erases stale coverage, retains immutable + attempt-specific isolated-PostgreSQL metadata, preserves the 78-percent global + floor, and runs a separate 90-percent report for every changed subsystem. + +## Commands Run + +```bash +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_artifact_contracts.py +python3 scripts/check_loop_memory_state.py +python3 scripts/test_agent_gates.py +python3 scripts/check_internal_review_evidence.py +git diff --check +sha256sum +git show HEAD: | sha256sum +python3 scripts/check_stale_authorization_docs.py +``` + +Results: + +- Markdown links passed for 35 changed Markdown files. +- General stale wording, artifact-contract and loop-memory checks passed. +- Agent gate regression suite passed: 71 tests. +- The internal-evidence gate correctly remains red in this uncommitted planning + worktree because its reviewed-SHA protocol accepts only a committed candidate, + not the supplementary planning-tree digest. Before any PR, commit the approved + planning candidate, rerun exact-head reviewers/evidence, and require this gate + to pass; this local evidence is not PR-ready proof. +- `git diff --check` passed. +- Superseded after the 2026-07-15 end-to-end reconciliation: the Markdown is + now an editable working transcription with a new truthful hash in + `SOURCE_MANIFEST.md`; the generation-2 PDF hash remains unchanged. +- Authorization stale-contract scan intentionally rejects the unadopted raw + candidate Markdown for `/v1` and legacy human-worker vocabulary. This is the + evidence requiring archival treatment and a reconciled active spec in CON-01, + not a gate waiver for an active document. + +## Remaining Risks + +- D1/D2/D7/D8 and the callback PermissionId require explicit human approval. +- Original PDF disposition remains a pre-existing user-worktree concern; + generation-2 PDF preservation and working-Markdown provenance remain CON-01 + gates. +- AUTH, ART and REV prerequisites are unmerged. The WS-REV owner must adopt and + internally review `JOINT_RELEASE_HANDOFF.md` before either public surface can + activate. +- Exact migration numbers, merged symbols, production adapter/provider and live + values must be refreshed at each approved implementation chunk. +- This uncommitted reviewed plan still requires a committed exact-head review + cycle before it can be published or treated as PR evidence. + +## Stop Condition + +Planning is internally reviewed. No implementation/specification chunk is +active. Await explicit human approval; do not start WS-CON-001-01 automatically. diff --git a/docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf b/docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf new file mode 100644 index 0000000000000000000000000000000000000000..72fcf5ac72442f4f7132bf8f7458c0b9cf8d2e36 GIT binary patch literal 283397 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 W$v*R@FfEGaxk5W~)^U(Erb$EY)+$+hVPU2E z0C^PxJy{l=D9)AuVC4U1rjX_A1xf(B5dR(Pv;w+wOGou$@AM^V@Hig(cuks6pDuICtR<$H0YwwWHZ z+By9`GhQC(;sL>*TB?@_V&xT9WM7!y^nmUv6SvUga_gXVvl#+`rC#!7`7Jip-FdlM zEAy)WYLylc&pko|&*k&0UtM-g_WidfCe869Esiy^7lLio;&0Y*!5Y^9T=kOT**ZeR zva4;mGDH^uhqTuzh84OYH%2dK3W(HGK8~ikdWeq4?C`QH>Db(`VQUsAgzv^ej0nDpM=L zsuv}3e@|qVlH8FYw<5Z^eQh_&)x$&@9Z6w0 zJ_wm%zyTs~P#ZqQ?Px2P35*A4i~20cz2n6mSeYJ`EM(}%WUaGz4EpyV6(=p z-oFql&?e8rcOj8aXLc%6lQFowH-1kk<&G%AOmGm@2tc(9=hDGMWU!IE!(vmM-Pav3 zq&J|g`{Ya?z5tpzw4}=&i9VZ77TS}ZWUS6I6UOiFdh*l`vNC>_tgd?Bzng>B`LXVl zc=5;QBk@6YYps%NCalr)j_{3hzZN4+OhJQ{1SN9wLT_hc$wb$5N!O6q^ffT^Qr ze+?&D6BF0vF6}XP7hVm|EJeN=Qdjhv%w@zq!J@;0j$^B>wyN8FIe8BSwsk(N(?FQ~ zJrC107Om+Cd^;VEj5hrKS`z+qN}Y-eLe9sgF+KJ^&C+YtZcLK9t!&2Lab+W`rqThO zJ`H1UuP|I-At-A~Jz1(x-kGyz1V4T@EpE1tY-_Eik-XhDnc6z?#1{K|>Rn;#JXRY6 zlZWTl-WBTFnpyhM@o&~u0R=k>4=?Bu6!i0{jF>OLo1Itlfl8Aqu+=|l}G8(EtiXRj?}QnjgYA?nsP4#F5YR4cX2~g*<;Bshl%5~+QC^;>QrbUuq)st@-S>h#AAI#4^Wd3l?%WE}-uaNHOb+$G#>(bP z6%OuCgzGT5;zk7jK2l8rZha-2rsC5NjG8~RH)Xjo(;ak z{+Y-4W93&WoV-5E>(^ z<&~7-tbYZyZ8PM$%@_4qAU&F2V9as*{PUOFDG>Zk4oik=V2i(V=QoNW>$ZR@k&uBZ zo{9eOrz|pZRVV&b5x@2(>&p#%nL1o@rT&7B<%(7@Ot zVD+wOvkc=VW|d5&b>^XOQNMKRCGmEAW7^q}1V0{E>%qkJ-YlbWLGdHi6aHM+JKwV- zd8JD0pjHR-*TGu&0EYPul=X7o79Djrn#=~s2wT|vaaUiq0at3YlhU_3Dx(hDmutAT zb53+N7)-6_FQ^HJNpM=*?bV<`D+VzNHLJsO^z(ZY!l=@(G*2|mu#N4wcig3$XZ_UA zcQ7y_oyHo+_pa@|?@sN>ZUOn?E1Y3pdC{_#)jYZZ!06?*cE1W}dUnZsvPdE*Ljg@Z z;ypL7rxvlPy?)>^Y|BM;63xF6ss=Zu4E4prPE;z}o zVK9UC7sZeZ`R+Ppgd}@iiZ|_}V_Mz6fIB|x6RDA4X@YdL4yZzK@>=HatK(7j&;`|P zCGDF`#W$}uXS_Y#&PRX>jpLdI$choYD@TvxYqH*RHx}BTSc=sqS6IQk$nuuoJd>qb zv)R-8`Cb7|C2cutS(4l7cg*}wDd9-_v-vAOk>{jT)Q)CwYfjkku$`S{#iPce|S?(G@c?BTk2J8I^!qd6NgLVHs-umzZh0u*eX@hcoa0ZiwMAC z4>D6ay~*Am-m3L_U~IOuGrZrUy>=&9N0`sB>toP<-5<_&V}|v3rdV+!Q0T%``tX<7 zh8_=CBVmLPViX*#Vej9S;(yGj|5v7<-TSY0x+(X7eP@b})v}mXO%0%t=;#uKbcRlV zdRU|S=h=KC_ZMg64p(c93a#S($Ca;-O*GZZ*>=katGHEH}0#KvAGykLz>JH#na}0%(VL%5JxUldvC6I>*8hFEUosXGBz}B zjXflp(YgXpYPAgPTeh>jGw_-w^ji_5|S zTOoVvE&rtOe1Go$Ugr$ZH!Y-;Yza3V_zOS|Qu$yAcd3iBEzu_E^>-Js(_zC|vzjuE z{`GJYBJ&Phb@|0amXh`vS4d&v9*Qz)H=?UG2u--$aM*X-h=+}Q_u#9{XV`XBrS(s7 zMl)u&W)lvONVU5#TYv$n@BuAM2=ypl4QxoMu&cRm-){VwTQ-S#ZVl(CIVpyuSO18= z`4pgl(Vh{)LFuuN`=gZ>!aiH+U}Yx!i$BTI$AcO zS}pQe9Tq+LdDMO2Q|}&bs&`qV)%K3LP@{|G92&_1|D^RiB7j&izRL5%pScRsL!(24 zraCzuny#X0&QmQV(jwVSR`PmwsXX0F?OfVwK+{dMKW9|K-}TS_(rhGgxeP(4oLt?u zdw%+&DWJYA?6fz&Mp5sDCBtS z!cNLX61ZTb=ZvHLAz-v))GM{hv$xq^m z=y_EwK>Ax4+iL?rImxqucDkpejb4vE;|x%H!|U%=hsNAQamb<(A1!?>CaR0&lj(; zR0^Sy4ewGCaH~=fcs1-bKR|nNJJi4P&(RN;k7H>JjraY7xS0n{&?`LW@VN*MSGCB~ zD|#&Y{y1wyz?-yxGMAy6)pj{z|JIH0Q|q0l1JDW+-BIOE9tu+RY>}*bO?~>b{4Y?8 z7Uj{P3AII?{O+b7c(gPv=sH%7-Z5;Jm`^PGhf=4`e^C|#Ux{KO3WjV*#gg3I!^T?w>P)wG z8~Nu)(u|lJ{r1a~qO#+OpXoe>roH0aOS&aMBcCG0@ELJ6@1-Aa(+c0V>sIjU$ldM~ z_`9g$T!e=0nz>>v*#|^|2X1p~!1xc}Tn-Xfz+c&gcbvl+AL|A)Gpm59Wxz z6B07+;eI(oX4hX{(%5@%o(}rz#JF`f#v@xhFAV5|)TSr8J89ISVW|AaUug-Dhl5+D zsv{#2M=k5`fGn>?0r(iD9%)zP&S0Z(w%sZEJ+`C4Z1>l#UQJiIlzR7IIzQycF254{ z7c525RkJAP!`5RS44R)`3!m&zp1cq3(QI}6Sl`xP3mQzv>YiM6Ll^6mA?b6UdN6#e zEKdD|oK3Fwf)pIk>R6p6)&12ll6wM5y?yRcuLJ^>W1me!#z*A#45qyXTBd<-$)C z(@DK<_WDj|0Lodj4{3r8+Iu0!?P0C88;_vuj~YXSilD(|(-y=uA0IVzMLhUIY*#uH zb=R}AwMWBC&@;0gXSE(v0bRT+bYAl@4RNu1U9T4U3YEXv;a$<2S65;%*OG9x;{phT!zCd_ih$OQHx4wqBqhyvNl-ZVphgN{*#z2?tYO|3IC? z#?9Xg!=d{j31Mf2iMg(GMeQs10PfYBSCWzBDgr=IZ?6#oEFb3B2z!s|K+450do!EaRVGgR?9qmuGuDl{hR3?wg5_#F{{$iv;ME@{{mNz9k zm-t=>cpsJL9xrdN)oQ*f>!2689vo|X<_|_eZMNzReLB>~y{~A7@qnwi5K-r-^IT0m z@#%Oy^lMv^ZSI8ec)L0u=KZ}g8!y#_A~4mULkf1{Q*gI5;8F#xv9r#kyCNd}dqB+U z#+?+GrZGB=89|z@H<`Mwpp7^_U4|6B{5a09EfM0}zNNVvWZMoU3U*6CuhAoXQ{Rhk zxpYDTYs{z8V)>}D$6r)qT$tHMiW~LrlbB`RyiTNi1-7iAOH+(4;!_I*>iSK>acb0TQ(xd==M7yxsI*5KY0Hw##C)12|r}?$gYh?oEHw$ z1FqSXC4xMTK^1S~fYwdHM9f}7>C%~+8=9NTTqmK*{m~!oHN_TT{V<5+oQOMbwu@)! z=|<8&)_7_H4b6cK-lSq~IuC3E+?0RTB}2;m>4sX%vRE)}vo^XuGf4Bc+EwbELga5{ zBA-O5ZCh@BbMfiaAzx<|Wv!w#+5UC8tK+UOf79XV***=k(htxne>jnm<@R;t`Dm6k zz`bu?h`;UaNG83G@{47BE?wgN?+A_`QW#0kgoe1T!OS+#kLY$UTaik^@ zc)a$QF^ZN>O9dV71gNl0e?44Q(yG%Dw}2(S|8>h-lotS2Q>DUt8=?=R-5)4rNe5$| zBunm|O{{XBgQvFM%Dcm@Vei6lsJ(Z5J8hHcs8QO_c^%Tdr?wdKZU3Mz>kZYC<$c#c zhpb@F{zw7d9(J;Sq=hzD{+us^YA~Cc#IG){exk@4f4kX2U~YY&cA`?xdv8|fd1;2T zozZpHbn~(70&;w_-hPl^U8%*5+w6RElRp}ZI}=2&|GBNp?3s0UY5U8Ws&s-<;Fh79pq)T;;};S!fWU0l-(r{4OsEgKa{`RRw_(xYylW&M00;L*}v7gRp6}OSnF8q zI28vK+POsK{5ovCy@X`5$9vi0S_^CSdPVi;q@$M4{kKrv;(wU4Xs9}V-#in)xKG(& z!o#B%#tZp2{u{1zV>?{W<;lDMGq?M%K4jPI zZMhhto966J*K*rmEf;}cJ+tQD`nG5{pL>t4+}PSsnT z?9g~d_vbS;V$54U@BPtrBR5vcU?!oYb?1R5TC&UMSxv~^y|nL6DgZJ|Hthi97f3d+ z78p|5KWv$H7kSKNaGrlI#~gG~(Hq%x(v0Zcue?w>89#31`&6A3unDScDX}JEntRv`Vj&hB{iL+~&Q9X0;acLAFOve0{{4)VREsS%N{Xsu@)PZ5NmE z4i&q2e|%6S<~o!!bD{pC(e%EM-*qok8fxKC_csMLhuW+3sBHp~=#*`_X#<@zdQ$t_ zwW#fdCGko>`@{A7J@5-J_clA;o z59Ht|Vk3ebb)8(A*Za%I>OErKqHzA$qk2+7_f2tGJYARu2&QyYR<&RG-KXbA*ia4=;~O8Fp3Y znuxt3^TH#&R}og(n~1foeW%2*B1Bksy>crbFTdash9=S6wI_svN%Qt^f_Q7yf6B0E z_|$@dA2*pJ=@DF|fUT@YJWzaiterIJ^+}i=(X|byJ^HgA-C$t~QMdHUu5GsO!c#k| z(00m%vtw1CFtWmLN{~E!=AdF&_VqiH#*KF3Zf@OAYMdPFF^F2@_u&17#HqX=f|U(_ zgpP4onRDL03bvfvx%*saHv0p9TOIg1so;IE=k3Jlf^f3~VKgbP-Gjd`^-8`-qFWKY zK0VYsb39YQ9(wbaNG9%wtT4cD)t)pFXUA6QR^8#J5f#bJyTY8Oy_ho7*H<}Npz@pm z*pQicRKSmaZMgr*$@@Plv2^?Yk6Ma;;f|kNt}a^i%)NnEqOWK;)TVA{e3p&Jj=cg} zSmz04979ZneU2{;q%vhn$9cUt-Hrp>kV#$lh`m#B;sOH`p5OHMM4p&$!7o@Ba90QkC|dhjr|69c8;*wyc@4 z0`SWMyz5ad&bOR|2F0s_ZAIA1p4M3_Iqr1BUxw$$)$=`Url0*((NVd z?$|ay`%%ltpZq%0YkA`m@pc+ljA^#N^gj5zk2N?W|Ezxg9)j3{pLeiDHaL{4K~j=N zgETGQjf-4Ox{+N2gB>h)z(v4Nv7KYW^1G?2-k~98hsBZeDTee?~OkIV~;j}&vD}-#CNG(hMs;K?N3C_80*G95o$0>2ZZ|ua} zXRHyoC2@6{+iaU(Pim9qBx?(`Q>t|3$_rojalz}woiTq$HEQdYzh}L}R=||DKs#6o ztd&}>cATz`fCy{!LEf z(o7=z3yXu8F`Q1?Ti;Hlw={867`(0pG8{hm5$XLFw>lE?(kwT zG$*|e>+yBv^GtsEP$)iYV07RsQ}2uFmihvQ)(9>kz4>(rZqa5ND=w6^&*kpdFJid` zon6yMN&|9(9Xw>QaRiaBw`VYsOqF3*I_Og1&vDA+HBRMPoAZEVfU!L0(&5I1Z`<@6 zgTOtcjS8vN>ZW0VMUQ*^tB>FWqX91f6{N^nK$6+?(aGR1(Qeb<7uGuTW)UPBGJCw< zB<#!ji36RIrzvxL{&&Bq#mkOchJA@n(ibq@-8z{yuoe0mNaFE*!8KtHYzN!P==D-z z=o~EDH!xj0U!*Qo%L^?!9Rj!%U)D?iGws}(lKH{dkHm6e!X{0=^#>*ai)*hhT+%3^ zBln^yJ*LtEvc7G028+-0;ij?YwU8rFqr-ev$g43(K&l~qF`LsZ<(d_f{FWC(!F=g| z9(|3QSjuFLR7}L6p%vL|)vPzqs#Vpyia&i^z!tyv*Aa}`gz#S94j&m{khtk2tRJ`a z6)65av3xs#W!swK_E!NUP~KLDacf_${sq?Z)lrbwti68F=V`dk)9=By>R)U#dnrCU zA-{X}T_Kk7fJN5)o2<2pL1l7yh2GaF4?9A#p3yI@_s&e+(XnvbnpQ7GFcR6|K}eT% zFx6f}!o##R?*qW|nGsjpE?{WCl#jDNuL8QBMO4XnHIl#dGR!Yq?HAY3=Ti-R=xjbI!?>%wi^~DCZu^JGO0=^v( z^=vnov_90m45Yt}{>Lj_Ahq^(f4|8!>CxHT^7eiAy8PP*q=3|(-$P^cwcM#LZU3fA z!7~RSqftQlMSt{-D#%~Iw>&SdNB*lFGKsp4C+Bm*l^xuS$tJsnZNWe zCz$Gk^IMVA1RA6wJ^QTs)z5$L-P}<86<97TG?Z-~!*c7Q1RtezGu`-oAmD~2~L27>~cRt{r28#p5*@~y_5IsRFE$)77)-; zyduN+@N!&zuMqV5oSt77e3akx=?XldhEA#V4T|MT?9~k|M1$dYFYHUxv3-5bZkw`V zA#R1dpy7Alqef+1sb1s9dLc#HH#pVReKK?m#sy^bn&Ih^c!L)vh0)GQ}q1Lna?BAeioA0ja&CnwOudn(0B<${PB$+_j zRf4uXS3}lckjPXM2vw~_hx*q1V4%->b;Ck8!JF7ySZa1CA4lNRAxXP0jaOB5g@_erB zKMur8f7?c4H;T)vWOo9EL%y7#uOiuB_D`SYhO!G65*m;NaZeqC3|Z( zn#S@+UR6)%ibQ&sN^JI3`jVOCB5wEG*<%m<b-(o<0ovt82pN zH5{f~jYjv4E{Mx+FN+6*4{p6lT8!L#{Q_{s_H{;W8#kMw;=!T<18YmG+AQh3|2rar z$(7kX+y%LJO5=O^2HC7OrU-36MsMqLS+1NT9b(4@F%$;x)#7zM30LzZnd0hQ?BCUi zJKRQ=`HH>vsC}n_ErL7Lb@a%#!}X^%wl{y%M6ySEu$}mqSt-l^xH($M2z(L$u*r4X zr#IV|TIRIfDC8Xfu?5qdZf`>UJm%I4-+6_=w~IZ)Stwr%^jkVHZey-^WD$V*b8D5OYU|NpZc&v?djU*|oJPuKZv zew=g6M(z8yt?RP59qm~_+vNMXJBI}MFfteUzz9tHGKYL=`sCB^M~cqxa$de{gI4d& z!-Ag_i=Vr7OK4qgC^um@eV__rZ)hW&oYQvV~ zo($RQpZG^LhHJnzn;E8s_vl!m8*9H`*@>m^GKkf5Lap+Ji>pI~4Eu6Xjm zpD;0CV94>@TLQb_#sE8Qb;tc1-yw{LvCB86*WN{|9TT8D%8q;3!&f+GM)J19ln;6} zXTd|60{|z3-kQCzI1uVWFD$b~{_x%`xx&p(f@=vQyAOMDs?}lmSczRfNAyPrNM*HV zpYyZ%?M(QBksbryo9VfqT|=bjo@=)206EWF{&R~n^>6gX&z3Ib6DBELe62wyyF>o{ z<{nNNw2~XGpvZbzm2ZYv$M+Z2h6YEagy*zWOJ6)yfWCsbtj?rV3 zkP%ioeoqS|phA~c;hp!bDi1`VaHpw${OtxkPrYaJsuOC6{T)@rFB^Sn9F}?K#hzyLaMEtFFQZWX=h?stMrZmHG1Nm zE$!a$`r)HE9y&Qq<8#w0TzbrzfNr%X7O9kLqwNhQ<^~>cDg~{lEPC}lo*#sE)ddM+V{ICht} zBp8-f7UxZ?Kl1!Z3@P4r{5q5)%h7I2Q*WB{5v>(vX}-@f{#CqO$B_dpW7xqjC!?tqr}z43?+=GCOIXyQA5_;a$Q07` zkZ68fZ7r?6_GCL~?ltcCS)Uug4>}}PI%ms^uxvKY6D_YDRpG-%`y;W6vq#5OT~s{< zrpir+h4BUJ^7$gLY2e+|URA!*f+Fnd>hbKUV4iK)|41DmbW2+LYRWdN?z)sog;-2l zqg{QZSC2}u5aF)fd6^wtdu#Y+7;$5&9aK9tv&Rqb1(B;|*Yon_dWE1^CZDeG!14w2 zx;r)}4N@h7?%7CwVqX5lm0gGS-^c2mm#SZOr#hJoKaHvwB@qG**SztgCdH%shbT9K zZi`Bq#;5hFNp~{+gzXHh6B{gI?K`vmewzu!*oM;Y&tM>2WC`?8j3VJ9ZVX?*d4-#E@y1iqma9U zA!2H`@b5eIAcG(8-{j+rNtK0l86XL@25It_8mm3C(Aymy(iM7UTT?(H# z{HMlDFr19p-~B*fI~wbhP~irJjLYfGKNap>sVv_=?K`g-EI#v>CG~5>dgG4kGL=E2ON1)BjS=f?|vn^TFT99HQ3W(=w&Fh&HU8& z525psQvevyf+C`OxC&B1Yu7z^{btwc%C4cmCQh<~+HUvb)Xg#qp=k4c)adLV@-O>y zxc+g`YTu~bGZY$+UY~pAD_)~RtSI(^=2&lX$S#@65HisNtI7s7Wki0OHH1Go^9M3S z!{0{xo-aERu~iqa3h!%tZspODAsP4cXxc{#DZ-!=I1@tu=CS$it#@cB`Q~Gt`Kgh* z+vdNJnRek*Qctp4rOJ@H)7#bnDp5JZ0&r6o0+(L>oKqc>cBX zLH1@Wae0nPQ5CJ^;i$xx=~XEG4#4m`h*6gvk~2=72Jv^jN9}s&iU{hwRWBD@;P_<`Z4&yRbonM z`T6q(IibO+xW?g-G-x`@V^Z-u=6Un+qy~ zjoIn@+{EjZN`#jAdJQdf)_b{*OMV&xmgQn6>1cw-L+Z3b^VGL%b+4pa zZ@A9p1<93#eKwa))L?*>i(;Bp*&FW`pQ!R=d)eNsq@Ee|MqkHSV)p|YuZ?f#eiCO8 z1W13FTb&I&5i%x^ey1H3g~_Bm`>9sr4Gk?-^u zSC7uUKUR4*kkO~#fHgHkpxG)6L5#y+Z*YI4Qvc-*uEsR~af3Vl$bL90!V~`@C+pN~ zt}^4(MCjX;-|4Tg#@LiiZn}I#WC78K*;K%uRV?GuXf}s@;-S7Zp3RkR%%0I1A(cVI zg4y9yXo`90m3+B|*PI~B>hCAyGg^~>8+bb?)>f)ArDleIvs8mQWPawTHvu?krW<_P zdG5Qf4nDoGIeCk{Q~$H91jD<`C#{XK?H(GG>4)*HT!{yl6E>oc3C#z~8`DnChkgET zRC0CsNX2( zGSU4>pckz-x}{mk8~lXv*m9@a=ADJaI}`NU<3Sv4S>7$qe*Fa|tgrbXm$_e`mxr~5 z_tI$%`H~dKUH9PbyUVT#^m>W!lf)y_Inr&8B9iPQJx_Osc_lv#F0Qd!znzZX6H4e< zem=l%q%zGPI;k~Qdtd?#^*a{}ywEB_?YL5i2Iz3I7^-F1HCT}Fsw*xS7Uc4J?T?75 zFZ^joY|D5|Keczyi>;|Pms-owcO|F$H&pee%K8=_;omC6XJij;gKG0^bu`{yZ&u1Y zvtmk2J9D^OJR~;?Z1X~BCj1WC)~E}&ZNih#*l9H?dHzzEo0CB?-q1+i(F%LzD{ z;g5x*;H=7_j{K&g_!}45h|H4j$1}TapSYys#H}sezOxC6E=!RAYk&|SHaaplv01;r z-2Jd$u0V0^+l-oG_F675`p$0ljIWw*u*1`2xxL=v*X!!a0BCB}cEalIu(je6-}S5t z2GHLR{+>T{A1PUj+{$q<1ph}b*ly0H z**!~oGnfvlXgO0tS5sb$sUw+t&db^)y_-{{N++(Av@se;u~5IC>?`m!kr2+`E~57| zy=B+aQz4s<_Rezqxu09NQWN8B^Qock482AdH(fnFue_<$TC+8Ne**Aak>A>Be^-aT zaYj4yp+MGguH^?CI)~#B0j|VS4`yiPGpYM@ZZU_??laFk@=9|#sNAI}TvMm4(?0Z% zsFk}(>nYSu5e74@=3ZF^AfVVz_X8LXI+Z{!w=D)Z5isyzb6#5uuDMbc-`e`EhQGqq`p-6 zLwh2CGzbZt_n~?*537fBe&xqwcLC}Bjj9oDVJ!yYZ&&i2uTfqwB4c%eb9&f>D`1G0 zj@)xE4}tjMzpG}Udthp9C@2dTpyZSajm+jZ5iwJL7ug3{~1$bNP*VNOqd22lp_CP{IbPa zC{{LyOmT|m&L6B+`j&}9*@@sBmy@3MJuc%HdU}9;{{ULxJuK)9^^%o5%DhlFEA=rq zk!Z+*tfu-nh8og}uP+vlL`)5sZL(7|hwnqp95?)Joc3ys%ZceVHhwqaK(}{Aa}!up zucyD4fczwW^}H!TQRT&2J9m6drscd?gib^0 z%WCo~h<0}iQUT!Kr{Tei7Y8=n!rZzX1MMXoH$K?!w_al72h$m9g>#rCT=tMpaOd~@ zjGFvxomLLLgzR_FrsaZIzVC4b&DYOs`cpcg5B|>TYRK*#o-#J8`7}h57(HN z6W;yVx4JIX>3Qq266E-sM|RfagOAp^Oqt`8Q6JBqP4|*yiTS{*d{Wq$aY*J4uU`Ie zW z=$mU!N|+V6N!sk}C#vctsiIR}oX(pt#sMJa^LZe)z3JW)c=Oob%G`Ews15fg6W$H2 z9U9CZ|NuY6pb!(i0!4fCC223oV=Bnn6sN&)DSU*bE1x;>7KoM|Sl&aek8q34Hs?-M;EU zc?F4`6*s8?8R_?v_9EYRq3){ESjje~ zv^Ch4gxVv0x(-6Zz1d9HZ|98q!1mSisI)HcMo|e`v}${aH%uPs%=+st zaA<{M?G&x-EVie*ujf*L?P9M~N0pX{fv2t~mv6}+)BnTaYRcYlm?YPu682mdu!3D?Wl?RgKnj;KaCYorvu@o^F=Qr-QIr91In zqSCR6R< z{PNk(wEb8JC#YBQ>v42eaPYexjB^i=r_XM2)*>eK0ZxTZrRD_JC4g__@+0dkeP`D? zq1i%be^6X?a4ynrGAPjuI-o>ZRYxyWR=K8!oj5c*ZCPYF*l|uIgt&O%)jG!Ho zb}TkKh!Np665@>Sq8gD` ztc#O-A{2yS4mN?q)Y#mVL~GE-vmfkBV~MKxTF0W-HX~;_-#fs^7|h<0(lH zl!#n1gp}!toGh^4c4=4wcX~q?8Y_GIZ3H64Xe67D%mM?lJvkhErKDC_OTYt;#;t)sm%^ZupAo#9%F3p5~XLlAYZ4fy0`qGn!5o| z!&pQ?sq~mmBSkCfnY|5c$AD_}fNCXfEkxowDukZvrDUePtWwsM0j1wY=S;ORKenff z&M)f_&xN(s0c@mM8T}x2#+ve>{G|4M@f1Xk&|$ zT7GOV{v$xs(Maa-7NubwR+Q6-{oGso?>%)SsW!iM>pf%Eo%eHFF9-V>8@-OhvsxEl zCFqn4&oFNwm|JZ+zKwQ?hC*p3e167S@wWK3CTwSXlgmb)TBF$`6?A>rT2+eBL2jSw zkQn-uxm7vj<$Bxfz$3G@)P4vpIH{$xCtfVz{!h&(0$#+v3?~ zrqP}js!Kkb=A*Wv=+kLv3^S|sY9V;-*=a!*GIK-M&Oh7k+N(*if`7cj>s>xrL0>p# z_1e3;TVJ1^dm?MAQhj(X5qrt|E<2v*hKJL@w)>D{5yzF2>L;5+2Zh66MHp6IN3%%J z4I$_#a$F+v2m5+jvi^Of&2rx(ESPg`n6+~}l%&doL;5bR{lRO=w9(Vgl9|HwWCR%l zmZe#$CD>c5g_P*U`Fic5nYogl-u~u^tfEC#&i7k`?=33PLA!0)aJmi`i+63Dsko-u zCJV#!BeGbseJA}9`9wUNpJ$dQ<*&23 zf8%u{>3_`TfNy>Je(bgGFkWvX^WE~Wia+nFfptSmAl)U_AU+G1@X$93X{Ypl zG$8+uhj;MjD2~K8!*1f z4|x&*RuiNe4~yIRX%;kdxlG_1)8>?%zUdcKA?f$60obNO>oib5Adk%wS%?-R2LEaw zHU40*1GPq0v$Yf)3 zTW-J9+uR_9_s=+X0$*>{q72=4Ug8T<6q9dGgv1{64T#UAe|z~{{jj>>R;K5#6lDF- zcczs0w~;hAKf_}8IdXa+s#6}^qDhe0YwKOf_`jC&nw75`H+@_BxY{Uo zlJ@?tp*~?~a6)v_=cs^f@{p*wwLsQZ>bYy$tjAB3a#mM$_(ofek#L>*xX~}*$cm)* zIU0wu*KV5$!Bcx_3FQTCnrU?zi{h!gLQ5cd9vWoKvOwygQe=huoR7cOhWSfcY$9 z*Sc~V6vL6y8XQl3gyLqEsje+<*>iD&&h_Pn{dBZdpyT$m7k3c7YN0VOjz<^exDfh+ zk5#zBXg*_4KWX4}?esiRdi8>}Zw)l)y@xa&m;g%n<)_J)SC#4s_D1)$)Ce}jaW;bh z9n)<8s`cliikO!Eyz#~5x|D5rz0Y#e!Eah>*MmlGn<9w7{_2$rM?f^PrfY$o&yIq6 zZ|Giy)< zy^*XLGGXU=QW4Ci!HY+3PF)sfKO0|%KdIzGu@?!3!7J+=V0~*K_mGob3+k23SNFIv zGzKhHL8IX7<&1W9_$q8xZ0nn$$#%$%NgpH>qh0%b3XyE$WR}H!PH*1`IGG?1_HLhIadsPP zdHS?rEQOM1`*O2fm3jkkNX%8)@bbQ>&;_;HMcc@CFIFmob)_isyrF8}ao+egyQ-6X zyv!<3Swu#|Rn^$2Np zj8XSQ7qU8JyF=f(bn&vkpftVmhlLjn-a!8kYKA$!6T-y$uCV#Bftwk+;~^L|>gpmA zvDD*;-n7piLNu-GdU0X1Go!-~-F%S2} zT3ny*xrHslR+#r&y;%w)*ID+v_K1SBy{BcWW8S24MVs6ph95#zYPhx7fICAH&8K@y ziz~i&VDw(^t>`elY%F@GD^BzM5Ida~H_N7K!7Jf(T(g@@^=-^1nf|i5D&Dff2V2%S zv^L3{qOn0jEi{jf%9TRbp81vw$$MrKLRa^BKBiYf8}H>iAf_aPtK6??C6}_wa_KfW z)_Nf%AET~Wd#4L%T7upEP;!^pWO=Jdv+Jp$n~eVIb;Sh0f@#ISV>6-`zE1_1_i+m7 z8l=2D1wr|%Jb-9k(G{5VO}ctax589~Qeivp=6vMN&YCrATZ|gbC`&hdlgS?NPF&YZ zH>sLpr^H8y3LQ5`0A{MQ4VIxf3%esoX|CQ8H$Lv~@^nn{OA$jy?;8w55d+ET)) z_1$oqQSAXSsEDN4fgPZb&d$sUh z-0x$e_a4iq*E7i|oai2rJoo#p#-?z7l-$AZK?rcNq@ZpuBWJ3srq?V6=j8>OMdDI} zv(~`FML=sVi5^YFiWrvMT?J(~(%^VjEb!BhmulQ>B6a8Uc z0g!a>{eWy!@!H58&kwhLBW{&;jr-aY^n|Vl)w6@6x!PUV(t*1BPOT)WKF=Ovo}Woo zjiD}Qf0H%%FuNH#W7yOPrz$~M6}*Ku7?`=LLs8p1AeOX0A$@;f%! zC0?~5Ce;SKnwb&oaY6f??WZN_SeHvG^=n(ab?#vQUzq2+<&1XH;?35ILibhBwS zEM;UAyTvp&haG!6%W*eCT>N4wHlcXCQ74+I=Bvd_;ngkQKkZwS9=TpKRfeU^d*4}> zf^}z>%XKP2D^t9P{qbX6>JLjl>a<{A3#FtTVLt(FHLjNCA4xuQ9n=wL)@9^-q#j?L zO_?nF>sCR@N~^3slB?Z8pKfNp7pd|fzJv~ywgA`CU1>d(eP&*|?=$P3|C>f7NJ|ZR z#sn%#;3sX~TJ=>;3AoCW7O(Hq)_=V}S!US`IkNr)de%mp?=A)yP0D@vIS$Jkym`6+ z?#5lrJHNU_<+w@*jY^%(;b_edBQ86_ubr7?iR60S`q;Z+Yw`HSp?;3sMuXhWYeW{@ z7SX%;!qC2aMiyK@&EKfQ^!)`IbFRFOgJnc#V!2$lRzY@!XId4L`~a~HS!QR}7{8LQ z>}zTG2gttkrf3tgjsg(8TB5Fwk?4(b&JrMn2xs*^V!)hvj zh4$DUrV_6tTbwKVMRC5zMVA;pR=V;GaF7q+#Vza?hV^Nhu+(f%x<=Bw7JKs zM;(xY*&Hw%=_wbgTD9?>t**HDjn$r`tJg#GP8ZeLQNqy)NjePaKVcEtP#(8zIa791 z^&ZYUpLy77D4#oWaBQv=sqNQjEIyssF=M# zNuX9e?kXX+5z2H8T^VpZdQK@xvZr?7HG^BDEOH;NW zdmI=%Z9;D>Irwf*b>vcw_Z1fh59TxauKo5p7q*+Xsol`4Xg>u-F?3(bE%K-V3FQv2 zM>X+JpRU{)qiR*tP#|qf40~+Z&v7%d560zSnpON^2H5eDy>;Bf$Q>6Spo44hOgrd< zX0MLef!2xmmO2khzr^^q=i_wPWj{danChl5;ny!D(K4-C_RZH2-@oIK_}fwmfI9+Z zWbLZCZ3kUs`InI(9MR|X|RbPCGFWKCR127{`H*jFDzRWM>7AZBKWiO z_>U>X8aUA0ofvr@*F4_K6SS=*#o8-f*7L-N?ZRuNIn%UdTHwAAxMA%?%D$0%-3f-O zeaTm>QRdh*aN#~HP@BDTecDIY$SF|iK!D0i?@teD2i)SH6Z~v=t5r>E_2BEzS@h+x z*L829Ox?ncJNC6ZszKapZ2K_5UeEWH`3#yh&sP0DzJ2TJ3#ah?qW!FOt8R+Uvz_m7 zGdiyI(&2Ca@3daz!$_E;rz#$r z6`bt|yu+s#>0P)DTN4q=dN$-?2*QAQvY>dXAV&}Sf+Cz0I z!3kmcU|nc4D7(Yix)~HaQb=DsqwwY{uIXFzGlEp~VhD`&d~rya`KJC_6?mhP@5Zrpzkx?;uC#@8M`RxA z<6LVYKktBJ%Cw7r*JtfcntRC~*ER21UI?K3Th>mKY@Vl95J59X%x(*G>~A;v%+FqLZ00YoRkjPvmtsqN z31!MURw!%E;n^DNwB|N>(?r)}XVbewz!EpS4J%rv@r6`0QKWisHgpb}v+Rw+lPSHO z?#%pJ^r;GV$J)~&N? zJ^ZvPEX30aJ+eyCJ?(PEU5)Ks#vK}(_hzf#nms>r*#(*Gew|B<;kpasm=#?hsWE4F z!w7U#u}9#yNEYgFk?-s_!Cw-84 zZ<99XgDAr*-xOgK=Hb>7>HSVP%k9faA%^kHDjpno;stc|FS{|WVBNF6{=^N=`Udb;`k|?W|3n0 z$>f^@CMvT9ui({CZ^~cOe`rDA90|s8g%txQf z*)$Vmd=WlF8;mUeWvga$9~EXB$QY=&$eZ}xy4gec01M$bPgLVc>4AD_WztWB+*t8u z6{A9Ng9Eg|+PGW6HkQMu%ouQJ;&K5n?RGURB!M4^!2q9R-!d@M9#nU&HK!oTS={)6 zIT&zdzdv@laB-Uv?aQF^lq<~c%w9bq-vaL${=zD0w zbkk4N)fb0)w>uzTzVBq*H@2?ah1`qz0CvJecyApQjd7emync{a)fD!L(rBklJ=R=q zkLSAK=hDx;w#8km@j}>Cj91%Sh-Vmq0E}y#*R0R@3{V9n*9MS>hnx@<%9ASJ)zkSP0b%N~;`i>$4609={8N(gDjJhyWZF;k*io z(*m=d0ZoZ{K1*?pQW)6j4w~N?bmliLeuzKY>Efnd8X}6o{{ba|*Qkv~r9et*&7reN zkGXN!`()Yg5;}DcIgWPNwqa)fAFGAlOAD9(Y(+W5E!%IM; z$Ty-*Z`p1%6xP6A!>t#G`yb>l(xk0IOT6zxD2sa9JACc>8MM05mJ*`8*uu88TAE20rDePKo)cGntJX(q^>&&)8irBTm`>vI z06S98e!sB+iUC$;vLj*xOCXqf6RR6s zdan(dEeM|f;?qLQNC%_b$H>%a876^=wgazv(mdn1Gr4FcZ@!tdt^@=Z)gLD4TkV%C>U-lL!=fSFt&;70lH0x%qD}Gp z-6Gq>4%@|am?NZ4d9es9te$_v6b5Err`iHNgEG_0V1=N3J?*dDa?s&dKfvu6hFPGw z*}gF0E(}`Uj$j=_a@|S$#5Z4wkRioK=}EfQ$m!NQYT=f)Cy05VR6M9}Pfv1HteRNw zYMvX1^1AXn+5q;7Vz#k^=0+xOUEobAi<^0pvJJ`_HTT6WB^btj95GtGy|354YYW`% zP^oULTp6qO_*4HiL~K2rFvhadxfYmQI0lyH(+zizYzj=iV6j;|@9nlfq2hY&F)HNm zUA;%=kKF;=mTQfwV$jX@K9M)N1IUVeCVE~dY_~iPup(yWM)9uFU)iND2GZFzPjX4~ zHG0$ab!wg8x0SwE*+#$keAAndC!DCcmyJO%6=s9&Xo5pN=mynW?@m&BN#0Bs5OM8i zGkK0Efbs=DOzQh#`z6LIXSPQftK|VX{E*e!U!)CHfgqXO>MQ1&u?KJmjvC$DWj|u=U*5W1VWgg{QDpU6GIN=lHQVjb)Df8G@YaOTER9mxO z9Xs9&m)&VlDoSm|e1y(9gS{I0QrW8spepJi%>~z~L{A2(cJ_l3mT6MMgYoKy5?W~% zk0rg;E95Y(R2E4{k2H|U>BO}A7XZGgygaa_$;rV&A&7NN9cLRcUf`!-pA(Htuqyei zVzR9m5W0uBh>w`zqTF%G>Mt{DH2-?$`4|2dif#VG|MDkE@t?a6H-AGGhs*AUVw-7* z!#QT~s6Xl7n`u^~UD_?HrmD2TS3fNAmgykg;B|>^F zsm0Hy$eoos4hGvCK9|2OAi3=|%jUdGwzaHErIvsBw1-%W~%O1A=0ozY2TC zP396sEvKvEPv76>Z(>fc_cq9p5L5Z|-EaOCKqa9N@~tSvEoHAYn$!Kt2b)SeuJ-eb zf^2Axa_BVEPU|x)v_2zXa>89>U-Npm*@7XAd-UUa$~rg8OH~YMRqyVnR-<9@%*=}| zG%L)1=5c1{h+i8m2j|t(vLBmqpBNGLXOtWY(Jeji5A_DuT3@@ad?>O>M<^2N=$qzU zz{alh=+g=s-}i!_={qhrfG_o^8e}w=p}@X$tFEK^GB`n9~(IhCushJAJkrZZaIPVDh?Z8|la(BCU<6W3-fCsDB81a3NK z{mITD7uu`it|n#6mcamfZw1=Az-LO+?BxSPs#qbhW$#uKD)!>ph8*r-9V{+c@-D&F zi@ScJ8vRV0SK_LC7Mg>V3V@RLx7jM(0Nx>!A+6G_W~~!I{{_M%aZ1QqS!kg zDej`2?G|>nj5&$PHw0t|e4+d)e8tx7&UHhjkNs?YGntQ?^UnhQls2S|k#-NpA7|@0 zisVC*um0|HF=)&a^HUPyA#$~b|e&w z5z~Tse8fPGCFHzeTS@pS-c*JCaNDXaHU+!UkQqB`MS&GEO-Tr-no!qCKxlaSKD%<1 z$9jvpm%55A5g)CI+1K$QWr^CEZsan#&+`=27Z@VD8LyrzucA5qBIVPGSV06w#c-Y^ zuW*cla9*qL>@a~Sto`oWrn|ewdODvOlRZ)Em$2xalLcZ5;pPfTUpLd*F&jUb-^i4t zMf0pPIA|I0Q!3Z1Xekg0(U{+^5R&ueC+eI(E$^LPtzx{3tXY{Ks?;nWW@hux?6v#a zF-TsUUyD93BT=lEe{Czj>thc@eUAfr>aC`~4NOZ1omG_y#31aJ38F31Z%n$jghCX@ z<_(2TUcnEPD9t|VR^Wff&&}iwRH)-;!kvj;#zDj@KmW;2@a$`)&4rpjzx!9U%PmN@ zq{$~eD{eIX`@sn$+wp(hIhHA8d;{H3WlerTb1M4vdaqG^Sw6X0L^M#$Lmsgd3i)MlP~RUpYq?+8ak~f%8M>tLgXt+y+tz54VQ7_c_He(uM5hjjW16HdN|5m zKr&>w(xIw7j^`LCboe_`UFxPO{BporY- z5rARN4_UTir{UzT?MLFzVEXHH4>Vfqnyr67Wvvgm43*ugp#{>mV}qNJN-D4-tPXn< z``j5{jC?jc4b0@TkjGX^XR)(xrvvH%IqRZm<;!XD*v}7Y&DCaN9pvh3Zqu{tI}7%^ z*QPJ57-=^U+6DJ%F5p`!c?RFr21Oh{GquUiDG8OYuS&)@|9PSEP+Xpg4>?xW=@lQ) zD|!3KcMLd9AU`!r67dK%wHDJXzSSA+EhU#F|E4 zw)L18=y+YAl)O6;I*Uxc_O){Ho0W3SW)~B)wTabgnE!{g^V(Kb>(=eFDA9lkBM2%A zq6Ec2QZWz|MNu5S|88raa!T1}pLO@&&8s;_aSoyP*1oUSknCUu-JrTPM|*;0N-ncL zy4Z=vrZoKW;p*9rdb_`I2R6m9mumvH3|P;9kAu8yHOGf$ove%1qTji~Kj24?mj8o8 zOgx`;dQdz6hz|}GN88fm3l0`@Plw4$`8I^sW4mChx3~J(&RQ+3<2LfolaC^Q=;$n- z%IT)qE{+}}`v!-f^WPYWPS$WbYyY5^GP~biXmHGgV1~lj@$w5A%_Y1mNEFC`mroRz z7w4aT?wHsxq|{Ir7iE?G6-NH}QXU@ZH!3Z>uBt+FfmYJoN6hxG@*-pGL1Z>vB{iuZ8A@)!EpzUWMU{us))xS?T$m_f zeN7I zxjC0v3<6=%xx=!ZFYj;9!Ea8iS()vw04&+-tKQ3F?3d$ugWlzLbmc3C-L$%YUA2u9 zwBnOP3*!ZITf--ucHNy%N=O;=o^P z>Qz5GkjmfVlkkN7)`xn_l82p(dmm)f`7?oIVNciZd5|MDI#Je21SS}#nQ8nZxk|z9?-;f;tDzS-O$)mVLh5L>h&8>gTuhz zwK-#(@YP{}lM*c7!xG-R4j%{Q+=@nrW6!Olotw?&#>Y7W7C`pY>%^xn5VFV65kW;# z$SSKtb(PA0-&fizQ7?bg6y*CzY~^|O)V*NSq7>s%O|F*(_L%<+9}HUOl;Z~XAGHQS zfSQggS1~A^{n%A=5jTp*9IRf1ZEgJYeBlhQksZ4jU2bcn)?Z60eU2&eS}J|oP}DY0 zhd41Soy@=RnoJ#T>#R-N`Z5Xdaqs%pOs-firItP1)&OJn7@A>6t$@JCjBs|UKAPMD zBN27;XJ3oY?s0lTUJdg8wXOwckxzc)#JbL#*el#D>qhDm#YKmIN3*`4jB0v+-9Y$H zpxVvRU$WpWi8Tj%oYou2M0odf6=ZnV=V5 zRu?cVl8QW+E3F3H1eIs^vJF~FfBrihSb46xNb4r6`nDjlz zkScrLv^?-_$Ijn%v6J`X1hn+iXV_J?b4e(sR!a1vWz}IwSwVw<=fjpL4mw*UH z)2(W*EL4v;{C2JY`Rd2zSB^Y;3UE$DG(Pc0?}OZNb`EpdWFvp_^GamX1rEq4h#uO08zu1Yn~Dyp9TXhA;YRqWJ8KP8G^Csutw z@d*qI1VWv>K%A8v@gigDO;ui-<4cAV3wU_diSMwz!|u-Wc8!@7*N|8TUnL7X2Ypc4 zn2K0}SOHb(R+5WbUHg!{S#AHPFQKG$`F`6Z$zoGvdAs+MZK=zd*3n>g{f8LRk+BLm0Cr2V~e>DW~8 z2e!^#(fVAnY^va$a;G|sPC_X{*Uovpr5_tqQ}%1xs1j9Hy|=W6>v3)LO~VQ^VFMt-aW%V*xLy$f1R)&y*4z1_!D*+!83@L9RFawkB2jY_Z3)k0g7r=nogvZ__+u43Ts3zNZQ zQLZU1tT*Wx_WnAPp^*Eg!Q3=_%RByIkLvB`gWFK%5|U)k_26&?N-B&3m+&}hbi`k` zoOK||!tc|jb|{R>#fKeqlFPnJQ6UYyL+IsVqtAUZnb-_2Pr7S+(xCr}MWZ)3oK71S zkjItXr#~;We|NAk;{rWff9Y-bj3imeMXh~#%I3efuW&cuV~3fp*hvhSg7Y)r7Tk-c z#WCTAqerEQzj`OOz0-3}VI}L{0LsN)`Tg)hKu& zc)dSAO~E0iAEVcWKeo#%1(wWe!*?$J>l|7?H{bZ%G*)qD2WeMuY0tWD7K4@sXdnK} zk!!E=z>BL+v$TNnA-!-9?tXO9I*AfKps6yb+OCm+hbMjQDwxH0$#6qHW&+)6woWe{ z`KaY{<9XqsYI+0U8yDmtnK@BysuLIb|5FovLg5lI|iX0?~!$)+-Oz zm?DyQ5PL$F%(9Kewjzl`q8GKHp#Fa3M~b1n(yl}e2a?iuhu!1+ye_B3cYbTi2Qk#m zhxe9x=k2|cbYCV59svbC3CJg4IJcvXjbPnuQt?Nyw#?2wwT<3Tc*3ca&Ax}Lqy8K|gH{Dwo!8iO zO>7_cnR{DTBOT*RY2L5B*dPL7?xYWI%MBc|6pCFwuN{v$RXvg4ZdjLq=>0*Q z*PFHbb~t`~_i=?SpkIA!bXv$~LhpwYv0Jy_t4r`lFSYcY+job51DCeS=J^eF1d!O5 zXmt9+R>YTD+cUPHrcbECtKT~#3H0L=(8D{S3}aFF?iVZLvZ(ipKX^g#dVXQ9`SznC)Z4LeNp(q>snL2=Z6jg_aEm&t2mb2>uc;zIA%8Pvv3AMpJi zK83FtD1#lsj30k_11(Y-IWp!`_qC|$tIvmZJf&cZvAYm_cYsRDfbxt7S}2dNPPj=% zm1=KqYA{9l;d|G{HC zu@iQxIqAJ@dXA!xJmg(j_U?{W9T zt*9aic!ganxkK`DO+p5?@a?;Ex3rkeN6O-Ot{8=CcYBI<#oTl8cc>l5d2SJazvOkv zkF8!NtWT)*8J3+E+8C*odGx-Nf;JWmm&3fi=B`G7LKuFp2eZ7K(b1CmyGG{T)PLG7 zT|T_KnsM!J2iv*n*#PK*;l7)&VEx_~njt(!fX$#^QwilhCWjq=%iba$KB3vhfdO`L zXwlRBEXm>6+1*XL@q6sA1^7Z+U3peK^ zLq{OL`Kv3=2M!SCk|S#_x3B&IURBm>-R?xKN9qPQ@??vzihu%#Awce8e_mdWK8-u| zn5aGb53%^GIfdEa#Abnaa3M~RkJXP|Wud;-iu~MOL&@W(j);#AbKk>w@UoNN-t?lX zy_LQ<)PC|HuS>a*kmj+wT_CSli@vR3s88`7htS2zyl6P=j&C6;0~ZWua!rs$`n4J& ze@N%M+^kQmy5}w^)I`^;PWp?-z4o&|U1soE1jc$&+)C0m2!O?Q8O;KHc}~|IRh4^6 z$m9+id>H=@2=cx3dkH?fduAqt4dfg}heh&1M#Yja+P$S}@5VZVT-#kP!Gjhr$D8?* zl{<~UZvBvd1RKc!jbPa5MT!{q?I!mLcAWNXwYk*wwyoV$#J7+hzAPBD#^p>IdRI-E zeQ398^X4V0HE;{BAyyu|quS%`+zxrY6>jO0qgSX>aWKA!7||~WO;$BVyOy+WVIRtx zY<*_6|2S>AdvFFr9qdInDP?A)7Vwa6AU`?LNKGZSBUM>zndb z_Uzl;jQ=*ig<;2u(|b*(Fy69_(~GJ_6WL}>dSX>}kO9_yxtB0}A%jjGpcm!KNPD|y zE80H~_t}C40Zd(L3}Ko!GB0L=P~5RBe5Y+W)Dm;k2iL zT+P0Ubn>)+KFpHR9|uc9^7LBqq+je7^a{j24z00>4NnesMCgmQe4Q3&8;4BCbF5#6 zb8M1p{>C*Axz?}ELGqW|A6~y@^Oud*^Q)mD(FEUM$Laa4B=NP^$ zclhhwD+7jb3a8+$SmOpk9lBNYIAZ(UEA%(z3ZcH}$l#o(eXTx+MFwxy^v(1UUq$&V zP=>DZ+T5Qn_MLN9Om-k!&)+5*_f=KyRv>xRuGP0W`FdKnN6S^IxQVfijm%DT?g2&T zmx4BmMzYyHlFFb_2=Mr~a?q$)9~QnmUukxquzt{pB}#w2z1-|f=^GyGOQR{#l>3)! z{x-L^bR%l_%f(-?Hy2P_@muUno8-S=QXSwFcvbNxH}=NUYRcKLrLFWYJ0hUnN&@17 zPbJAkuN{!xssp(*O)LevXyDQ&#D6`u{Ra$Sy7s?UZ?YaGNvZbV4B(K*pOQKFG}}$C zc(SSWSFZJs=Yv&Z>%Y+gFjS3V8!A6J9;-i>Ws7?;pf2d;r-k{=I;HWS2M6`?w>*FP z{qIkQarGu1+S2MOqX!8(Rq0MEFJHi3A=VvY4GV3{DbvY8zd`uukm5BoLew$+D{a#i zn$ItS3joa?tGmCGCSGMVI$bDr>5~#n-wK}{Z-%}2ad+^!5FFqB2W@gkcSl0>O!1sv zAJZQ{10*a-ANQI?_wL7q$HS-4?O(%PHCN8awO0pwvIi|#v)MUK-QxFt0lOz3&`5!5 zciKP_DXZ@#WfhOG%DXd1N**uj>hxwb`{CM0`%^r z@cDI5t=>96*f-{H)17hc{KKLQ&&2+kfZM#NL~gSygz$R(6khaw8kPQJ;|RY4^U-2} zb|;I5eX4!7t!XOAr}ijduCT>{%bK5uktH2D!{l43tT#O6v}&O7b^DhDoGaP5{FghQ z66)0&mcj%b*JtUn@Hl;wGufF_`@YFb+6<6~qQM#oH4swY?34w|eSv)!haiBTG^wukvBdsn&YXlGoK zYdMRNlH{5l#k>rP(6oV@%elyZP1cVEqA?;`!^1syWsF%*t0!fN(SzPl>udS`Bi--D z%uKJ=hB9ZE)2eIog}v$hp=Zo^wiS0V30q!H;1wG5Sduo-JWLciRF|@>6cd!oI_g(u z9s#$pQMKxI$}@WH&x<+@(aA{;KbByXvk$h+ySJ+oSa$tZ)5^{2_sS^B`Ax(aE6Z8j zqT3BUph7;Gdf96DCF(hFExgN8RBaQL&d~T%LCZSPu4pu1G*m4YGM2H7;)h=L&aNeI zYdfyG)ffT-0X8HgZp3><#xmQyoS4EB>73qWb6TX5S1UIQI{N8L$YM~w8~Tctb^^6U zih0HvG|{cIy!?iSqG=l(QM^cTAN74nbsWFKW)gaYwxKg-Z6pcmj>(pH$D0Oo8FO?s)nw` zxW+0SY}0DyRQ?Vr{bLFKRxSL#ztRC&Wxr_;zj7H`y()-?dS zk)ct2`G2C|tI42?$m3*`;Q{D>s0La(vD)hwT-fMQUCQLt7zmL)5rXx_@I(=SX7%TI zVKa_ybq7Z(makF2cI~&V;k~PWP=tUke`sxSLNzX5SgJSYySNV#uwh|w0oD9BS%`JM zG|*lEK1$QwqXQ|SY-GLEBW4DH=00ZyRmh?wZ7#JQURfH~+uq0Cqv(SG!MXeBeS~K2 z@E(h_HWI2Rg#4!uf4GRoKWaK;!yGO9Yd7rI4(TPORVdNyR){GUK>WQ8phl=cMpf>U zzT@(R-=}o=F~WKA`D~y&&)o*S`fPr{hD3*A@4rIWVan}JFJ3O6ZK~~H-PyE^E82$Y z{0ty{A-_+uzzs%uaL5AQcUWOpBB*Nj)KkklSP-Gs5F66YkREO>x5oN(8Mr|c)g+2o zTWrt!+}3%2+(6}ZkhMnFA$|QbA{aeHSX3hnd^I259ewWhJt|aO$u(yfdqm68k8~ zmL6T2oCSY*g%D@4^62k*na)4kv%hBB$_JDEu1Geif;vyE(%_3d@-5-HAG}c7+xTno zprKr^c35A(ElEXOY*&YeOD{orlr1!vrRn!>rM%iZmi-DzHqsCCBOo4;OJC#*f+5oed$7pCjGV zDuV9Ad4+9V`er@)07;$I&_^l#BE3(cB~-$yare&LI7`5E_g>V}{iY?%jsyq7n|4dQ z!6^0)T)JW=C2J&(_pg|qh0kdyNmnbKTVC!pwYWXtWmxHDt>Rzt?E z#vJpkf!!?SwjE=lmoG*&uL?=MJ-xQS+t;};%38f$ktIe2D+5`U^Vf_|Qh}6yYyLsz zF``T6(!VCWdG{cfTz3&OxO?o^%W0wF9x74kd>+x>O1}w8Vc-74**A!?OrtuA>C20AtYAFt!57#_xTf`W z;^OtpxVR$cmCE?WS8mtzMj5;bD>RGfLrS_@~g2*Ss-tTa>`*Glwjz#n_^qeOKTQ>Q1|R zuRuk{*LNE!Z{X){g75q29dc@J3#FZE9X#@C`5QRQq%hZNe8i&_Z~J`4{Wpu=&EidD z61htk{*ZsYICTFLgwX#+1N_feJ>Zagk2YPbKD=Mpq;IA5w5ngqc=PcmU!9UQJ`Nkx z!umV2b+p*+gDOHFP1;l!BfY>mi8R zhU6TW(xe?hHS z>P)cp->8GWS}4ft7Sw|_MnbG>21gjkFy2D zCKGfLuQ2nrP{`?H@@Wi+hkukj6#b z$!z2kt;}BkabC^n0Tja5+v==i4o8+jf(Ou)EQR7H1YKkYO3_wUm}@Tjb*s0S#=z;3 z>147h=X&p?-ZIjwR=zmv`F*C1$YJnWlDUx|5$FWVE-8<%jteahHtrE=Nv9zEg9O1Q z`i^z#Ol>L^hNad_eLOioUC|=G`@eT&Y|ed=3a86B_sQJlE(aP_J^Jf9)lbjs6wmpr zNHr~2>V23p1PPjrvS)?)6+MNhPgtC_o)9uz)C!tTEiqD$&pchOl_$c}xZBRXQ-{bc zIYb<#>3Le2$Zc<(?oFlb;)TZFKu5jQ!Gkzr7L-@zKQx|V!$v>*M$KG_&4X(D)0;<4 z@wlR0uHF)m+7oVEb4gqbI`8MHYG2Chp4@%jf?O(q*xHUM{&lEt(p-(4VMJj5wE)b0 z@nIbl(nfcaT8tL`)CpGQL`GRt%4R@Qp@&j7v+0fCSh%C36P3Pv|IZia1JG;#%BxT? z>GHTiKb;s~+GAmR0~hhI+iouF3(X0s<=MCOkD=Y#TZHG^7o&B5YK>Dzyp9|k8FN{Y z$;9W$n!ZXERs*~56n5Q*LCg=gvok%aL^}Tf=jigGOYEF9u3PTCsQ<=k(XqBh0xY?T zaa-21C2L;yHlU!CeJS zQsDsM=LF=Y{egTO1_(YM^yBesqQ`S-)VeiV)+RqNuFFN9BjJ@ZhC|i@nSxWDecy(5 zu7WX7DP)BTFDmujv-Fnu^=!T`nMzCc3$*~JFXzwAI4wFoefxIb%KX_T+ZFbrl|Q28 zb2P7cQ}nN6lw`WGl6{ywrcj6J;i7vb7=o7DfHMlGE2OyY-|xR$!>XCed3mCpL0Vjm zxN5U1I@Im6q`Cul2R-n!oj;>J9%SHU0BP#oQ0a_2&y9F~wl6{H8Cuh5YxMd#Nv<{y z`RQ|tJ1dCZyJG(HXdEP=>GZITf7y(Aop$sm(;VOrR$EC5he@*qz6r*Tv`9>%NxyAFa7P z#rygrEgg|=#q=y2IwgOZ^Rw;SrUJLj6-b)Lc$chTS)uJU;yEGrum0XArsSZ;!tqPk z5COG|1uFPC*?g%LgOyjlJY4yYYFDH|>dxv82}-Z?-#H4)0u3&}$`lL|;a6*4yT!ee zl$x8wRqF$ZbI|?h{p_IjsZ|`Fy7jyJEv;*oS7{z=g`QE=RXS;}{viRNf=E6uV|Q7z7Xy0Sk>+jWA z?}ig+Him}CQOuNjb8;?bV&A{qo{}KY2d<9O=|Nigb)d`^l3=8uBkgv%EuPHdpXL1F zu`}h#p7isK(rY(~JV|Ek3i_A9(mF3QSec(sO{~OWg)!gZkLqfuS}-FYDWgj@mpjR% zU-`YXe|?|-C&1w*UHhN=Td2u}+<_}fIAdvGX;N!_9UnEouPJ=0l}66vBjPt{QBQ7z z*WN9}I^yC`OI=qF;7-3BlyHJxJ*oZj_xaMh6%eL6-3(}Q~)<*@=XlG?fXpUvs(?1|=Iu#>73gkReJ^CN~!!#7Qi6^H3Q#cp~h zN{cq^;9At7EsfM$7vD6aqW{quR@h;M97Bfm}<+rJSm@@}~eg>z({cm_sIt znaPuRoV$0?F_ak7qtgGwB@i&&o1&^>TA@*mcICsRelZQsI(x#jRQ+~GNoP_BPt3tO z-NVo~r28%Nv9!#U^Uw0Bv7AZQ*3^Jt$tA~Y{hHLtdGUN~jki4)>k`Ho8aEq>2$|Nj zzUc>WPzIuUwR@)~eDxd1lWPbPChLSO)Pcl~hTrmH)C1@f&QSMLjPP$g!0LX%?~!SV z?&2X)uh&8Nl>0|D$)gt?aiE$0en^1t+}dk_VZwu&Rjh{lSbf_?u5r7z5r8Vx-pgNI zwn38m#ahYk_F3WA*yJk*{cB;a(Ki&03?G8EgOJT>o?WZv2%f%_T8vJ{-j!c>_NIIR zkzF_qqJj73yGy^t@J_L@213IbzZSzFJ05SR8UTWvZsod98uI<1O~zmRGlcJikXudy zwN&+P*Wvg!T+-RunH<>}b2@CwP@FCuDO}a!LX}x<9mdcHvsQGUW@APjc2#*yw}&9qrf@gY0`kU7@VyA)d!}l{NaR8=FYAOOtHT% zenaeU3N0p5{0s9K8wsy)R$X)O-`=L&Wn#{k1#MNzEoPLQ6E)V`U<#wmO+c4*k z*O4-5etLVFS!iqC7D~CYSY)kT!0zm5`!`v^fwEGptwESkJ-?^|heP`MF8obnelhN$ zG3?d55)L;}IJy6rW%drGGQ#f_{WQ&d?So_IbAoU0+r|5X8tRa4ictF4obSg} zfb{`@axFMNX)bg#HznQu2LuHBk*7!yO}jjAmG0 zHV}ULN1s^cYKKyx=TP;V0n3F4G#|UVo~;8-}&f=N#iVGQW6QN1q0+jinIgblR z)dMH>Z$ArNwjD6f8v; zrd%%nc@tYop5+X+9#3Z=%X?Y4V0RYp+d_SmM+_;y-OH(D>;j@G5O zN9qN0NVW5TqRcjaJb%0hY1KUbjp0T^M?!z%RG zD*Xm`ZKmg9E#I)q_TD?}>&{=baiO9OupOpN?RUAI=G5X;C+$?6 zS%5EbeIpeg^}1?sN_DX60{NKn|2jQ&T4dMV5s&<8K&I^j)q$-(sAe~;vLDIyuS!%M zdgT{`jN`++sKsZ*X>7U_^IEs({IsGLIZatW59qY=P-W_^B0*M2UIKkJ>d#QhpJ;P3cDeHw%)(1kIp*?4N2gm57|yryv2mC+^b98y~njO z-LmWa9)KZLzMEL+lykHD=^e4n+w?1N(PQnUfL*ZSy1vo$eN{`dGkffhsUPuy#qvtN zs#$NjXZ16fq07HTakxDr!Q}FfRU!>^RYeT27kZe5cee)vAxLGKl`Kob>9>w44fTNvRD zfI&uF#iodT`qOWVNIT|Vf_R_L_+ZTjmCigKT)S`vYR^8KaW;H!NW*4zbUGafAmZAA z?_PfoO1BcSl4X0@fus_WGt_SqB&IjnjOE4XakSsdcua(xP@g?U|6b z>F_x}N*x8?Y(MUX+a%-Q5xCSHxj(jf!o2)(mSqn9TOVff;$X>XBP?z$jxz#zUH0=M$9v?4@ zKmj6wKI@-mrNQ8C%Uh&kg`IDAQFvdV-_V0c`jMShH_n)UJu5LQxA2d0*^6UF-Bl5~ z@HPv`!VFVVCau1hW!h<~TJEEDm^7*J3 zjq+}+P}&K{XI);l(gI{C`B^g5?9 z=DaTPQy&8;jQ_Mqqunf+%YdbY*|@7o5AZ`z`8u273-b?s6Rk>Jz1IkTm-_5AIzo3~ z30ag!wFWmGMoPbz&CKX;?M{1a-b_GM=R1Rj(z{hkXo=j*xlRR_&QX%ffh=t^sW(;W zX=_8j1=DeIyygdVd@Xf8#kmw>!h=fyUoV>a%lh&PHmg!S=~g0U9^6Z@nVZBZzI8}YTO zoDigp)#HTvOgjtTyThEdusHHJ1I6ft@0#^XdtQPH_Ef}k+WMaBN4lpU$GJlrfcE*Y zyyUi@-Wr5Qn^E+FCQomV=#%o389i!B`=|*ipA+!q;+;2VOcTNv-{yr|@wxbRof+aC z(zrV2iGsw8CnC^A!bjt5SZ=;FLG(y7OMWgo+$qVE_kEX{eQ|H{|pQH zQPx=#t2ErvHAvyR#^?9p(eL)W>r|G9?tIXC7s{HK7WLJpyc|Lr^JD(NVEIq^#cR~9 z*@fgN4dO<+4uZt$qh02eFA$0`i_!}W-g}%@Tc5&?g5PL#2 z(1mirx+_F!jGiS1wIh^hcqU8#7WH|B>ekikZrr;`{@G{&Qc9it(n8tT338t#0NMBDZ5lN5{-*iF4+ZeqmNEevzFzBN;Xxj7_le=$WEn zJTl>AZc<~0iZwZ`)Us@cCM~3U?Hyv=sKStX- zMT!pSqMz&Xs@L>!1W!Pgt0&xjU6`fX{Wd+NyQ2z`s6wu~eW*U1wfRlQ_dB_<$jWV1 zuq`{#gYx<^@4taYft%`dDNy^YYh_4?S;!cU0?1Q0@>yY6!L}7vA=ltD)eI9(wBGY zD;TS0zxL9gV>Y*^1SeHaZMOboyPy2)^(t1oUZc@gdij#mKBoPiQLrWW^?9CM4s;hC zS3G^f`cUKwYSs;0&~Apj`b6HyAGs{N;K-=?=UP~8=GE`)z7-K9T;t`-VKsJlhi`sQ z%qz1SfT`e9JuPY;SiL?*d*Q!!cH?!s_tZX+myLUVzI#?KP7f}&*UxbSZfFbh=8I#{ zDr-X0hG-eugsvDi`7602n-Uw=h;j7_Ok=ETtGxUCRck@YQk+C2)V`UmJine7WDT$_ zUwxHF3%a)3T4f2MJDzY+x)=;$t;$3N3qgj=+gFdXx8Xa(c9`N11h(7H7E4*!97<$1 z68OHZFB(SwhORs?d~(=&9<7c$vYb!dCcAiWgj*$Px6`UO<*$^ajHiHpq}tXxgRUg$ ztYv2la+~E;d^VgACU&gv!T?iS9y{cthwOV zsss+VAHRBs9p0(8spXEkj<1D{VXd|`Za8T3-Ck9knYnO7xlI!X=~%CJ1<2-r{0iU%B>=u)4<>kL8};!aibJILah)>v zmWm8mkv;?B>09iiGg%L&#rqov?5<+;7i2P<_IZM9(6pyhb-bADeGs{<)gX0#w+` zSEM#B$7W5Z>6voQJj2`)pUi8ZNd7@i*l$-^oZ6pCQ2#sH?jYUlR9L<;IjGbJkdVDA zraK_PushAa{;F|^wVaFiJ%%-B-}f>W!`g{m-aJf$ukChSQP}PRrBly0+x0_jR`2@S zf01@(TdHc=7X20!5wHSlKtRL-K>nLPnb?~Fiq-_taqAeY_lAxc_?SBzt8SiJ&zmP%ypPALt;dj4Ibe5!?`O7a2xX( zLVX6~NDamXg#%T}^UV{PG&GU1su_ zT^zIaDO}86tTa^>NEG*uZ_RU@eV%Nu*@pc<5+}az@oCq2}DYn9dsgW7}!loFwq>9$-Zf#)jtC3l2s(k?z5g^z0tk>T4*!SnKe%D$m zl@HIuDf3`@A%%bU8}7_?ILtZjU;R;M&?MJ~<%92TTB`T0dn=^BaeHs8&~1J}2Ze_w(ZGM+vo*VKUbJ}U zbY$-zH+H{o9Ya{=Q0k;MZHx-$c-$b5{N%|s-{J3?aQ$Wp?416)Uu3P<` z!A$OtN#`VWe-Rx!F#UDODiayF**KoN%H{}Yeq*xTsq&uSD>;38hAD65mD>PQW8vLk zaFAsw@Q(xf`#m2R>{butq}Z{>cfRv)M=B1w2RM2B+~K3>J~xZu#>%XNCdc1S50Oyd z#0^RK*{Hk$l%4w~+Udc%gd6-9Ht8MGAr~3^^A++HFkU#1Y<+$3sKzm_^xwlAOH5~T zn+NqKensQo>-#=L+25h)%`zK4zP8olvv;#@9sc@a01Qco-O~tvJ3jj^2$OST3!ABL z??P{9p9?74qQUm!3^DPbt@RhOK>Mg|kwWhqy^4I~Oom-;&TTHjd89|tcKiN#s+rfPsLwho{ zNUz`@TH|Xsvn<&sO>g&-TjmsA9vu~h1hFl-b^(jBt^n>0|Jl3M2!N01vT-q>hR?Vnv@@^?@0}*eH zS7%*aU(JGd?R-o-n>-BT2G|y^rDpjW!g(S7&6xiEZIJfsgGJ>J=V_>AL^uv}~hhb;VP%C>*1O?zS;w8X5$b}|b_eR$jZzTQT; z_`coQ;&%4Ms?Q*V>>rX;wkvmW+qM@xx;o@E9=}vV-_HM{oUzJ&{pWSIW83%3N6+#{ zKt>Gqt+2J4r|U{NEEwIDu|smW+{D^xz7#4JxvV8{@`%5SZ%t<`h$j9fOq{cm8eq`2qK2X)p!h#prT&^-;ka13fdf zmc)V5_m4Sq9K8GTya!cd7m$bGIb&QD&j8C# z8@u5PqSo0;Oh7;v!LvBmL-&2SFeUOOZvMDa3Xb3E7N_fQYIyYTr(x#W8n*}v$Q&;9 zt8VRM-)ZN`xr`8IyEt&ugZQy3eE*lP_a=TmEjcpK5x<>jV}{#ku51wDJ!(1Rp8s9T z7P5y0lrcp&>1`}d#RhSoo-UQuUELWz3)!Og5v#>qeLA@qSC|hakofPQ z+WB_+vMni>ykA??=L|zzBwqAEV0fHWp*K01rF3p0x{|g0eCpFxSv;(aWHdG;Hcb(C zGQf;wb+uX-eq1F=`1>rw z`R5LB*zEB3k$Mn-C^Z4_+|lZkDV}{oRHtI`ctfPopwcIFC@V#L)DNkuGCui}0eA_( zy4SvBbNlS0;&GGjh@yZs`RUfuUD-OuX72eKFwq)ol(7RkgOFhsJT)M^BZbURsL6}iN_&ogvsqRz4I>A$5A$jUpQjasvxrULuE9=;r~1qjH|o#2G%AkwFls@)b}OaK<|2= z!=5j7yYp#?H=^|cp$37q9AA)IopXQJH*>kD{psY8Qt^!4^g~iVh~|L^&@A_gqV24i zy?N=PPezk!BW%~7d%$v>y8UFc-SjK|bIn1TkquJk2_3IYWdC9CQZC2k;xog4@SZYZ zcitO4$ompmM_Mg7l|G_2w-z7~$mVtXmEh!NE}O__G>1loQ11U0eldL>k;jBV7a0f= z+11v$;kvJ4xDvchPqUDxldMTgcaDpCws~1xnIfB=><1eFSF@Q>{Q+(tyqLy*)~KV; z7B`445Vs8QcR8}>=p{%{ueFB}{@OZ^4vrTl&FTTadZ1^7vR6(94oh|*GkkfpYGzJ8 z9I!tH`8S6y*I|ThAP|=XA_r5l#YRZU5hwN)7oEswjG|}>NcQ>cN6LX7`O}Xob zzd;Co-Lzd;8q3)dDdna=6D@WlP81C4=L7iw6hDjmAXoee;h~Tp=?}}9>bU`Lz^hHK z^Og0@^>;yA#$;QiBRrNac``pWLqlaxdEx;u&2bu~xMI>NQP zYXLqJ>&At$dZ={C(FNK}#LJp3n$KaQgyYv$HllO<)Sso~wD~&U^K`2}Cit%0uda-P zR*g%1r*J~>--Djf#=X{A7=?a~FUd=>d6BBktWoQEHSY+tVIt4_@Qk z9f$Q*z~taJ}>uSKNaGz zc3l?uTGv14)D;sLCtIda7S`W;?rG4) zNjD#b!}+=rb?r(cHz?Jz)%PObqE`^Ud(0RFYqv8d1H7CD)9bRsLsmHktKab{es&Me zGAm7eLQee3oNh>~=^o!G-D&^ud_9>UjH|<0p3LvU@t2fZ>&LfiDY4jH?1oKX5R}}0 zb7QQ;sCxGg5JaXAdvo~RFIGc82%qsjtdEYY5yowPIG21<&szbpq4ZLxgxI= z>MMlXXYpM9BH#P!=H9c2>2u-r#(d`_`i5q?_wQ`p{E4m7h3uJo%lYZs)2(dFV{9gg zkhq+d{9DhD7Wq|SbHiUte?V^KqQLH=f=r#weHmSV2%Ct?u7QwHp?QNDtJ=Dzc(qe+ zMww9|7d$cicWBN^PQVgEj33hZ&EOubERNqA2Z5>71*JTjhcWlg_h+MGkWBE={;KpA z%x(Qz1NL;;cnMAYhxLoZWJc52lATCH+_=HbtGhj)qDIqzxuAACN9(^m$NUqrd;70c zu)oSz;!muevNKbKtWhEC8x5rSzSzG{M6p-xTns88N>G%~?hUpuqJNNvnT_e}>Vf^)s_R#~MxxJT>1`K(J!o(IfMDH1omt_*e(}Jz$ zMSnes@;tb3|8oL5bYYO`d3Weu+fKZe{yf(cM;N z<$Gg2G}`(7_;+T?IilBB$OTFc%#V%KMY?ds&~mL`_->`|EKi(~(M)L|4KW<4+k9{C zpGU-?yG^pScHn+UsFi06BsQoUgIS@}?iDh~&0Y|XU-|M(9Bf_e^fIMU7JXMr6x6&+ zU96B1b|0iw6jle$Y3hYav#{%Il-+`mD<)b&>g^s^FjH(b$OQf{dI#?X{}<9^7tCRvhSKBo_NZ&OxI6`}`NrpPDM^!z^3!-X3eW%$SF>r+S_qCutk5>}M z*O2RJlvprpNXum{v~;XdAk|$o9aB4~q|AH@fH4veMq%Dvc~qY8rHsuWYpeV%r9Z* z5=IFz;?e1y+*(M#0ykK&^;PG$IW!-=(SCeFc8s%ks8&DroMZNNf>|DP$-k>t!QwuB z@N_xj8uotoH=))(_X{@3R#o1WogdR)BVF-&Ii_*NziP{9y9Ke72)FAsBRcQ2gH{~2 z*>rw%E*)ag5d7@TNV_Z#&)LRX*2E?Eaz;CtlGW{xJTp&L`e+CezTKYciGb#kC-l?f z-(tdBwKFLl7UU+H@1+u0xZ@{RGG1?70TD2jug3yZZPunApv#+xyjEK6c`Y}r2<9_} zDQK(+YuZ1TV079dl8!GuAI6oDzuc_52+rrJ`1PTby;sGjtFDK(8>sVXWs|Gxsm^9f ztvJrOwtn%_CcZ$EfT{V_Y(;Z!pze*$E=)$jY36m?RpA8=1^(WX1(VOouowL!lzcu` z=M&@-PVYfi=XGX+x5fDA?R59k+U|>xyDhehy=Q?Omd09f{UAQ?tuHLV2)6IH=c2{>6@70zJ0Rx9Y9qR7T%)%&0`T0y}k+oN{Y+ zci)r4d?VSHmzwz$RE>Wc=4s<|dCpGJ~HD@lKC#>s*MP0V|Z(Wp=tl^hK{kq#8gqG z59<$sYc-tBKjU^>_-Tz+S8*8~fEs^vAuL|;C#9gVe!Nkr_0q_AHJV7YmuX;nodjZi zl|PvbIBX!nGEdCIx0Jg>%XHf-&-F>Gu$(Sl+Ov78TxF%PsbX5dYUkWt23os%-ZZ(B z25yA;@_8-E(@UE96|+^f*15`CaosS+U`1~K?JNAB@Y<`5|6L3_g_STzVBiyL_}NZy z$|vVj?~p$E_w|7ci`S|VEKg~Vp5`BQo;$F>f!xe4r)>LML%Xxw>!w2FyS2cIalN|c zGEJ!=O{iy&h$G=Sl*+9Gy2`=VhDQ1%+7mT7uCLoCR=j3PQAB_eX`uk0=^mEV5swec z1e?Q)Ic~jU%Wkot6^#*DOc32jw_aJwG%Ib`nDF%>)$F!9UN1tM2=&XJ>roYIpMzUp zpidXNff`KKlLadIlgWY3QX{W?#dU|di>q5ci_%t}c@BEb>hY(xN&KG6?S}-PUlk{v zY6+`WYNC!M&(EMS2@$q<&U@`k#(WKxJf_68MAUL~9IjLCWAS(z&{(v#{NoPv&QY1F z<9~tz{cUFDo~W2@d!#w zhgA-=Oqy2AE)O%EWQY$n=?WlSOafMr+Xvx#aKaBk6})9@*6a2d2n^hJy0m))K^k?{v0y?z+)J@FHZQ#-W@BNRCH>{CeaJ>PeL08IG%d6N~p$I5W;@9SUm z8mFhMdWRNRRpOpKSZaij=&6WZR!6mrm7eFlrwy8dMuCIQ6XO zR;KG3S>3AHUz0)mc)3fodAsus+RNf8&)?TnDtt_)`BE7Q#6rk@!z_j{xY z0intnPBXcN6E~b@+`k*SQ2)Y+p^4O{+BU!|FE1NjzBz(voBiYwH2v9ja~c6FM$4}Y z$o5I$X1Vr-A|F%=JXY2!XM+V^ONp5 zWH_i1gVjD)0gp~;nvDT$E!QF5zyocW8XK7fkySd|5ok=NnEY~|dxn_KbIN=_s&|9$%4o$ere%`+)wIxhdu7bx+?=YAp6IrAAB&tgbrjKs z+XMIt&ngdBD#dvi2|;>4)cv4yQ_O5f%e_-+{N6))5OKnwvI+K`PYi=S8NWZjpnsEN1}4`8u}06BrQG zVahOUlYUonFL&-mk_rCZ5YuyrZ$Z!k&!Oyy0R&AJkKT0{d?yO&P>b~r$P(iCo^2d+ zkH=zVR^jaX1vVV^Hq`y<9q8O(oPi<;&|rG;ydKgLn-$PKU3f=6?0#W$_YE+rD?&`; zXH*bND*0HnmIX+Y=>PWA)##rx!4$TZ z;Wl?_IeSZ7@6?p4^J6PBf)qbCzgYlxgrb2*Q83Nn>#oJMG?W$^f1k=b?anLXGStQ~Wzc8Aus!jj&F5kaJQTL*sXM=Zapnx?XU3>KFVDzFyGXIspY#ayvg^Ey3zd>_N{oqOF*IH|CCGNK!R0~oXpUwaRxSd>V= zmJ=4$buqRozf8Y9s*)938O^4n?{q42&2f#oFJ@12a zKKG9_0fF;p`FGqim%CK#eyGl9mDgLElb`dUSNRQ=pleO1D_l%dUR_{EsgpAH#1cvn zGU*)LNe$0WuN$+IsXS9iFVh&bTMy%uzvHm z$E1J4Kc}jHO{9QkwqFSI zTO(yoOv&Mh|AJq9JdH8~vMu>5p#uDqlmCR5cNEut0g~^+J3SS@#Up=RiovK;d6Z~< z6-~MJu9|sms)F(glG|td`EHTPEEMRXX~xxHxM=>y^tf}I$HaPXV1N_ZdS_*%XH3#^5hnDqrF?ea@QTcs#m z3EYwBZU3QFY}=1>*a2cJlOH7;Euz*gZpNkCYAzp?{$h5T-p5}t-yPG9&)l3`gIyLK zk-j?%q1v@*s}|d-?Z#Gl>>qN!?j{QeuQiwPk4&J->anTK9HS8X(){Y~?_nW@D?^YLXe-$q2hzyBKX{*=2q@jpRB|${*83gMfw3v;YRM zR%htHrKJ3#I}6*fB0Q7K9SnIg8B(EUD~|)Hh92q1v-Xld$yeJ{=I`-hoN8osJ(t35 ziZR^EwlSwhM7cX%{M~CrT$iZi>p0D&GMngx{!83)E;9!3PI(9qX1?oY_GRYF`gl1r z(_4Ki_}U$O0%RV^kR81@^2IGB=FU$mbL$LXDR=1XHki&omTGPpu>RRIV7!K)T&6^D zK;}le*GrV>`BpoU*JZ?PJR2j_oMp_;?%?G%PO@J=?(XC=`iY-csmI(7tQahQtz&0@ z9V{Af0JcDHu0<_EaK#14NSWh24=rQrn&Xc-LeBB4QoXTixU1IJX&jhpR5hd z##Mf7%E27fn(2fb!_ze?qWx2`AO8y0VyY=ib|e(E=FOeXD5+cPw0ykz)cxS)T7Zdc zrR=7M3H{*S826NJ0b@@{QM;8i+QU8|SXRcR@#`=kH^Ws(hq=Q$J|%@BVx}N`6WyDi zY30byRtCCecQV?=snh-7=QG&=qlQdwPftLK?Phs!I{}ImIn#sHg_X6zBFeK@_qsaf z-LVeBw0>kEUU}HA&Ky360_61d%|RD|h`X*AcZ=J2&YY)Fz`-B!WXgBHasCvNm-@Y`)Xr=nzeV1FW>4AhXdWQ?RhUZ2?RXw_Q;ak^!Qjk%oFOa*j=)Sq9 zF)K`n*8^uodXKBau9sB5pL|oCT4SsS$SiA&H%Gr#`;oCTWbH1L+90tD&lgo2p|xy5 zaZ#&cKlplR^A;J9Z!3y#28;T0E^% zdDS=#;YhybosLl)z8+sM7aLul5jRcUrW{;~sCb(B)i)gGKVAO{q?$&p{PCp|{iI*_ z#)~aju429xuZU|7N0dRL=WBnef$91!?*PAX7@a7#>ZG-;5zv|Z)LUCUsRYSC?G3PN ztTWm<1Z(;~fAzYa+STnGwqTWh{~Is?tgHtblRjXCB=pOL+BB0#1rC?5tUA0(vCloG z?;s99FSaEftm*A;we*_F=r|hzazfnW%pVCYvZHkdm`}aQrUVF`6_GYv}i< zET1=~H=pr+7L$Zqy1c?NaW~B_`o*L6PSsQI*Z)L>%eCbq;9dMOLhehtdeRU%g}5E| zwz&gPnC+gSp@@8$i5vm*B#Vbt?Ce~;}W6{7_&Qyl+7Ftq7CF`oZq*?Hz>i# z;P}0l;qk1_VPDw!B%n-%53_xkpPBCRauC(@^cd$zw)sH;!UOh~QMJO&_Cm9GQm#4( zM!?!en#Q_5!22WcwCl6>>-M_|Hhc~v^r&WM)5PYvH=g!Jmw1V@n`}@a+_5p-%HFcs zspVI9^YqDXeX(#8-UvoA-~IDl3=6d2|xbzfOW(Xyj)ZauDV z7iek5_vl2+-dxMgcizSttLBaL-K|B^vG$phASi2hF|G^!jQXK;KymD2p9e#@tKU!J zSvN`QdVUH5VCRKN4>m=UA+?yaoLu>Wu+ha+F4bQXK1T9&Rq7a*12K0r1eMzL8jiQp zvsCgI1oboD{_vH!0y9Jb9G3`CMX+_&gcHe=^^Dc8D z*Agp_C}cDHYOU4XehIFyVv%L5?S(`04f!v0hzxF>-Sr+Du?W>CFiW83@2cd@d5wT; zZDUuPS{PCT-!`hZ@&&W1M*CU@IrW$whUOTsGg`eF$i7!e1Kx^*$zB()k+jgkR>~{n z{l}hW;0-3$GgmQ;#(hJfIk)U?dz}aR%WVw_eQll((hzMx@NU|;l0*RVlZr<%11?JV zpl#}PzV_ZiPvXNabvmP4nah=Khr+NAph~S9RBuO~=UPN{uN6Q#WhNM}X>R%L+iP3;cDk5$lEL&O}|iG9La+xeDW9u~MZU zF!sGpN9Mz*t)?}ue3kXlYbTXiUvzaBV3^z|?jo=rc`%SMoOb<^qx1s@|9pcuW3AKB;0%%mbN=FgMl z9hf1z;8%-V&RFR7XO-Rx*-xnI4U0T)Z~Kj0)RO{B=Kb+dK*Cmtr=$M(YW&Lc>9~j8 zWPFz!m4yOo#p9=(OdH*Ujz_r8DO&sGfo;6;3MXK?3!0wM!zRqCJf66vx*)#@%KjGvbi+Z{MB&gi71| zYcX~IeQ;N}8UM#ZR`lCjfQg(NXU}|}$sXN&?YqAkt{OL9Jou-@VX;#3g;5jdR{5Jd zcq;A5G3w?mA+7JdL8V*t9~5*_trL22)D|iuA?V4B=Y89q*kAqbSoGtyEE+rZVP$GE z;+HS5!XDz=afWyL-*yv=MhON$gXO0>{_cNf$WKOgc1#LwY{AM^`Ow2243V3iQ{^(v z?pEBdF^o1}OdxIrS`X~dFTCyWo!VCC9Mmu~fTGPXSLZ&rPI@W}8==^lhR5H@!F!pt z-w&u|Gwi;En%zg6$>uq^?}iKu5faj92aQe=-!@>DvFvPwZmh-YI@02P-b;$}(=Tv4 zxy^WCR?XY{CjD}F=_upkn_py(nP*qGau5jLXdFsZ1BKA0kKKAKa8sc0p0a~NaSfB1 zm~p`scp4P$8O~Psz*_&B*Q{9AOF@$%0FGP0Np#zJv2xhX?)tSKw460RfK*4vF}vDX zVW_4sSRdkQ<_F!})faCySvnqeip_bsd#8e|*pVwm=ValJ=9$7uU>Rwqon{NaW&t42 zHz6(tLYOz_3>)L?tveTdj8gm7Ct9oxDRbT}{a6JIL1of=Zu5^i%BbM;Qg!Dk*@_$A$SWiM?J+7E8}|VGKCD z`5NOcJh{4DcYCb}^L#7RkbEwIHlS8G&Ls{8i!&uS(o=I{whG||TQ92xTl^j27`Dv3 z=u(}YRNWecM`I7fcqVD(Lm@8AhtBaZWpjK^vGvR(LC@ih+069mrCR(_JF)>Kzx%Ba zaQ!$a#r}sDfBgDEm6PFz1wKsg_J+SLHN7P_veMI!>|yqByOXEK-?GqF2`2AlyO46c ztoaZ=Jr=?8o(_Rk6wl!5CmI9TZ{5ap<<{I)4#Ha$zwn(SGVbNeTNdk;cOA2nHH#Aa z&PHtsNo1u~d~Tnci@2mqk0T`@Z5Z+v?IMuJUD|h>}N4~FfJ)^9)MvEih%~s~_pY&Xu7Er$! zw1O+_Bqo}V-rHhtl?v5e!>=+No4F^C&x#>C-wbx%cVyboA18!R)*ImA zsD8f*%oAjsX|8SW^67SZ8%o7Y7AJQ3&!R#XW|>mfL$6X!B2V{&5jgVwq7{%rt2c2^ zH#)1|r}gRHWUCCAIte{Z!rq7a3x$K}$)`b% zBI~1Ovaa=|2V_?OV=9J^=7o1UpT*@ZQgKVgJ-cZi_GEQmybp|8*bS~B3Nd+Uh>W_| zTktzx?M1jAk?;(X7ICA!OIOXf`sgK(tD}`LZg{b{XULGsrSZ*1+IHCOyETz5z3{Sr z*?1ENK+Z=(aRaPtABQ_Fv)azLi@$&2{R3<(-D>~kviK)pCkP*A^dAz#d@b&G-%`)p zAv1ETH(CR=G;MucB41&=;O}(hO9=^WVIS8lQvzSKH)JSH#Xbxrw)d_L#^kAKha5Z$E&I;U0vw4 zZmMaIuF4D^&(yP!73UdxP--FBQ^zm$}j?$?_owbx-9Y_Y-FS`O~Bb_fu z-sGuYBZS>xt`5d!(NWN$UW!sA+uWpLiN3KDQz@%py)0kn+UK>rj+-!JZaM7sF{+n* zC9j6z5g#B^|BD>+%XixQTvn(#C=V~$YhYZ)lPObYeFC(vRBk;Tt@R7Ect(SE`~737 z{S_Iy`mi;5@z*l3kw4{L7h5~W>%`cpt-a<~lw?dPYq(eEvB8Z4R{B`C z-P5HTp9^g7#{fa>oq4sm3w;^!^-pby=%*V}4lBWP+k=Ag-mgFlTsG*`OvZs^Iw;-@ zOlC0I&fZS62B*=gDOaA`Oz;E6+zJ7s_~HbrJSm+J@~18QOmi}(#KG(qWzmjMD7bLe2%<8z|JSGqq2^_hoNf z;X6df&jg{1cqga`)aHR2+swRh)b)~a99}>CQ69OnTR$^-$GuUdXL2$Y@mqNhe5+dV z=8tx=FIf+BK9t(Idb$1Z2JZ#fPv&R8xG9%IJEY&?t6slKpGo1u?d*G_3^Um2rgO+2 z#lf&Hgq3rtB)63bcz&47vWO*mNo_GJ^V(i#H?iDeT6NQe4Zygbkmz%~ zZoc~SE;NJ+HNKbI?wcRAWSuBY-RFQ!lQeAn*Xj3>ttt=fpO$ObyJ0YXF-U(>qkE_J zN}5&XwK9ZCCRvA5PJNQ?+QBLB(#3`psGU+g{hAB4M6_Wt{-MO3Ui= zt4g3jo+E@U_O3b9FU5`p~fk zn(QJ;GuCJ1o&N4e`_=&{@QTl)ApDl5F3E8OCrg?9_*7=GNa zE1}hG@U>2++~3Yc?c1h&>*KS4^;^t0b+ba0EgfhahhnYhzW@(cRbbQ1o?W$VPOCHK zqvkWgM9a_MIKSL6q1ze{W@ks=rES7~yx%XV7-D4m8pgf2TEgK523mmR{&V%lqI9_= zH;JSlGe~gfZd*w4l)u*r8(p3rvC7iTBu?XTW+XZaz2m~l8FPlkdHQH2_s97KV(#YBOK0SNGiKtu-n%T9IarRri zooDpR6h6|?;^#(n78i-2uPlbwS|~ifgp7t9>|IuXjb0|qfeG`un${V9noVMu9O@Tk z>5i0bMzfCKBB(tp%P8;h^3P^~*; z^IjOX8=Ga8zlz;8v|mQIO0G`V>6WW^jtVv>kIloTM0M*@WkoBfHp^c4%uh%nG*Imv ztEDVM-fGqYpf~gBu+McrAe9AqTx0uQ?v2BSTI9D7?Tgjhr`Dn-}=|@jfxS3<%jxqohH77WI{=+`c;NEvFgueNT%f$x zp&w2%LA54L_VTA9?2n+NvhPo@JzxIh-spej-sY0$50fJ`_Wy70t)Kamd+U`6xiD_^ z-@0aZN@ZyAL~;M$xwjpq7ysnmN?=~nHBy&XLx%Y8+}p%`LGJB( zV=m**f+;e^2IStdqig=$tJd)p8w}p+i5U*YgMDa=-|t=NLD5j^WT{a#%%`hG+RVjt#7Qui0znH&&PX#DDE;V`XSa{Q*;-#xKaUe!3o|I&ykX~efYVqOfQz9 z94>7eV!ntZC3S2Y@99n&V=KDap++>XmP$$HHY?0e10geb@Ah8VttH_hX>{K0vZOtE zc-ecCCu6(s#_7ClS=psxscwhp7v$$e#WI`IzSsmfND$9jmoIFxkWJ})>g4Bz-D*gd zA3Wy``5W3*QeKJLv1JAM!?&HwJk<*_(7Lu^hlA;Q8JDEM9nDU7(Jkc*o;($=mG)%n zR;8HnXH1gKfz@pTErd8t~_15-j3y%G1e0QA^KF#c#*$BxO z&-%Vz-HO&kbD?HYtRSAv*6^Y77WU^MT?iTQ=uor5SNYSJYq#8@VmDcLzp$ zqWM*_WNN~^*Vt7{>wE)Ri~&^%0KA*UOJjEsU&*$(&_sZ+Kx+He{f$=Jvvaq4nd)%# z-fHgmv)ElW?bo`EB{GpNYrWc`^u2aJC1)i>tRC>2aAG}DD1J7Mp^s&|U=u40H}f~h z%~}57!M{?K@eYLli|DB0HA{mUy55`4HRzRebi0*(1uoK4te4Pl}Y910_ZRzw-GKiXOa=lC`>FOQp?F z#h$IWXc?pBQF`Tjedomr>x6;SDoA)^>gx7iS~HK==HV4Fsk(7Zd&h@yg5ybX*Lnoz z0P&J<;o>xgfxWxZr~bjw$+Wbe z0^=@YZLY0G_bsr;TRq;iE-iF^KN)cBXriBcv)n_28TX(>xLFHTZyl>N!Dru7zV`^X zq$M{_O;Hf-SYgTMgZkBB|C|!~YE!FSgi|8ni~&qz zsq}3V!HInWd$rk?g?`S>1Y&*z@-FO9xeUrs%}??mtWcqD$36hn%T*_tK|T9IG^hs3 zN&ZH1!xL15XAeWVhqgjoF9%@gB|`#5)I4lX*lt597xM0zk4u1I6`BxA*H$3K68Cg* zPy(+{@wRBZ=O|rh?x$z^H#+IVBVQqACvdcOF&j~j4a=#oFB*sqoWYUO>+ShNS;Sr%KwzLbdQedx;v2KR)aSf`aj8B)qSidV_B-0BtYdv{Z5|6==D zjyr~hWx&O0mOqftHM|?3@4nntR3GP2QL5a+x4J#rPpWqMAJWdXZ8^1V+rLFKg`ydi zNF^ds3C%Pm6$xkk|92nHr{}$&``h?FuCZL#c}mBz@7uPni-G0cH-Kxo&==vUE;XZN>tQa;oM`{AQq6x{4h>W7&@#riO$eNv zK3(Yk!Z;qUj!E;Gjd#x*+vH_zUh?L%qV#u61m{FN(zQ+nZkPVG+JU zewelA?06lEK8*}UPydrPNsYSiH=YZyXjU1ZMS3|W^d?CSnBz}V4YGTk?_p29Hzkek z&zry3+C>W8KO!wd_;1fk{P{S*xVQ$G`A~bh4Dd+3-9dPL{l{xE86iu9HZgWATElt% zU#`8 zytJRfq%5Bjf5Y+(ZS?-Cxpd2kxyEf;mIlj)V|Vi+QS>qt3li1nCB%1^&8%bRWpwsL z37Q$bqgKCp8vD$&?D`!u2Zp1K&$E&!%n_@EZNt1pbsc^t+FJYD{qoUD`4KfLY)d~Y zC`wvCRW16LY_q+8Z%xk8LZvAm7WiJ)$!T^(qDr&Yn0;bh4f>69bV!B zl5=eqw642b8G8NnP3y1G+xXA#&uy}CXzi$% z)OONNbRXb}oQ@x&I@&TMS7px*E8&nltbH#V(gl54iaC`AHMn;B4S$Hez^2rH@ouCU zR1>|$os~aXZeQ(1DYU{y2$;vK{t=RMn`*Ut*5b`%Zd$$+2y+q)=D8diu*Yq->>&JA znMwP3fgVqR1$KVk!HM)YII-<&(x{Ikb?dad%lilpBpK0#Iq36w-ucQZjJkSD>l$Jf z|5;^#!7sbh>h!2?!J^aLxZk4#+O!+Bx^-I-wC|mPx=HKt5JX%{t&>QEFef=cW0=Rk zEdlcB?AQ4_JrC8Uvh~Ae?)=c0Llsd{YtSc$AHmkSCKLpJ0Q@8#z458CEykDT^cce| zHCQ#LPTKThx)V+a5on-%d^-PzoiA)#Pr1Pb3HtThsYdfhH(DgAC%(R=c~ADbWPq}$HU+AV9a(|T@C1MKhJ`}D!%I-IljJc4$!{^BxuPwWS| zFo$xE-;YA%ONd8}e!O}wrP5m&(+Wes_j+M(jrQR+B3`!syjp+!?fb~z91o_T%RfRP zarN-$?jl**swkg`+0M<;$C%GWExwSPxfg%2 zR+B5jQR`Z>L|a)nm`YdeJ$YdDymgJ_T0E)^552Q?35BkE7eh+@7Zu4*`2%C8v z8KSCX_Xy@)Ls}^O0p#>35UYycijhYL-shYz{v=fCq6ZH+HcVsrPKmV>M$E}X^NMw_ z>*#pXTWp_tyTUg6k7>$9xBA6qxK9s{w{aCP;-!Zn@k2SWb@byBD80RWlTTbJa zCyeHI1a5ZTI%gfNRGQq!2Y!@LaHQ@&^)O3ZqbFFWcRf$rt+r&U$IdUC)yj`{fUlPK z=~(I)*Rb5_r$Uss`i=3e%}RAHpXVR6IT?PpTG#5m`4w>PE03Eqbjc^>Y3)2|w-Ls>Ag5l)IJ*Hd%xCV%NS&( z%*h@PT?4%|3*`A3>GS#!+3L>&j7bOE`JpBmwZB*0qhLevKB1x!B!ARKc%HYpeaV|9 zsWskoI%=*vI`n89azqdw{I<)?T$OVdNXRG2rS!?;$0|6Fy8@C6(!YA)AciX2kRx-2 z<*`Nf+w8q;wM;kp+>yr`BthOY1852GIODTa;l~jgMH4YGU`#LXv_%JCA~x*r!dCq= z;K;-YoaSuOV;*&+0SLN9QHiATIlK`yFim-Z+7yTN@ouw}NN&~7<$i0}i6q5F2` z!m?jz*$y=qpPb;7>$T*U3Z^;1^`Snvt@UVKfw9WVO&oos@Ci+op_cWMgOZ+~BWPA| z_2C;vg%4@EZG;{~KDtk4Axa4PJ1%O6J5zx*fd5`EpZ9<`Ggm^7!5oZCcaO2-*Glhrt`?2Djo9N1;E z1@y%66TF(s%AiQMJd+HQqIAa}%!n`5qgD6mO^>C{LvKib#ZIXgD`DeWAj6*yzo+uL z{Ox+x<9c(i?e%)R-5x%4?PsZ9i4^zE8zF8-cGZmp@1QE@7ZRyJqY;e3#Mk$|8+In> zLwi2$6Q^_Y1rM?`^mkN)@6&%5@Sg%Cm8mL>TN>5j%DxXUW%-LY=>sUi#4SJT(?sD_ z4s8Hf)a}POetqOLb?@bgUG&@3d;#=c;1?sr99Hn*2`w(gPvHc}+y3+U)Z1KN?Ki|W zIvBov^|BM0vT?X=Hg~M3oxoH1fkUwrxDSaY1}E;ACE=H*&zD7Y6sqy2$64k65$FO~ zaAyG{bd;;0)!n$C0ZF|Iu+}ul;r!*SU-|w{ZWsl-vH9rGa0!b3{_AF2xZ4Mp(c)oCYT+*i(z<#2A@7lP zYZTHq-)wj|tWL4Ng`HnT^>OKDOJyl09Jen`cJ-Rx3SNaE; zSLYI1e$uMUjNr(YL9Rs7k|?Mq{Bw$mm;GpT=vxP4T8}W+i#3!>MrOw= z@Yn^KkPm?to;bx={_B5Qgtl1`3+9v}`{j8Zqcgr~_s1)p z>fO_d11Bxzy6<(B$6b&%1GzKpR`R@qRk7!xLx{~bwK3myPd@~`8Dz{SUDzOvcHF|x zV1l zY)~8vOK|YKnZ~JBDNJ|J3j%!$b)Eol6G~P)WO2*Cq+q0O`}4VzBaqpRBV5QDOkV`d zqWI}$$AWDBsYvU;Sa6Q@Ufviv+WUADw#Y=B2bJi)7JUX8)E(<&o<7ZPAb-a`AS?dC zW-+fa{X%rO9kuTsPE-q4CaqqJ@Le9fbBjhXnw*x!O|gd&W?Hz z@U_}RJ6~8VXr3^Z+y=Snt^8%}C0er?e*s6Kh0ut;Knl>Y_KqKpz+(N&xowV(Gx<^f zHY=m+v|&uzRW5AJiv8Y*7X`ZfH-N7GCM{im>3Z>d=EafKDaLeeMbjVh*(0Y;H=l`! zQ-cp{AAAzx-@MA0;v+3WjZM8ZvLSsBC%DAk#75$rz3-@>^fxjxzi*Rsl{)>`mxNY_IhX!;n@)(owFX+Cz_ zDv8eJi+gxHB4r#21K$<3)$nY!8!$zDa>n~rs-7B+@i4J5IT}&BqyzBDt*uz3peGRfPkGyxWiO9DP-^ zTKYh6*{p0fJ)|dYhW(K>-ONw3_t0(c5EF_W?eEO!kjp}{MQVdmrc~kA{O*d$vt(Lb z6C1U)dt-Jww^fh9uE#?&L8-jzM~z@|(Hy|(LR9D)C>QX_P%rin56WsyzT9;meF7Td z5mx7mdRY zq|u;i{8=ta?G=ND%TOGch74~4>I-^5DKaP2PoxZyezBH3`k6A%2{#=mSW z2TNq?c!N&6j9sT!9D=9)?&}>Ki0!f$lxuzUelo9>a8Ys=bONc;Z{EHBWc>WLKYQRs zwHB`xvyc+^sFlidt&A=TM!wJVNwzV%Lo8J$w(EE;?DQjgZnbtDg?UlbuwP8yNG;kN zH0}tc!{WhoYLdU9$z2+u_xGb^H&W$LL*j`udb-!fDVSKg8!iA~)5EFDxW~&HuwW8X+F9wXZ5QgUx z^E2hsYV&%ODSM*U5>_4@<$waVZY>W-t9#MtPrtSMvl^FFKv^Pm5AGv#Y(U?1Q09CD zcfH0-(L|tKbg3j`N^&X$2i3!U`$++45%x#TRsC9(Kd4x$;Z>_eEU*&A8MW54uZ)q@ zmF!Q0rS_kF-|SP1yO)yFP`QlFTlan}SzfMh{^bngjqV!FX42m0YT6`Ml*zt4%g;b~ zo4RRhTPj`;@lo;n-bB4vk56Gg%o_i2sfD#5eyw)T%pc(kk0$nehQqI$F@o^&Rc-U~ zVlKe2EGS$CWB|q~@`&^|uF5~8yIuPH7EusP3kdIso9ct}{!%8Eb9(>&i)Tf-eP3MK zYS2G7mwv8P9k)}8xCGAaAh}K`3!Qqm@(gyD(f#jjyuzAvJ%8;;C6~_aXskZ7$58T* zrwv?P2P{nlPbOgYMeLkLerH#1P_yUj!vh#u;*hnpX|JoW)&elGaiEeXnUgww{x?zs zvD!?(lM+D@heq~r*_*=LTQkwMf`9iilPl#cF)$EtAbE+py(T226iXxwS0xQfl01%7rGzgc>_m>2bvYhEqH zXs*@5<~F-LtD9aluMh2ZH4m;`75>DP-|Jpp5E`j3%g4IXpdA3&nK!WZ(V!>dV4- zV?EylUdWZ6qYUlIhZ#MQk-MLUQux@|<`|}yq=mKS{?RKtQ?bML&yOLWt9_gBxo8%63j+lK#q zvt6i`fD6UAg(qcUJZK}ITR72!XFmIFt5grdQGe;*aGA_nXLT;{_vwnRZMq)@;F(je z!Gs0c4m%G~Pm5Jq>6NFY3Tc-`q!DQj*Z~HGsE{TU;NMx;T5G?z(K#)ug#$qIufrnA znRM4Sa`5b(@{>m5mV(3fTy_UJ9oIst-cC04<><2AX1GrGPu0z3puv_HuYz{TqU-mf zvMK~Qk7PbIocuKhaKJxSZ}a_|RrjaiZKJ= z*U_s@m2zb3>-p$tYTpLe5ZK^X*^t)+<)+R#utN65awi<$s0(c{n0M#Va!N7bc4Ach z4pM8~4&(fLBbKn!t@pYgmS#x=keSpZ9Z}EPG!zskyll!KC%q>^10^ zS?z9blHH1HltE_8t!MCPz$nx&v#V;X>+!69q^1iT#cE>PPSj4}Sj*+*Gwp@vuK_(1 zgAzUvC3w0R-CezVG+GBGoj){Y&5tfg=4IiMuz(_Hvf3Cqpq{BLr|v^5pzBY(o94t& z0Zeqoe=kQapagaLwYbKE;M42O`17VR3Sj;X>1BWjTZ_h0z8+Hdi=_B;@OLyn(lOTt z6lY*1KYDks0VK+V?D^_uVQ>8y-YG%f1K(42t3sduE`_M=egtYe7(ed5&>e5i zc)_nwn9RmGFyX*!LO=A)lKDkz6m;b;_x85CT5A*3geu(Skn0Iy0mk53ViFTVn}o}D zlgCGu=Hu3K*X6jcbgouiKK+$06~;HRx>ksLawa# zHcU%9XEpvs`7Lu$gv1iV5=?&!33~?W5WUMZo$-hKE8=$}|491p`z-%zsjq8GEddpw z{~J&Ho6@WJU5)^I-5KT6+U{N=nsY{VjSt_t^^o&REm?i2HXm*_STvh6lAYv#i`;E= zv&n9oto^FX^s0^A%#8d{k^c@=z587*$rUX*FjJq8iUW1IgCXdN?=NEl*y>$0Sb=wR zH*7GQUeLkW8VCdlq=_6w)ycENy)uIg+@~;axYt!l;2Q7yosk7*Kp2PsVAL?`B@s4tP)NE+5T>Uc05|L6g)EZuzgU*bhnjmA9;p zdVaI1c3r1?1#GF&R?<$U86%N(EV?K^kZ1FSHy9<80V7}}J zL#MHmN|znn^4@AphV03$+%t;YjMod@UPw~f6?53nJRDq+=@{Ns55Qy|Y@ z(EeHmSK#GFe^pD$GtgmY%3x=n7o)CI>R`>RY}}sF^iX@S^ly^Zo_;W^}b!iDFd)7a@yX2%)RYPaVGW%eok2~Kk~E!N6>MR~)n?VAIH zWU!Q*;;EQo*NUl93G?z(5i)%)nGCIy%5Cm8u`z9bXaD@1Ay@WWvA{8%r4S9ux5||U z5Oues^`dKuv1%s_h_}KYW0B*^V-zN85ow+KjmPK$R_=_Mf2=(l-4Bt|%|)5Tf1|r32N0>gwZnv~um@@eBuEs$VLd40I-?EqvB*#f!PZ zefar1D4c}T`G_vJxR7^Wf82YY7}UatN0iO_DB_KnRKoM$uD^p>cn z>u)G2+FM&7g2fv~e(bpFV(8batWXy-yG+!YNiwKtay8>h$Q!^$KlTTX7jNc;x$CnD zdrto=oRj_+a89WI{QsVi99inpou^zHDoXQR6DoO7oUOCkyWMbud3NgP&*1L$YRVqa zN4Lvb8gH&?U{o6D=_}rO=LLM{=-F4@B4NH9aFd3n|vo?DhMtOPbVvXx?*Pu-@h0nMd zQdz{zJoCvmE~PY&&KPzp@?=|mmk#k4SHJsbUb^R++F=2S@l7+UYCH#}*KnnllUGTs zN~JDGOXWqm<4GBSR|(_h)pZK1f011i&8`1zh#$JSja3MVeji-37yfV7qQUF7&h6^c za(zN#!P6A>MZmBB!fj*AqR1g!c9wIuh0o~XJU_R!efdSFfyjYq!ZQ3zO8$Uc1 z_Z=jisM*V5SMY%CZ`H#gHx!K>&4LZ}+mc#xu2bf&T%)(6yiu)*)-=*>8Djk9Lg|9! z2WR@~*G@#o=&wZ$t++HeOGE(9A6AruhvXHmdr4%1xhdi1Z7un#5P^c1uqhu}0G;n5I(&I`^zk)mkUG zY@PD7&G}U*N*#cs^g0fplA!hl=euwTx-(yz#^CAJOKZ*sNu&RsQ?u0&yotFj0hr{k zeOQp2=Ayai)u7_DwVT^DZ;owV)fUy)r+O(P#QP;))UbJTNeD+w+-LtCu0QYF(}hSX zp$^phtvvdD?nVBzEtIvkxZ#bS-#r7vLKR00>iWwCkE*t}vPZb@KCe*w&U&AoR%n?! z!FrRApmb_W@9|-_-9E!RxYgFl*QEW`pCMpB%7OV6c^syE?a)-Rv_RKyK8$Gcuz*9}T3>Nvr7xKh}#h z-N$beH%i#)sMffx+rx!^XOCV~F)!VQ3&aa}DrSQ2?^A=6K9PJ~sa~VlEpFGf!$zhS zdzw||i9@yt(ZZ23;3MfmKRJ;%{t=y`J@>%+bEEw6H(rbRRRQo+YBRytoc~=1#Ny67 zC;HA%%#3%Xq~Dx#4XDZYf4e@?fN0ywkNeoIb=x=Qb%>Kt%$56tihQIP2XjE;un5&W z5KM;XZP#lO2gf-??oZ)2??giy=2?^*MG%e-)R!GEwZ2P!^(G7+M*M-p?l&@WiaJom z4w$m3Dpvgq5DlkA{9LztVBK|)Loda=H<~Q%T`@O-ne@arR($AmTa$}}+vSsEvfJ{b z!yYPhD0ho@dpwH952|_zD(B0*dE8*nFs!w#VQVM8Z`t32o8_pm#w_f=)lzFuLu|UR znToN<`^$2WMX3`IbnhJ4v%`10i~Fd)&nN2s++S&@`d9p}%3rd-*EIHnWZ>v+R)ba7 z)Jc{2?9cmeWxFZwdVh(1a?0D8@{HDjaNO;*K7ip9%$ADgS+1$^SsxR@sBvBQ<|)9q z71l+H05)kb!$G)!ubpH-4v0;L-pA9s1@+VG?yP2abVI13t1ZXtvh$mBJLJ7@47a7LEkDQ-V8`fQVZ{zIS5>g@AU7?dx zYlN4+8`AX}El>64st|V3vbEtnPWW30qg@@YC$`*$pYW2Z;I>~ppkeJbjTjqNmtH`}J9()Kj>PdC>Dni-@DX)^LeAKz*5kSUnxibpq zzped%y15AH|AtkALKu{4RWRkMH)k7$)AE!r1%&*3pSHCAYV%zwE8a(O=l0S?>R0!V z-$A+t5Fen2iaR$$T3C=Ln6IPg3s)yz~!adas_?6(+MsIOzwH#2y>x{Fb-k z+92D{&&1@o(CpRqX-#q=b~3yjQAJ~*i(D;S?Bea+Mej7T?9@HzPPUj0Raou)&eV5E1a?d-;tmO z`PV_X3)Qdu=n}~?{K(BIjkA9-o{7`uHK`5#as54J-EpmV-kC!alg~Bis zf}Ek_Ur@x6qiGLTS1%s8N#HDONg6mUSb)Lv2nLlh^1XfzfQHxwkR{*0NJG4 z_hhoHAM?k4LEClCF$2`C)p_V%%k9#A`o1uATffFFux3JKaI!0HHhc?QopR78;w9<| z^G3M_o+~~UINOFQOeLE4UrZ1bf=}V2%=i13bgaQs&*$|&xdo0WrH!!FcDFFEuy@J{ zy+7_Os%?nw1H^}3)tiNvDZauEu>*H#YVAr#>i7Hc?tCzL#z|UwCg=@Hm2Z$-4mz9q z4#zdrgqpvJQQJ*?{e{oX7@OlT!}DxZ+H~>Cl|R4ZRco_r$ZC!G1N7K;b;^N*T&V@8 zOLa;8R^)3ZG}rk_tqPox{t8(yUp(b3$z5^7m)kjK_TI8Jy|OQ-m=i3b4F1roF(ybL~ALwqTkI~w=uH>r&#c@YW`y*)0Pl&fR4SM zDo4>T7s3@AaHxFEzjH$!I)Yi|EgFAzqkvvNVG{`QPx4b+<(L_R^&e*OHH~Ao;!oZB z@!UVXm||~mzAeIKeq393@m;Vhw$)#q+jOVHSOpL^o_1IFv1Xy3aTb_%d7<1m>QZ^l ztlVx@ImGV1u@(Qe&eY-aR;(*KCnF21%XFiT`&;KXEpYE$yXXRqubACh#oQe$!0Dn2 z&nm)P(`@+#o%L8-N!*p^{Nl>_VsoURTs*KDrl;@1q=-lDv%EAWH(|(VqXmwPCBN@y+GWElugcooV2wyVbU0D*gzQgUt+vH&qnQ}-W%NBR-)%+5({TQ^(VWj;7oEzz^J8hKwsnxn)&m?6yBV?tE$VaIqnx!K$O%Ft7s z{q`mJMd-I-(u$VJFX zPnfcU*Y91v?U(s@A`cGTv%dCgZC*&;o=*9->ae&jcMEE8xr$o8}M zF?TmRH{PQJNIx2W`4?cL-F7{yj~l9n8&dccpSYqA);fFNXVBv&n(spAhL&5Hzb;-C z;kDU?Dt)V3!7D#8f@3#-?{q%)(1r$|svnJR)Pd3esg2j|eEc#WIA7XUYl5|DQViyE z-q}!!g)-l?z2(}5E7711N`L25j=g922X3|+xTUGhOW)_XwM)Q3g z3@W{!@n26K|APJ4Xwv^D=kdSp^QFsIXh&eu1rLxn7TH4Z6l<$1%p0>AQZQz;fphKh z^0RH5x{+$<#SSP5rIyp^jtjXO@jaH-PV`tANdWpsEWv8TPSAiXBl@(eAJS5I#3Ktncnw(?Dcs~_G+<`0%0_~$d(4)JF!a5L%;D@;8qDtITUMKHZZYLbsMrgSdoad08vuC z;G7iPJwmQgHRv6T9r}ibA6HG1EdNco%H5b?^gmL%5q1%Vjk@YyfPS5N_4<<+vff!Z z**~;NlTPoQ7JJGZq*;~o301A$=1jwP&Dy29lOd&RqH3&vW43Cs zLQv_sTxW;grPa#6jfSkYJ{K~rOwWD*y3K#6eh8>$9{{hhwKuiXWxmvCoy; zk12}f7HdE66P3mcj!+xL7?W$e=|Md1>lLoo+ok_As0Dr_9y`%CC?!903E~m=~d6${!~W8N|i9>Jbz@HMxE7yt_2i40o310vzmH zc2KjzdbLxIe<7w|K0`?J_w{guZoxF@dPL(hn;m!CjiB~h;!>biyjF%?>0tY1hjPBA~~7`#)BKDyMZw)uneNl=Ry7k z3i${EB$!GEXi(VD)6;8ktARAMu-q4%mhrh1%cNYSV^;Df*ZefWa;_<;Q?#;f8FO%qLmycW zq>=V_UWv!3pF3{f-R)KH^fc~$zmKh~-h48RIRF$PM@QY}3gLURf2coO=t&&~AJCpQ)qMz}V;bYavgVVCX)cFoZrN_XFKgtOy(2vCH!MpgKHHd{ zMcAQmUo-=>yVtw9JXWb(zK5sPY$Jag!}2iBKNn;wU2ak^{#BdXaQI}dR*sMwo?)ws zQg`xRh##?Mx|m;|C%X06x73!_U|S>~^s|5LYj<-|@q#mylRjhqfuVxN4zbB(HgBm} zf&K}0H9HD$aeeL%ve=H&{;9S~U~hHf`=5Igp6uJFc){+w@mo`cf-fkyxt+hxNKN?;A+IY)&;8mtVL*bi@bqxzlvBM%snqn@ObCh%9iX} z`ob3>Yq2u7JeQy8RzuAzi^BPp zEc%!FuQ!?NxuYKWMdS7bh|}~0FreXia|Zvzvos$aEAK7ZXC^(LYMkqUT*>0?F8OtK zs>SM^2Y!l1eIXr%^n6yJvHSM#`a+v()-d!RhdzK!mZOk>@#x9_BVsg1g5ZJpe_gGYFoLcLO{ju9OX9RZkHXdR< zm0UP#MU#fg-Q1p|{eP91(*FV~3TKc1b137^XTkoT@NMX=%a2l6p^a2p9AbU8`Nw)@ z7TjftN&5f{t?T1hXF7x~)2J(vxcZ0*bR_CFosZ?`W`%q$x&(~(vos2t& z8t%Z4D#jpk48D|GS9n%DbS7^&7#D3GKS+4o+-hVWweM~Ga_6=+Bij#49p^S!Ipufz zaQHb{$5Y&>#FHQ0Pf~W}AAm1>FQI1I^skA~2_@-jjPpoi81}*fMx6=ug(R)IPPb>m zeD9-lQ`~Xc;9w2mS;aOqg>T>xR);;dX= z!M$O&f66t^$m4Lsbo_ixK3I!Eyt$^*awOW%!eKqUTOF=qPq&H_Yb&vHVe>Z7B&Yg) z?0m~Ny!EP2CTIjwrYjL7^)`bq;==d-%9P^pTBH?Et367is#-l@CS$7YfISUIBu$M4 z$;w-m<1jksdxq7fZ+(uPpT@Z#@@VpF98oB7FT5}Kb$w}L`ryL9nROXgo1B*(u%6J& zEfZJA-?v;jZuN4r+%osDr~8WW3lYB7AIm?Yyo_^mzgn)5STdRnvY=mS(|-YP;e!yVGzGD8 zDR!mSAp_#`#o}d-HZJ9h0DY)+%UOl$zV{56nn$-T zl?t$=U!gvYz0Ol7a{DF2|NL4-S}-YQPXY>wKS(TjmE?-Se|E>ypv4{^J0@}HBu1aM{)uo^(=9p@W zZ#Vr>)Mn49#WShm&ci|y3X=aPt$Mqb zAcBqk4;M;LqPnJZ{n;7IaE%fvrYxtkto>#s>m^&Q_0I+et`*HYJE}UM_F3Bda*B$0Jvn9lRl$=MCl;*InbQ zH~q2!E5BOG3WYAcXO)(S{i*twAD8z_2?5^ociv?3r`jMFbhEz*19N-57nL*6_?|{O zKH_84PR66`?ijo8U*TudR^t!f%r{=cDK4H<^XfGgy~U$h9+G8#=ZvlMJ2UdtBQhTE zw5N9SB9YJjt`O4pj>VoZVDPj~1sFY3$hAC`AAhxb51xw&sV-(%|K3PJ3DTlw{7BHy=oWj5G}MZ=bNEW0aS|@Y884-_PwA(9IReqW$eq8(4R zx6zgUGTYBP7ZEBPN`{DBD`XoxPW!pVQH0<;48r4`J$8yUxU!e-Llk6CgIQ>oMmGj6 z&ib21HCj?DKcZE4ftNxJeIJB_|0!+*Qm~`OrU=eW?>!)E^WmwqXp4KG_g8w2v~f9~ z8h^d@B~SMAg#;@VE4}$?)8-@PvyT`C`D`znI|DB}cxHk4o(1b4{#%F9e%LsoAyeo4 zr&qJ?-iRN=+?@HYXIcZ{&v3yWxTz-NR$CGNCii9xxOz2itkN+QOXSSs%v~AmOkwUQmEI>g4L9hZvu|N?)RKNno`v33D z-R{fYC*Sfpvt`SOFkr1Y$LM{Teb%m!-2zzl2WC zyejlmHYm4_VOc3^)m_!#sPSa=qgjIXfg0Cu_PM)BwHn98`!(D4s)t5nRfL`SdHD2& zi;=wh!S1xWY=ZF&FdA*jnJ|;W(A7syQnD{Iph@)m)5cj@w0F*%%A=a_c#o$;v!JIG zn)^ih?c-EiSSzb_Ot@4YM>=#pbJsAxx-Tbof|tLxhN^q&FzA7PV;Z&!=VkWjkIT$Z z#+nJ9T{)xSqlzHD!T5*gue)m1@C?r?hu5{d6Ziv@T6rWNWQ{en-299CV@^k;3Lc=Q zDR=yha=O#g>?=kaf1T+51E9H9X8$Xpwf_YxsS{ml+2u!H`zN%iSr@zCJ$uDPd7zFj zOMto0mw$`|7{AyNK^H2;sqgdLwN)bF5$cy4kfwp;M2K=pa9}?%u<% znb5Cg6QO}*u-?Y&iSfNON|$YRiVmr0?zf zS}9m>)68X`agpH&M3CX7hdts^XIW<&w^jOCQ-e+iadv_^sJ65Ig;iTheE4P>dUkbR zF@pPgHSou-e0c1;;-^wPu7~P^EFB-4r@K{3+v|G(EZbN9fTazUwx!4Xvp*C-d18_N zru?i7Kj%uTWS`|A7tsR+zRwe;|($-^!cidS`Z|D3+Z)7AD@OPAbK+KYEG@vRBy zSPr!aEYgIRlP-0F!ij2P8Z+8e{fqDHohv}RN=RgC)7w!#g!hN{@>%*bsdeAy{bC=i zcS6azd)8t(p%I#{s?upb$B9ES+3dhZa>F*^jZjPN?hntD=JiaZsj26q9nv zBd@`uu_+h4J)J%0)t*3IUua*(hvVB#BDe#WBXp>k8C!nf)QL*CWE#QSwtr~;A4?4`NG+$t)Yb@BihkbZ-O0)3V(Les%48RJ3>g_?REavoXjKc8mlaX6! zt)JE1N-x%qA7Mq;x$Te4^wCt%oYHa;PY(O(U{HRJ28%WnHA)xLXXI&}esEJ`2|h%2 zRR2v!FANjh=#}dWU+sy1$HK(oR?;4OYbuI^Px`Ph3z#UWh1M66sTRKq_`)!x!YGx(vEJT#24}^4xkWM ztxYoUG;e(BWl$u0Pg4p4yXE7zZKjWdz>m_%@j{|DD35r++#K@NH?;9`pikc0!D8oC zh|Wn2rz0%Og5jX|t+)CI5K>u!GKFo$GFGC<@LF@ksvr-7yX-fpF)6J(1ad6)t1W%6 zLyFVVQdVi2H0P9H>DMv4EZ1p8D>+jbFWdE3tj7VZE=6XY(OSVRhgW`W%ycAMR42qs z|CYeGZsIn7TYjAn@~we@a#5C(5&h~1_-!%d1uW7Xb_VhgX8W;Jy|-40c=sg}{-|N) zFvpS}2(0CKTd}_}1pedFIx5}_pLc=P1lg}X7%?*!!mkzA{0KRv10XIYm(8^EE804< z?}&?f8p7z3x9S-1UW+VQpSAFQU0{_jin;(NYO+VA0su7bxX8r-4ow7jxALb-Q(V<6 zZM;1@2?977E6341o1|sa2Zjkh*B0mLGw$!QZ*k_rn7MQCF_!nHEsmp?`Ga5 zuRfH!dNuml1=X78NEq)FZ5!{@2Ge@wQog1ep^q6SmtkHQxW4jpG0A~KrJ)Ernd*_e zRSwH3@UurTmA8ArJl~+Mp@Itor}oWgg1IOpP{!rXWtsuDYa1@z9lg&^CxTfg!)o@s zqqy$}l&H1gVmjQODu~uXl$s6OYT|oHwAMhH+dHZV)s0L4lG4I3&4&DHTc|Jf?xEQl zR^w0dGMkUe1Zv~a5LwnU{QhQ=K@wqdacXHlV08azVESdGUoSTf1dNokiistcl&g(A~r9cN3wIGkz4? zUDBH0#;Yt&|K?V&cNrcdQ1z~>?(^mv7YG^<2QrdB{;JWARlP7SWbMKB{I2~nMYNr| zy-v`?^tFyj*I^@DD*$VHb%THX$(II73m?06uuoVBzd^TJ_oY7HXw@oG)jAdPT~eQS z&phpCU!!?N+TDx89y`<3+h{0Kul@ad@F(KZPDQ`#W78V)&Iq0WoU$r>c_AJ0J9bZ= zvPf)?KUU}SOqCiY<{#O(_@T*&Rkpp>2pjj7D$y4zqaox~M+Yj*-@9ll>Z9?(6)>gO zedJYgn-Q~CV|kpyLfljvxA=yNWc@Xlu%fjr)TmxYBQT)^F{W|Dy>-(A7%1N*vlG|0 zG7!8f4wfh6t&Q>|^69Bjfja^YJv=;l}!*IZ31Ujym&_N671 zR?LAS|2gb^{49IFE!))SlcQF@HJZV5LkU?i%0%pxmC&z_--puu*qa*J^YfY$<;+WD zv#nDdiqP}y^kUkM{N!KRneeNoM(-`6YJ58@+9EVAEo*Ttl&?JH2_4fLXxX(Lk}}dL zNtd3q&lPy9UywKJh~}HU0@Ksg$Nc?03YT!o8x?_IIhY1S9gz^LG- z(q}%n+gWIKpIg5-f^%JqlKys=X#4|`zQWi3`z`@?v(8Nmj@dyKBg!FKd$0AlP2VnK z;-bwO^B5?$HlCreC1xy0otk_@~|&CyD!{8=6xWV zNnwkmYZShzchxS=4ct{T_Q})S&%0mk)Oy!S03mL`>{OLfPbjbSZW|KP;$&4>Qm0vc z&>L@C+mke_jrI(sA0ZeLTutOF7j}(>ScgON&f7`58F8!h_K~~}vbib*xV!h?(blj92gU-K+Zttf*wS0rgC=qj%Y zo41B+G`c(7&agMt;eDm&xJLBb!{_cU{@Qme6>Dv39*2>Ld{#{TZl_PCm3F~do%Rn} zLVmhSkf4Jq%i#0*yar7E=|i&U+eYaP+s0EMLohIHyI+B&b-R5p$Z28;1T`<{)oaLS5dz;GvZ|jdKv+U3dg(MtF0%JN}eLlE{@O3tu!?YL>K%3kF9l)% znxllq3pD=v1Us@PMHlg*2%2CO*|4>i$V1JqQ11E7NOr@rQpzt)9*)7cGO3`R==8N% z?!)^`qb{pfRrx}1=;_P(-jXxK`#`-28N2lsg8nHFwY>#JVB~DD*e?fmrVrdoqRy-V z>i@c0p5U%VC_SR93&X!Tt>F#2!@kxY zmfz~ONv}?Lap}6H$>u(1 zI`y^uQnxY2?K^|FtQ8nH^iIvrt~eMJN1Ze%YdBQazWv;|Hn#4{_xz&AJMT8BZF1Z5 z? z^lB3z`nlRS+>h+<*$Z=4<9p>R6?;)@LtU#w4qJ*fDM+?^1qSKz+0OE0XW#7Mxt z{Em_rxk|lfOxwxiDBfSkoM*GaPp)N)azEmg0~b(rVUTaZd+5>w_TLln_T50L^uN{p zmkf3dLWWXe3cWO^D_*&CE_hh9x~eX~Xnk^ifiY$M&#<(y=BbQ(mr_srHevD2?8xi1 zy_?Z1Vw%|%$>^R5`%0EUMRcYn6D{j3hK4#0o!#dfWS|;XcoKb{UE+FuxJ($Jr0;%i z?NwU_%~$>zGG)?|wWmoms&wZOv@{=*ksHPy;MO45ei4rScF)iq8^*5R$2PyezU%*m z`d%*oZ|EQd;uny=XAfpDXEfejxpk|ynfM3l%zYsJ@f14D!Dh2`zKb?C1Oa&O!X1z3 za$hGW=peIoZ!fGBC4JakRdU17ZAmvMz_U5+a#DL>8JBZsw840-+K$&DW`vhou+72K zBjf{&+hx0GyYdj;#Ic?SDJssms+^d}mM^QPHKJX9^f;|eGL*AZpm41WE(o)pZ+9Dc zH3#MDuQT`OcRO%?4W*IfI%UK(n%o6ZKA#7d_qG~po%&ChjYD!v%6rA+B@GCFBZ-65+GiLGU80j?DvjbF*DCbOctXiVq z;wY!&Bs%q97g>&(7vsmvPK_>dnle>ua-(FTK-CIflMy=?zV+;F3i0YKLf6OE?B$R( zF@08#_iDC0+oRy6!?WtALuIgjG{#m(3yUht%P8N2fVZLVXc(Xuih)#}y}PuqZ?jb0 zZRe-rLhZ1MDyI6S>d5=X!`*$A_-Yw?$~}RJG(5uPwtw@lQ6$_hNQn%-H(s%&c zIz^&8RM>dp!EC6N9qG?zb^LS{m0zQ z%F|Wmx(ey=^9Lp6@C?=p5bN62X|kSgnm5KZi7p{8f9CGQ_@C zji$~|Fd%EMt#Mqh!wVvoq7crIdsNvRXe@u@nREXSZ+!-Yy-OW91qZ5l;YJCUX62Z2 zvYez3DY}fZm(iHJ?z*Oyet?BA*H_NDDw!X|SVj8lBGeA|oK|>F216?O9`h3p=U61I zf38JnfuGr81bXq9vuBsBpbrU&FF?`1)&Zm+DsD!z8d*$eVGS^$OFyuqtCC zPAxAZZ(8e2`@NLE$!UEcG{h>>Txmr@ezTCRVg1dt+K>u|Wq;RnXkg@lCr$5(O~-e4 ztFa|IwkDBe_UhGAH>B&P-WoYkm&qFK^=^=HmN&UJ&;4G#<4&tEy>>HKrNxiZIW=$S z8PaXZ8zd*@s+J#E^ZK3>H;<_GL#n9Me1;zT89iI@%EJl;vcf!lFF>~20 z;*(wPS8A?Do7;w|2X!5ujCl>Jh7jNSxGLriskQx; zqoFT#;bmEDZL`Md6wSxvo9VSebJyLamSVS>TX`NyWu|Fg!gYVGk>zjx>0Dl7*X}AI zm1^^D{(`^D!{gpL)~3iB!?LAtTPbVZXI$#f;&?j={GzxQx~Uqzy?6v|joupHrX5_- zk-OU!XY6cB2pWzcTzJ_XmXLZVNK)fHs_t4NONzcFwZFtm>~lJWfCW8$b_UJ7XH-2* z{qBu93kG|bfPa3Ep7WjMrwc1fxdZ{;6}QSL{O8ymct{7VK9V<}U%*SwJ`s46muEgA z`@fsgt8$71X%pi50cE^b@#=h`2C88g4^4NwQm2qN+Cig`RNfiMDW>;K9V6iHd%+}g zsK$symU7<$pduwHST##R(gJkk8=ku5a5XJ{+i<)aMu#vNguk-9ew*w7-k`bna(r+o zes#&#UPheb`EQ_tg?n-x3-}R275fpHVIR%$?6pNJ(Q{BjB&U63FOARQ**2X+VG^C_ zK|#Hr)Yjd56-n@~^@$RT$rB?ypE}7KY~Xmmg{%mFP~Sd&e#{SffcqjJ6d-Sv2Lsq#aOv!a31yV%%{oeZX;#oh08r6hUWIKV1hfGU+cQsP6E?iNmq0G(<< z1~~#B2s&HgyG@9C7L!kMT<^&|V|}9!CqbwiKgmBSN)Y`@vxR`y%l<;0gx3MoW6PN( zu`H~2o>ncR9{w^f-0Qs(?9z6){p(@jUy$OJ#{W^o{C}i4$5Gw32Fsi4M>XEY=s9je z;Xe+*_idtEFM9#cZxdZ9AF6-$7&KJd_e<-NIf20AK7&i1Sz+{}Renl4pz~d>FUP%5 z^_h`?jFCB@{D}5#Yx`|Ky!EiclbifbhfEJJJB3AQQf;-)Z_xkYqR`F|$eBHka+Nr~ z*hTe4*6;N{{ddYLX3t)&HgcCJl`$NuIX+iBcXLpN(X}!yWxQhzZR~$0+3%SE);Aj0 z?pZQc#rNRx5=ZYxK_qVY!Om%$fm|LEeUF=OM_@R3A2s<8m})Q}cSHuytZ@3U8Uu#t zxg7fN^%jfz$4W@m1@lZ%l-V>H_=9f%tZ{L(3y`1afedjvUA+v;}y={}~8 zs}x7ieP;9H=ao@n0>z;;+T>BPwKyYm?^Hhwho|)OrY7@}v`dbSO}5hFH4vEw_Xpli zzT-@fTtgAftB~_F%3vVq8u*|aD12`!UO)R>pqZQTE&_GWyDBORY@Q~}*va9S`g4D~ zWM6Ha;LRCj60C`4uI@PkN`NLoORF5U6Ty60^(JFz<93dEwD`EScJxc}{ZiZE$ps}h zKF&b)qy;L_;(J7X8()ytCY@KuW1t^<_*5%cr2Y^vgGbJkk@ggYZK|Yo(nsFA*sEyLQ zuR?eBb_z4ARcfg0rDKrirjVsa>S?<@D!W5%3#{Y45U?GfABlNsUcFY@^up2d8-7}% zi^F}1dUQ-aAMJ>#5kfIb8_r}yKG>Ox2W@qNPMpgr3$>(!6G{N1FG-elEnA3aA| z7T&kQ8E-;%ad2aH2X`M7rSi7R)s#u0opSkLSRg0Dh$1ta$L#$5kr$8o^)~5mRc~i} zs?f-WU_3u&^JY1zfDx;>BK;Jxx|mX!Jb_rybzZOOh}N#93vnBixb2G>+I#YW$n9lS6Q`Rex)~Gi&ou4=0wJ@8BKPD+ zy)H#uz@#ZaT~Xp(vX2X=F3y&%&8K|&R;I4n3Dw-ac4HOBSUhK!TZDW;kfw9L`Z-SD zRIN?adg>b~XLg4&_iOF=hS(&{^BYf02bQ;E+^I~k99vQle&P-*=A(SjKVIW0%bS30 z_a7-ABgey`3b5(E8Z7+_e6Co|S)$u=er3Y3$GzhOWc^(rgATU3?XIN8!2&#>kci@# z%wsDB5WHrh2$hzmFTKh6*`#txR`680SuSL+==*cr4Y2m@iovn7oIx^ExpwyA$A0XR#S^*{%RGkU#DeHf!9LGB*`CD4aeFP z0+I@F~k@RYW`p%ka`_oQzcYU#Nm24)aAu+nUkMfWeq=SHdI1vS~j6$&mocJH_ zW2L-ukAG);*cNM4xxG&}=>1;%!jkHyfMMZHZZPet3=K5fVg}h4KJL`y-6n!;w=tl1 zLAd0`oL9{R!R0=hhMN*QzO2JY^T%_iZ@N*-Rhvp{j1H=^dgg%Ev=^J*t`=0-1WC2p zvSX$c@6#s_5|f34eL!@g&B$tw$zAzNCuV^0|4a+lL4Op{FeZ#|`xkM}WUurPUp!W& zkp<=oL+423+w1rEI3eR0vxD1*S;kO4Q=Q_ZUKQ$dn39`xl*uIZBV67?_wr=!^AN5Q zz*k-ER_DC7@jr`_ynYnv4+^v|_k8&*bZ&)+-h1kOqU}0QS#q1Y=f(HtbjYyo8ps7+OEH-;MM~l5sW+xw580+Dt3?}+~FKv$UjdopF zJlz2Lsd=;7Ov_hXgVguFu@5p^EC(5b*XiW0#OrgSM5pt-iv956fw){b>~z}9KV1Ll zj{1ATI4#KdE|YyDDnREBHYvej1?d-V+4`c^SMxs;HIweQpXm|lHE44ctntyO+{!>M z*HBHh2_P=~w%4b`Tnsz2XIqrnCJ!bweA zu{=8FppkDu1t1<68@g+BSIfLZ620@PtXE3oWZ(w!0npcd@=I@o&G(l%xvd*?T@5n5 zA#UzMRu{YJVax+Ey>I?{z_zL=xYRjHftdvxa6vQK;nTLcaQzvG#-DCswLg@U~VCz?I~V%V;MuLF08*9qE+pljV__Va)O(J!m-NVS#zd z(C5;8S!{Zg_;R&fwJ`nUwj(HTaXo%{QhMuRU1t&L^+4~EnR4$&bNN7#Rrwx|_nU+0 ztsZqK7lgOisMvE#sy&L9n#@KWX<(0}?3u)NLRF_{hlWo~yx==+R^8QiS9@=A^I9&n z7L&(nYRi6mLBWY58)sXBZxI|YN1C=|_j1Q^t(6Q)ZI%2&sI7GE03XJi6c?Cxub=Av zvn*L=q*Ukxe|ZVK`nEbfFDV6#{q48;rbG^V^?6{{8{b!}x$b;khJd35tFh>zmA-yy zL|TOA4W=BXtv4i<^->nSrUEv6l-Sr^O;_Tl!wUu+ zyWe&ny3NOSsCMk6_?&bnVvl>-(R3WWS!3_}?*Pvz;=O8lxYnE#GC&RTWWUR`BnXIn zo3Nz#f!O`9j-G-F;E7YA^@Jzn6~{}}s=a9|Gcc*YKfXg8y4!qyCsH9NvXnAP-fU7t zj`TsAw9$t#IG!=Ljm`%0xmJ45gHk^8sQ2U&=meOpU*G)px$!qqi~Bpd-i_dUDytT((6dBw!!(Z_%l7CvG!J zg~b}|gF$6Gvgz;Ymr1X+7YNKor*{8I z2H(!01kETbT=d6|n>QbiT-Jh|73yb+CKRi#HE9J}Cq-VLW$ zcSsG#UZvPN`uExv?=_q@6UcMVX3UN;%QHK=QiIFS4?#DT6S0uYqX{s3lq*G5CqwVq zVtu<-I_rol&zARdN0=+^?x^#QC|7f7!0iFzVGpbvvzpB?P{m5&Rl#X!sFM$-j0#_DaFFib}&Yy$E0yJuuFy>iV(XI^>lpe3SEASgR2 zshyy0US4ws_+`?oYq$N&e$gH8ftEnE3k8^(^3Dp0POR>qsh`ZCJ^pm69c!y9yL@kP zl4(5KHI0>lN|OT^!u3XckW(DuZTs`xra91LVQxqmw;lPe|0Rb|=LE;+KH8VKn zEVr7U1#=G}Za-lrr;u8ww$T5M+vOnMGMx%BS9g)B7{Nv&?ziSyIw=a_biY=55H0WRM5;ohmG?-qD}e#q|B!WPn5v&Pd(%7RuD_e>n(@Hz9H z_TNi#=B<r11l11!hiLL3`ar90hICTI`y#}d(O)t}|^$o*}4YwtAq zqA9TiuNYhz5DyHT7+|V*YR2b({5H2)h4fDNB0<)K9*I%`isGRBb z@N&?Z9)>7$rDC0ISWC1+2h;Om;4KDHp;zRfxDR(WTE;2G)-5%f$5t84Fi`Gpn4?&)Tb&H~ro2P>Ktw_=_LIg%BggH1Tq zPJdW%g)#kLWqgvpA{9DKY@@TrwpDb#iLeZ(e6?}M(3A!LVe;MNjWv(`43^}7v#pMA z%_+{l||4xi_-pAY zHMxaRW8J+vTJ`BDfv`<~KmOyaIRkWa?bjr+Q45J?C=t!mezO5}Q5BQ0plsp&#F+7J z>PX+`742}HpDFfAqok;3+G4SUFSKL-3^$uBV2H_!(nNw`d^rtmMYnv3Gjg)I6H#}( z9kUbiMdlImUOPrN@C>3xHGjF`qeZW|zX3z7cZwl4g5b~0pm6D`o&LS8%cD4}&%Q2A z=RGP5G4D)f?QQL0^V>+f^+XdlT`v5F5MWq$>1_zl)J)uIzm7bmZnfg8Jgv(_^WD&= zlT7dcYQu-U7pW5=e8fkV*LazlzGgw7;{<4luN&Q(HQ6F18ZC>2*SG< zjZZY*h)g#16pr_2P5Af}qSFRlm^8MF^<$ys?kVzSrXz;r@lOhE3Vy)49g_|oIik23 zGV%PbOiKv&-MtjYOdAqj_#L{9bRXR)Sk=9Aj>73VnB>2hWxW(rk6UxYDGV@GPrZgvBVU3>BML?rM1^2FC`^;udcYNg(6zH=1||56}H@`gdUi-*d7eN5{fNPM%4 z31q;47{{mONQWUUVH+Y{Y|s-xCJ!>54I1UDPjZQC1rbr~v3^;1uJg$RxHjeMW&Yc1 zjWPbSf+h9ggQe?Jxy(eRp!8_b+X?%EgNXl(Df#*2vc5M_hexTn`B+;;%?PQ^*dEzx z5g=Pw$Sn-yaaz|MEl2`}D#hHymGFKg!gKu*_fu_+9nRzJ7Pul0rCON8X*sVJy(?Rb zOC7yTn0)uK@90!JXa_L!_&%${11&$j&$xM75J*M%VqEJj+V1D1hUIa-ik2`SL1z z_)PQrv~?Nd+L9yk^R%*4MQcUbrQbbv22Xl5GbRLh?1)QpuQ$(L-L5V;v%Ue3v}$6{ zNxOf)Ojq_?-^}aVJ^kFI!{C-oY?l)$^(B}`i7cx_poh@!QwPgECRE$C!Tw{M5S*S6 zCz71ZkgY_OsBNx>DO#bC2G*6OO6zq$-{q2<#$@TjH2!QSBh1P3_jX$FM)5gYQ?Aa` z2?PJz%0>H9?%ml75cBPyW|WeDUkOZBDz;XAysK=r$_CB){+^U>^vfumC15l{=qQgl zhC3`r(iw8v*ts(~BQ0C64^XdF&xA%_L!bzHSgpHY#8$Cnjg;EY=GmT$D%@WeJJa%W zS-V`xzbWxMpemo{m2{HveZvPYz3|?CJ92z;7%mEoOnjU>QC=-?cdPEhvJpPJ^=;SO z53~2%T4&$>G8*5L=_^~aQxi(%A~I)?1Jb=+Iy{TjhZ+_uDx2?mne5(;wx{7cAKzYY z36CaA8a}#p9ly4>5Gq(Rs~OnZ1=_38y@GK45uwy=DzA;TnhGd;Q?lxStDl<1&L>yB z|5lvF^W1he2)}crOujR_YSCz5yYoVW()Sdy@w>#GqIV!p9zwUX zNIu9+?rC18uTbo!!#qEo&g4h-;XjvZeRO<}t?3DoEug{+Vx@6@HRbC(nFrS${Qj5~ zJsUsR8nVnDN_t_z9*c7KG#O`});u(=?@C@q*F;guSdSSmzOeD)KjmY!{^I?`etvA+ zn!MgS)JbM};Lu7|`v?B*IbJk`zg_U*Z`&g1j^M&G`2%_Q#fg(wZH;hIg`~dkn#W(C1v$j)Yg-;~gqC_n z)IL}36V7+vKKeykK3t5&Ol}u@8zy;bGaK!58!|n^LP0TxopT)|fx}S#`0~AuGEy?(v}&^!(Nk$VwU+&Q{F$Ff7_C5+VyC8eO&h#;itRjCp_rhYcF}it?bhFJQ+mqV!m5~3onWL!Sl}(4SilybT zxO!X*gx_GCc;{MP`*2)!r?<<~K!6V&Z^%Et1D#J^;TV-@rMXrzu{;QUw%;;b(;wH* zWL)DqvNVQxbl<`jlRD8=^3P8ZYNwm)r&2>MPGP7PyEEsDd??|{Y~>SNUjtKvojY)w zwlaf7y$^Ok4Yans0nmkxa^hlt>J__pn>f`w75shffQ8SdfXma0??bPDz8CsP3Kh@d zNvF9g=@{S9w~QUe_xGyhwaUT5)tk;<5LSY(AO-X=?iJqjv{Oi(IUua}A*nI4$M3yE zMGqGEdVhejB07|*(A~azJ~xbj=o&2Gn=x>V%#0zI>ac~qal^ul@eNP58Vbu5V-V(6< zm&v_O%s~A1A>f8*LkNxw}5>cb8@L zcF$*SK<5|L`yGGyvOTEKkbfv~;>UaBzq=$FMr!xsJsJDsnS*ABs;p$Z1M25=raSqQ z^pGgB8Ds(EGTQH9j~X;@wXRq<#7V=?e)IGTXCX?9W%Xz8l)pz1rrE8IlN!MBQjO2A zO4EB~&Slm&Do~KA+&z3+WN%cYH&^A#ECBGrhTmj;o=w&(?tpXt16+lCh8fvw*eDiG zQ@a?hp#W4rA1u?6CmF=C!+aU=L5be5CVN#Kac;0DCIn&E*n*!OanG%>7N_1GGT$VD zj7<=t+*)*PlP@-gL=)MPlajuAeKFw(Y)RwpZpwF^1-twgi~0L%vdrV=4Y2H< zzBOh5=uxp;-1p+uYqwZ$E9&^JZLD;!Wq*xjPPep0r~Fx+n-4hiy6Rd7%H|H=Sy~Gw zAfmZ5RPSYrR0Ys;I#TB2V_jqtCsBFIciQd_=EjskR_9MbJb55mlr$YJN+GPq& zDAkR{^YZptpx5l_QrgQHUCRH4?bGcmaZsU3T(wSh1PAYczj zR>Yd|+UZAn`-)wCif)(fraU@ThZ@xN#v8GnLrX_$>lTdQX~|XjI@wQe?K7^)fP6#>b&p;DGWU4+&axEC+G%=wYw&hm+bmX)p8xKwjf7D`0Aa-TvZ-VPW8QVJ)TGL=9%Ry z=r1qx0OK|e)Hzovld~v zkh}egPpK|9(>=NNCy%%(WWsCaHJqKw$rG?S^B4c@nT7sIQeH8#%}p++W?LOqGNfM} zeDeN5hi0dJ8!zInT%hxOZ`UhmTt0uQb1CBoKz`jG{m(v4_4O^B6c!bt5};fw#NC7Q zQCe>%r-6K{-joMUp)*UjhH~?P`q#lujZZG4K$UGl%%jqi(+=@S6QsDK^+!DXEIl}d z-7cd!%l5H~%U2fUss1IA@VU3n?fx*{%(9EZksak6ezLX)efHX&*_*C#7j}DkN)AavjfqG5D@vGv-;+3?PV@biHmKga{PpbcFSP$g?SI2l z@t^S2DF++)GAtK$!+D|jdYY9^)~1gZ;q#dT4(e%6kBH~S+N*n+8rdKK82A88TXx;d zz-;a4GsY+7@M`y{fn;|}~0XQ+!fJSDwt`g(_C&>CQ!>;bH% z269?6p|U0cg{^0a62{NA)j4enLMb7t_O1#bs!fqZoyy<~0=LqXSHX(5epPM2ou2di zd^g>#_+-|;So8aEJy!O+7xdC}{4yC7rxI^?Xb{+?{@UAP@jB#y6FCR zJ-JSCyrF!>DIY4g@#OcY&peXcbc18}xZG0L72>14J3oF1JOs{7MX2M+@s=T~EGI2I zLTk>>*Vn#09=e7#&9?_Db$g_XE0juC;hR#PmHB9&O%}y&CBJHjhHo3N&imHI=20Yb zoBl}a|0n%Yv14r6$SMZUEW!qHWeKT2Pt^<6gUGLlMPuJ;_1)cewg08pdVNh?=f%N% z4W>P-3q-ECCVahOWyR{`TXn}#r(IMzlO7Vqu$4z2a8PJ~QSHz#*!JnuHGy)`(%b9- zvSBHRYPW~qNLci|`}KtT4Ju>)gnqN$y8!#$3IcU$qq`GxFKgg@I?UNzoE~{N`69Rlk zAvUXtJh=MVeCV(@T1v@#v2`8L&b{E z2F5b__=B<3@z^%=5pIe?6-@4dGxi+2dmGqzU5AiTn)ID!{4Mvp)uW4Csnq-!MQ|x} z8w&v-!&SYe8Y_X*8b+(NAMWmCHr?H}T(ZdC9`}{Ht_-#ntIE)Wwewn+SoOu0#xapM zQsoIc@;+KnXU$T(c05#Y89b)7-;ui*OW%SA+m&kGrk$l(4@~K(HyUFg(KoX4ue}?> zWN=A8?V7H*5tgJ9-f6%QS+n`s8a%S4}-XN!_MuCGeyL*j(`TjyF;Z~SeX*xpl@_T&dh zTQjZJUSDj0MRiInK1#N8nA=_-qIWjO+k4Eg7+UPJFg3Hig8LS@H9rlj+gP1ILDH+N zDJt=rdhz7-qf%?2kK2=7ze_`AXs}K0%iB0N&*kVHA-k?qElZG6)E_N{dWAX<}qYlv|BD3^VXU z?!(G7{3s`lZpXnNs|!21xcdETFWT36T1vCtJWD;GDl!>myN7Tq&bs64XXtbFA<0KQ zq#+NRd*OcDW?__g%Z6?gj?wfpXwThCVE|*JVWS%EX4b?x4THTK=j40$yy9Q`#x-<$uBv@=^)RNJ=bx2T8;mLMXcVvPuhARgY(tApe4n*Pbo$!xC!kx)*KoA2O1QNlX+t--Ns~81g*eV)EDOp~vTx z99=#vSMKy#C{(16Cub+Bq-7Oo5!j!uwhmvSF(VRT7dD`!Q(LsV3vzX?UEjqebv?F; z)-L#FnKccOODWq$rfGhZ-jPbPalaG}rEr$djX=1;VBl59nv&gU6GnCb3GnE1$%XAF z{k#ddO*LlDC+9~@oSS&7k)wrqDmEFTg|hT|;J2IeYxT}PhJi$1UPt7GzpZWN&?kt} z`_y?CQ~%}E{H9?JkI+s;&hDC1zO#1#=pT!Hi8_BO}yy9Chxbq^4Z>rGM@)7ya&(G7cKa~lY zYI#30Qs3dLa=e|e%J&UehTgJSz786AzqH1z<>b>*`v-i{fhk?n9d&2as~xFi!^oeL zdVY}m)N7x{{a%E5U$s+k9n2b9y&;;rAR}S8IndBf$a85ppswb(*j`eb{dZa#tgfm$ zMDABhA~vJOG~d5ik)aLj>TdyaMMT7416J96YCpt}m&mMFw4w`s8CK~j@RPH`^W7Dw zRn)uh&@34fw_Usyg}aKqXG%$Y)HwYFk=<2+l3y9T{AW_!xVn?`VUb^Lgv>F)7PWND zRP@1f_V8`2rdYTe`-1HQqZxB7FBkmIWMcIGJbFNNxY&I%aZr8t>X z1QSadoilfAS4^~1-UAV^ynl`Y)a^PHx=nMhtyk1n<$ULhznY4++LkX>hRE+(B-O2b-x)w%># zW6%ec6aYO|%Q|Nt;#YktWaVCX`VnRMfu&&&^~w(A+t*}KV#*ar`p$&)E<|dTELk+h znf@R=&AOk(o)ZX$eygvLEH38P(F~Zd&zSbkO0#*1Lv2)D^jk^emeeI-vM6J%{-uZK zqlni-e7HhxtX*q>s;Mug-8)8-2WCHDwnSX+qbM{C|+H3X*yv!Xj({r-pMM7J?+sXL6AP$Sd*T`Ka zqwNj&{GCf&T49CBncIil#L9f!@}+2u(7oU7a}?D}R<&*Jrf|E6SzTp_&9}-n@2#&& z@k(3s7c8{MJ(T)N8?iSRTBP3?X$#0@T)TkkDD%`AVDG7PMz6x2;+H*rK7iL8_;X2n z`msc1u?w3SgHE%&5A()5KJmXdMZa}zEsk{W$X$g^q?Vm9k(c%iEOpwamkh}6YfSk#)aL3?&uHu>`h^b8OOinqZF!(s`*jMmG1&vCr(Ntkw|~@% za&7Xt7!NTn-%=$`VewsimtorRY_~990&76?@mPW~@ldQciq+>KueL>145D0lST5bt zh|am(e%-+;AbquJXY#ygWBG(VEcw?(I(uu_!*51*1Z8-0z#S zPH`3cDOw?*XQ5cIn*f8_?D>NMV6W|tjaTQgox1w{`)9$I-L%rd*a}M}%zC+%{34gw z_G93DkFZ7Y`1?>y$kC>ok%h}kZPBl@0PRG#mxA3A@n0g|Z(W|wYF(V42VALbEs;{c z-S+?b82%U3`9}NyQRh!Uo$qbHe%PWfk`QC)Togxl{2mM|v#jJ=h)D$tCBDN-cEeM> zs?Htjxq8$yfi^KJE!X~{e^ZmsK#F+i)83N@5tvjJpkL1*S4zM{NXajdBZCJqx3SQX1yZ-%0rl zGE)E~H#wfSTG`yXGi>$(CdTdhDC!i~^n>Zkx8D9`zn!y>HrkWx?XBM^(RO<{zetib zx!u|i3cu{SX^zcBr^suDqw#g1W{*2v*mK`b|AM^11|5E~`3_T`ot|#~;A6YYW z(Qn_T-sEbx+$Xm4BBP|&FVGg!U#wNCR4X6i6Wu->s%=y;zM8(d)uvtJ{Jbz!9FRTb z9AVH?aLgA}2&qQ~jr{#u$S3g|cg~!sp=@I}u)DxW!VWbgVyy9$j~Q{i>(9_r_ta+k zi!ehr3$yjM_Wqor!TL;m&MX<<~0q!Zy4AeYJ=8dZoyD@U!-2e@`qO7Vz*+3-9FJba@oT> z#`07T^Nw5mt2~Q?@q~F!Pid)X9+q|7ZIw4g4Ow**Fei#Z_lqEte5I?5irtp(7wW|w zOEuGDei>YQi~FdTDb9GKR1c9flwad^yR?iO3QQQ4udgFLk;U`)L+>R&vM}HprY+H(;Q&8 zX}8sLUU9pdO&Xjg9mma?lmtv*oqzQ*W0D7A4<6@gJ*(yNQt_gg^pz6pVXhn6gORI= zze~mVS>l#XV(;orIydUhw(4xFk!y=a=C-5Xz%A!N@5^@P!h62ej`gXg^+a`xUHV{wRGM|Ilt*m5YacA|)>qF~w0kw)Ot_38 z{kA#q$c&S@06&fK>C!I@M-wI7bXeSR_yYqSh(!YeOm=GY$!b1*0leUX+$!#5;tqSI z%Kw14U^Cwx$({3u}U(sq&+S0aqBk9K<5diCPG>KY&~^v}gvl|^=s zu?nNFn_@9L55JiE&}FmAt#i-rwGZh?3py(QQLwhdlv^z_t|i3vy<_-#%xBjnl#im_DZ!50`WY`+`H8?h==y5wtT4neD4ryJswt1 z;>m_$Nbzys!3JbJ(m==-2vU4P(BvdiIMZ-T_vh! zP7$f)|N1ii7Zm3P*slM1Ct}YG6{%BnxIo6iDSQ0%=4OmsL~um9l{7lpIe;}LEKF5` zPt=?#n7FujLebb69fmC6y@flOm*oUuF(q$TIqu2k3eXp<`WB_-t~W|qRF zt|V3)2?0c|wza!nVE8{UfLjwvSz%`Q(tTB(XMr19QkWe#TXf!Hv0%K)CF|^}A?)dR z4NyUfo6$;rcqsigQx3~-PwPRApgIk4&HdKuHl=d@(EYLXcH_N^jHlc z2mpk~pvn2bUM34Bj=Z~*+Z>_=pGn7HWRaOtR%f`tijv}Z+syhdo!_0a9QB7Ay7Zfz zYtDKJQan{SUq8Zq#l-g+w#e4&+%HI*1bNLcUFxS)@)SFt7V5PV+pKSD*Qy{TgQ#A! zi?8CKTDX(dtMYpSK+`a$0*~IOi54GfZ4+JENFJN1jD}+Gv^&xD89wLs-@E#QUpu|t z$X?lvToLKnMgt{ZL-7V#)q)u&@L89r|CBaiFDft@oG*kh6~KWq(C#i_HsZ~6%b_#3 zD>{MdMQLqziZeJlY=!fO#ra2mHfmK~edRYI-k@To@wweEr@!gyJ~$kMdI);b&-Rq7 zI#yF~*OFhow_mNX02o)NahT2Djn8Q}UVG!+w^c2j@LVjxa-J&`hE?Ht>gWOS_-!^- z+OK%^OUkl9o@-SVXXSwdRl)Q8~OB1kdBFH_v^VW6a)A+emaDz8X z{pBx_OozyfqD*!ccCYEcDbx@dPuY!@Z76(s!-m29!@_>Eo8$JD%0OETGpB-|O={V) zryAdbLFB03%f@#H{>d&^^Pwd=l#uk3L}O}byE=eCf~~pA^wKKb<^}L~IA+f^!TnpB zo?AYC$xp`>7{e;ypIuCJyS3h}G;3@MLUR@m!lGaPlBoOGiZ~Oj^^5!K)4oiYqusK< zobnCN_uDj?nZcC(eq1zG-=SB409S?V=NAI^DB7~r$t+H9fSlIxg}MD)XC`|njH!{$ zpg6Zc$EWT-_qoLcR1TnG+#TTAq04TyYOTE@rli70=_CZx`o zfxUxx&T3^y<3k$VSnfPBEe_TW0VWa5Y#TmW_F4HV0W~L8Cmvh z1Z;kz-Bq7@BjlCTU-HF#_SNeT- zcV#?kKG4kka(m%N>D3I-;pnt~Z*uh|RR1QN0}8dU^Lf0li|64qxDi!d$)U$Ae9E%D z^lDx^yKLO(m-;_;S?Y@~HY~b%Xp5_+gMBi9qvGp8OhE*M1k~>7C>OMZExu+>lX3Z* zO{u?LJy9j*zEyw`=NgL!e|VA8gyYw^szQSNwYO_8$Z#RsXEwhY#_`C~>7CdLpS8)D zU~B7cqnO_xse&XHPG}Y&L zS38!X-AMfAE3d+@J@yOTX3qv}ePMr=4XEGb?ziQ!N_cHxMT+zA6{CkYrQ5G{=NHJN zgbtCR)9Aw9^|@fosT)?S-;8j6lAToy0Jc$?@bzOG$+6A6lUpX#_$dWGreWKLw#Jov z&uS%qdk?n%1%Z?xTCM;09{f+vZcISV&U%Y(_A*(`_zE^5Wsz1ZxtoR6L_l&s#*5-9 zr$*BSo|)4lL0pB~bXwRltIJE^smz*8<{XP-U}#V-?5iwKdxa0TsVp-mtH|*eX(!jU zU9r+?Dm%J6E}r{leljG18=mg`NxB8DMO1mZanu$ye#uQoA$spuWRy3gfXL2AX!cR< znPTVqJZ7?s=K{&Q#%Oomo)mJkx~(j84fa5QY&%(uZT|3XJYj3ntp6P5)n9$~8W;Po zV$wfXzZ1F{r|;L<;-Y(AQbbNnbW?rPugY0Y){ZggOsVjFRHsT%1$KB?oJr`r6Rnmu~3%ifzSLgpfv~apYvwVwN=ay z#_P|ceK{`UY>g?L7VA}y>iNSfGTG%yw0(Kb8U}fdyV={4;|Ht4uso~?Wl+PPwckNs z;n@N5qaVY=n|!j}8pr0I&l~$D10yOBP0eel{l;xO%wL7h6O7xcllN}StWonOfS!H4 z3j;jEhaXNJf6c*$2PVDS6V?E^NASu$SI10_O4u!8Rja9+Qy@Ell|K2=X|W+S=-baw zOchJjvd6cj(y1i2uld`lP_XEB$FIh2!~g6SyUu7Mp|yLanrmi#vA38<-Vrf@y`;FDrpz5ANYlxtV1m!V`*(niy^Ku+TN_Y1aB+(eUu zHGR&ft!lpBUzE-Cdu(8j6Ic0?pb| z)NkJEuZBEpwx-S}zb`^ZoDB<MMzEb-9+7Ws=k;1&X?QKXmn))I zHdx1Hsx^J9VZ^v+_n`fKIYf0?#Ar5x9_lC(9uzIdV4 zJU02Rh-w{d(%R=cy=(1}6q6cn@l%>30E^QK=?1>*jLRFQBKF~SYGJK<=3peh^6#|* zxAllTio+t&?SZI#-#TZbQ~O06E@t9Kuw)m;D~la}isD6-sVPWg_t;LH6rQ!wc~?2| z3O=xmt-fleTmvH)Bz77c0*mcV*x_56M6;98_q`+5=T&8pt z#P>qsiB2zG?)cT$8HSK9tMWJNm-$=|!~C=oy=GIQ7;1yjd7Glr7uKsuEa5&5dO>2_ z$mht25PPBgFza;|v7<87wD;5LF_h`@`uKpra>Sk6jk}n6sylKW4wn@qt4Ui+pYm8= z_FOe>6vTr(cM+LFXuWVs5UFW`3v|%@?6E@s$HXwl?ac6QK{g4$4*2W)priDK>*HB1 zjo(-F)GTC;$B!5G{az;fn4MX(nyE*Z(y7@T#~f4|=?-gMTRp{9W>;dnqatps5$Nl> z&AjsOlV)%?PolZ<=&GfQ?%+cS(jB4p+^OTmx*iUGq0|KSprv`LV5L9+n^ zBAhVV_f7Pm6BqKtP9z9VN^h7ja!n!$2QPOd*Hr(P&*D`rv}#-TaXnaXh1_GqhMw6u zy$_AoE`@ce{9RAXio9MfrpbfHj%OfM?AWiV=w(-2oRug1qRi5PE8@>#p~Y>6$1z7K z2DqUNXDVkl{TzKuuZg^^;GSC7DajDjY;ZFTeKj&iRMU8|)9tl9jV!A;RlkSl8hKR8 zORUE~0aX%AY9Q&VO_3P0r=+&?07$&?UuVj7RdHCWQH~GP^Iludc6u^DOma2HHz3sK zgz4`xQk#2n!%hyPiFS-F$=m$~_ufT2pFG4_wr4BI7_FCUy;D1G4*kUo`+n!6g1<1e!7R-)x}dcIHKm{%Hzl0#AVj~ zV1j$nR*M*GXYnb|4*V|)?8t?-Y)uEVM6ccy%%j^*TIP`0GJAtk)j(s{(FZp3HZB8sQl=dlm<8ah`{S!e5U~{|e?x{ntu$ z9f!+OzKnL1&N|L}`Bm;x(;pShFdp_#%fc&W;0s8KO_DOP9QivztqGZHS}H2u(bLIC z&+Ti|Uu`^B&LhB>6y(7s_oW_L?C5~Qq;bfUJbMUsnV`!d;0x^PL@hV$xjA0WXB$*` z(X8BR^mg#QA&uP!gof;nETj*U8cl)9+rJ#Ve6?FI+Pehy1oK26kr4Jm3-RSu2={Gr zn@y3ymtDecme>~S_4$C)y03%)`dt*z00k*^8qq2I=C9uBv&l{pff~5eyysx|3!5*^ zPq%euFq_Sv_ud#^kA9Oaa$JD0btT@d=g&l&{!05X_dxILZE%r);85{hKt|G$S2JNj zI+@aeseWX&V#zi#p5?d-r!-&uh90NJ_||s|3T?pL7#tmWGKOq=gp`&aefB5oA%z25Rxm)4PP)a%M`obm;9gW<*`Q}Xu4E6Gs6jS+a7faxFW<{%^>l`yJ-*?dV|~s$AUCgm`YzXc zkH)7;f8?x0tzmUG^8~#)-O@vm=xmOkUu8Vh-oQ|ixiX^?F@#dhv$y!Ho;{ootb z`eTS}Vmz_GlrmFlh2+PJzFtAO5BAaL*F$gULD<1<4C^QP^Wmb;Df1%Z`m6n27R~)Z zDaI7X@M>wAf1ovbTCUxq-e6c@Hd{y?SE4HddAMLOTD(e1z6uD%Og{nM$h6B4t7Rf< z?dg4C)Wj2nh<&_>MikAzn#U5|VmiZ;aR3xVA7*-wXEObBj)Q&Ba}!LtTe-4uhhw0X z+y$!3zqk4!sM7O;>81KhcbD(A0WpEorhmzz<>#Esek*XfQD7XjpRYJ?wytsCdzVTD zmKt5D`3TRSzP_mnm zmO8`gm3Tnn2?X=;ZE9)b!KQMUY&@E$VW<8`F^-?b~ARUv=;=jW!hWo z7)bp6J*ej95FQdMmCl(QLC`a!&#KDl*}C_@VYXtX&)cLx7t@_0y-yRiu;^sJ)Uva9 z>cc#>lf2q;&W%v5cJJ-Clg20uQjd4!sNO3bL`hGbXxh8p$W=GlU_p&nNi@qMdBA`iH4{0#>_!@Vt^mOv5 zPWkW}gaj>rL%%d{|c6^muITSI2c>uF%ws7w7vsbM{M_Oz=a8Sh>;Lr-?r| zd$Y|BJW9ofdMWAZq4(Tltm7;Pf}L5WFC*tpYuj0mTEZ?MXdNu{u(dArFDL`NMK&uI z>y=B+JPnR@ibk5 z_@H`RtXu?$%w-r%ncQCw82<(UOZ~I|c=*+)9Kxd%y17lDmQ%2rx#uB$(YJU@jDn^1 z=XT#S@XvrISHyh6+S9%}L{hc+VW82=E`JLpD zmoIdk+R<(U!ZQyLbD;U<<>9?M_Ld&M2dL!*yI0oMS}z=)lXrJa87rmf&gk_mAb^h> zR?3)u;dy>ouA0$e^_0@RB`-v6wLdQGZ+*@62z%8jan4PXiNu`FSW|(=u3ePkjmz!_ zGB>kN)d&8f(Nw=zVqnkdnOkY@iR}mARAuKlc2@0@KmO_`3Y$yK$i76CbzC`-i<%C` zkPzN~d1-L>+K>FU#3e-!Dw9|_J8SsilWyyl_GW~(+trjipXH17(&xo?_G2D4u=KV| zj)J+44c1_=t%h<4%a7UOslsGXWvK1qy&6j8uPMyehrr&{cPdmcIeOfpAav%n{f|UkLbf#&Sy(Xw^ud??-{a`%NX6?RT`Wt)pYiIA$ z$MI>LVD9FBhT z_FltAQKcK$-!Xkpe^=|HJ8pUul5jCw=UYE$7AnP(yRBS2JNNaIKINYH8y~oVxy9pO z!?CCBSwqYHyX)$lPZ3u z0)2^%MkmPwUP1dIU>QiQ5j^;XT+?6s z>jAN7Nr7_3S!*;3s~?>n?Lkf>n|sgs(KGs_eH;wrzML|#4gcGg|bj}Zz4jxdc~)~ke}(7IKdO5q}s<%2iVs_cqZuvPfiLq z!e2j=iL%S5ZGt-T{Jl1?=OoL#I&Cp+vh^&gL7k=BY^uCA?*@fcca$Tjq1oe4t2YOF z_%AQ=`^Dl2`%88gHG{opM4M%^Qu#iN4X-hUBVWVG(fZmx?@Iibw7`Vgz<%wp@6E6C z+kUU+=?<*%?8y!gv~6^iwVTlaYmgv?osg9!ul9cUP0DmLtM7?%Hq?rmu5w$@LJTf5 z#XXI;2`Mo8)tirXdPBkpo>XcS5)K#FECFTjG+y^x@DwRfD zzEcJ(!FEbW^!54fmrJ$wWl}j0;R15Q{X@r|PrtvxbdXrsL%6|<~(l;pO~znCvakDVNK>vF*p+WA>7dwugF!?({C8|Nv^72h#c ze^0tIH7{Z8x`b4i(e}cfHVsI4-SDD0ZygP>_HECe)@a!HW+xjz#jC#2+uuZ0fO=l3 zODY=`t`SjRpDFkK@p>Cn>CxrT6b|{B4{fciyl)Yn(rGl~p=X$5SQZW|cnS?!Y9#IQ5ebNM54V1)&-4i?agw`VTQ2@! zaT`40Q%In{E2f1W(N%I3#)>gd%M2qTV;?K9 zRm%DdQ#g-kl}qIQd1yL%cRowr$SQf7X=>#{v2H(*1r(|1J<{BjN9J!emyhdpwA(hchEhuXAwj=~D~E)sRCcDfO)QH#xn9ROf>ynolhG%t5HOaZ zG|hKCcK}ayHop%G_2#(oKET-ax-OoM-7npSA@1aOa$aO8g4*{`b+vb-T$$bGaG6@ZkWqN`Bvg>Yv1V6kn;ncCq`Fwd z+xEJ@ymdZft-5B=KK9Tpj;ttEny5FsPexL$W9wo^&$RNQUH5!g7PhZ6@=q$4t^AC3 zW?f!uAzG@2ncV@!o>QVSpME-amOjjVqV;{e8`)`AZ}%=mPG=mkZ6s6Jsdbl9hBb}o zaX*Z`jJYx=*VBm^rVh>27NePVLcbjfph-v@Z&m zNFaJ!=j-gnDlT@_rd|8=%6#i{C{&h*@Q{{``}}dYCv@B;0Qj3JB;In=S*luWfIQ;|4=hg<8eDBHevTY^RYNe~bOK4R} z4Oj$Bg7P}4s|CdA4F_p$3xdg;$+I&6o9yPR%TVfd<=SJyl~abS*aVygE+3b2thu^z3WoHAEqCC8#unusozv8ca#=|iHBVUfDh+(dczeq%ghX{V#xMTs##b>?3dPHn|`x-OeF8BM?DQ{ELea?90|35T4nx@$-M_r}Rl>rI)C45A9a z&gQLuZ@+JOm+UX5uSVQ=3FHmdDH7*+4t(&!7TL*3F#8FM-Q~DXz?_t=-Q@g30tC|i z@Hvj+jrvI9caM?{|d_7n_5LVNkz)g3t+;si7f5kcIAA-=mMf9wp}sEw;xvcMXbad3w!VpPK%#puPK+olNc+drVN>hz`n? zl8mYF#XDWbSIVu-i(aVAk zPa>xU1iKsWX1Kmy-PKE-6oCvU#@QxXtuIvfR}0^@!qv2fJHQ5Z(1EmR71^|Vz*sn- zY%+DOE1x?_7qplk4wPX>FE5-_?U5iWDg1f&T+1F+S7Ki<^}2l>*JeMih0F$17rS*| z3)mW9Qr1gCYuO^3*k8{U{|5frVE)0=IDF%7xY!*(|GVsZ&Gp+v7LxC!+oY|-<+gha z1}f|g2;69DN;mG2%@*Z%=H{0gN1ye*VIU$DLF%W|``(K!w*sRBg5{%qt!dO zIc8maD0wd84|Vut)Qah6acI6L2s({t0TI>K*XRAFlw2>|kGI3@*+84m60ncRJVb_Q zwQXvhaL1z;wtOiJOIdgZY;nYiEd->8=TBzZB!7k5vBc=dmEOOok0N|Q&jlfC@2*n3 z?XBIt`Kk|sQso`E*~57CX=Vz)45zq0@PH!>RAQ}suXM8}z)=j|3Bwz?dSy4c;GA1C zUm2beR>HbF(QboxS32)2$1NiT!+}>rhJhvfS(M8&tDjSoGkyB0L0(kitOl85fJB?) z2cvkI*8uW)cW1?8%`a7s6QPWeV!B)vkHBsf$-8ocgrBs#bEBG3Zn5Q!l?x^IIFvBT76*CtLi(OEF)%4<|^wtD**7_7j(jTX;KJ;*_M(FiToAMk!t?*ygOwdE88bI{9n zXsE-eh*x0u({s7DzzK8cMU8q6dG{CDO#tWH$7r6R#`%FbvpWxX){l8A@!@Cv3#;Yh z#D?_iX^BqvuM2wIYzyCWJ}nk{?x#~=QpsKPo+{bbKQ=p2s|0Urw>C|I*qO*IR`u7? zGas8}Rt%EoQ`??L6|(9b-UUBI(&!;=C#Ai8T|8h1Sr zBLH6QUUjrNG3Q@#_EX91{QKN|&xV@J?k6B^VlsG}_iel&TbJoEH%d*PB+}LkcHEfX z%FqkpvuRXD0!7)=D&o)CY?Tf3cl`&0I*IAYW@E6TAhF))_pCg2>ywx&CA6%xZnHr$?ev#3MfNArO#u1 ze=EaxoR6Q|$9pNg*hh8OdQU(teF%OBICIITxh(X%<)$osH$V0f^>f3zUI+A6@3m%4 zva#rA7xStdPMPxt2mTb29rocG-LD^8UZ>SvYIkHnB#cPm^S-=B;ip_nT8-=afB^E$ z9ZVd%S7VG~K+dw6z4@3Cg)Dl{AeW=9^w4J&nUuXwtzCjkJ#qgL2L{X2^5$Um`wI5n z+=86hAI68BkjB?twYOqw9k!YqV6GdFn)W@@x$I8r1Xz}$6z)t=)>+vm7FUMp_x-&` zJt#BQgBHxrH|{?7+&9{l3jIAdkZoz*V3BuP>$KX)_(t}x$yOb1`Rt$yK`o499un6s zMznZuVfH4LC-B+b?!0pC9+fW}iB~g+~$KG^(Y^lryb!FhzI0wHRYmJj2 zm_XjPj2X=ziHoJzN~e4pZ5zKkYp_1rj=Jj{qj#rdKi3#;eu1I*S94o;7CG6Rwpf1r zEAjK=D$Y<*8jG{$@p>?e!}Mqt;Q&y+e#!GmEJ(+ta^~djz_g~5p>PogC`3svgFs(R z*Jzr<_lu8pd9+unT(m64*bO`)%r$&l$8m~CjpB5`I8!PU)-fjaUF=cJFKANCt1*i= zUgu)a-gdW+=ejVq^4;DN zAx*a8eRAqvD??yA0*wzf5D18=3|apQzcu2mg<}pw4Sa%KVs7+J4@{2FI_KUI|9)z% zO1%YisMfA5y_L41z*JgiS6JNHl&7=8mM)bdYpu<$8m1Z3R_3DAzROqngesZ3c7BdV zDqz8{j8C0Ky$AFP^@=59}f!KdOZ148Yfu zn)D(pq^e5X-pFs4XY;h{HPmWmf{k2f%^J>^zdebgGK|2oG74{M3y~|cxLA^Z5c*pW z`&Rd&Vk|wm^r(kK7rn^;K}W%#u7?+FcH0*^2vpWMuDUAr;>rE88Z|Gr6Svv<_Uc!1 z#q!h(nd~<3in7L&3IPrht3Xg0Qxlfn&KcmFD@?~pz=(A=%llST&W-kCC5J%cXVa4S zfr!=;fBp5$^Kba0t@eNMM{{m}_@+0-rkZuha?shz71GV>*J}wz+WBAR$KSAF(n6^!9QJG~H-NK?F$RPUlgfa%_u=^MF>pSR%u0zPrVlqq`OdgO%iy+&FidU1Nb;Th&8 zwniJ_P5#K8u(w-=Uc_Hq3ht&#=865VS^Sk=| z*^7)dLoj98iK_&@>}PK)@nxvlxAdDAO%P<{+KxVVHe#(ERegXFu9aCC#(5`eYu3+*p#PD+xwuOW(F!s_H&-3|^9|6Y*P4M4`LR04&3A(j zEB~BEW?R?6`X=sri|lFBT+MojwhrnYwCTVekm@{o*>ve;eg;&|PG`@V5$SnS61D!` zMk!nMWYCz*%X`X0Jk{pai}@~*%ORXZHy>9vW8qjSvUvSjI$?aL(Rq&53r*O1WgnW9&W}0=Vb> zUcE0jpai0T*`)H{VRG$a98=eje#s_#fa?4%%NGVx5hn+tLsSy)F(-hFT_qDIqn5P! z)|7M1zBG6K{N`@6ZFA7@5xTZNc+4RyQkAc=vZhh4?zMYleom1JlTOW*$R!89ulje3 zkEjh~DI8R16-yh=(6F`T_CD0H6htixEJo=K$(q5bDq3$3@K?V3{NBj3+J)4uY;7h z(%j50Cq3m2Z3#!;I}vxR(zJy-InZHQT-H}sjWG?5C3!+G*40!f3{9wnzCnPY<%04K zI*IlCVtl^1nInGdBV*OwWSJ9MkWggQU$jDE6Fr)?yr(N$tzo2VfMxs;s?_!+P)B(< z?o3rmR|)4;bQ@x!(|DFjT@K8FreP{HQU8#tFc#zYaAh;0z*dG1cu4x|@X*>;YFV%o zs`0xt6AuZNL3f^C8fd<~Bw=eqN0P?$39e&wHht_feZ)X#pKrutvA+R@wN<@|WxW#Z zADGkH8OVyYiq8FurS{kvk2e@|*Tn?e_xL>grv}C(H#H)Fzk)EW{bXzF*2EpFn;oMQDk4W~y^D{oQut)9v*mVH3GbJZ|5Dz% zcSps!BV7(i=gD$=Td0O7ffTu$PCx{GaMs)fv6Tp3TuL0e^^jOvJ{u@CLeh z70)(_>^$)b5Wc_S|$=+ku#`gZc=v-_T9exqIL#mrNw=G|Go^Dfb%e z(hfh!&r+ta9pJp&3JayG%2=6E=J-3=%Sh}27-(H1#*OL0Zs&T7SU_Um`RGLv_an>x z2+D%kcZFm7c^zwF({S4Qw%1>~^+VNxrVQF?PU+6>27!+?ut8tN&NaK2OFA2*kB6YJ z)QTJYu+C?A-0Y}ea}|sNc|0Kbbn&gIZ{vHrqI<)cPBY^iJfPMD>!tup{Vng^A*X!Y z3$mKEdxuDB&H>-qTNnCPGMAnHpRw`mpbdqAD3T=v*$R-^ngm$GGBeIC+`~Z zGx>hj!+kwP>l?{lTesfMs7(xB#D2x6`}?uoqcDB_=5T~{_;=hlH^sx1Nm_tabhN|BOXKtHt-5d!{Nb z6Q}Sj=RFq_`p%W~O0p7R&@6jiai?4sWow zC}skq&HBJTDKK>X)u=thh=sqRX>pPt_f63nUa%aBAhx^lX9G-5s z+M;$w>tX*yp}Q{5)%SQa?uHIT@1|>DcGLu$5gtF#w4=BqoC0^sf0cl2+!FP@$~Xxj1ySW`FbM2(F5*^W^bYy$jH}d`i5sxHQjPbaWH;(#!QQgIyKJh- zr{dDvOtY>2Wi?Ek?x%FIYjl%qtS($BerNmacWa2!1a&HB?seo50=cFp87=Bv&G?deizv+)>?HdiJLUXAa6$ zVH@O!t&bglJ!@{JS1J^Fl^OSnv*C~=7H4f(3AVnyAMqv_A z^*g+Lgq4(eK5&hd4g}jcwuZaj;+SZQ7g@R6L8&pup6bl!EA2)yV*`0L`J9>*Lxmki z?{@oz`qqxk+5;t=qvj&Sb3tLEb@ZH0%|nl;Gcx=(&#Czx?{sF()P%9j>=4-=j@JOy zuXauiCW4*UwAFtYm4p;AjAp$-p)z2}UpmOmRDxHd(>f^)y~(^hYKHQR{Z&_HE%mKQ zyR^BRMK17>WfY)xy}zq0(v5y7Y|{dzDZ#?N$&>^#-~P99ydO@zVogiNR4sU(>XpYd zA^7s_ozGA2(zu*&NLRM1#pOfVKK4#N|7^Ld6j}mB+s`~ruG!!Oe%6spGezh2WjyJ6 zq?q}>v%6&`Hhvod3eE&j*8K5kX@0=l(F8jr0t@?1h|;Y3N%3)iUE;g8smls-i@v7< zllB%%x6Va8Hfc3TM{m%%u1KF2Y-ms0h=~aNZ7yYhZl;g*5XJ#%p_xI5z-LH=5_B9C zj4-e-&i6eEO|kp|mK&}OC!hRAq!XW=KvV3S?KWx9Kx*0j;LGa-Ukj<3!(Y@zzV=9iSP27-vb_K}r5^df^wws}2gv*G=B9V;y0 zbEcA=2|;FZb&?aNlrwj?_Z?75nD5Gt^YU3EsJq&M~9$W>IgiPgR zmTMFH+xD2!jiiSW!zvLRtOSPm;upd2Zm9AZ_k!VZ465>l?c`a;MgY5Q7h4{7rAs;QYYG`={dPalQgvm*3Xdq+CTH zzkiUk?F0e}x%2ninx%!jww-SWVW8c7Y_-YO!LN&--)76#)`h*xxF!;>oE+9?9{7Sh zEw3L00*5a?Cm##NAwZ=Bc=$+gNzrV{K;DGk?i!s7y7JZq{nk4tKUMbF^OE4%W zW84NKAq!F7F(ni;*>jyrg9ErVAkLBzJ7{we7Aq@0Obc{i9-W%{_&odfBbCk8m>fSP zX9g<4(w}%bBe*l1;%ZCf2_2br;=YV=FRe`j*!((N<<8|;>HpU8eDrGsl{s#;AupQY z-DO=qwI51!=`<_<-JtsmC@IS^{{Ro1enW_?q7eUsW5@todR%yWcQb0k`?T6pc28z* zJ6kn~)%Rk+iSTg_-OfR|%(CM_1I)Fu?v5FKCXKt9{I@x;-mCB^8Jbw6E}u-Pxw`C^ z(ZSX7u*83-hX8JZMRe(V@SyI@li`%G^b`;qqXe1Y)w_H+l(2&o>hk<`fJD7>oCz=P zfk+V~*E4%#5=_kA`+-295pDAID;Ss0)Q`}aY9*f(VMyJ)ZJQ#Q<$1mZkb3=VISCvpfH#N28}rG{0(qSMT_Q&tZNvu+5U^(M zQ`MsPsDbA0MO55hsHx5ZZc%IoDbnhtDRFANe;eRiiNoEif9SZI`X^$iO!3$nV;#L> zuSQ->lXLBtW%81--55rGFqu{!!$%V>?v*OC&#spFy5B_E_GVJFI#Tod4ZtVtGq?Gn zv_1@8!|Uv_D&fo;eq`&d;j#BDhJ5$!+WHQLY}e)Xug~|UrAweJzOE1 znI@)%x!IFor@+gr{R8YR62!({+CUR+R=_1VLvd`Yzj>C7gZ zC6miN*nw3~wyD$`2$MFBRI*hmN6D(<$MRvJcQYQlv(9_aN@cf;df_#asskn}ep^(L zJB_%J2l#M1w=_xEYU7=9nWVpkZ!>y%%Mzg3^V4kg&i%ftIXm+A*r?wqHuk(J>aSk5 z4=UGcpeu`{PZ^5}rCf_PzT4;UC8!Yc^XGibow%`0IpQV~E4kv^69>&5@LXpXFApi4 zEcKYK`cxD`0ACp`C*OrtU+8wZR#C9k-8PP1|31aB>13b93UkBt^Q8(7!2DI49v(-N z%RyNe{Z{P&vB%$>?e=$N?%vFwI{1$)4%baoo{aB(xo{Ip0AgF0AN%}fyC}%pccr>a zt;{W3jngc&2z%wQ1{^(a|KUqXe!pT?@AC7O;rrc1G$VKIw||y!Aw_X<@p|tZ5w884 zPIu6&Y#;NwF;(4jTeuw;Ig!~q4azRm3fP&o1M85f$L5qL3(8Jqc-NxH!9AbR8^fJb&SJ=Tn^kL#52`+1 z@s=sWEwzL;E-NJ|{~F4DbX~vV42?fqm!fhEAfeT6v7MdR!TXrZ#f|LO^U#*}8m+s> zF|$`At(}|V8Z_cY?ObN6dS$YX4q*e)KEk=M%#8s33+U}|)h+OiBqE^)qxROIOG*k( zdn)4XC>WDjCa9h$#V1Qm>w(w>_IfJQi@mV>5!L&pc5R<7i$n08GKJ|}9`{Q0Ww^6$x?n?IuT3eFDpFQr=LlkZcYU%9Axj)4rac%0Y~&O zDLP&t(28ix{`Sc(8)xm4-}uO)Gr^i1d5w(1+@}CS=T@`Ym}2d=0;l3z(_2(q zr9;)VjPzCSO=_=fj$~;nz;XWK0vBP&(S?3#{><_vXy~Hxwymy*7i|&LZKbEK2An-E z6`esB*1rOxGWu;^I?g)jz_*(>OF_>=cRBx37qVhEe=Whh>@t=$=dN5&Fvi_VgUMsS zGf$DVdk(W@XL8&dMfxmJ_CBI?eS_j&qb0aXOYaJ3t0iX)fBUXu#Sbx3h{vhvKzd)< z>9ltjH~D=EMl|#O{@%NV3o%6Qi{-TK6hK8mVH8LZZ9q)*t)-x!)sQot-)>lUP3ww%B;V#bRO^e z@(hO7`DIjFkD?FOUVoQ6SF6m5sncK8$IJbuw*aE>Zj8KYGFTaq+F)o-{Ec7rz(oAb zIoYNGPE)W)HcG^%S*rslf)84~Y>9j<+Ka;P3L?ZQm&wcz7t&MnZ52@<#Tb{!d}NRq zKK@Lei2uwlLbtzp&MrFR7uNpH?__azTbc!x%K;-+VEvuu5UFfVapS}-&5CElTDx(F zu*kH6eEDQknIkQCf=Z-8SNzRUvHYl6;t_{acBD6GpEK|6hekVGP7x2Gq}1o9MB7m) z4Q6m;NDne=^jRb?zv_e=H9onRcIfK;Zb5gnOV!%*S2RdqMpjWX%=NaiOhB4krS&5Y zyWje<wnIB z{sKD;qSJrOdmtG;{r{)}x0X^ws}CFh>3gR={p#AbYW?eYaR5!A+jhw$CvkUov~zEB zQ(Li9DI;=Fl(-cKARh{khgJC%LfBvpXW!BsdBNEfu^`V|mSx2m`!WT_*J=Yb-y)p zK;L)#jX174*RGJ)>CY+TOLk`OFgnc#EotRC{&5f_tO#wHoZPyv#U4FJ zGRv;Q++yS|s=Gxn4n7$ivsOR!H*mUFd9^t<`)=*}zXz?&cg#88QS-FQY0r?%yT|UX z`R40;>H0hmx8c+emQhPin%J#e|2(+~!B3Bw|2t^ixOwoZd4CFBQK|YUYC9fo&{UD# zb-_b9J_dK=S59ueIPG=_vN6cl1*y4N;-0yA8zq95*Z7Pf)@{A&xOj5kE7r0Mx&XR5lJAvj{kK#`2T0;_DpA#*pu8+ulJ|n80J053y7guOA_3S+^eB^MjmyZodi;n0U zm-Zz7;`is`sfpX))vti^W(^7brCK1pII#+cL1X{Q5_7*3W-qDu6+J23L5D0?e~J zlqcL`EUf#63&H`FCi!PL4oHQ#@k^dCl<Bh6>iHl@n z_B%~?YrTBlrP9`XefV4QT(-T;ejfl98pff?i8#c8QFj(gdsKwoaDFz!h|X{cW46&4 ztu@?CXnI8BY_@*-ja@KBq(g&v=mI9KD2Ep~elR`^2FB}^tg!->b&bNv>TFM|_4q@+ zP2XvL8fz=NePw%~)6T5le%9bz?zhLP$|k#-Ar5mm?y^(u{(Sn(*I~~|FNrlYqz4OO zbZ~puUr!;|y1I<~*G)I!2-esT*w>(zK^>->O&V(H(Ue*hZiF}-j>8s5UaaA8-C-;l z?9zR;G#`7>ShS=QO;n3Q5tf4f_e0Z47#|Jx=7Ku(;jIG1L|e zl46Sa{c#&CRCW4tD4iHIc?z=ILnW&utR798kOe<`>wNcqyY7}TBrB+wJd={`W!uj2 zxz-9zqQGgD@_Q0P0X?!Ak2-nK@jRJ;PjR(l9tU0`JUiWLfk0<%dAWsW$(>eNe@SRH z?lWLZQF~M9f9WEzrk2YSK0Z73vc4U=_WH43!#~?r9!H_|+AGa0BYnQr1L0D&ZZkq|xk#sr_v>2%$;OOoS@P5D&!5F?7bBo)pnI7{I_mbi(;=3$_UG;4Lg`E3`EtP5h3%j= zsSaPSf_Uf2mDhKZA+x;QZ}s(T`(zoNGd`zGvokLNZF6a6$_LaKE)T={&3)ItXVTDr zrC!&c6sy_uN3L4+kW#Pks+R^crS{~i&t=X2T%yJtrV!;p_1p*_sms0^*W>x%ZM|Es zti~)`UUc~N<2}LvG;^-c3O)Wmk4b+4gk}ZtU-Kx}Z03-YjlQw|#`*58Hu}tm=idH& zI(yG)_7Ldl_yL8L4wg-e2$Crl{NK~sG|rfwn?UK0x)-RkZ?^#ieWSwYV^0C+5{gXk zfx3L|0^2e`p(5wyxw^^_6)?l;lj#y4?ba(T>O8Vj@$5-5w0bksZ68*0nE!5X2=?%X z4;s%;Q6P?yY$o|-2GR8N{@gB;$&h@`h_m(TgMfiQ8wX0^puCB1>A882}HO-~% zeEMOh+hhJ+DxHa(>RvNsEm=$-BSnCV`NW1nV#hNY(W=s(K4Ta}ndG1YD<_v)IN*d# zw8vHH;DPRiU8nPc8GxJO<*9LYU@W%Fyj!#OWMdIH+sXeL2lHLseAUye+=l+w4+u*FE+3YS-rd0V&G{4oSQPIs@k9sCNzf0utP7 z$2G(hto(k2=3i_j6|711l4gj-yYmR)#FI4c^+o*Rh)1~190z^sh~}O~7o@JL)h*o0 zIJ5!M#@%IjY*b%DH=4{l-66}A0IB6m-Oth$wzEF?O)n?0-@rG;q)ySNE@Mm%wNc2d za`XYx?#1_AE0cjw3l=JDi?DezGKP{Q)w1`R)pK{fEtPEfu$-iBGV1r5abfFf!f)u< zQ#u{CT4GMc`v=4B!m$mhOiuvI2F6N2th@%_*rx~hh$OsKExv{K0A$fueiQ&V@~5A_ z{zg&6OtEt+zA(tRA%m!56U!_&Vgf(+@n0}dT6?m3Vji_+-}zz04Kh@Vta+1^k8{0Y zm&yyGLbKL=Dj#~AN$5`=Qu7mchu;rAQ(V~UBnmM?OY=8t4dhe4UpRM`6^qcq;1Ium|R&>7?GMm}t1cggi9EQ(VFcN zYdfW?Vr>S^L{|VXt+VknwGQ<6yL4`4EbcbEk!o9-Uo(kFEK8NSr?Pn2S{$QgYk z?2n%*VDYONkV=+f_TB2_&+p%MFT0iB655`^vN#{jdd{s~dk?qsFs5-u8x>}Dz!`q~ao*LR+k8+jw2+898AU~C z-*14l6PZfSD87%@>wf)}xZQW3(a^2cS}jei0;pAg^ZjhX#f9lc?UX+o{{Af&!AJi} zfX@=pg5$}zgjL#0E@QfBq0aW%5?*Tjs?hc8Wau*vYPMlQFZ9Nl3pMgi-1eeQB&T8I z?f0AgC0EXPlbv0h`(gt$0!Q$}h0%IS07YiF0wpiu#Vpv}YlHUJ0<_)It&X28a7DFT zLYfpuyy8UNCV_Sw|Bmk1Kg(~zoHtG_q0c{lVtmxP%(ssV;)tsk>dJ-;+Lv1M`O2&_ zYxg*t0V7o#7I&Fa1|&n`YPs3Yb>%i`pG(uGm5A9A+gul4y`Vtd6)ZNTxi*)tec!kt z{<#S{lK3KL>Eg|U18J#yxm+8i8c{Qz{nv4`Y)&5lF_8|}JFUZt^}?n>kmeHKK{D;~bh zrPQCq*uA5*8U@$fjcV8}8N5}aR@1&ym?aYs9e18pe<`*105z6E>G%{F9ZrUuGqI*~ zn>%{R*X5DVaDrgo@y^>$thU)PUzEvq;yfj6A7Cm@K~tX#b-&!c(j#Qnh!G1C=4hVn z-{g1wJ6d9c%N8FW4t8;Y z71GDBJ+TOKejUHs^?^PvJ3XhAtFDT**&I*VHkbSIc(Rr*%tzS^ZM6KZyq@lJ9Vw3! zX`b@BUhFvUL3`W`k`gAY3hB}>7}p1{lWP{z0r`BvT+JJ7pV=4?Y2_b_Qt+N!i-YX+ zkv_|sKZzHUE!}%(M;lF_9qWO6Wmb)c<3>scg&(AL*Y?^&IX1uew5DPQCy&HjHK%=` z^AGd}7f3MP_e&I7y={O1KPYRQ6jol2j_4IMz}nhBHdjwLH|}zxV{CG)@VSLKa_L0f zP3!T8AX8IE0nf_-HanS z0Jy%?_;G~hR4>oidP#jU^JA)_@ieLAA13RJbM;?eX1=&(sZ!%Y`{gtcN_Zi#uaf|uLxcQOX|Vrwpq2iH?9NpF)nKUI8jX)6Vau2w ztoW7-C%xj#lY3?c>*oL)+bO+=?s^C6uE^2~s#(pCnh%)H`5>{bk_=wy9`7ztj#pbt zf(kI-lGYt|#}dc~smo3!Ez98>ISt3(oxfTot7?~HZZUeLrC}q%Yusvht2SSgHCyY~ z>ctf=f5ag3s(rNAD_=PZ2LMzY#B5@{bDw?Ybyr9z7@V_lVZ3WM)%!C&TqekwT=zg% zI(~u(VfQ;8C0FdUvaXzL)(6=PgAbK0H78~YcO8qYidivFtq{)cEsqW0alqD6IP(M~ zuQMgQ;ZCZq&hU>y>wNjnj#PtYwTQbg+cis)Fa3mcU^iU67kXq)_PWj~(C}e>&^>n# zKP7K7`f&Xu<{a935`gl&7;DYo(}mRPbdO8GW3fbGF|;FwS?$~WS8pb|vn0z%a>vi5`H|UBW79LSG=FUEyFe|e%Hvg? z{55-88CMr?qHw@0Hq!`9aswlbqC*0rh*eL((}QR9bl+jS+u7_D*~cRNc(+)04KA4c ze7v%na1UqvX|vO9XC<-vBizCMB$xfS*b5mZsVpZ_7gIB^b5MIu1xokwU=xun@D;d+(I>m%&(Z=UX7{+u;Xkxo?ByXX|nJ(LL1w2unu|F`w0j}sJK6nr%-}0sB{qg5{O5Q&}gaOw_7?( zP2a_rF^hK3)9!U>R{K_T1Ar8OC%}SupdGdo@#VGA>#Lh8q8pCJ%Y#}ZcpFXa43zdE`K)lD~)F2j92&~!QjKxd68e@|lt=oY9^>n|sW$S}AGPhIo!Z3D+8)jPgqV0*f6{l{WJl!QLE@ z)VYm!+c$hKH}0)n(r{payt@gY>D2t^y zMs)RpHh_ycbr1MuBMTMhA1(IaG=%qTZDo%3O1(=>kByU%(|~<*j)u*RDHzMau8%D( z>D9^rE1k~^=!BZx19qO+;PTBmg=2yoJHG|a&)fUYxpN8)2=Z^8VK~35o5>0jN3>V~ z4*T_aP~zF1y>S7z=u6l7oFQkYbaYYV5~LiP*{>@{>mkYI$as^fjrN0h1^!;do?I{8 zX(;jyxznHBZ4wQCf>jwc8)Cbuj}0go=CesoN&1(`eXu_)t})H(;ngRD!&*yPnT&ot zt5Kof#;V-laiy3ho|Dt+(cu<*ceXI&B|QSV{&JgM+d*z!t1h)~b367nXnGpyh2ins zs-&0J81AyOvf%eBgmMC?2<+(=Vc1VZsCi3x{dXz`xfG<8` z2qV&Fvwz&X@45D1Vfu!tSa`0F8BA;l%4fdJZ7BfZmmNFMii1oarfk(}2X;5^4gFZ% zz4mqjk-IQ+K2YdBXgTw+hfT8OY#m%E9h;q(A|&G9ZdB< z@+GF|EcfMhm%o)AK&`c--}~Kt;^DX6IUR?)ZFBvlu==bew&tBnTrQQl>$Jbxt&cXk z_3O7wWgqa+uS25pcguE`!=G>k(cE&k1ZD~tiDLxdB6n4YsZw{jq{4DHzH5nn80poH z*XU97v9ZM)5~ltb49DJJ(?DjY;p69I4qC28T)oc+d%WwNTj_vlrGy3lN1gGgxpW1G zour?E*mvr?_m`uhX+<26Hbm8{#(E9}F1zhFV&PIdOp!yml4@jc`%FuS8(VfnQmqZHxs`T05$Ap>ORc;|fiFV=^)=6r@K6VaIIyLv zwMTOP+Weq)SvanFf8YZw^ChZy#~+#f$1y`=(}lH~ueh1EX~#GQKZHe}Z4$GgU(S${ z`hvahXMCS!hvR#Nl;vlqcX8u5tVz*QJvTmHA-FY;}EFZ%h0z&q1S#=ndl z+;Q@k#dFYV9Yg(=&yGgDcVR!yN{KUD=IPMd%ILTMmdaF>;oql?jMtXj&Tb{f&2#X{ z=aJfVA8Y8-czoC^%G7*f`l3nnC(addZeEbdO?i<2zE`fFgqz)puAuItprZ6ee|rl9 z=0Uw1!X8H;Q{FC*=%v@xGwSqXwpPp}-k;y9c{{B3eZ*IHXET_;?v)LTACvsNTBxv| zGDG(YI*bN8*gN+Itl1e3${BtUCw{$Pe9!LC(w^6oVSLs-H_#dz+zAiIVb$7z#km_4 zwU$wr3rE4-RR_Q^{S>uTI~x^x&vrR~K19QZ26&9q^Zr%4lkC32GsrQsSjzYwg_$NI zVP6s7Tv}mnN~SQXD~6p?zL5={3Y?7wr*cVmJxZvrkXo7nxYV($yRwuN?BQN{IP;Gt z8pNKKSw)42$d0B9x5YrLR-FDk-3cp29M?E3=uvWfukZDdR@i8yyDc2Y+R#9U+43V` z4Svbsc)>}zKelPFEww~pb8r2?!Wov=xAtVhA2T~7XV@X!bx0Nwryuk+7CG=bF#4q~ zPTbLcG8gPh3j(g!L2IMl>gvtUZ!P$qZGv_Wfz3CeZ@x=`1pLN%0C+OTJ!U#jb$-jO zws5L&%XI5dZ_%v|ZUlwUJD1Q_@BG_69Pf1%fq7JQGZ$U3XY14J{mwkggY#-pXudWs zBMctg1#a9lFnyN@l9obu=d_jJXzmFZiQu?;$<@$m`sWr(mSON&tsWftVJgTw4QpSq zeR*YyO4A0G$sr&2+y&7iOYQZtmNRoA^}Jo5E5JLDqkes-jvK+2CL_lw0qkPk9A!XD zO0t~yDV<>YCRaN1pPt#H6M$Mg#)5~H5(0d`>SamvM!i?FOID}ox}+he83?f(0%$K! z;3p(+>tvlb>itKZ0(|&qeUNAheu#SX#WTR+s=DtR&rpjRMUlm+@jigTpb1jk3H4nP zUsRIbK>nz#^kQbr0!!W?``)1G$OS8DZ2L!Vj-vOf95FfTSKeOA=gAg^!$?9LcXa&{ z)C!66E3ePi6eox8kvss8A)&P1-^XKfyk@JT%}8(aPu3a4eXZK9ot|_)0sqOIr?3@w zt$aVH`Lny;>u}NC7e}W%o5Gg>4m0Pjy0^l1G(NKx-&kJ?%YYh?lHb7_y zye2KiWw)cXP%zDhreiRsyLJev`40IK0?)5|JM!jrA<|-htbgNUMF*_WVSOzz2;5X( zxI}ft;cVp%p2I?}F(phoDAZo|wX|iar+>Iz>p`=*WY<@6{%Q_|+t-{Qkg@?~fXtU8 z>Hf8fW*(x&G;nt}YegbCijC@6c;LmxiiG!ik9=$N;$@FL7t^<5PWO-PMme7=53fp6 zTkf6lPYk?dsjAI%q~2h?-#pOyvai;P<;|+<3s(>y9VDON_E1O|TCH)3c~VU^JjiLi z2IILRgmFE6!yJ`vhF`5V2|gj;?K<-j)9dUiWgcqobN|oR=-&XvIhy~c=uH6-`bTeK z)}dI$931ij!nB=FDy0!=UnV+x=_Bngj04z9%l*2yMazQfhJXl}g5o+j3CQnUcaRw& zM)PToXZ9*b2-gN?fwAPgedK-B%XdD}M?c+;+!#9h_z-p#(2f6>u|&;(GbX0D3e!6T zu3jT?XWiG2ZaL~kv&Hqk2$oj6W%3`!ya#d7{{;55u$%aG)jt_L5`>FUyFVNJ!alaL z$L+H-&wCYPI2z2QZf)i7lC!qWDYrH_rz>uTrii%7?;>PHwdiuXk^bOm`LwaRcl)&L zB1y4sWqyF`g2`^AG7BI7*#)s%0z2HcQ+{7% z-e#?*%Sg@HdDv_RtbWgz+eq$WUq5v3x7%Ni1$8gh>sMt@&pU)ZAx;cZzC7(0XHdP$ z#Hep?t*<)kmId=ueCedpfeCMV1tajQ~(kV5r>G{&bEh( zvnsgHTozjDEiijV2ylQBp3FK`uKZ5UsWrs&;qBU6^xj^-wtRwn%7#^Bcz$g) zbMsbb^tEib^?l>%YOlIIY7C~5+qa4sK(((;Pi9H0_@w7OMO*1gx#Bg7S<-0UpgZ&X zg<0k}D1igS2SL`urngV%Y_(TO3areC@NIJw_o8Oi#KFZ9h-^m+=xh&uV@%BOqqLw* z+2=PIJG?g`PZhl|WqQSx|3uNlDERXaX(-;8X!=)kl*F4tvpKMjt>dR9)x4yW{e?vT zp+R7*iEL+M@N~WACVe5Z(Cw@2-yQOL(!HromZ=MCJJXN&+immuDBH<^n;L7Nh^>MZ zN%#RhsClom&yLy_w#&VnXNLAn*vX%jO*b=BH;<1eWWzVI<+#;GHG_TQhl7Y52_AA_ zgZsHStQ>Ed^&)GfSnfE#Q&^Yw$?c>lWwE!D0ZnL>2hbyVt&z_qw&Ej1ettRNW982; zY&#iDCoLGsRwfF4+CUuUci1ig-4J-i++29EvY;W2X%qQ$ySKL9N3O|(qsYev-sw_X zZ)|g0MBGE0c0*MRW_soE3{vW}uQ77CjfyEyg{$AP*ckzszFoP;99BW5TqScTpDS_F z9sl$IFgtdH8UU9I-Tb2_dM|o-`9{;$(o%-(48%q=t)s2^;d*I3g7=}9-|emodD6b$ znT+Zj&0KDHhc!_`WHGZ-#T&JD?Y&{En`60_tg~?U+bp`*lvx5lqdd#+Ww7ZCxaT`8 zE+lQNwaOFydFWY`%VfN}YLtEoloOUQ`)$0+k(5;CXlpPj}x&GK%{l)s-T>*)8=YmfD+@%dTL!}p@U8n%Am>(a%g_*uWQZ4ODz z*<3pTXf(Bu)vvMW&tC;M_qcM?5-);!XICF~n*Hh^B>Ss*d)P_e5)DTQWJ2L^0^uZo0@6&}7 zZu11Zi{Sv#jR&)(urg*W_DZ`ap*7ikHD2BF(deAB#$;}^A}dN3E5?WC9O*t9rKSpS z$|~`h22c>u!b9+6<-@Ml=X%vEB->2<(8?q-9A7=VDNqiUj zR+lBSt8Wk2MlLyzj<54>u9;xO+`nOUNmYjAHLh&d=WRN1h&nJ&Z*CHZ@S?_xPs=0V zYtxeH8C4z;Kv3AqW?PG|20IcT{X_gL#_h!hF?XMo>@sUe8s?z9oNjit)MR^uqWLLi zZCjo3I+N#W@i`b$LB`IrjcR4XNN#dM>PcsUD!>rDpdAdoOz$p;26>Q(;MQZ)?}uBf zfW6ty>MkXx#})*Walu&n{o*l?wsm}@{oK2d=|3k&`$tm8Xw_Rs>szVV6WMp}ZgrY3 zX>mGho6qfj7_SPT7JGIU?xQ-5gQqt#7H+FUJqYYs-*pT2Ez?Tw#r~G|5#o4jx*%Y4 z(e2}!-=RH81#KGf{>4pi-HM_M=<~R=7Pquxc_5CHB0SUEFaJm!xAnm!9%tQLV8dtSr??E`jYwlQ4q*i6h^@-VLpHp;-Q##)8RHd=C$xqXS zlfzr@h}hHMdAya9^j02x8s?|jn? z^lg|?+ybv(HBoun+FPh=bQ-B$bNHszzMDOt!WCPWU57A9V?#k)rrtfdt=Ei1w!7bu zBTP5}k_2QF<}al+Tn~@*5^|mo?7TiScEeFwDZ1UPpE87$K);}e4o&?Ixwx<}0k|mg^3_vnp> zV%uT&d9`FaoEE=%qw&bn-EEX91LH(?3+?`4P+nnOYGC(A&OP}i>wEGWQV83Zlgmas z-f=q{LYX@h6q*~A+6R6c0V(kl=fvp|<4kpomQi^HIJjglP@!lh6K)y9l^LDdxqyh8(`%POKsj6l(QF>nba6x;r5r$M?rP&w`He~39NmI_FjW4TM*{53S?C*I-3L2G?sv-&DGl()c`ieK3aWuMe;R~#ND5aWeB065&g zuPEa1RlLh^lG-WK$s=VFys4n&HQv8q)0L#oF8@>7cQq@^H0_?>zv5OgBa(xH0dqi5 zM8%9KiUD)guKnwGujk<1-@~k`@8Df$YieY2Pj^rEb#=4D&m_Aa4~xSXRe%RuDhJ-p zjd|8f90bS4XUW36VPsBi#*$;idu9n+FXrb;iC2ERyz>!&PXf(K^-tqdP=u7+OL%t1C;WFu9x^t>W za_jQrI9@8U_d@_vl^V7*VP1$jmGSIJsr6((8hsk$7q;$hccV%+fBk65Z{?}fCh_gm z-+3wi-Fy`<*KMM36xEzN2mKca5MEpwau|xAQoR*jrRx)-Kpc7fTOjQ^+w`!Tb3T1~ z^_0FOp2r@*&_r_Yt04%HZGAI~ciYt)yhK*d-k<NX8}%u@Z6eonHpp z?ZXd?mNMDRtSGaL;Wx6VYxzcRpR{j42^zUjqzoAIH}_jz1n&>xx~(l29suzgua%v0}!+2uw*j<~XR{F%Hgi z438$X3i&De!`^Y9&sWK2IZ|6C*hG|kWp~HqxH^BrSo{{l0W) z*_@156<>K_I(dNXS?v~!F2rTa>$EBtJX3KEuh)FonMQE*cWd9Ol?szsY5XX}#Nwec zPpwS4M5O9jleXFZqsxt+d2Lo?_v+GHRYnJ@6>HGV<>JsQ6 zH?giAB`@CCEzjFgA(kA23pj&2*8I|?W<|ki6}|g24J75SsM2RhLR_%q$ePP+2 zU82;Yvl|g=ZpZYl;{75X6wvghpQxM!0G_k7CFNsJj0BTj`!f%g&+@K)H;8nTV;4YR zl}LgR6o`8{gMDZ9Zd+zjK-GQI8iZb_*>0`cF@?xc*$ao1G)u>XR;-ebz2thmubjK3 zAhRcCom@V8N(_5|*!uA6hsy@;U%k7fW2suIl^a`$$lCibEvKh7rTO!?_4C8+BGYzC zY)u>_C$s+8q_+|K_3-DHyOC}*BaMJsxbqya+mjdyI+?#p!HQ>^cRO* z=~&Z=h$p3;5yc3Zxwpg=aF`6KjM#84xpx(^IhSrWa+!X)c4QjttRARjk936lT;uDs z_H-vU6LojT);kV7)wK*{0l&COAyt9<%Z+FJZ6#kj5;Gp_uP=pzDc|OOli=&6 z50jkLNcG9O_;?1M{6`U9ui0I-JVPIe&ZV^++!6y~;7bJ(+Lgt-7BOo%{EhyJ_j&t0s*r;Pul!#A3jWpKmLD@9ZD3 zNF#l#PVNUbz3O&5#6ER%bZy58!`I;R>VBso>bcU=&>Akd(807 zskt@fPbUfD>!?PeUr$dC;;xyFB)a6{ZLcZj5~F2J%ap5yWOb9-;%XUq^9rYebfYV? z3o&8U+5TFW_G+e+S3Wm}G?m#Y;rr?da{G1~GZ75>8r448+g*N-R}k7%m?RSYUp1}& z28*2J{)I*U&ub7b`tTYAwB6TWP|o*OkgDoznO+L07<*QA+=(eU9(WHhNL_3QJpk&- z(UE(9m2Y8D!*9$=@sn;B1BX)}vi?z9p1GvcjR0Qo#H*z?V4XDHr>wQv9KZuJwD-3wwwU+HpO}v?8ftq2)1Jrc#JMh*xZhU6t~qa#AKLBb6)aF#c4``{J&C zUY+%6*=;W|V|ktBUir%HG0c81G;8aMd#EV!&$yLvqMuZ`x**I?7qepEie!MIJk6!A z62Sb8fh*Rpq{<`xT6fZoh@In|Bg2(C>tLff8^y_V&#m*j%D&i(QrD>@w&ss-wW&MR ze5LEy^)kC4gO?WFMDs5^>+YM58;QHZJndVAa?J?qaQ_eptY4V+1WrL|)eomv+<~K8p)Q_b~ zKsP(?xj0Y`ce*V`oSx(`oDrm;mfV>Yf}T8_%_{V<}pJ z$XvNQkYS6|Fa5su1GCam9y-A-vZ5GY&23A^vc^I%x^fi{#@$1oHz;lUn#hyg{ctHt zr{FA{--bT#XGb*`ycyZ(4S=x7^%xT%vaU)R*)^^$bIR~rUfE{nJtC|JTdz1ttWs9p zJ4E%HwYz(g;FZ{(JvC)(m$`wUIl0rlvMajSxExP(_v^Xqv(??D26wnG5b zgsQg`yaS}|_B@6GlBub1u~>V>zgnWo`4MH1hB#gh%P6Uu$Ic^DW?37oB?uH*u6ls) zZTheJ=sOk%fN^2o-KpUwJCh@6`I*95^lOK*8Q(dXRW*9un#T&9==yX!7cs|Y8C2y|_GuWM7|sHWttQIN{(wG#W@Zw$R}x|^fQH)>25J9=6ivEYKy1E!P73$BIk9Rv!~}%_tUM+y=$!kUkL{B((>HY zRcvNX%L9ie3pZ-oz(yBg8z0W+5|Cn4c4BmT8GpCrv<>_a6)M$NDh5vV3gr|CW0~~# zdc#@moA6v)FJFOCE{)eWkM6vCqplUeAx*Hg+q0A_ELM&+ekyq0O$f=;)|=m+O+XA? zGOhvKNv?jKO@T6wlUDRDJIu;UEZW7`%cW2<--Q|nFR8=^NQP%8y>Xb00k>$iVwty? z60F0lbDk;@xeQdqq;Vh6v)StLT~DV*Kil)~{rqHkmS*R=)FCpEVE#OPM%&TQrAK&> zl5_Libg5;FL?qr&GWDnmIUBTk&HLkP{2jYOlwbpJjHg{^(PU$Xj9jt1`Fd^DjP)y% zNz!~i8bZYGY|Lh_c-o}vbVZGMEI(h28f*J<-k-`v%ba8yaYemCpjN$LCFG%~nNDum z&Lx%uBeFGYh?ein}HwU)j{iJ5p-W}6Zd`EBGw zq`7fHrmN-$Z?GSMJJe>B%kH4J&XhUXjus`dXPdfzINiv`JJapXEIwT>Hnx>)b%4kHb$dA(f794; z{p1hDyf2@J`TM(^p_`eqF}E9RD;5L*C9YD~V`@xY*MAf2zU^lohg5>flI?Qrl8u)< zcMjWyQLRI|x=Wg8r~Rm^Kr&-QV^u4+T&;V#^5cwsrR8APmyWZGJJy? z6vf7b1&W0T4UksLN@T3M@uL|rtG$tR7HjRzGLdIz(d^*K76jWEoJ*XUfG?EQg9Mw@?9n(qR{HWYfCQj2C!^Z zg!H8p{%jw3ciz8cE9=o!k3k}7IVij{v)j9W$?SULS7iP?Q5HFDLPSz4B$ilu?)hP98d3-e|9Hl{e;Qik)O9emq#5RqOF~r1{8X z-pW&bx}3U9M?}0_Bd>#NP>x9nD_Yg=ME7V;eKS9`fO42?s#)Q>TZ*L-z(rSQ}CYbcL1z=RH& zSawxf+6Ghi(hbk!<%WNjzk{byg0!RVa@QBgN@LEa?AES4EnP8@SR_c$6F0>u@b_Y# zbNS{wrp>0=C9yAPaX&weByQ9USU~*v4gh1a5>fRg=6NHf@ZxUL&R%`(aEO-r zqRz{Q*zs!nrZv4SJ33nIbaY`>7SKvore8ZjK+^ciSuXA|IvEp7WuatUNZw)Bq_S|9 znO5$VqzBgn&T{KX3m;AN1*E0oQy|kK)6BS&DFQfF@oLqJy;;1WOV(@nSjl|laIH>< zvCE2Yv;ps&JLlLYe#>}v{(9psrrPFGua>z!ti5dq9?9ZE;9Jb6nI~@o$9h#Imygv; z8})ktyp^r&_v#VQ22O@n)i`zgfv9};<}PpQ7!S%dGYa$aAPGb&Iz0B@P<+b71kKdf;VAL3u^TMwDlq&T3 zn%Lu+`p^;-uTQ_@kZftIvzoxg5~5t0=2*Z-oI-eXdniw;)@VCmdWqyM^Auy}7mh7c zz(ifqQ&bACKH{!D%JVmgx~f!aut_i2yY)y$C%|ZV%nDvz!JCKJc>X>IZ%h=1Y%P0k z-n`A#8WN8S%eUfAVcG5F^GTI@GIIX|ef-|mt#sDKPmslM$g+*dZaa1k6cZe5@OMHZ9npDau zsNCXo+v5orNTSrkWZEA5fG#ZNm+IxX6C%8sTY4Fg-Zc1|CE-RzEU&pRR;#!}3&LBr?CHDw9y0huG(1i;;J}Y#hr^T`l z@n#JmplPM!K}LW1LA)9$&+WY9FttSI)V*OIq@3_&kbJEm7)(GeH#I;`0i?vPyU7Hr zsGiSEOU5%xi|x zHoPbA7uxXccS#S}5mvhkDv9%(-rdIYt*Ro;+}BI(Hye1S=w>TebZWI%cIo+;Nv{ZI z)Kd7ttpJ0I;MtxM#iv{HirZ1UNy1l3E?+AXTKWSs#yCAMc9y$9X{40fjMsj@PEA$2vaR zPF|JWlkCbts?SH4MQt-RBN%>YR=a&=#!YLlNh}hr$M*$iaj-tqp3Pij4~OhpHf6Z# zVl?eaD{#(~FY|RUR$ESATsyV*yd4Zz^1A0(xtS77Mk_^1;1S!L7vrQhk3*<@ zhVz2>eM0B}&wZ%Y^O+bRf-&#}1|sdy_q*NIqL^R-fo(PxllxxPqt*5+`|P)tk1A7u zJ=Z$gUA*>v3q7y?7B%UeJ%SH3xaV)fr?M4*eQrR-lo)9@?B=!vB-xMepsZ{**oAF1 zyUE}>ZcSGCOl}fio7^6#opNp}zTP=eyyC4O$uZiPRG;_!?&FoZ_-yEao+JmW1+c{| zCKP$dtSouFoIf>}xs&{gH6KSkgDV_ljOZ-r;U4*(ZvdIBLI!JF)JM&sw5E>t3ab;A zvheYRHr@>Oy-sE$OTdromva3YK4~t5`Mmf90L_&>YMi*{%Y80hvYa;JW#yeZeO}`H zJ{nxI0l$>LpC-Mn3D>b$J*BAQ`l8j^0HZMwtEu$0A_pepcxnUE$p^V9LtCZFIpGW< z^TLBHcq7PIE{H$?eyPW(UIp)2kqc?`45CG!KkJL(WMePANmXx<))CoMPM%>}!`hkUvZgrJ6o4Z? zMRGG){ASM8XuKdey)9>Et8MP6$R$;$>UL^bZ?%AaoQuTUOS_@Q<-P`C;6|sKdSk(5 z4N*s({qgdh4xhtqW)Q=-7++6U(pYJ16k-51wYE-~%%J<-Uaqx8Kg-7->GQM%bY4;~ zmrO$hn77GIM-MIOopxW~OB7P?89@1wqQNP6u&%Y1?V)NqJm0a)*;DkCY%SKC8G!#7 zeb9%x9qw4`LPCWlOuN16o)fA(IhzF5u6_bE=-kZgZX4abSQDa!k-v0u{d=#@YBrLw%T zuSL=ACtPmN6jwJh(deD;@?pXkQ)l2v1OBk>cI!{t*PfiIPAjQRP;I95afdqRFN9u{ zhB?mMdE4C_R$9TR*W2FfnPHoLLJs(u-IsRCS$^&=rwL27jm^Ag9>`;C@aPqvr}R6* zN4gj!u#QHLp#X#m?TtROiF~e=JhRdfxB;=vna~rrc1vkXw`B6w0;DKz8&t?+(jd^bq*nD&T(*2t>Oct(>QdWN$g=5=rL=lkvqs3c59~0Q2D^RF_mJbr>>uq&G)P2^J4eP5M%zhY5>{S zz;J9g+DUf|?ox-)qZ1oh*3Kt*BHReI%zXukl;>okk}{2*20{5bpF06v=VvT*3gxpm zce|@fX&4`*sJivAfdPSyZ{u0p2ggrEq4e}9GB*#6ls{8S)$GWokAq~yF*7luwu7`I zyr67X$wH*96)@ufVA!@hDbnS|x11TIu~kNnb-c&$IMbrd2Yzf-A@iwXrCW+0`7{UK zutuImqW&(9dhd4mZ2{RYXEBciV|P0BboWEmDox-KhMe+3ST*l-ER1 z@r2fSC)Z={YFSzhuGCJP#~Ye9S-A^7CU24eOm~WAK0;0*Tm6_Qt|?T!l;LyoF2DH;b0i%XZ1FX`ctxQPDekYUM?JaB7l^m#tUzFuMw_ zQ^3~cUOz7|O{F)Z-;fEKyyu8^dwC-VxtP>5wn08 zXro=bi=o=Ndhn*uZxhPg+<2K$`l(L&d99}x={CQ)Ub=L$8goX^?sjOl^?S`By1C8( z<9nMSUlArFF9%>Yl%}=x>QW*1QI_a!AkCL=R-Hs}^$yvJn|Yz%_u&B659&MhTPsx~Pt3VEm2AGDZx#2EVWjLOIs=|;>Qs^p*dk; z0JD8P#y?+Mt?kO@tr(;?8^wrj8sJPB-9B@G?~k{Ilvz-6R&{G~Uba@ygVTlFTjfpj z&ii?C-f;0cWC}$R_4>r^e?GSjtxZWte{ea&!>lK9a*u6qKCs~`5B&I$T}7`2w%CK% zOml9PNxR>j8@~6-PgkbtdwntS(UZlqv0B~$MI=j3moLKK_fu!-v1$-z+`+)}{VvE# zGyB4e+{vPnG|F> zybF7Rt9p^#IGWkyu}i|EMv(1nxLYv34@z3D$8&LF->5n@^@RgvWrFWz*5e{Dq#L8> z?32?raw-M({W{L>j^-_23++m zw!Bw-ZgSZ-Acvv+ZvR9Z)@%5EY)=l8=hrC!VIaG$w7ZQ4>2)v1(yZqyd+)9l^{Wt(c0g=YnH;2F2RUkM}gGs!kYbURgV8C~U+oGaL%0M}d)=TDm5v|sv2*H@ie&n?V zR&@Wo?OYj$*x-WuZB%P}b|OYT8eWSOznRuDjT4eHF-{928n2$K&+cMx z>aM&jmd|w~$1UrlME9edD_U|r6I!FDVSW6I*e{-%FV2el8NLLKY&yCf|9-P`$0$H9 zXXmVSoWLnVY@{lKs?=v|OnTL5uSVz8VuGc!v%MjmpT;x3?#Z1fuNEWoVtrHU7SpHO zlChfY=MyW6luw!0ainHlTQZwH+mcRgc9-H+E8UvD)7%?7VmuQs^0s>`e`2iTO@L!7;Lhp7nIS% zX6i(5N#|Fe>e0Q#MA>X@@0s$^z~`U<^xi4B5Dwm3E$mX`0c($@GOYgj_u}0i?)v=WGnOy$HKVRDoVg+>~zmsIu(mHm}wYk9AMN z=4H>|ITkN%pC^UF`c1Z6#3y}bIJhzKC!qJ8N^ifN-1(77{!qBba$N#aCYwj~*vR#A zHEn&JludEpofI>}?cIEgpWFCOGx*YT(_LYn?_R1gf7wutxpuIo+n2QIP8A3p0`|jv zo_szFVA6lD!sVtsoeEYT-@Z}cUD5%1(GuGAY<~0p#v^HQpq1>;Chhpm%F~|J_g6*& z>+)WR3Z^WN^<+62baH&@ee>3ZbtfKF^2Vg>V53b+(ksEGc`#|Ih2-{UQItBkv#bKYxFDcu?T}dVl{@#zR`~&)?tRKV=jH!5yJ8nnmleEI=BE z>TwddFG6Jki+)d(AP?%_^(c}BsFY9{B_eH541=@*NdfRs6#6ZXj)M|J2oVm|lNh8g zG$|tErD+D~AI%7WSNQMm(HsqTXQ&L236V09M*2)k0y0+&MI(J?XaVUn!_r8f8BRd@ z%m@@Rr;NxWeP&4t=`&05NS|4TLi)_IJX*&8Qcw7$or4P9xp|q>p@ZIdQcR)9uzRyAm5`&WFJs8&4* zqD2X5gMk?g*JBtGX@lV?qzy(uWFo~#4AKTmA@>o*GAz;t%W+5>tboWciv49Da1?R} zP#hy7ZE&1~w84oaGFLo_$QO#I5t&W#ERD1Q;tFYl7g?kYf#kw+ml9}1hEW2G+#i&{ zqvI9CANaC=-DQ+WN=W}ih78{+u>H{W6`?c8_ax9rLTyMCqBBrX4cP}0Do-KkLqPVQ zB#Gg1&?JSdB~6056zU5c88STgKk7kv95kHY@Hl7?CE@j;VQArT&~UAW?+=<1k+VwE zByykAG>zyWG|eJ<)6X$S#sOII$T;BoK*qr^G%^lY4rCmRz#`*dBrd!jpiT0~daw*4 zhiH})ko8~%5g7+7A$ljMVaOSz0R;pZ2W%l^92{JF;eEi9h|GaopF_qWkYuZU zL&^k@+Tk_?*wIKCs;h{wg~D?x3OpH}KM{_3c%DU2@5B39ggHRUL=rhOq6n8>xPKyC zQb-vqp=GEpCBi_^dN5na_t3p7f(nexfkY$rktl(Z9{wIIIWo@@kK8GuBp`RAD8WpJ zz9)fbM$6Fkg`LZV*BlsNr0`yoNRAHo52O$x4?rc9!s{!Ms4gH;Bw{m36bQ=jIKXa1 z%UI;Tl;8pm&%Hzm$UcyO>lzuy&*c+t7X&^sFF%AnNIeFz!C=Xe`&XiQ6bEd>$rOG$!+_!jkolvj@cI3*_QSFc%0S^oz6XK>DdWTP8GeiSTA&P(8&D>p^9(jS zG7g3g%OQ#c-ZrE!pdz8a<-__P{1))>!sB2NefP%;9QL0=8CYiF-@+Xbl8I0c+4oS! zhwV!!Lwo>GCWdttaOaTdZ^5iZ#=$XRJ05<^hR-ULA-;kimr+>OK^fxzgEEj};W^-c zSvN3eLNbB^?`hcHhcZNug);ac(uNSW{h%Ibis55Ao2=)6k+`Zyb*AThQJ8wkv=I0vvmx z?}3&We%k?O9TV1f|8dua*9~mqu%8Azo4=I7#Tx!Cxa$zP0q(l64oq=y7Q%aj6Vda= zQxYPxL8_r;JcsNnUV>&q^8zMu`2GdwE~3+ba6$aG0G}&{Z4y{=Dy-AM3^2&P7eUnv zpG%RGkb4lUnXpbn{n&nC87tAqdkXcVXNS*+1ir}d9Dx23-fQ57L;UR^?CJ1%180uF zhQ0?|92Bg7&oj8(koyBHFp#|AdY~(ZWEeOo5Z?nRgfI)C-_r1|78);Dbcp|y1`{ki zFEm`gVf%w-P+uPnubkmK9)uMc)=xp$BX4rxC_r=p8obI#U%)RF-Y;OxAi6Rbt5n!; z0q!-pxI*&+no8Km1GT{86s{*BK3_06q2W+HFjK;JGX3M{3bzX_g!ect{0Q05_k@4@ zCqFO8zaCzHWcg3NQ~&#CA&a6*?peljJjP>p6nO2p!)_-ylDFUO*n?a8-)pS?#Q%;C zkNfM>cXoe|hv4vXK8O8Zqu%_xzq{YtA^7~w<^Jyd Reviewer ContributionRecord + | +--> ContributionRecorded + | +--> zero or more CompensationAwards + | + +--> if decision = accept: + Submitter ContributionRecord + +--> ContributionRecorded + +--> zero or more CompensationAwards + +Each CompensationAward + | + +--> CompensationFulfillmentRequested + | + +--> external money or project-points adapter + | + +--> CompensationFulfillmentReported + | + +--> immutable fulfillment receipt + +--> mutable status projection +~~~ + +Workstream records the fact that work was performed and the exact project-scoped compensation authorized for it. Workstream does not implement payment-provider transactions, point balances, or provider ledgers. + +--- + +## 2. Implementation Status and Proof Boundary + +The coding agent MUST preserve the difference between proven behaviour, locked design, and deferred work. + +| Lifecycle area | Status | +|---|---| +| Project guide, submission policy, task lock, submission finalization, and durable checker run | Proven | +| Transition through review_pending | Proven | +| Reviewer routing, leases, immutable decisions, and revision chain | Locked by WS-REV-001; not yet runtime-proven | +| ActorProfile and centralized Authorization Service contract | Locked by WS-AUTH-001; implementation proof required before protected WS-CON APIs | +| Reviewer Contribution Record for every completed Review | Locked by this specification | +| Submitter Contribution Record after accept | Locked by this specification | +| Project CompensationPolicy and immutable versions | Locked by this specification | +| Money and project-points CompensationAwards | Locked by this specification | +| External fulfillment event and callback boundary | Locked by this specification | +| Contribution evidence-bundle projection and retention | Locked by this revision; not yet runtime-proven | +| Provider payment requests, attempts, settlement, balances, and reconciliation | External and deferred | +| Project-points ledger and balances | External and deferred | +| Reputation scoring formula and aggregate | Deferred | +| Adjudication and contribution adjustment | Deferred | + +### 2.1 Starting preconditions + +This specification begins when WS-REV-001 is recording a valid Review against an active ReviewLease. + +The Review decision may be: + +- accept; +- needs_revision; +- reject. + +No Contribution Record may be created for: + +- an automated checker result; +- a pending or merely claimed review; +- an expired lease; +- a manually released lease; +- an administratively revoked lease; +- an invalid or rolled-back Review transaction. + +### 2.2 Narrow precedence over WS-REV-001 + +WS-REV-001 section 12.1 uses ContributionRecordRequested as a temporary integration event because contribution creation was deferred to the next specification. + +After WS-CON-001 is implemented, the following rules supersede only that temporary seam: + +1. Every valid Review transaction creates the reviewer Contribution Record directly. +2. An accept Review transaction additionally creates the submitter Contribution Record directly. +3. Those records, their CompensationAwards, and their outbox events are committed atomically with the Review. +4. ContributionRecordRequested MUST NOT be emitted by the completed implementation. +5. ContributionRecorded and CompensationFulfillmentRequested are the canonical downstream events. + +All other WS-REV-001 authority, routing, lease, revision, reject, and immutability rules remain unchanged. + +For authorization identifiers only, merged `WS-AUTH-001` is authoritative. +`review.decision`, `artifact.verification_job.retry`, and +`artifact.verification.execute` are canonical. `outbox.dispatch` and the +WS-CON actions in section 5.4 remain proposed until AUTH registers them; this +reference cannot make an identifier executable by naming it. + +--- + +## 3. Normative Language + +The terms MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY are normative. + +- MUST or REQUIRED means the implementation is non-conformant if the rule is absent. +- MUST NOT means the behaviour is prohibited. +- SHOULD means deviation requires an explicit Architecture Decision Record. +- MAY means the implementation choice is allowed without changing domain behaviour. + +Database time is authoritative for all transaction timestamps. Decimal quantities MUST never be represented or calculated using binary floating-point types. + +**Version notation:** Workstream and this lifecycle specification are release v0.1. The `/api/v1` API prefix, `event_version: 1`, event idempotency suffix `:v1`, route-key suffix `-v1`, and references such as `Submission(v1)` are independent API, event-schema, route, or submission-version identifiers. None denotes a Workstream v1.0 release. + +--- + +## 4. Locked v0.1 Decisions + +The following decisions are not left to coding-agent interpretation. + +1. Contribution Records are globally addressable in Workstream and always carry a mandatory project_id. +2. Global contribution history can be filtered by project, contributor, task, contribution type, and time. +3. A valid completed Review always creates exactly one reviewer Contribution Record, regardless of accept, needs_revision, or reject. +4. An accept Review additionally creates exactly one submitter Contribution Record. +5. Needs-revision and reject Reviews do not create submitter Contribution Records. +6. Every completed revision-review round is an independently recognized reviewer contribution. +7. Expired, released, and revoked review leases create no contribution and no compensation. +8. Contribution Records are immutable and have no mutable fulfillment fields. +9. Review, contribution, award, and outbox creation occur in one database transaction. +10. Every project MUST bind an active published CompensationPolicyVersion before new TaskAssignments or ReviewLeases can be created. +11. Unpaid work uses an explicit policy rule with no awards; missing policy configuration is never treated as unpaid. +12. V0.1 compensation is fixed per project and contribution type. +13. V0.1 has no contributor-specific rates, manually negotiated rates, compensation tiers, or task-specific overrides. +14. Submitter compensation terms are frozen on TaskAssignment creation. +15. Reviewer compensation terms are frozen on successful ReviewLease creation. +16. A later project-policy change never alters an existing TaskAssignment, ReviewLease, Contribution Record, or CompensationAward. +17. V0.1 supports only money and project_points compensation instruments. +18. Monetary awards are project obligations even when their unit is a standard currency. +19. Project points belong to a project-specific namespace and are not global Workstream points. +20. A contribution may create no award, one award, or two awards: at most one money award and at most one project-points award. +21. Workstream creates immutable CompensationAwards and emits fulfillment events. +22. External adapters own payment requests, provider attempts, finance approval, point ledgers, balances, provider retries, and provider reconciliation. +23. Workstream retries event delivery only until the external adapter acknowledges receipt. +24. Adapter delivery acknowledgement is not proof of compensation fulfillment. +25. Fulfillment is reported later through an authenticated, idempotent callback. +26. V0.1 fulfillment outcomes are fulfilled or failed; partial fulfillment is prohibited. +27. A failed award may later receive a valid fulfilled receipt. +28. A fulfilled award is terminal and cannot later become failed. +29. Fulfillment responses create immutable receipts and update a derived status projection; they never mutate the Contribution Record or CompensationAward. +30. Reputation consumes ContributionRecorded independently of compensation fulfillment. +31. Reputation scoring formulas and reputation aggregates are not implemented by this specification. +32. Acceptance is final in v0.1; no adjudication or adjustment lifecycle exists. +33. All provider-specific and ledger-specific objects remain outside Workstream. +34. `WS-AUTH-001` is the sole authority for ActorProfile resolution, AdminRoleGrant evaluation, contributor self-read authority, project scope, service-actor status, and authorization decisions. +35. Finance Authority is the only human Admin role that creates, edits, publishes, retires, or activates compensation policy and manages compensation adapter bindings in v0.1. +36. A reason-bound Operator may request authorized compensation delivery +reconciliation but cannot execute provider delivery, publish policy, alter +awards, or mark fulfillment complete. +37. An external fulfillment adapter reports results only through an active service ActorProfile and the exact frozen ProjectCompensationAdapterBinding for the referenced award. +38. Workstream owns ContributionRecord, CompensationAward, fulfillment receipt, projection, and lifecycle meaning. Artifact Storage owns contribution-evidence bundle bytes, content identity, verification, generic bindings, receipts, retention, and recovery. +39. Every ContributionRecord produces one asynchronous, deterministic contribution-evidence projection request after the canonical Review/contribution transaction commits. +40. Artifact projection failure never rolls back or mutates a committed Review, ContributionRecord, CompensationAward, or fulfillment receipt. +41. Human Identity Issuer tokens are never forwarded to Artifact Storage or compensation adapters. Workstream uses separately authorized service identities and least-privilege scopes. +42. Public contribution evidence references use Workstream ArtifactBinding IDs. Raw provider CIDs, arbitrary URLs, filesystem paths, credentials, and provider tokens are not public authority. + +--- + +## 5. Actor and Authority Model + +### 5.1 Relevant actors + +~~~text +Workstream Actor +├── Admin +│ ├── Access Administrator +│ ├── Operator +│ ├── Project Manager +│ ├── Finance Authority +│ └── Audit Authority +│ +├── Contributor +│ ├── Submitter +│ ├── Reviewer +│ └── Both +│ +└── External Service Actor + ├── Money Fulfillment Adapter + └── Project Points Fulfillment Adapter +~~~ + +External adapters are service actors. They are not Admins or Contributors and receive no authority over Reviews, tasks, assignments, policies, or Contribution Records. + +These are authority domains, not separate human profiles. One Identity Issuer subject resolves to one Workstream ActorProfile. An ActorProfile may hold AdminRoleGrants and project contributor grants independently; neither implies the other. + +### 5.2 Normative relationship to WS-AUTH-001 + +`WS-AUTH-001` is authoritative for: + +- Identity Issuer token verification; +- ActorProfile and ActorIdentityLink provisioning and state; +- AdminRoleGrant and ProjectRoleGrant evaluation; +- registered permission identifiers; +- system, project and record scope; +- service ActorProfile provisioning; +- authorization decisions, revocation and audit linkage. + +`WS-AUTH-001` is authoritative where it replaces broad preliminary permission names with the closed granular action/resource catalogue. This document consumes those exact identifiers and introduces no compatibility alias. + +This specification is authoritative for: + +- compensation policy and adapter-binding lifecycle guards; +- contribution and award creation invariants; +- frozen compensation terms; +- adapter-binding ownership of fulfillment callbacks; +- immutable receipt and projection behavior; +- contribution-evidence ArtifactBinding and projection guards. + +Every protected request first obtains an AuthorizationDecision. An allowed decision permits an attempt; WS-CON domain services still enforce policy state, frozen references, ownership, adapter binding, award state, artifact visibility and transaction invariants. + +### 5.3 Identity boundary + +All human and service requests pass through the Identity Issuer boundary. + +~~~text +Identity Issuer token + -> TokenVerifier verifies issuer, subject, audience, expiry and coarse scopes + -> AuthorizationService resolves current ActorProfile and identity link + -> Workstream loads the canonical policy, contribution, award, binding or receipt resource chain + -> AuthorizationService evaluates the registered permission and canonical scope + -> WS-CON service applies compensation, ownership and state guards + -> operation proceeds only when every layer allows it +~~~ + +A valid service token is insufficient by itself. The service actor must also match the adapter binding frozen on the referenced CompensationAward. + +The human or service token is consumed at the Workstream boundary. It is never forwarded to Artifact Storage or from Workstream to an external fulfillment provider. + +### 5.4 Required ActionId to PermissionId mapping + +The public boundary is the request-scoped +`AuthorizationService.require(action_id, typed_resource_context)`. The service +already owns the current AuthorizationContext and caller-owned AsyncSession. +WS-CON never passes a raw PermissionId, role, grant, session, or unit of work. + +| ActionId | Canonical PermissionId | Activation owner | +|---|---|---| +| `contribution.read_self` | `contribution.read_self` | CON-09B; reused by CON-10A | +| `contribution.read_project` | `contribution.read_project` | CON-09B; reused by CON-10A | +| `compensation.policy.read` | `compensation.policy.manage` | CON-04B | +| `compensation.policy.create_draft` | `compensation.policy.manage` | CON-04B | +| `compensation.policy.update_draft` | `compensation.policy.manage` | CON-04B | +| `compensation.policy.publish` | `compensation.policy.manage` | CON-04B | +| `compensation.policy.retire` | `compensation.policy.manage` | CON-04B | +| `compensation.adapter_binding.read` | `compensation.adapter_binding.manage` | CON-04A | +| `compensation.adapter_binding.create` | `compensation.adapter_binding.manage` | CON-04A | +| `compensation.adapter_binding.suspend` | `compensation.adapter_binding.manage` | CON-04A | +| `compensation.adapter_binding.resume` | `compensation.adapter_binding.manage` | CON-04A | +| `compensation.adapter_binding.retire` | `compensation.adapter_binding.manage` | CON-10B | +| `compensation.award.read_self` | `contribution.read_self` | CON-10A | +| `compensation.award.read_project` | `compensation.award.read` | CON-10A | +| `compensation.delivery.reconcile` | `compensation.delivery.reconcile` | CON-10B | +| `compensation.status.read` | `operations.status.read` | CON-10B | +| `compensation.reconcile.run` | `operations.reconcile.run` | CON-10B | +| `contribution.projection.rebuild` | `operations.projection.rebuild` | CON-10B | +| `audit.read` | `audit.read` | CON-10B | +| `audit.export` | `audit.export` | CON-10B | +| `compensation.fulfillment.report` | new service-only `compensation.fulfillment.report` | CON-08B after AUTH registration | +| `outbox.dispatch` | new service-only `outbox.dispatch` | shared-outbox CON-02B prerequisite; consumed by CON-08A | +| `artifact.contribution_evidence.binding.create` | `artifact.binding.create` | named ART prerequisite; consumed by CON-09A | + +`compensation.fulfillment.report` is assigned only to the service ActorProfile +on the exact ProjectCompensationAdapterBinding frozen on an existing award. +`outbox.dispatch` is assigned only to the fixed shared-outbox dispatcher. Human +AdminRoleGrant, ProjectRoleGrant, Finance Authority, reconciliation, or +`operations.outbox.retry` authority cannot satisfy either action. + +ContributionRecord and CompensationAward writes are mandatory internal +participants in the already-authorized `review.decision` transaction. They +flush through its caller-owned session and never commit or require separate +materialization actions. Artifact reads and recovery use narrow ART-owned typed +capabilities; operators request verification recovery through the existing +`artifact.verification_job.retry` action, and ART owns execution. + +### 5.5 Human authority matrix + +| Action | Authorized human authority in v0.1 | +|---|---| +| Manage any compensation-policy lifecycle stage | Finance Authority within covered project scope | +| Manage money or project-points adapter binding | Finance Authority within covered project scope | +| Read own Contribution Records | Contributor owning the records | +| Read project Contribution Records | Project Manager, Finance Authority, Audit Authority, or operationally authorized Operator within covered scope | +| Read global cross-project contribution history | Contributor reading only their own history; Admin cross-project analysis uses separately authorized audit/operational projections, not a contribution-history bypass | +| Read monetary award and fulfillment detail | Finance Authority, Audit Authority, or operationally authorized Operator within covered scope | +| Request compensation integrity reconciliation | Reason-bound Operator within covered project/system scope; fixed shared-outbox dispatcher executes any async work | +| Request compensation delivery reconciliation | Finance Authority for covered project work or reason-bound system-scoped Operator; fixed shared-outbox dispatcher executes any requeued delivery | +| Request eligible artifact recovery | Covered Operator with `artifact.verification_job.retry`; fixed recovery actor executes | +| Create ContributionRecord or CompensationAward | No human authority; system transaction only | +| Report fulfillment | No human authority; bound service actor only | + +Project Manager may read project contribution history needed for project management but cannot create, publish, activate, retire or edit compensation policy and cannot manage adapter bindings solely by that role. Operator recovers delivery/runtime state but cannot change economic policy, award quantity, or fulfillment truth. + +### 5.6 Canonical resource contexts + +The authorization service receives canonical relationships loaded from Workstream records, never trusted from request paths or callback payload fields. + +| Resource | Canonical project resolution | Required guard attributes | +|---|---|---| +| CompensationPolicy/Version | stored project_id, cross-checked through owning policy and Project | status; version; current active reference; instruments | +| AdapterBinding | stored project_id | instrument; adapter_actor_id; status; reference usage | +| ContributionRecord | source Review -> Submission -> Task -> Project | contributor owner; type; source review; immutable state | +| CompensationAward | ContributionRecord -> Project and frozen policy/binding | contributor; instrument; binding; quantity; fulfilled state | +| FulfillmentReceipt | Award -> ContributionRecord -> Project | adapter binding; external event; current fulfilled receipt | +| Contribution ArtifactBinding | Binding owner -> ContributionRecord -> source Review/Task -> Project | artifact role; visibility; integrity/projection state | + +Any mismatch fails closed with `resource_project_mismatch` and produces an integrity alert. + +### 5.7 Authorization evaluation points + +Authorization MUST be evaluated: + +1. before returning contribution, award, policy, binding, receipt or evidence metadata; +2. inside policy publication/activation/retirement transactions; +3. inside adapter-binding mutation transactions; +4. inside delivery reconciliation mutations; +5. inside every fulfillment callback transaction after loading the award and binding; +6. again before any actor-attributed deferred job commits; +7. before every contribution-evidence retrieval. + +Routers MUST NOT query AdminRoleGrant tables, inspect role strings, infer project scope from request JSON, or reproduce callback-binding authorization. + +Every route and independently invocable asynchronous command declares exactly +one primary ActionId from `WS-AUTH-001`. Derived contribution and award writes +are mandatory internal participants of the originating `review.decision` +transaction; they are not separate commands or authorities. + +### 5.8 System-owned creation + +ContributionRecord, CompensationAward, their canonical outbox events and +evidence-projection requests are created inside the authorized Review decision +transaction using its caller-owned AsyncSession. Each participant flushes but +never commits, and the originating decision remains linked as causation. + +Background dispatch, projection and reconciliation workers use provisioned service ActorProfiles with explicit system permissions. They do not fabricate a Finance Authority, Operator or Contributor identity. + +No API permits an Admin, Contributor, or adapter to create or edit a Contribution Record directly. + +--- + +## 6. Core Object Model + +### 6.1 ContributionRecord + +ContributionRecord is the permanent recognition that one contributor completed one eligible unit of work. + +~~~yaml +ContributionRecord: + id: uuid + project_id: uuid + task_id: uuid + contributor_id: uuid + + contribution_type: enum [ + accepted_submission, + completed_review + ] + + source_review_id: uuid + source_review_lease_id: uuid | null + source_task_assignment_id: uuid + submission_id: uuid + + compensation_policy_version_id: uuid + + source_submission_artifact_digest: string + recorded_at: timestamp + recorded_by: system_actor_id + + correlation_id: string + causation_event_id: uuid | null +~~~ + +#### ContributionRecord invariants + +- The record is immutable from insertion. +- project_id, task_id, contributor_id, source Review, assignment, submission version, and compensation version MUST all belong to one internally consistent chain. +- contribution_type = accepted_submission requires Review.decision = accept. +- contribution_type = accepted_submission requires contributor_id to equal the submission creator and TaskAssignment contributor. +- contribution_type = completed_review requires contributor_id to equal Review.reviewer_id. +- contribution_type = completed_review requires source_review_lease_id to equal Review.review_lease_id. +- accepted_submission records reference the active submitter TaskAssignment completed by the accept Review. +- completed_review records reference the TaskAssignment whose work was reviewed but do not attribute that assignment to the reviewer. +- source_submission_artifact_digest equals the immutable digest locked to the reviewed Submission. For `completed_review`, it identifies the work judged; it is not misrepresented as the reviewer's own artifact. +- compensation_policy_version_id comes from the frozen TaskAssignment field for accepted_submission. +- compensation_policy_version_id comes from the frozen ReviewLease field for completed_review. +- Exactly one accepted_submission record may exist per accepted Review. +- Exactly one completed_review record may exist per Review. +- An accept Review therefore creates exactly two Contribution Records unless one of the contributors is represented by a prohibited self-review, which WS-REV-001 prevents. +- Needs-revision and reject Reviews create exactly one Contribution Record: completed_review. +- A record may exist even when its compensation policy produces no awards. +- The record has no payment_status, points_status, mutable status, deleted_at, or editable metadata. + +Recommended uniqueness constraints: + +~~~text +UNIQUE(source_review_id, contribution_type) +UNIQUE(id, project_id) +~~~ + +### 6.2 CompensationPolicy + +CompensationPolicy is the stable project-owned policy identity. + +~~~yaml +CompensationPolicy: + id: uuid + project_id: uuid + name: string + status: enum [draft, active, retired] + current_published_version_id: uuid | null + + created_by: actor_id + created_at: timestamp + retired_by: actor_id | null + retired_at: timestamp | null +~~~ + +One project may have multiple historical policy identities, but at most one CompensationPolicy and, when the project is configured for new work, exactly one published version are active at a time. A newly created policy remains draft with a null current_published_version_id until its first version is published. + +### 6.3 CompensationPolicyVersion + +~~~yaml +CompensationPolicyVersion: + id: uuid + compensation_policy_id: uuid + project_id: uuid + version_number: int + status: enum [draft, published, retired] + + created_by: actor_id + created_at: timestamp + published_by: actor_id | null + published_at: timestamp | null + retired_by: actor_id | null + retired_at: timestamp | null +~~~ + +#### Version invariants + +- version_number starts at 1 and increases monotonically within one CompensationPolicy. +- Draft versions may be edited only through explicit draft APIs. +- Publishing validates the complete version and makes every field and award definition immutable. +- A published version may be retired but never edited or deleted. +- Retiring a version does not invalidate frozen references from assignments or leases. +- A retired version remains valid for contribution and award creation when it was frozen before retirement. +- At most one published version is active for new work within a project. + +### 6.4 CompensationRule + +Every policy version contains exactly one rule for each contribution type. This makes unpaid work explicit rather than indistinguishable from missing configuration. + +~~~yaml +CompensationRule: + id: uuid + compensation_policy_version_id: uuid + project_id: uuid + contribution_type: enum [ + accepted_submission, + completed_review + ] + compensation_mode: enum [compensated, unpaid] +~~~ + +#### Rule invariants + +- Exactly one accepted_submission rule and one completed_review rule exist in every publishable version. +- A compensated rule has at least one and at most two award definitions. +- An unpaid rule has zero award definitions. +- Rule and definitions become immutable together when the version is published. +- V0.1 rules have no condition expression, priority, fallback, multiplier, or outcome selector. + +### 6.5 CompensationAwardDefinition + +Each published version defines fixed awards for the two contribution types. + +~~~yaml +CompensationAwardDefinition: + id: uuid + compensation_rule_id: uuid + compensation_policy_version_id: uuid + project_id: uuid + + contribution_type: enum [ + accepted_submission, + completed_review + ] + + instrument_type: enum [ + money, + project_points + ] + + unit_code: string + quantity: decimal + adapter_binding_id: uuid +~~~ + +#### Definition invariants + +- At most one definition exists for each contribution_type and instrument_type within a version. +- quantity MUST be greater than zero. +- Money unit_code MUST be an uppercase ISO 4217 currency code configured for the project. +- Project-points unit_code MUST match the project-scoped point unit configured by the policy. +- A points unit has identity (project_id, unit_code). The same text in another project is a different unit. +- adapter_binding_id must match the same project and instrument. +- Published definitions are immutable. +- An explicitly unpaid rule has zero award definitions. +- Zero-quantity award definitions are prohibited. +- V0.1 rule evaluation is exact matching on contribution_type only. No other condition, multiplier, tier, score, task class, contributor class, or outcome rule is allowed. + +### 6.6 Frozen compensation references + +WS-CON-001 extends Project and two existing work objects. + +~~~yaml +Project: + # existing fields omitted + active_compensation_policy_version_id: uuid | null +~~~ + +~~~yaml +TaskAssignment: + # existing fields omitted + submitter_compensation_policy_version_id: uuid +~~~ + +~~~yaml +ReviewLease: + # existing fields omitted + reviewer_compensation_policy_version_id: uuid +~~~ + +The references are set once: + +- TaskAssignment freezes the project active version in the assignment-creation transaction. +- ReviewLease freezes the project active version in the successful claim transaction. +- Neither field may be updated later. +- Policy retirement does not change either field. + +### 6.7 CompensationAward + +CompensationAward is Workstream's immutable statement of what the project authorized for one contribution. + +~~~yaml +CompensationAward: + id: uuid + project_id: uuid + contribution_record_id: uuid + contributor_id: uuid + + compensation_policy_version_id: uuid + award_definition_id: uuid + adapter_binding_id: uuid + + instrument_type: enum [ + money, + project_points + ] + + unit_code: string + quantity: decimal + + created_at: timestamp + correlation_id: string +~~~ + +#### CompensationAward invariants + +- Immutable from insertion. +- Project, contributor, policy version, and contribution must match. +- Instrument, unit, quantity, and adapter binding are copied exactly from the published definition. +- At most one award exists per contribution and instrument type. +- A completed_review award does not depend on Review.decision. +- No award may be created for a released, expired, or revoked lease. +- No award may be created by an adapter callback. +- Failed or fulfilled status is never stored on this record. + +Recommended uniqueness constraint: + +~~~text +UNIQUE(contribution_record_id, instrument_type) +~~~ + +### 6.8 ProjectCompensationAdapterBinding + +The binding identifies the logical adapter authorized for one project and instrument. + +~~~yaml +ProjectCompensationAdapterBinding: + id: uuid + project_id: uuid + instrument_type: enum [money, project_points] + adapter_actor_id: actor_id + route_key: string + status: enum [active, suspended, retired] + + created_by: actor_id + created_at: timestamp + suspended_at: timestamp | null + retired_at: timestamp | null +~~~ + +#### Binding invariants + +- At most one active binding exists per project and instrument. +- Published award definitions reference a binding for the same project and instrument. +- The binding identity is frozen into each CompensationAward. +- Endpoint, credentials, and provider configuration are deployment secrets and are not domain fields. +- Suspending a binding pauses new delivery but does not cancel or alter awards. +- Retiring a binding is prohibited while it is referenced by an active policy version, by unfinished work whose frozen policy version contains it, or by an unfulfilled award. +- A service actor bound to money cannot report project-points fulfillment and vice versa. + +### 6.9 CompensationFulfillmentReceipt + +Each valid callback creates an immutable receipt. + +~~~yaml +CompensationFulfillmentReceipt: + id: uuid + compensation_award_id: uuid + project_id: uuid + adapter_binding_id: uuid + + external_event_id: string + reported_status: enum [fulfilled, failed] + + fulfilled_quantity: decimal | null + fulfilled_at: timestamp | null + + failure_code: string | null + + reported_at: timestamp + received_at: timestamp + correlation_id: string +~~~ + +#### Receipt invariants + +- Immutable from insertion. +- external_event_id is an opaque idempotency token, 1-128 ASCII characters + from `[A-Za-z0-9._:-]`, globally unique per adapter binding, and never + returned by contributor/product reads or emitted in integration events. +- fulfilled requires fulfilled_quantity and fulfilled_at. +- fulfilled_quantity must equal the CompensationAward quantity exactly. +- failed requires failure_code. +- failure_code is a closed Workstream-mapped code or a 1-64 character ASCII + token from `[A-Z0-9_:-]`; free-form/provider messages are rejected and never + stored, logged, emitted, or returned. +- failed must have null fulfilled_quantity and fulfilled_at. +- Project, binding, contributor, instrument, unit, and authorized quantity cannot be changed by the callback. +- Multiple failed receipts may exist for one award when their external_event_id values differ. +- At most one fulfilled receipt may exist for one award. +- A fulfilled award rejects all later failed or fulfilled callbacks except an exact idempotent replay of the accepted fulfilled callback. + +### 6.10 CompensationStatusProjection + +This projection exists only for efficient reads and operations. + +~~~yaml +CompensationStatusProjection: + compensation_award_id: uuid + delivery_status: enum [ + pending_delivery, + acknowledged_by_adapter + ] + fulfillment_status: enum [ + pending, + failed, + fulfilled + ] + + latest_receipt_id: uuid | null + last_failure_code: string | null + delivered_at: timestamp | null + fulfilled_at: timestamp | null + updated_at: timestamp +~~~ + +The projection is mutable and rebuildable. It is not the source of truth. ContributionRecord, CompensationAward, outbox delivery history, and CompensationFulfillmentReceipt are authoritative. + +### 6.11 ContributionEvidenceProjection + +Every ContributionRecord receives one rebuildable projection status row for its immutable contribution-evidence bundle. + +~~~yaml +ContributionEvidenceProjection: + contribution_record_id: uuid + project_id: uuid + projection_schema_version: int + status: enum [pending, projected, failed] + + artifact_binding_id: uuid | null + content_digest: string | null + last_error_code: string | null + last_attempt_at: timestamp | null + projected_at: timestamp | null + updated_at: timestamp +~~~ + +The projection row is mutable and rebuildable. ContributionRecord and its source Review chain remain canonical. + +#### Logical evidence-bundle schema + +The deterministic bundle is a versioned manifest; it references already retained artifacts rather than duplicating their bytes. + +~~~yaml +ContributionEvidenceBundle: + schema_version: int + contribution_record_id: uuid + contribution_type: accepted_submission | completed_review + project_id: uuid + task_id: uuid + contributor_id: uuid + + source_task_assignment_id: uuid + submission_id: uuid + source_submission_artifact_digest: string + + locked_task_context_ref: uuid + project_guide_version_ref: uuid + effective_project_policy_version_ref: uuid + review_policy_version_ref: uuid + submission_artifact_binding_ids: list[uuid] + canonical_recorded_at: timestamp +~~~ + +The bundle proves the contribution against its immutable task/submission and +published policy context. It excludes reviewer-private findings, resolutions, +reviewer identity/lease data, compensation policy/award data, provider data, +and internal checker evidence. Any richer derivative requires its own schema, +ActionId, disclosure review, and behavioral tests. + +#### Evidence projection invariants + +- Exactly one ContributionEvidenceProjection row exists per ContributionRecord. +- `artifact_binding_id`, when present, references a verified generic ArtifactBinding with owner_type `contribution_record` and artifact_role `contribution_evidence_bundle`. +- Bundle project, task, contributor, and submission references resolve to the + same canonical chain; excluded review-private and compensation data is not + reintroduced through references. +- Guide, effective-policy and review-policy references are copied from the task's immutable locked context; the worker MUST NOT load the project's current versions as substitutes. +- Bundle generation reads canonical committed Workstream records; it never trusts event payload fields as independent authority. +- The serialized bundle is deterministic for one ContributionRecord and projection schema version. +- Same projection identity and bytes return the same logical storage receipt; changed bytes under the same identity are an integrity conflict. +- Projection failure does not modify or invalidate the ContributionRecord or compensation lifecycle. +- Artifact Storage contains the immutable bundle bytes/manifest; PostgreSQL contains canonical lifecycle truth and projection status/reference. + +#### Canonical serialization contract + +- Media type is `application/vnd.workstream.contribution-evidence+json;version=1`. +- JSON is serialized with RFC 8785 JSON Canonicalization Scheme rules and UTF-8 bytes. +- Timestamps use UTC RFC 3339 form with normalized fractional precision. +- UUIDs are lowercase canonical strings. +- All list fields are present, use empty lists rather than null, and are ordered by canonical record creation time followed by id. +- Scalar optional fields use explicit null when the schema permits null. +- Mutable compensation delivery/fulfillment projections, mutable evidence status and provider-local references are excluded from the bundle. +- `content_digest` is lowercase `sha256:` over the exact canonical bytes. +- A projection schema-version change is required for any semantic or serialization change. + +### 6.12 Artifact Storage ownership boundary + +WS-CON consumes narrow typed contribution-evidence write and read capabilities +owned by ART. It never receives the raw ArtifactStore, provider references, or +provider credentials and never imports storage-adapter internals. + +~~~text +Workstream owns + ContributionRecord and compensation meaning + source Review/task/submission relationships + evidence-bundle schema and projection status + contribution-evidence schema, meaning and visibility + authorization, audit and outbox state + +Artifact Storage owns + prepared-byte admission and raw provider I/O + content identity, verification and generic ArtifactBinding persistence + storage receipts, recovery, fencing and idempotency + immutable completed-object retention policy +~~~ + +The required capability shape is: + +~~~python +class ContributionEvidenceWritePort: + async def write(request: ContributionEvidenceWriteRequest): ... + +class ContributionEvidenceReadPort: + async def read(request: ContributionEvidenceReadRequest): ... +~~~ + +The write request carries canonical contribution/project/schema identity, +expected digest, media type, stable idempotency identity, and deterministic +prepared bytes or a bounded byte source. The read request accepts a Workstream +ArtifactBinding id plus the already-authorized contribution context. ART admits, +stores, verifies, binds, receipts, and recovers the operation; responses expose +only bounded binding/receipt data or verified bytes/stream, never a raw provider +reference. Only ART's ArtifactStorageOrchestrator receives the raw store. + +The projection identity is: + +~~~text +contribution:{contribution_record_id}:evidence-bundle:{projection_schema_version} +~~~ + +### 6.13 Contribution evidence projection flow + +The canonical Review/contribution transaction performs no remote storage call. It creates the ContributionRecord, a pending ContributionEvidenceProjection row and a `ContributionEvidenceProjectionRequested` transactional outbox event. + +After commit, the projection worker: + +1. runs as a provisioned Workstream system actor; +2. loads the ContributionRecord and complete canonical source chain; +3. resolves every referenced Workstream ArtifactBinding and verifies project/task consistency; +4. builds the deterministic versioned bundle; +5. computes the expected digest before the provider call; +6. calls the ART-owned write capability with the stable operation identity; +7. validates the bounded ART receipt, digest, size, media type, scope and operation identity; +8. records the verified `contribution_evidence_bundle` ArtifactBinding returned by ART; +9. updates ContributionEvidenceProjection to `projected`; +10. emits `ContributionEvidenceProjected` audit/integration evidence. + +No ContributionRecord, award, receipt or Review is inferred from provider content. Projection always begins from canonical Workstream records. + +### 6.14 Authorized evidence retrieval + +Contribution-list endpoints return evidence status and authorized Workstream references only; they do not inline artifact bytes. + +When a caller requests contribution evidence: + +1. AuthorizationService requires `contribution.read_self` or `contribution.read_project` for the canonical ContributionRecord. +2. Workstream proves the projection ArtifactBinding belongs to that ContributionRecord and project. +3. Workstream calls the ART-owned typed read capability with that binding and authorized context. +4. ART verifies the binding and exact digest before returning bounded bytes or a stream. +5. Workstream records an attributable access receipt/audit reference. +6. Workstream returns the authorized bundle or approved derivative representation. + +There is no semantic-search disclosure path in v0.1. + +### 6.15 Artifact failure semantics + +| Failure | WS-CON effect | +|---|---| +| Artifact Storage unavailable after contribution commit | Contribution and awards remain canonical; projection stays pending/failed and retries | +| Projection receipt digest mismatch | Do not bind receipt; mark failed; raise integrity alert | +| Same operation identity with different bundle bytes | Permanent integrity conflict; bind nothing and alert | +| Evidence bundle unavailable during authorized read | Return `contribution_evidence_unavailable`; do not change contribution or compensation status | +| Provider outcome uncertain | Use the existing idempotent artifact recovery contract; never guess success | + +An Artifact Storage failure never creates or changes an award, fulfillment receipt, contributor reputation signal, or review outcome. + +### 6.16 Storage-adapter equivalence + +LocalStorage is limited to focused development/tests. MinIO proves the +S3-compatible protocol locally and in CI, and AWS S3 is the v0.1 production +provider. R2 and Flow Node are deferred. Every enabled adapter must preserve +the same digest, binding, idempotency, authorization, and recovery semantics. +Recovery remains an ART orchestration concern through its typed operator port +and existing `artifact.verification_job.retry` action. + +--- + +## 7. Project Scope and Global Contribution Views + +### 7.1 Global record identity + +ContributionRecord.id is globally unique within Workstream. A contributor's complete history may span projects. + +~~~text +Contributor +└── Contribution history + ├── Project A + │ ├── accepted_submission + │ └── completed_review + ├── Project B + │ └── completed_review + └── Project C + └── accepted_submission +~~~ + +### 7.2 Project-scoped economics + +Every CompensationPolicy, policy version, award definition, CompensationAward, adapter binding, and fulfillment receipt has a project_id. + +- A Project A policy cannot compensate Project B work. +- Project A points cannot be fulfilled into Project B's point namespace. +- A USD award from Project A remains Project A's obligation; it is not a global Workstream balance. +- Cross-project totals are read-model calculations only. + +### 7.3 Read views + +Required views: + +- contributor global contribution history; +- contributor history filtered to one project; +- project contribution history; +- task contribution history; +- Contribution Record detail with derived compensation summary; +- Contribution Record detail with contribution-evidence projection status and authorized ArtifactBinding reference; +- project outstanding compensation awards by instrument and age; +- adapter delivery and fulfillment operational view. + +--- + +## 8. Compensation Policy Lifecycle + +### 8.1 Create draft + +An active Finance Authority whose effective scope covers the project and whose AuthorizationDecision allows `compensation.policy.create_draft` creates a CompensationPolicy and version 1 draft, or creates the next draft version under an existing policy. + +Draft creation does not affect existing or new work until publication and activation. + +### 8.2 Validate draft + +Publication validation MUST confirm: + +- policy and every definition belong to the same project; +- only accepted_submission and completed_review rules exist; +- only money and project_points instruments exist; +- no duplicate instrument exists within a contribution type; +- every quantity is a positive decimal; +- every unit code is valid for its instrument; +- every adapter binding belongs to the project, supports the instrument, and is active; +- both contribution types are explicitly present as either compensated or unpaid; +- no task, contributor, tier, outcome, skill, or reputation condition exists; +- AuthorizationService allows `compensation.policy.update_draft` for draft replacement and `compensation.policy.publish` for publication validation on the canonical resource. + +### 8.3 Publish and activate + +Publication and project activation occur in one transaction: + +~~~text +validate complete draft +lock project's active compensation policy reference +publish version immutably +set owning CompensationPolicy.status -> active +set owning CompensationPolicy.current_published_version_id -> new version id +retire any different previously active CompensationPolicy identity +set project active_compensation_policy_version_id +retire prior version for new-work selection +write policy audit events +commit +~~~ + +The transaction revalidates `compensation.policy.publish` through AuthorizationService after loading and locking the canonical project/version resources. Retirement separately revalidates `compensation.policy.retire`. A router-level role check is insufficient. + +Retiring the prior version means it is no longer selected for new assignments or leases. It remains valid for previously frozen work. + +If an active version is retired without an immediate replacement, the same transaction sets Project.active_compensation_policy_version_id to null and CompensationPolicy.status to retired. New TaskAssignments and ReviewLeases then fail until another version is activated. Existing frozen work remains valid. + +### 8.4 Explicit unpaid policy + +An unpaid project still requires a published version. + +~~~yaml +accepted_submission: + compensation_mode: unpaid + awards: [] + +completed_review: + compensation_mode: unpaid + awards: [] +~~~ + +This prevents missing configuration from silently removing contributor compensation. + +### 8.5 Policy-change boundary + +If version 2 becomes active: + +- existing TaskAssignments retain their frozen version; +- existing ReviewLeases retain their frozen version; +- new TaskAssignments freeze version 2; +- new ReviewLeases freeze version 2; +- queued but unleased ReviewQueueEntries use the version active when a reviewer successfully claims them; +- Contribution Records always copy the version from their assignment or lease, never from the project's current setting at decision time. + +--- + +## 9. Contribution Creation Matrix + +| Review outcome or lease result | Reviewer Contribution Record | Submitter Contribution Record | Reviewer compensation evaluated | Submitter compensation evaluated | +|---|---:|---:|---:|---:| +| accept | Yes | Yes | Yes | Yes | +| needs_revision | Yes | No | Yes | No | +| reject | Yes | No | Yes | No | +| manual release | No | No | No | No | +| lease expiry | No | No | No | No | +| administrative revocation | No | No | No | No | +| invalid decision attempt | No | No | No | No | +| idempotent replay of committed decision | Return existing | Return existing if accept | Return existing | Return existing if accept | + +Review compensation is decision-neutral. No award definition may match or vary by decision. + +--- + +## 10. State Machines + +### 10.1 ContributionRecord lifecycle + +ContributionRecord has no mutable state machine. + +~~~text +not present --valid Review transaction--> recorded permanently +~~~ + +It cannot move to pending, failed, fulfilled, cancelled, voided, or deleted. + +### 10.2 CompensationPolicyVersion + +~~~text +draft --publish and activate--> published --replace for new work--> retired +~~~ + +- draft may be edited; +- published is immutable and selectable for new work; +- retired is immutable and valid only through frozen references. + +### 10.3 CompensationAward fulfillment projection + +~~~text + adapter callback: failed + +-------------------------+ + | v +pending_delivery -> acknowledged pending -> failed + | | | | + | | | +--later fulfilled callback--+ + | | | | + +--valid fulfilled callback-----------+---------------------------------v + fulfilled +~~~ + +Normative rules: + +- Delivery acknowledgement changes only delivery_status. +- A failed callback changes fulfillment_status to failed. +- A later valid fulfilled callback changes failed to fulfilled. +- Fulfilled is terminal. +- Delivery state and fulfillment state are independent. +- A callback may arrive before local delivery acknowledgement; it is accepted if otherwise valid and MUST NOT later regress. + +--- + +## 11. Frozen-Terms Operations + +### 11.1 Create TaskAssignment + +Preconditions: + +- project has an active published CompensationPolicyVersion; +- AuthorizationService allows the upstream `task.claim` operation through an active submitter/both ProjectRoleGrant; +- task and project are claimable under existing rules. + +Transaction: + +~~~text +lock project active compensation policy reference +validate version is published +create TaskAssignment +copy version id -> submitter_compensation_policy_version_id +write CompensationTermsFrozenForAssignment +commit +~~~ + +If no active version exists, assignment creation fails with compensation_policy_missing. + +### 11.2 Create ReviewLease + +This extends the atomic WS-REV-001 claim transaction. + +Preconditions: + +- AuthorizationService allows `review.claim` inside the claim transaction and every WS-REV-001 eligibility/capacity guard passes; +- project has an active published CompensationPolicyVersion. + +Transaction addition: + +~~~text +lock project active compensation policy reference +validate version is published +create ReviewLease +copy version id -> reviewer_compensation_policy_version_id +write CompensationTermsFrozenForReviewLease +commit with queue claim +~~~ + +If the project changes policy concurrently, row locking ensures the lease freezes either the old active version before replacement commits or the new active version after replacement commits. It cannot freeze an indeterminate mixture. + +### 11.3 Released, expired, or revoked lease + +The frozen reference remains on the permanent ReviewLease attempt for audit. It creates no contribution or award because no valid Review was recorded. + +--- + +## 12. Atomic Review-to-Contribution Operations + +### 12.1 Common decision transaction + +Every valid Review decision uses one PostgreSQL transaction and one unit of work. + +The caller's primary ActionId is `review.decision` on the active ReviewLease. +Contribution and award creation are mandatory internal participants in that +same caller-owned transaction, with no separate action, authority, or commit. + +After all WS-REV-001 validations pass, the transaction MUST: + +~~~text +1. create immutable Review and any ReviewFinding/FindingResolution records +2. consume ReviewLease and close ReviewQueueEntry +3. apply the decision-specific Task and TaskAssignment transition +4. create reviewer ContributionRecord +5. create reviewer ContributionEvidenceProjection(status=pending) +6. write reviewer ContributionEvidenceProjectionRequested outbox event +7. evaluate the ReviewLease's frozen policy version +8. create reviewer CompensationAwards from exact completed_review definitions +9. create reviewer ContributionRecorded outbox event +10. create CompensationAwardCreated audit/outbox event for each award +11. create CompensationFulfillmentRequested outbox event for each award +12. if decision = accept: + a. create submitter ContributionRecord + b. create submitter ContributionEvidenceProjection(status=pending) + c. write submitter ContributionEvidenceProjectionRequested outbox event + d. evaluate the TaskAssignment's frozen policy version + e. create submitter CompensationAwards from exact accepted_submission definitions + f. create submitter ContributionRecorded outbox event + g. create award and fulfillment-requested events for each award +13. link the originating Review AuthorizationDecision and write all review, contribution, compensation, task, and assignment audit events +14. commit +~~~ + +If any database insert, invariant, event write, or decision-specific transition fails, the entire transaction rolls back. + +No compensation-adapter or Artifact Storage call occurs inside this transaction. External availability therefore cannot delay or invalidate the human decision or contribution recognition. + +### 12.2 Reviewer contribution creation + +Input: + +- canonical Review being created; +- consumed ReviewLease; +- reviewed Submission; +- reviewed TaskAssignment; +- frozen ReviewLease reviewer_compensation_policy_version_id. + +Output: + +~~~yaml +contribution_type: completed_review +contributor_id: Review.reviewer_id +source_review_id: Review.id +source_review_lease_id: ReviewLease.id +source_task_assignment_id: TaskAssignment.id +submission_id: Review.submission_id +compensation_policy_version_id: ReviewLease.reviewer_compensation_policy_version_id +source_submission_artifact_digest: Submission.artifact_digest +~~~ + +The algorithm is identical for accept, needs_revision, and reject. Branching compensation logic by Review.decision is prohibited. + +### 12.3 Submitter contribution creation on accept + +Input: + +- Review with decision = accept; +- accepted Submission; +- completed TaskAssignment; +- frozen TaskAssignment submitter_compensation_policy_version_id. + +Output: + +~~~yaml +contribution_type: accepted_submission +contributor_id: Submission.created_by +source_review_id: Review.id +source_review_lease_id: null +source_task_assignment_id: TaskAssignment.id +submission_id: Review.submission_id +compensation_policy_version_id: TaskAssignment.submitter_compensation_policy_version_id +source_submission_artifact_digest: Submission.artifact_digest +~~~ + +The contribution is created only after all accept validations pass but before transaction commit. + +### 12.4 Needs revision + +Needs revision creates: + +- one completed_review Contribution Record; +- zero or more reviewer CompensationAwards; +- no accepted_submission Contribution Record; +- no submitter CompensationAward. + +When a later submission version is reviewed, that later Review creates another completed_review record. There is no maximum compensated review-round count in v0.1. + +Structured findings, immutable chains, no-self-review, reviewer leasing, and audit events remain the controls against abusive revision cycling. + +### 12.5 Reject + +Reject creates: + +- one completed_review Contribution Record; +- zero or more reviewer CompensationAwards; +- no submitter Contribution Record; +- no submitter CompensationAward. + +Reviewer compensation remains valid even though the submitter TaskAssignment becomes blocked and the task closes. + +### 12.6 Explicitly unpaid result + +If the frozen policy version has no award definition for the relevant contribution type: + +- create the Contribution Record; +- create ContributionRecorded; +- create no CompensationAward; +- create no CompensationFulfillmentRequested event; +- do not treat the absence of an award as an error. + +The Contribution Record's policy version proves that the explicit unpaid rule was evaluated. + +### 12.7 Integrity failure + +If a frozen policy reference is missing, corrupt, from the wrong project, or contains prohibited duplicate definitions: + +- reject the decision transaction with compensation_policy_integrity_error; +- create no Review or contribution; +- after rollback, write a structured integrity-error log, increment workstream_compensation_policy_integrity_errors_total, and trigger the configured operator alert; +- require operator remediation. + +The implementation MUST NOT substitute the current project policy or silently treat the work as unpaid. + +--- + +## 13. Compensation Evaluation + +### 13.1 Deterministic algorithm + +For one Contribution Record: + +~~~text +load exact frozen CompensationPolicyVersion +validate project match +select the one CompensationRule matching record.contribution_type +if rule is unpaid, return zero awards +if rule is compensated, load its award definitions +order definitions deterministically by instrument_type +for each definition: + copy definition fields into immutable CompensationAward + resolve the exact frozen adapter binding + create award and outbox events +return created awards +~~~ + +No scoring engine, rules interpreter, dynamic expression, network call, current reputation lookup, or current project-policy lookup is permitted. + +### 13.2 Decision neutrality + +For completed_review: + +~~~text +award(completed_review, accept) + = award(completed_review, needs_revision) + = award(completed_review, reject) +~~~ + +The Review outcome may be included as provenance in ContributionRecorded, but it cannot select or modify compensation. + +### 13.3 Multiple instruments + +If a completed-review rule defines money and project points: + +~~~text +one ContributionRecord + -> one money CompensationAward + -> one project_points CompensationAward + -> two independent fulfillment events +~~~ + +One instrument's delivery or fulfillment status never blocks or changes the other. + +### 13.4 Decimal and unit rules + +- Use an exact decimal database type. +- API quantities are decimal strings, never JSON floating-point numbers. +- Money quantities are interpreted according to unit_code but are not rounded by Workstream after policy publication. +- Policy publication rejects quantities exceeding the configured currency precision. +- Project-points quantities MUST be whole positive numbers in v0.1. +- Unit conversion is prohibited. +- Adapters cannot substitute another currency or point unit. + +--- + +## 14. Transactional Event Contract + +### 14.1 Outbox requirement + +Every outbound domain or integration event is written to the shared +transactional outbox introduced by prerequisite CON-02A in the same transaction +as its source record. + +The dispatcher uses at-least-once delivery. Consumers and adapters MUST implement idempotency. + +No code path may: + +- commit a Contribution Record and publish its event outside the outbox; +- publish an event before the database transaction commits; +- call an external adapter from the Review transaction; +- delete an outbox event because delivery is temporarily failing. + +### 14.2 Common event envelope + +~~~yaml +event_id: uuid +event_type: string +event_version: 1 +occurred_at: timestamp +producer: workstream + +project_id: uuid +correlation_id: string +causation_event_id: uuid | null +idempotency_key: string + +payload: object +~~~ + +The canonical idempotency key is stable for the logical event and does not change across delivery retries. + +### 14.3 ContributionRecorded + +One event is emitted per Contribution Record. + +~~~yaml +event_type: ContributionRecorded +event_version: 1 +idempotency_key: "contribution:{contribution_record_id}:recorded:v1" + +payload: + contribution_record_id: uuid + project_id: uuid + task_id: uuid + contributor_id: uuid + contribution_type: accepted_submission | completed_review + source_review_id: uuid + source_review_lease_id: uuid | null + source_task_assignment_id: uuid + submission_id: uuid + source_submission_artifact_digest: string + review_decision: accept | needs_revision | reject + compensation_policy_version_id: uuid + compensation_award_ids: list[uuid] + recorded_at: timestamp +~~~ + +Consumers may use this event for reputation signals, analytics, notifications, evidence export, or other authorized projections. + +The event does not assert that compensation has been fulfilled. + +### 14.4 ContributionEvidenceProjectionRequested + +One internal projection event is emitted per Contribution Record in the same transaction that creates it. + +~~~yaml +event_type: ContributionEvidenceProjectionRequested +event_version: 1 +idempotency_key: "contribution:{contribution_record_id}:evidence-bundle:1" + +payload: + contribution_record_id: uuid + project_id: uuid + projection_schema_version: 1 + requested_at: timestamp +~~~ + +The payload is a wake-up reference, not independent evidence. The worker MUST reload the canonical ContributionRecord, Review, Submission, task policy context, ArtifactBindings, findings, resolutions, compensation policy and awards before generating the bundle. + +After verified storage, Workstream emits `ContributionEvidenceProjected` with the Workstream ArtifactBinding ID and verified digest. Raw provider references MUST NOT appear in public integration events. + +~~~yaml +event_type: ContributionEvidenceProjected +event_version: 1 +idempotency_key: "contribution:{contribution_record_id}:evidence-projected:{projection_schema_version}" + +payload: + contribution_record_id: uuid + project_id: uuid + projection_schema_version: int + artifact_binding_id: uuid + content_digest: string + projected_at: timestamp +~~~ + +### 14.5 CompensationAwardCreated + +~~~yaml +event_type: CompensationAwardCreated +event_version: 1 +idempotency_key: "compensation-award:{compensation_award_id}:created:v1" + +payload: + compensation_award_id: uuid + contribution_record_id: uuid + project_id: uuid + contributor_id: uuid + instrument_type: money | project_points + unit_code: string + quantity: decimal_string + compensation_policy_version_id: uuid + adapter_binding_id: uuid + created_at: timestamp +~~~ + +This event is an immutable domain fact. It is not itself the adapter instruction. + +### 14.6 CompensationFulfillmentRequested + +One event is emitted per CompensationAward. + +~~~yaml +event_type: CompensationFulfillmentRequested +event_version: 1 +idempotency_key: "compensation-award:{compensation_award_id}:fulfill:v1" + +payload: + compensation_award_id: uuid + contribution_record_id: uuid + project_id: uuid + contributor_id: uuid + + instrument_type: money | project_points + unit_code: string + quantity: decimal_string + + compensation_policy_version_id: uuid + adapter_binding_id: uuid + adapter_route_key: string + + contribution_type: accepted_submission | completed_review + source_review_id: uuid + created_at: timestamp +~~~ + +The event contains the complete authorized instruction. The adapter MUST NOT query mutable project policy to determine a different quantity. + +### 14.7 CompensationFulfillmentRecorded + +One event is emitted for every accepted fulfillment receipt. + +~~~yaml +event_type: CompensationFulfillmentRecorded +event_version: 1 +idempotency_key: "fulfillment-receipt:{fulfillment_receipt_id}:recorded:v1" + +payload: + fulfillment_receipt_id: uuid + compensation_award_id: uuid + contribution_record_id: uuid + project_id: uuid + contributor_id: uuid + instrument_type: money | project_points + unit_code: string + authorized_quantity: decimal_string + reported_status: fulfilled | failed + failure_code: string | null + fulfilled_at: timestamp | null + received_at: timestamp +~~~ + +This event reports Workstream's accepted receipt. It does not expose provider credentials or create a new award. + +### 14.8 Sensitive-data restriction + +Events MUST NOT contain: + +- bank details; +- wallet private keys; +- provider access tokens; +- Identity Issuer bearer tokens; +- point-account credentials; +- raw personal financial data. +- raw provider CIDs, filesystem paths, or storage credentials. + +The adapter resolves its own external beneficiary mapping from contributor_id through its authorized integration. + +--- + +## 15. External Adapter Contract + +### 15.1 Workstream adapter port + +Workstream exposes one outbound port to its outbox dispatcher. Provider-specific implementations remain outside the Workstream domain. + +~~~python +class CompensationDeliveryAdapter( + ExternalServiceAdapter[ + CompensationFulfillmentRequested, + AdapterDeliveryAcknowledgement, + ], + Protocol, +): + async def deliver( + self, + binding_id: UUID, + event: CompensationFulfillmentRequested, + ) -> AdapterDeliveryAcknowledgement: + ... + + +class AdapterDeliveryAcknowledgement: + event_id: UUID + accepted: Literal[True] + acknowledged_at: datetime +~~~ + +The port implementation MUST: + +- route only through the persisted adapter_binding_id; +- send the persisted event without recalculating it; +- authenticate Workstream to the adapter; +- return success only after the adapter durably stores the event idempotency key; +- translate timeouts and non-success responses into a delivery failure so the outbox retries. + +The adapter is resolved only through the explicitly composed +`ExternalServiceAdapterFactory[CompensationDeliveryAdapter]`. Runtime discovery, +service locators, fallback constructors, concrete adapter imports in domain +services, and a second feature-local factory are prohibited. The repository +includes only the typed adapter contract, shared dispatcher integration, and a +deterministic test adapter for the live drill. + +### 15.2 Delivery + +The outbox dispatcher routes CompensationFulfillmentRequested using the frozen adapter_binding_id and route_key. + +Adapter response to delivery: + +- 2xx means the adapter durably accepted the instruction and its idempotency key; +- non-2xx or timeout means delivery was not acknowledged and Workstream retries; +- a 2xx acknowledgement does not mean money or points were fulfilled. + +After acknowledgement, Workstream does not create provider retries. The adapter owns all provider-side processing. + +### 15.3 Adapter idempotency + +The adapter MUST treat compensation_award_id and the event idempotency key as stable identifiers. + +Repeated delivery of the same event: + +- must not create another payment request; +- must not credit points twice; +- must return a successful acknowledgement after the original instruction is durably recognized. + +### 15.4 Fulfillment callback request + +~~~yaml +CompensationFulfillmentReported: + external_event_id: string + compensation_award_id: uuid + status: fulfilled | failed + + fulfilled_quantity: decimal_string | null + fulfilled_at: timestamp | null + + failure_code: string | null + reported_at: timestamp +~~~ + +The callback does not accept project_id, contributor_id, instrument_type, unit_code, or authorized quantity as mutable authority. Workstream loads those from CompensationAward. + +### 15.5 Callback authentication and authorization + +Workstream MUST: + +1. verify the Identity Issuer service token; +2. resolve one active service ActorProfile and active ActorIdentityLink through WS-AUTH-001; +3. load and lock the CompensationAward, ContributionRecord and frozen adapter binding from canonical identifiers; +4. ask AuthorizationService for `compensation.fulfillment.report` on the canonical award resource; +5. require the service actor to equal the frozen binding adapter_actor_id; +6. require the binding project and instrument to match the award; +7. validate callback schema and timestamps; +8. enforce idempotency before insertion; +9. persist the AuthorizationDecision reference with the callback audit chain. + +The request body cannot supply project, contributor, instrument, quantity, binding or authorization scope. Those values are loaded from the award chain. + +An `active` binding accepts delivery and callback work. A `suspended` binding accepts valid callbacks for already-issued awards but receives no new delivery; this permits an adapter to report a result for work it accepted before suspension. Retirement is prohibited while an award remains unfulfilled. After retirement, only an exact replay of a previously accepted receipt may return its stored result. + +The service permission is binding-derived and award-scoped. A human Admin token, contributor token, different adapter actor, disabled service actor, revoked identity link, or valid service actor without the exact frozen binding is denied. + +### 15.6 Fulfilled callback + +Validation: + +- fulfilled_quantity exactly equals award.quantity; +- fulfilled_at is present and not unreasonably in the future; +- no different fulfilled receipt already exists; +- award project and binding remain internally consistent. + +Effect in one transaction: + +~~~text +revalidate compensation.fulfillment.report against locked canonical award/binding +insert immutable fulfilled receipt +update status projection -> fulfilled +write CompensationFulfilled audit event linked to AuthorizationDecision +write CompensationFulfillmentRecorded outbox event +commit +~~~ + +Fulfilled is terminal. + +### 15.7 Failed callback + +Validation: + +- failure_code is non-empty; +- fulfilled_quantity and fulfilled_at are null; +- no fulfilled receipt already exists. + +Effect: + +~~~text +revalidate compensation.fulfillment.report against locked canonical award/binding +insert immutable failed receipt +update status projection -> failed +write CompensationFulfillmentFailed audit event linked to AuthorizationDecision +write CompensationFulfillmentRecorded outbox event +commit +~~~ + +The adapter may later report fulfilled using a new external_event_id. + +### 15.8 Prohibited partial fulfillment + +If fulfilled_quantity differs from award.quantity: + +- reject with 422 partial_fulfillment_not_supported; +- create no receipt; +- do not change the projection; +- write a rejected-callback security/audit event. + +The adapter must resolve partial provider behaviour internally before reporting the Workstream award as fulfilled. + +### 15.9 Contradictory callbacks + +- failed followed by fulfilled: allowed. +- failed followed by another failed with a new external_event_id: allowed. +- fulfilled followed by failed: rejected with 409 award_already_fulfilled. +- fulfilled followed by a different fulfilled event: rejected with 409 award_already_fulfilled. +- exact replay of an accepted callback: return the existing receipt with 200. +- reuse of external_event_id with different payload: reject with 409 idempotency_mismatch. + +--- + +## 16. Reputation Boundary + +ContributionRecorded is the canonical reputation input from this lifecycle. + +Recommended raw signal mapping: + +| contribution_type | reputation signal | +|---|---| +| accepted_submission | submission_accepted | +| completed_review | review_completed | + +Normative rules: + +- Signal creation is independent of compensation awards. +- Signal creation is independent of adapter delivery and fulfillment. +- A completed-review signal may carry Review.decision as provenance, but this specification assigns no positive or negative score based on that outcome. +- Needs revision does not automatically reduce submitter reputation. +- Reject does not create a submitter Contribution Record and therefore produces no positive submitter contribution signal. +- Lease expiry and release signals remain the separate audit events defined by WS-REV-001. +- Reputation scoring, aggregation, decay, project-to-global weighting, grant automation, and reviewer-quality adjudication are outside this specification. + +The reputation consumer MUST deduplicate by contribution_record_id and event version. + +--- + +## 17. Read Model and API Composition + +### 17.1 Canonical versus composed data + +The canonical Contribution Record remains unchanged after creation. Contribution +reads compose only contribution and evidence state: + +~~~text +ContributionRecord + ContributionEvidenceProjection + = Contribution detail response +~~~ + +Award, delivery, receipt, and fulfillment data require the separate +`compensation.award.read_self` or `compensation.award.read_project` ActionId and +are returned only from award routes. + +The contribution read composer MUST authorize the canonical ContributionRecord +before loading evidence references. It never loads awards, receipts, or +provider-derived metadata; those require separately authorized award routes. +It MUST NOT use the caller-supplied project_id as authority. + +### 17.2 Example contribution response + +~~~json +{ + "id": "contribution-uuid", + "project_id": "project-uuid", + "task_id": "task-uuid", + "contributor_id": "contributor-uuid", + "contribution_type": "completed_review", + "source_review_id": "review-uuid", + "submission_id": "submission-version-uuid", + "source_submission_artifact_digest": "sha256:...", + "recorded_at": "2026-07-10T12:00:00Z", + "evidence": { + "status": "projected", + "artifact_binding_id": "artifact-binding-uuid", + "content_digest": "sha256:..." + } +} +~~~ + +This is a read representation, not a mutable aggregate stored as one row. + +The `artifact_binding_id` is a Workstream reference. The response does not disclose a raw provider CID, URL or filesystem path. `content_digest` proves integrity but grants no retrieval authority. + +--- + +## 18. API Contract + +The following paths are normative for Workstream v0.1. The `/api/v1` prefix is the independent API contract namespace, not a Workstream v1.0 release identifier. + +### 18.1 Compensation policies + +~~~text +POST /api/v1/projects/{project_id}/compensation-policies +POST /api/v1/projects/{project_id}/compensation-policies/{policy_id}/versions +PUT /api/v1/projects/{project_id}/compensation-policy-versions/{version_id}/draft +POST /api/v1/projects/{project_id}/compensation-policy-versions/{version_id}/publish +POST /api/v1/projects/{project_id}/compensation-policy-versions/{version_id}/retire +GET /api/v1/projects/{project_id}/compensation-policies +GET /api/v1/projects/{project_id}/compensation-policy-versions/{version_id} +~~~ + +Creating a new policy creates the policy identity and an empty version 1 draft. Creating a version under an existing policy copies the current published version into the next draft version. The draft remains inactive until explicitly published. + +Policy creation request: + +~~~json +{ + "name": "Project default compensation" +} +~~~ + +PUT replaces the complete draft rules; it does not merge individual fields. + +~~~json +{ + "rules": [ + { + "contribution_type": "accepted_submission", + "compensation_mode": "compensated", + "awards": [ + { + "instrument_type": "money", + "unit_code": "USD", + "quantity": "45.00", + "adapter_binding_id": "money-binding-uuid" + } + ] + }, + { + "contribution_type": "completed_review", + "compensation_mode": "compensated", + "awards": [ + { + "instrument_type": "money", + "unit_code": "USD", + "quantity": "60.00", + "adapter_binding_id": "money-binding-uuid" + }, + { + "instrument_type": "project_points", + "unit_code": "REVIEW_POINT", + "quantity": "5", + "adapter_binding_id": "points-binding-uuid" + } + ] + } + ] +} +~~~ + +The publish request and the retire request both require: + +~~~json +{ + "expected_current_version_id": "current-version-uuid-or-null" +} +~~~ + +No edit endpoint exists for a published or retired version. + +Policy routes use exactly one primary ActionId: `compensation.policy.create_draft`, `compensation.policy.update_draft`, `compensation.policy.publish`, `compensation.policy.retire`, or `compensation.policy.read`, matched to the operation and canonical target. Every write requires Finance Authority. Possession of a route path is not authority. + +### 18.2 Adapter bindings + +~~~text +POST /api/v1/projects/{project_id}/compensation-adapter-bindings +POST /api/v1/projects/{project_id}/compensation-adapter-bindings/{binding_id}/suspend +POST /api/v1/projects/{project_id}/compensation-adapter-bindings/{binding_id}/resume +POST /api/v1/projects/{project_id}/compensation-adapter-bindings/{binding_id}/retire +GET /api/v1/projects/{project_id}/compensation-adapter-bindings +~~~ + +Binding creation request: + +~~~json +{ + "instrument_type": "money", + "adapter_actor_id": "service-actor-uuid", + "route_key": "project-money-v1" +} +~~~ + +The route_key identifies deployment routing configuration and contains no endpoint credential or secret. + +Binding routes use exactly one primary ActionId: `compensation.adapter_binding.create`, `compensation.adapter_binding.suspend`, `compensation.adapter_binding.resume`, `compensation.adapter_binding.retire`, or `compensation.adapter_binding.read`, matched to the operation and canonical target. Every mutation requires Finance Authority. Operational views use `compensation.status.read`, `compensation.award.read_project`, or `audit.read` according to the canonical view. + +### 18.3 Contributions + +~~~text +GET /api/v1/contributors/me/contributions +GET /api/v1/contributors/me/contributions/{contribution_record_id} +GET /api/v1/contributors/me/contributions/{contribution_record_id}/evidence +GET /api/v1/projects/{project_id}/contributions +GET /api/v1/projects/{project_id}/contributions/{contribution_record_id} +GET /api/v1/projects/{project_id}/contributions/{contribution_record_id}/evidence +GET /api/v1/projects/{project_id}/contributors/{contributor_id}/contributions +GET /api/v1/projects/{project_id}/tasks/{task_id}/contributions +~~~ + +Supported filters: + +- project_id; +- contribution_type; +- task_id; +- recorded_from; +- recorded_to; +- cursor. + +Ordering is deterministic: + +~~~text +recorded_at DESC, id DESC +~~~ + +Authorization is deterministic: + +- `GET /api/v1/contributors/me/contributions` requires `contribution.read_self` and returns only records whose contributor_id is the caller's ActorProfile id; +- the two `/contributors/me/...` detail/evidence routes use `contribution.read_self` and require the record owner to equal the caller; +- every `/projects/{project_id}/...` contribution route uses `contribution.read_project` and derives exact scope from the canonical Project/ContributionRecord chain; +- project-scoped contributor history uses `/projects/{project_id}/contributors/{contributor_id}/contributions`; no cross-project Admin contributor-history route exists in v0.1; +- project and task endpoints require `contribution.read_project` for the canonical path project scope; +- records from unauthorized projects are never returned and are not revealed through total counts. + +No POST, PATCH, PUT, or DELETE Contribution Record endpoint exists. + +The self and project evidence endpoints apply their one declared contribution-read permission, validate the projection and ArtifactBinding chain, retrieve through ART-owned contribution-evidence capability with a Workstream service scope, verify the digest, record attributable access and return the approved bundle representation. + +Responses: + +- `200` when the verified bundle is available; +- `409 contribution_evidence_not_ready` while projection is pending; +- `503 contribution_evidence_unavailable` when projection or verified retrieval has failed; +- `404 contribution_not_found` when the record is absent or invisible. + +### 18.4 Compensation awards + +~~~text +GET /api/v1/contributors/me/compensation-awards +GET /api/v1/contributors/me/compensation-awards/{award_id} +GET /api/v1/projects/{project_id}/compensation-awards +GET /api/v1/projects/{project_id}/compensation-awards/{award_id} +GET /api/v1/projects/{project_id}/contributors/{contributor_id}/compensation-awards +POST /api/v1/projects/{project_id}/compensation-awards/{award_id}/reconcile-delivery +~~~ + +Supported operational filters: + +- instrument_type; +- delivery_status; +- fulfillment_status; +- created_from; +- created_to; +- minimum_pending_age. + +Self award routes require `compensation.award.read_self` and exact beneficiary +ownership. Project award routes require `compensation.award.read_project` and +covered canonical project scope. No unscoped award-detail or cross-project +Admin route exists, and contribution endpoints never compose award data. + +The reconciliation route requires `compensation.delivery.reconcile`, a mandatory `Idempotency-Key` header and a bounded structured reason. It may inspect delivery evidence or make the existing unacknowledged outbox instruction immediately eligible for dispatch with the same event_id, payload and idempotency key. It cannot create an award, change quantity/binding, fabricate acknowledgement, or mark fulfillment. A second equivalent request returns the stored result; an incompatible live request returns `409 compensation_reconciliation_in_progress`. + +### 18.5 Fulfillment callback + +~~~text +POST /api/v1/integrations/compensation/fulfillment-reports +~~~ + +Responses: + +- 201 when a new receipt is created; +- 200 for exact idempotent replay; +- 400 for malformed schema; +- 401 for invalid identity; +- 403 for unauthorized adapter or project/instrument mismatch; +- 404 for unknown award; +- 409 for callback conflict or idempotency mismatch; +- 422 for invalid fulfillment semantics. + +No endpoint allows an adapter to change the Contribution Record, CompensationAward, policy, assignment, lease, Review, task, or contributor. + +The callback requires an Identity Issuer service token and an allowed `compensation.fulfillment.report` AuthorizationDecision for the exact frozen award binding. Human Admin permissions cannot satisfy this route. + +--- + +## 19. Error Contract + +Errors MUST use the existing Workstream structured-error envelope and stable machine codes. + +| Code | HTTP | Meaning | +|---|---:|---| +| compensation_policy_missing | 409 | Project has no active published compensation version | +| compensation_policy_not_draft | 409 | Attempt to edit non-draft version | +| compensation_policy_invalid | 422 | Draft violates policy rules | +| compensation_policy_integrity_error | 500 | Frozen reference or published data is internally inconsistent | +| authentication_required | 401 | Required bearer token is absent | +| invalid_token | 401 | Identity Issuer token verification failed | +| actor_not_active | 403 | ActorProfile or identity link is not active | +| permission_not_granted | 403 | AuthorizationService denied the registered permission | +| resource_project_mismatch | 403 | Canonical record chain does not belong to the covered project scope | +| service_actor_not_provisioned | 403 | Callback identity is not an active provisioned service actor | +| adapter_binding_missing | 409 | Required instrument has no compatible binding | +| adapter_binding_in_use | 409 | Binding is referenced by active policy, unfinished frozen work, or unfulfilled awards | +| adapter_unauthorized | 403 | Callback actor is not bound to the award | +| compensation_reconciliation_in_progress | 409 | An incompatible live delivery-reconciliation request already exists for the award/event | +| contribution_not_found | 404 | Contribution Record does not exist or is not visible | +| compensation_award_not_found | 404 | Award does not exist or is not visible | +| contribution_already_recorded | 409 | Logical contribution already exists | +| compensation_award_already_exists | 409 | Logical award already exists | +| fulfillment_callback_invalid | 422 | Callback fields do not match status rules | +| partial_fulfillment_not_supported | 422 | Fulfilled quantity differs from authorized quantity | +| award_already_fulfilled | 409 | A contradictory post-fulfillment callback was attempted | +| idempotency_mismatch | 409 | Idempotency identifier was reused with different payload | +| contribution_evidence_not_ready | 409 | Contribution evidence projection has not completed | +| contribution_evidence_unavailable | 503 | Verified contribution evidence cannot currently be retrieved | +| artifact_binding_not_visible | 404 | ArtifactBinding does not exist in the caller's authorized contribution scope | +| artifact_integrity_mismatch | 500 | Stored evidence receipt or bytes do not match the expected digest or source identity | +| artifact_idempotency_conflict | 409 | Stable artifact operation identity was reused with different bytes or scope | +| artifact_verification_retry_ineligible | 409 | ART verification job is not exhausted provider_unavailable or is already queued/running | + +Internal uniqueness races MUST be translated into the corresponding stable conflict or idempotent success rather than leaking database errors. + +Authentication, authorization, domain-state, adapter-binding, and Artifact Storage failures MUST retain distinct codes. The API MUST NOT translate every denial into `not_found` or every dependency failure into a generic 500. + +--- + +## 20. Database Constraints and Indexes + +Required constraints: + +~~~text +ContributionRecord: + UNIQUE(source_review_id, contribution_type) + CHECK(contribution_type IN accepted_submission, completed_review) + source_submission_artifact_digest NOT NULL + +ContributionEvidenceProjection: + PRIMARY KEY(contribution_record_id) + CHECK(status IN pending, projected, failed) + CHECK(projected requires artifact_binding_id, content_digest, projected_at) + CHECK(pending or failed forbids projected_at) + +CompensationPolicyVersion: + UNIQUE(compensation_policy_id, version_number) + +CompensationPolicy: + partial UNIQUE(project_id) WHERE status = active + +CompensationRule: + UNIQUE(compensation_policy_version_id, contribution_type) + CHECK(compensation_mode IN compensated, unpaid) + +CompensationAwardDefinition: + UNIQUE(compensation_policy_version_id, contribution_type, instrument_type) + CHECK(quantity > 0) + +CompensationAward: + UNIQUE(contribution_record_id, instrument_type) + CHECK(quantity > 0) + +ProjectCompensationAdapterBinding: + partial UNIQUE(project_id, instrument_type) WHERE status = active + +CompensationFulfillmentReceipt: + UNIQUE(adapter_binding_id, external_event_id) + partial UNIQUE(compensation_award_id) WHERE reported_status = fulfilled + +CompensationStatusProjection: + PRIMARY KEY(compensation_award_id) + +TaskAssignment: + submitter_compensation_policy_version_id NOT NULL + +ReviewLease: + reviewer_compensation_policy_version_id NOT NULL + +~~~ + +The generic ArtifactBinding tables MUST enforce one verified `contribution_evidence_bundle` binding per `(contribution_record_id, projection_schema_version)` and the same project_id as the owner ContributionRecord. An ArtifactBinding from another owner, project or artifact role cannot satisfy a projection. + +Foreign keys MUST prevent project-chain mismatches. Composite foreign keys MUST be used where a single-column foreign key cannot express project ownership. Transaction-level validation remains additional defence and MUST NOT replace enforceable database ownership constraints. AuthorizationDecision references on sensitive audit/mutation records MUST point to an immutable WS-AUTH decision; bearer tokens are never stored. + +Required indexes: + +~~~text +ContributionRecord(contributor_id, recorded_at DESC, id DESC) +ContributionRecord(project_id, recorded_at DESC, id DESC) +ContributionRecord(project_id, task_id, recorded_at, id) +ContributionRecord(source_review_id, contribution_type) +ContributionEvidenceProjection(project_id, status, updated_at) +ContributionEvidenceProjection(status, last_attempt_at) + +CompensationPolicyVersion(project_id, status) +CompensationAward(contribution_record_id) +CompensationAward(project_id, created_at DESC) +CompensationAward(adapter_binding_id, created_at) + +CompensationFulfillmentReceipt(compensation_award_id, received_at) +CompensationStatusProjection(fulfillment_status, updated_at) + +Outbox(event_type, delivery_state, next_attempt_at) +~~~ + +All timestamps are stored in UTC. + +--- + +## 21. Concurrency and Idempotency + +### 21.1 Review-decision replay + +The WS-REV-001 decision idempotency key protects the entire combined transaction. + +Repeating the same committed decision request MUST return: + +- the existing Review; +- the existing reviewer Contribution Record; +- the existing submitter Contribution Record when decision = accept; +- the existing CompensationAwards; +- no new outbox events. + +Reusing the decision idempotency key with a different decision or payload returns 409 idempotency_mismatch. + +### 21.2 Concurrent decision attempts + +If two requests attempt to decide the same ReviewLease or Submission: + +- exactly one may create the Review; +- exactly one completed_review Contribution Record exists; +- at most one accepted_submission Contribution Record exists; +- award uniqueness follows the winning contribution records; +- the losing transaction returns the existing result only if it is an exact idempotent replay; otherwise it returns a conflict. + +### 21.3 Concurrent policy activation + +Project policy activation locks the project active-version reference. + +If two versions are activated concurrently: + +- exactly one becomes active first; +- the other transaction must re-evaluate and either replace it explicitly under its request semantics or fail with a version conflict; +- assignments and leases freeze one committed version, never a mixture. + +Activation endpoints MUST require expected_current_version_id. Null is supplied only when the project has no active version. + +### 21.4 Policy activation versus assignment + +Assignment and lease creation lock the same project active-version reference used by activation. + +The result is serializable at that boundary: + +- work freezes the old version before activation commits; or +- work freezes the new version after activation commits. + +Server request timing outside the transaction does not determine the version. + +### 21.5 Award duplication + +CompensationAward creation is part of the contribution transaction and protected by uniqueness constraints. + +An insert conflict caused by an exact replay resolves to the existing award. A conflict with different unit, quantity, policy version, or binding is an integrity error. + +### 21.6 Outbox delivery replay + +Outbox delivery is at-least-once. + +- The event_id and idempotency_key remain unchanged across retries. +- Delivery-attempt count and next-attempt time are operational metadata. +- A transient adapter failure does not create another CompensationAward or outbox event. +- After durable adapter acknowledgement, provider-side retries belong to the adapter. + +### 21.7 Concurrent callbacks + +Callback processing locks the CompensationAward or its status row. + +If failed and fulfilled callbacks race: + +- if fulfilled commits first, the failed callback is rejected; +- if failed commits first, the fulfilled callback may subsequently commit; +- final state is fulfilled. + +If two different fulfilled callbacks race, exactly one may create the unique fulfilled receipt. The other is rejected unless it is the exact idempotent replay of the winner. + +### 21.8 Callback before delivery acknowledgement + +A valid authenticated callback may be received before Workstream records local delivery acknowledgement. + +In that case: + +- accept and store the receipt; +- set fulfillment_status according to the receipt; +- set delivery_status to acknowledged_by_adapter because possession of the award instruction is proven; +- mark the associated outbox instruction delivered or suppress further delivery idempotently; +- never regress fulfilled state when a late dispatcher acknowledgement arrives. + +### 21.9 Authorization and mutation races + +Policy publication, binding mutation, outbox retry, projection rebuild, reconciliation and callback processing MUST evaluate AuthorizationService against canonical resources after those resources are loaded. Sensitive write transactions revalidate the decision after acquiring the rows whose state determines authority or domain validity. + +If a grant, service ActorProfile, identity link or binding becomes invalid before the write commits, the operation fails closed. A previously allowed router decision is not a perpetual capability and cannot authorize a later transaction after revocation. + +### 21.10 Contribution-evidence projection replay + +Decision replay returns the existing ContributionEvidenceProjection row and MUST NOT create another projection event. + +Projection delivery is at-least-once: + +- the worker always reloads canonical data; +- the same contribution id and projection schema version produce the same canonical serialization and digest; +- retry uses the same artifact operation identity and idempotency key; +- the same identity and digest resolves to the existing verified ArtifactBinding; +- the same identity with different bytes, owner, project, media type or scope is an integrity conflict; +- concurrent workers may produce at most one verified current projection for the contribution/schema version. + +An authorized rebuild to a later projection schema version creates a new deterministic storage identity and retains the prior ArtifactBinding for audit. It never rewrites an existing bundle. + +### 21.11 Artifact verification recovery + +WS-CON does not model provider recovery attempts. ART persists operation and +verification receipts. Only an exhausted `provider_unavailable` +ArtifactVerificationJob is operator-retry eligible through +`ArtifactOperatorRecoveryPort`; ART creates one ArtifactRecoveryAttempt and a +new retry ArtifactVerificationJob while leaving the exhausted source job +unchanged. The retry job's fixed `artifact.verification.execute` actor performs +execution. Exact replay returns the same attempt and retry-job ids. No CON executor, +lease, generation, provider-receipt lookup, or raw provider replay exists. + +--- + +## 22. Background Processing and Recovery + +### 22.1 Outbox dispatcher + +The dispatcher: + +- selects committed undelivered events; +- routes by adapter_binding_id and route_key; +- sends the exact persisted payload; +- records delivery attempts; +- retries transient failures using delay = min(300 seconds, 2 raised to attempt_number minus 1 seconds), plus uniformly distributed jitter from zero through ten percent of that delay; +- marks acknowledged only after a valid adapter 2xx response; +- preserves events until retention policy permits archival. + +It MUST NOT derive a new award quantity from current policy. + +Compensation delivery uses the bounded shared-outbox retry policy. Exhaustion +dead-letters the same immutable event and triggers the delayed-delivery alert; +reason-bound recovery requeues that event with its original payload and +idempotency identity. Tests prove no duplicate logical adapter effect. + +### 22.2 Contribution-evidence projection worker + +The worker consumes `ContributionEvidenceProjectionRequested` after commit and executes section 6.13 through ART-owned contribution-evidence capability. It runs under a provisioned Workstream system ActorProfile and uses least-privilege service scopes; it never impersonates the contributor or forwards the initiating human token. + +The worker MUST: + +- claim projection work idempotently; +- reload canonical records and authorized ArtifactBindings; +- serialize the versioned bundle deterministically; +- compute and retain the expected digest before storage; +- accept only the verified ArtifactBinding returned by ART; +- update the projection and audit/outbox records atomically after verified success; +- distinguish retryable availability failure, permanent canonical-integrity failure and uncertain provider outcome. + +### 22.3 Compensation status projection updater + +Projection updates happen synchronously in the same transaction that records adapter delivery acknowledgement or a fulfillment receipt. Projection rebuild remains an asynchronous recovery operation. + +The updater: + +- updates are idempotent; +- fulfilled cannot regress; +- the projection can be fully rebuilt; +- source receipts and delivery records remain authoritative. + +### 22.4 Reconciliation job + +The reconciliation job detects: + +- Review without required reviewer Contribution Record; +- accept Review without submitter Contribution Record; +- Contribution Record without ContributionRecorded outbox event; +- Contribution Record whose frozen policy version does not match its assignment or lease; +- award missing for a published definition; +- unexpected award for an unpaid contribution type; +- award without CompensationFulfillmentRequested; +- fulfilled projection without fulfilled receipt; +- fulfilled receipt whose quantity differs from award; +- multiple fulfilled receipts; +- adapter binding retired while referenced by an unfulfilled award; +- acknowledged delivery whose adapter binding does not match the award. +- Contribution Record without a pending or projected ContributionEvidenceProjection; +- Contribution Record without a ContributionEvidenceProjectionRequested outbox event; +- projected evidence row without one verified contribution_evidence_bundle ArtifactBinding; +- evidence bundle whose owner, project, source identity or digest differs from the canonical chain; +- a raw provider reference exposed by a public contribution read model. + +Reconciliation MUST alert operators and use explicit replay or compensating operational actions. It MUST NOT silently edit immutable Reviews, Contribution Records, awards, definitions, or receipts. + +### 22.5 Event replay + +Safe replay is allowed for: + +- rebuilding read projections; +- recreating a missing delivery attempt from an existing outbox event; +- re-delivering an unacknowledged event with the same identifiers; +- recreating a missing mutable status projection from authoritative records. +- re-running contribution evidence projection from the canonical ContributionRecord chain with the same schema version and operation identity; +- rebuilding a later evidence schema version under an authorized projection-rebuild operation. + +Replay MUST NOT create a second logical Contribution Record, award, fulfilled receipt, or bundle for the same contribution/schema version. + +### 22.6 Artifact recovery + +Recovery is entirely ART-owned. An authorized Operator may retry only an +exhausted `provider_unavailable` ArtifactVerificationJob through +`ArtifactOperatorRecoveryPort.retry_verification`. ART records the request, +creates one ArtifactRecoveryAttempt and a new retry ArtifactVerificationJob, +and leaves the exhausted source job unchanged. Exact replay returns the same +attempt/retry ids; only the retry job executes under the fixed verification +service actor. WS-CON observes the resulting binding/verification +state and never owns an artifact recovery row or provider operation. + +### 22.7 Adapter suspension + +When a binding is suspended: + +- existing awards remain valid; +- undelivered events remain pending; +- no award is cancelled; +- Review decisions and contribution creation continue if the policy version was already frozen; +- new policy publication cannot select the suspended binding; +- new TaskAssignments or ReviewLeases cannot freeze a current policy that depends on a suspended binding. + +Existing assignments and leases are honored because contributors began work under frozen terms. Delivery resumes when the same logical binding is reactivated. + +--- + +## 23. Audit Events + +The following event types are required. + +### Policy + +- CompensationPolicyCreated +- CompensationPolicyVersionDrafted +- CompensationPolicyVersionPublished +- CompensationPolicyVersionActivated +- CompensationPolicyVersionRetired +- CompensationAwardDefinitionCreated +- ProjectCompensationAdapterBound +- ProjectCompensationAdapterSuspended +- ProjectCompensationAdapterResumed +- ProjectCompensationAdapterRetired + +### Frozen terms + +- CompensationTermsFrozenForAssignment +- CompensationTermsFrozenForReviewLease + +### Contribution + +- ReviewerContributionRecorded +- SubmitterContributionRecorded +- ContributionRecorded +- ContributionEvidenceProjectionRequested +- ContributionEvidenceProjected +- ContributionEvidenceProjectionFailed +- ContributionEvidenceProjectionReconciled +- ContributionEvidenceAccessed +- ContributionEvidenceUnavailable +- ContributionEvidenceIntegrityMismatch + +### Award and delivery + +- CompensationAwardCreated +- CompensationFulfillmentRequested +- CompensationFulfillmentDeliveryAttempted +- CompensationFulfillmentDeliveryAcknowledged +- CompensationFulfillmentDeliveryFailed + +### Callback + +- CompensationFulfillmentReported +- CompensationFulfilled +- CompensationFulfillmentFailed +- CompensationFulfillmentCallbackRejected +- CompensationFulfillmentCallbackReplayed + +### Artifact recovery + +- ART-owned recovery attempt/retry-job ids and status may be linked as external + operational evidence; WS-CON emits no artifact-recovery lifecycle event. + +Every audit event records: + +~~~yaml +event_id: uuid +event_type: string +occurred_at: timestamp +actor_id: actor_id | system_actor_id +authorization_decision_id: uuid | null + +project_id: uuid +contributor_id: uuid | null +task_id: uuid | null +review_id: uuid | null +review_lease_id: uuid | null +contribution_record_id: uuid | null +compensation_award_id: uuid | null +compensation_policy_version_id: uuid | null +adapter_binding_id: uuid | null +artifact_binding_id: uuid | null +artifact_operation_id: uuid | null +artifact_recovery_attempt_id: uuid | null + +correlation_id: string +causation_event_id: uuid | null +reason_code: string | null +metadata: object +~~~ + +Audit metadata MUST redact credentials and sensitive financial data. + +Sensitive human and service mutations record the exact WS-AUTH AuthorizationDecision id, permission, canonical scope and policy version by reference. Audit records MUST NOT persist bearer tokens, Artifact Storage service credentials, raw provider URLs, or full evidence-bundle contents. + +--- + +## 24. Notifications and Operational Views + +Notification transport is an adapter concern. Workstream emits events sufficient to notify: + +- contributor that a submission contribution was recorded; +- reviewer that a review contribution was recorded; +- contributor of the compensation instruments authorized; +- Admin that adapter delivery is delayed; +- contributor or Admin that fulfillment was reported failed; +- contributor that fulfillment was reported completed; +- Admin that policy or adapter binding is missing or suspended. +- authorized Operator that an exhausted provider-unavailable artifact verification job is retry eligible through ART. + +### 24.1 Contributor view + +Must show: + +- global contribution history; +- project filter; +- contribution type and source task; +- recorded time; +- compensation awarded per instrument; +- pending, failed, or fulfilled status from the projection; +- contribution-evidence projection status and an authorized Workstream evidence reference when projected; +- external reference only when permitted by data policy. + +It MUST NOT imply that adapter acknowledgement means fulfillment. + +### 24.2 Project Admin view + +Must show: + +- active compensation version; +- historical frozen versions; +- assignment and lease counts by frozen version; +- contribution counts by type; +- awards by instrument and unit; +- oldest pending-delivery age; +- oldest pending-fulfillment age; +- failed fulfillment count and failure codes; +- adapter binding health and suspension state. +- contribution-evidence projection completion/failure counts and oldest pending age. + +### 24.3 Finance Authority view + +Within authorized project scope, Finance Authority may read: + +- monetary award totals; +- monetary awards by fulfillment status; +- policy versions containing money; +- money-adapter delivery health; +- external references returned by the authorized adapter. + +Workstream does not provide provider balances, payout batches, or settlement ledgers. + +### 24.4 Audit Authority and authorized reputation-consumer view + +Within covered scope, Audit Authority may read the attributable contribution, authorization, compensation and evidence-projection chain. An external reputation service consumes only the authorized `ContributionRecorded` event contract; it is a service consumer, not a human Admin role. + +The allowed view includes: + +- Contribution Records; +- contribution types; +- source Reviews and provenance; +- ContributionRecorded event delivery status to the reputation consumer. +- contribution-evidence projection status and audit references, without raw provider authority. + +Compensation fulfillment is not a reputation input. + +Every operational and aggregate view is filtered after AuthorizationService evaluates the canonical project/system scope. Unauthorized rows are excluded before counts, totals, oldest-age calculations or failure-code aggregation. + +--- + +## 25. Observability + +Required metrics: + +~~~text +workstream_contributions_created_total{project_id, contribution_type} +workstream_contribution_transaction_failures_total{reason} +workstream_compensation_awards_created_total{project_id, instrument_type, unit_code} +workstream_compensation_award_quantity_total{project_id, instrument_type, unit_code} +workstream_compensation_outbox_pending_total{adapter_binding_id} +workstream_compensation_outbox_oldest_seconds{adapter_binding_id} +workstream_compensation_delivery_attempts_total{adapter_binding_id, result} +workstream_compensation_fulfillment_callbacks_total{adapter_binding_id, status, result} +workstream_compensation_pending_fulfillment_total{project_id, instrument_type} +workstream_compensation_pending_fulfillment_oldest_seconds{project_id, instrument_type} +workstream_compensation_reconciliation_violations_total{type} +workstream_contribution_authorization_decisions_total{permission, result, reason_code} +workstream_contribution_evidence_projection_total{result, error_code} +workstream_contribution_evidence_projection_lag_seconds{project_id} +workstream_contribution_evidence_retrieval_total{result} +workstream_contribution_evidence_unavailable_total{reason} +workstream_contribution_evidence_integrity_mismatch_total{type} +workstream_contribution_artifact_recovery_total{result} +~~~ + +Required tracing attributes: + +- correlation_id; +- project_id; +- task_id; +- review_id; +- contribution_record_id; +- compensation_award_id; +- adapter_binding_id; +- event_id; +- authorization_decision_id; +- artifact_binding_id; +- artifact_operation_id; +- projection_schema_version. + +Logs MUST NOT contain bearer tokens, credentials, private keys, bank details, or full provider payloads containing sensitive data. + +Suggested alerts: + +- outbox oldest age exceeds project operational threshold; +- adapter delivery failure rate exceeds threshold; +- fulfillment callback rejection spikes; +- reconciliation detects any missing contribution or duplicate fulfilled receipt; +- an active policy loses a usable adapter binding; +- monetary awards remain pending beyond project service target; +- contribution-evidence projection lag exceeds the configured service target; +- any contribution-evidence integrity mismatch occurs; +- any ART verification retry remains exhausted or fails integrity checks; +- authorization denials or callback-actor mismatches spike unexpectedly. + +--- + +## 26. Security Requirements + +1. Verify Identity Issuer tokens and resolve the current ActorProfile/identity link on every protected human and service request. +2. Use WS-AUTH-001 AuthorizationService for every registered action; local role-name conditionals are prohibited. +3. Derive project and record scope from canonical Workstream rows, not request paths, query filters, event payloads or callback fields. +4. Require Finance Authority and the exact granular `compensation.policy.*` action from WS-AUTH-001 for every compensation-policy mutation, whether money, project points or unpaid. +5. Require Finance Authority and the exact granular `compensation.adapter_binding.*` action from WS-AUTH-001 for every adapter-binding mutation. +6. Never allow a human actor to create, edit, fulfill or delete ContributionRecords, CompensationAwards or fulfillment receipts. +7. Bind callbacks to an active service ActorProfile, `compensation.fulfillment.report`, and the exact frozen adapter actor, project, instrument and award. +8. Treat callback and external adapter payloads as untrusted input. +9. Use exact decimal parsing with bounded length and precision. +10. Reject reported_at or fulfilled_at more than five minutes ahead of database time. A fulfilled_at value must not be more than five minutes later than reported_at. +11. Enforce request-body size limits and rate-limit callback endpoints per adapter actor. +12. Store adapter and Artifact Storage credentials outside domain tables. +13. Sign or mutually authenticate adapter delivery in addition to service identity where deployment policy requires it. +14. Prevent insecure direct-object references in contribution, award, receipt, audit and evidence endpoints. +15. Re-authorize every Artifact Storage search candidate against its canonical ContributionRecord before disclosure. +16. Human bearer tokens MUST NOT cross the Workstream boundary. Artifact Storage and compensation adapters receive separate service credentials/scopes. +17. Artifact Storage service scopes MUST be least-privilege and bind project, owner, operation, artifact role and expiry where the provider supports those fields. +18. Verify contribution-evidence digest, source identity, project ownership, artifact role, media type and operation identity before creating an ArtifactBinding. +19. Do not expose artifact bytes through list endpoints or expose raw CIDs, arbitrary URLs, filesystem paths, credentials or provider capabilities as authority. +20. Redact external failure messages before showing them to contributors. +21. Preserve immutable, attributable audit evidence for authorization, policy publication, award creation, delivery, callbacks, evidence projection, access and recovery. +22. Treat money and project-points fulfillment events as economically sensitive messages. +23. Treat contribution evidence as project-confidential unless the project's explicit disclosure policy grants a broader authorized view. +24. A storage or adapter outage MUST fail the dependent projection/delivery operation without weakening authorization or mutating canonical contribution history. + +--- + +## 27. End-to-End Reference Sequences + +### 27.1 Accepted submission with paid reviewer and paid submitter + +~~~text +1. TaskAssignment created under CompensationPolicyVersion P1 + - submitter terms frozen to P1 +2. Submission v1 passes checkers and enters review queue +3. Reviewer claims under current policy P1 + - ReviewLease terms frozen to P1 +4. Reviewer records accept; AuthorizationService allows `review.decision` for the locked lease/task scope +5. One transaction: + - Review accept created + - lease consumed and queue closed + - Task.status -> accepted + - TaskAssignment.status -> completed + - reviewer completed_review ContributionRecord created + - reviewer awards created from P1 completed_review rules + - submitter accepted_submission ContributionRecord created + - submitter awards created from P1 accepted_submission rules + - one pending ContributionEvidenceProjection and projection event per ContributionRecord + - contribution, award, fulfillment and projection outbox events created + - commit +6. Evidence worker builds deterministic reviewer/submitter bundles and stores them through ART-owned contribution-evidence capability +7. Adapter deliveries occur after commit +8. Money and points adapters acknowledge independently +9. Each bound service actor is authorized and later reports fulfilled or failed +10. Workstream stores receipts and updates read projections +~~~ + +### 27.2 Needs revision with reviewer compensation + +~~~text +1. Reviewer records needs_revision with required findings +2. One transaction: + - Review created + - task -> needs_revision + - reviewer completed_review ContributionRecord created + - reviewer awards created independent of decision + - no submitter Contribution Record + - commit +3. Contributor submits v2 +4. v2 is reviewed later +5. That later valid Review creates another reviewer Contribution Record +~~~ + +### 27.3 Reject with reviewer compensation + +~~~text +1. Reviewer records reject +2. One transaction: + - Review reject created + - reviewer completed_review ContributionRecord and awards created + - submitter TaskAssignment blocked + - task closed + - no submitter Contribution Record + - commit +3. Reviewer compensation proceeds through external adapter +~~~ + +### 27.4 Explicitly unpaid project + +~~~text +1. Project has active published unpaid policy +2. Reviewer records accept +3. Reviewer and submitter Contribution Records are created +4. No CompensationAwards are created +5. ContributionRecorded events still feed reputation and history +~~~ + +### 27.5 Money plus project points + +~~~text +completed_review ContributionRecord + -> money award USD 1.25 -> money adapter + -> project points award REVIEW_POINT 5 -> points adapter + +money callback -> fulfilled +points callback -> failed + +read view: + money = fulfilled + points = failed + contribution remains permanently recorded +~~~ + +### 27.6 Adapter failure followed by success + +~~~text +1. Adapter acknowledges award instruction +2. Adapter reports failed with external_event_id F1 +3. Workstream stores failed receipt; projection -> failed +4. Adapter retries provider work internally +5. Adapter reports fulfilled with external_event_id F2 +6. Workstream stores fulfilled receipt; projection -> fulfilled +7. A later failed callback is rejected +~~~ + +### 27.7 Policy changes during existing work + +~~~text +1. TaskAssignment freezes P1 +2. Reviewer R1 claims and freezes P1 +3. Project activates P2 +4. R1 completes review: + - reviewer award uses P1 + - accepted submitter award uses TaskAssignment P1 +5. Reviewer R2 claims later: + - R2 lease freezes P2 +6. No existing object is rewritten +~~~ + +### 27.8 Duplicate decision and duplicate callback + +~~~text +1. Decision request commits Review, contributions, awards, and events +2. Same idempotency key and payload is retried +3. Existing complete result is returned; no duplicate records +4. Adapter callback commits one receipt +5. Same external_event_id and payload is retried +6. Existing receipt is returned with 200 +~~~ + +### 27.9 Authorized contribution-evidence retrieval + +~~~text +1. Caller requests the self or project-scoped contribution evidence route with Identity Issuer token +2. AuthorizationService allows contribution.read_self or contribution.read_project on canonical record +3. Workstream validates the projected ArtifactBinding owner, project, role and digest +4. Workstream retrieves through ART-owned contribution-evidence capability using a separate least-privilege service scope +5. Digest is verified and attributable access is recorded +6. Approved bundle representation is returned +7. Raw provider authority and the caller token are never forwarded or exposed +~~~ + +### 27.10 Storage outage and uncertain recovery + +~~~text +1. Review transaction commits Review, contributions, awards and pending evidence projections +2. Artifact Storage is unavailable; projection retry fails +3. Review, ContributionRecords and CompensationAwards remain valid +4. An exhausted provider_unavailable verification job becomes retry eligible +5. Authorized Operator requests retry through ART's typed recovery port +6. ART creates one recovery attempt and a new retry verification job while leaving the exhausted source job unchanged +7. Verified success supplies the binding; continued failure remains ART state +8. No WS-CON canonical lifecycle fact is rewritten +~~~ + +--- + +## 28. Conformance Tests + +An implementation is not conformant until all applicable tests pass against PostgreSQL and the real API transaction boundary. + +### 28.1 Policy tests + +1. Project without an active policy cannot create a TaskAssignment. +2. Project without an active policy cannot create a ReviewLease. +3. Explicit unpaid policy allows work and creates no awards. +4. Draft policy may be edited by Finance Authority with an allowed `compensation.policy.update_draft` decision for the canonical version. +5. Published policy cannot be edited. +6. Retired policy cannot be edited. +7. Money policy cannot be published by Project Manager, Operator, Access Administrator, Audit Authority or Contributor. +8. Points-only and explicitly unpaid policies have the same Finance Authority requirement; Project Manager cannot publish them. +9. Duplicate money definition for one contribution type is rejected. +10. Duplicate points definition for one contribution type is rejected. +11. Zero or negative quantity is rejected. +12. Floating-point JSON quantity is rejected when the API requires a decimal string. +13. Invalid currency code is rejected. +14. Fractional project points are rejected. +15. Definition using another project's binding is rejected. +16. Dynamic outcome, contributor, task, skill, tier, or reputation condition is rejected. +17. Concurrent activation produces one deterministic active version. +17a. Router-level role state without a transaction-time AuthorizationDecision cannot publish or retire a version. +17b. Revoked Finance Authority fails closed before policy mutation commits. +17c. Cross-project policy or adapter-binding path substitution is denied from canonical ownership. +17d. Finance Authority can create, suspend, resume and retire a valid project binding; Project Manager and Operator cannot. + +### 28.2 Freeze tests + +18. TaskAssignment stores the active version at creation. +19. ReviewLease stores the active version at claim. +20. Later activation does not change existing assignment. +21. Later activation does not change existing lease. +22. New assignment after activation uses the new version. +23. New lease after activation uses the new version. +24. Retired frozen version remains usable at decision time. +25. Suspended binding prevents new work from freezing a dependent current policy. +26. Existing frozen work remains recognizable while binding is suspended. +26a. TaskAssignment freeze is reached only after the upstream `task.claim` authorization succeeds. +26b. ReviewLease freeze is reached only after the upstream `review.claim` authorization succeeds. +26c. Binding suspension permits a valid callback for an already-issued award but prevents new delivery and new frozen work. + +### 28.3 Contribution tests + +27. Accept creates exactly one reviewer contribution. +28. Accept creates exactly one submitter contribution. +29. Needs revision creates exactly one reviewer contribution and no submitter contribution. +30. Reject creates exactly one reviewer contribution and no submitter contribution. +31. Review decision does not change reviewer award quantity. +32. Second completed revision review creates a second reviewer contribution. +33. Released lease creates no contribution. +34. Expired lease creates no contribution. +35. Revoked lease creates no contribution. +36. Automated checker result creates no Contribution Record. +37. Contribution project, task, assignment, submission, Review, and contributor chain must match. +38. Contribution Record cannot be updated. +39. Contribution Record cannot be deleted. +40. Global contributor view returns records from authorized projects. +41. Project filter returns only that project. +41a. Every ContributionRecord creates exactly one pending ContributionEvidenceProjection in the same transaction. +41b. Every ContributionRecord creates exactly one ContributionEvidenceProjectionRequested outbox event. +41c. Contribution source_submission_artifact_digest equals the judged Submission digest. +41d. A completed-review contribution identifies the reviewed submission; it does not invent a reviewer-upload artifact. + +### 28.4 Atomicity and idempotency tests + +42. Failure creating reviewer contribution rolls back Review. +43. Failure creating submitter contribution rolls back accept Review. +44. Failure creating an award rolls back Review and all contributions. +45. Failure writing an outbox event rolls back Review, contributions, and awards. +46. External adapter outage does not roll back committed Review. +47. Exact decision replay returns existing Review, contributions, and awards. +48. Changed payload with reused decision idempotency key is rejected. +49. Concurrent decision attempts create one Review and one logical set of contributions. +50. Award uniqueness prevents duplicates under replay. +50a. Failure creating a pending evidence-projection row rolls back the Review transaction. +50b. Failure writing the evidence-projection outbox event rolls back the Review transaction. +50c. Artifact Storage outage after commit does not roll back Review, contributions or awards. +50d. Exact decision replay returns existing projection rows and creates no new projection event. + +### 28.5 Compensation evaluation tests + +51. Completed-review money award is copied exactly from frozen definition. +52. Completed-review points award is copied exactly from frozen definition. +53. Accepted-submission awards use TaskAssignment frozen version. +54. Reviewer awards use ReviewLease frozen version. +55. One contribution can create money and points awards independently. +56. Unpaid contribution creates zero awards. +57. Current project policy is never consulted instead of frozen reference. +58. Missing frozen version fails with integrity error and commits nothing. +59. Money award carries project_id and project binding. +60. Same points unit text in different projects remains separately scoped. + +### 28.6 Delivery tests + +61. CompensationFulfillmentRequested is committed with each award. +62. Dispatcher sends exact persisted payload. +63. Retry preserves event_id and idempotency_key. +64. Non-2xx adapter response leaves event unacknowledged. +65. 2xx acknowledgement marks delivery acknowledged but fulfillment pending. +66. Repeated delivery does not create another award. +67. Suspended binding pauses delivery without cancelling award. +67a. Finance Authority or operational Operator with `compensation.delivery.reconcile` may request eligible delivery reconciliation in covered scope. +67b. Project Manager, Contributor and foreign-project Admin are denied delivery reconciliation. +67c. Reconciliation reuses the existing event_id, payload, adapter binding and idempotency key and cannot mark acknowledgement or fulfillment. + +### 28.7 Callback tests + +68. Active bound service ActorProfile with `compensation.fulfillment.report` may report its own award. +69. Invalid Identity Issuer token is rejected. +70. Money adapter cannot report points award. +71. Project A adapter cannot report Project B award. +72. Unknown award is rejected. +73. Fulfilled callback requires external reference, quantity, and timestamp. +74. Fulfilled quantity must exactly equal award quantity. +75. Partial fulfillment is rejected. +76. Failed callback requires failure code. +77. Failed callback creates immutable receipt. +78. Failed followed by fulfilled is allowed. +79. Fulfilled followed by failed is rejected. +80. Exact callback replay returns existing receipt. +81. Reused external_event_id with different payload is rejected. +82. Concurrent fulfilled callbacks produce one fulfilled receipt. +83. Callback does not mutate Contribution Record. +84. Callback does not mutate CompensationAward. +85. Valid callback before delivery acknowledgement does not regress later. +85a. Human Admin, contributor, unprovisioned service actor, disabled actor and revoked identity link cannot report fulfillment. +85b. Valid service actor bound to another project or instrument is denied. +85c. Suspended binding may report an existing award it previously accepted, but cannot receive new delivery. +85d. Retired binding accepts only exact replay of an already accepted receipt. +85e. Accepted callback audit chain references the exact AuthorizationDecision. +85f. Callback request project, contributor, instrument, quantity or binding fields cannot grant or alter authority. + +### 28.8 Read and recovery tests + +86. Contribution detail composes award status without modifying canonical record. +87. Projection can be rebuilt from awards, delivery records, and receipts. +88. Reconciliation detects accepted Review missing submitter contribution. +89. Reconciliation detects Review missing reviewer contribution. +90. Reconciliation detects missing award. +91. Reconciliation detects unexpected award for unpaid policy. +92. Reconciliation detects missing fulfillment event. +93. Reconciliation detects projection/receipt mismatch. +94. Reconciliation never silently edits immutable records. +95. Binding retirement is rejected while an active policy, unfinished frozen work, or unfulfilled award depends on it. +96. Retiring the active policy without replacement clears the project active-version reference and blocks new work. +97. No cross-project Admin contributor-history or contributor-award endpoint exists in v0.1. +98. `contribution.read_self` returns only the caller's ContributionRecords and composed award summaries. +99. `contribution.read_project` filters rows, counts, totals and ages to covered canonical project scope. +100. `compensation.award.read_project` is required for project award detail. +101. Unauthorized contribution/evidence IDs do not reveal record existence. +102. Projection worker reloads canonical data rather than trusting the projection event payload. +103. Same contribution/schema version produces identical canonical bytes and digest under repeated generation. +104. LocalStorage focused tests and MinIO S3-protocol conformance pass the same evidence-projection contract used by AWS S3 production. +105. ART capability result with wrong owner, project, source identity, artifact role, media type or digest is rejected. +106. Same artifact operation identity and bytes resolves to one verified ArtifactBinding. +107. Same artifact operation identity with changed bytes returns `artifact_idempotency_conflict` and binds nothing. +108. Contribution-list responses expose only evidence status and Workstream ArtifactBinding ID, not raw provider authority. +109. Authorized evidence retrieval verifies digest and creates an attributable access audit record. +110. Human Identity Issuer token is never forwarded to Artifact Storage or compensation adapters. +111. Artifact Storage outage returns the stable evidence error without changing contribution or compensation state. +112. Reconciliation detects missing projection row, missing event, invalid binding and digest mismatch. +113. Authorized rebuild to a newer schema version retains the prior immutable bundle. +114. Only exhausted provider_unavailable verification jobs are retry eligible. +115. Equivalent retry requests return the same ART recovery-attempt and retry-job ids; the exhausted source job is unchanged. +116. Non-eligible job status or failure class is denied without mutation. +117. WS-CON never persists an artifact recovery executor, lease, generation, or provider receipt. +118. ART verification retry cannot create a second logical ArtifactBinding. +119. Continued verification failure changes no ContributionRecord or award truth. +120. Operator requester identity never becomes artifact execution authority. +120a. The same outbox/idempotency/recovery contract passes under LocalStorage and MinIO; recovery is not skipped merely because storage is local. + +--- + +## 29. Implementation Delivery Order + +### Phase 0: Dependency contracts and authority catalogue + +- confirm WS-AUTH-001 ActorProfile, AuthorizationDecision and canonical resource-context interfaces; +- register the section 5.4 granular ActionIds through an AUTH-owned chunk and + map them to the listed stable PermissionIds; +- add the service-only `outbox.dispatch` and + `compensation.fulfillment.report` PermissionIds and exact service-action + assignments through AUTH; neither is currently registered; +- reuse the canonical `artifact.verification_job.retry` and + `artifact.verification.execute` actions through ART-owned capabilities; +- extend the existing `artifact.binding.create` resource mapping to ContributionRecord for the fixed projection system actor and `contribution_evidence_bundle` role; +- confirm updated WS-REV-001 Review, ReviewFinding, FindingResolution, Submission, ReviewLease and ArtifactBinding contracts; +- freeze the shared provider-independent ART-owned contribution-evidence capability conformance contract; +- add contract tests that prevent local role-name checks, human-token forwarding and raw provider-reference disclosure. + +### Phase 1: Schema and immutable policy model + +- CompensationPolicy and version tables; +- CompensationRule; +- award definitions; +- adapter bindings; +- frozen references on TaskAssignment and ReviewLease; +- ContributionRecord; +- CompensationAward; +- FulfillmentReceipt; +- status projection; +- ContributionEvidenceProjection; +- constraints and indexes. + +### Phase 2: Policy and binding APIs + +- draft creation and validation; +- WS-AUTH permission/resource enforcement and immutable decision linkage; +- publish/activate/retire transaction; +- adapter binding lifecycle; +- explicit unpaid policy; +- concurrency guards. + +### Phase 3: Freeze integration + +- TaskAssignment freeze; +- ReviewLease freeze; +- policy-change concurrency tests; +- legacy-data migration guard; +- suspended-binding behaviour. + +### Phase 4: Atomic Review integration + +- reviewer contribution for all decisions; +- submitter contribution for accept; +- deterministic award evaluation; +- outbox events; +- pending evidence projections and evidence-projection outbox events; +- exact decision replay; +- rollback and race tests; +- removal of ContributionRecordRequested emission. + +### Phase 5: External adapter boundary + +- outbox routing; +- delivery acknowledgement; +- callback authentication and authorization; +- exact bound service-actor permission evaluation; +- immutable receipts; +- status projection; +- conflict and idempotency handling. + +### Phase 6: Contribution evidence projection and authorized retrieval + +- deterministic versioned evidence-bundle generator; +- ART-owned contribution-evidence capability with LocalStorage focused-test and MinIO S3-protocol conformance; +- verified generic ArtifactBinding creation; +- authorized evidence retrieval and attributable access audit; +- ART verification-job retry and projection reconciliation; +- no search-result disclosure before Workstream reauthorization. + +### Phase 7: Read APIs and operations + +- global and project-filtered contribution views; +- compensation summaries; +- Admin operational views; +- metrics, tracing, alerts; +- reconciliation and projection rebuild. + +### Phase 8: Live API drill + +The drill MUST prove at minimum: + +1. paid accept producing reviewer and submitter contributions; +2. needs revision producing reviewer contribution only; +3. reject producing reviewer contribution only; +4. explicit unpaid policy; +5. policy change with frozen old and new work; +6. money and project-points awards from one contribution; +7. adapter acknowledgement without fulfillment; +8. failed callback followed by fulfilled callback; +9. exact decision and callback replay; +10. adapter outage with eventual delivery; +11. database evidence for atomicity and uniqueness; +12. projection rebuild and reconciliation. +13. Finance-only policy and binding mutation with Project Manager and Operator denials; +14. exact bound service-actor callback and human/foreign-adapter denials; +15. reviewer and submitter evidence-bundle projection through the configured ART-owned contribution-evidence capability; +16. storage outage after contribution commit with canonical records unchanged; +17. authorized evidence retrieval with digest verification and attributable access; +18. ART recovery creates one attempt and new retry job while leaving the exhausted source job unchanged; +19. LocalStorage focused-test and MinIO S3-protocol conformance evidence. + +The drill report must clearly separate observed runtime proof from specification claims. + +--- + +## 30. Definition of Done + +WS-CON-001 is implemented only when: + +- every valid Review creates exactly one reviewer Contribution Record; +- accept additionally creates exactly one submitter Contribution Record; +- no other outcome creates a submitter Contribution Record; +- review compensation is identical across accept, needs_revision, and reject under the same frozen policy; +- TaskAssignment and ReviewLease freeze immutable policy versions; +- policy replacement cannot alter existing work; +- explicit unpaid policy works without missing configuration; +- Contribution Records and CompensationAwards are immutable; +- money and project points remain project-scoped; +- Contribution Records remain globally addressable and project-filterable; +- Review, contribution, awards, and outbox events commit atomically; +- one pending ContributionEvidenceProjection and projection event commit atomically with every ContributionRecord; +- every protected human/service operation uses WS-AUTH-001 with the canonical resource context and immutable decision linkage; +- Finance Authority alone manages compensation policy and adapter bindings in v0.1; +- fulfillment callbacks require the exact bound active service actor and `compensation.fulfillment.report`; +- adapter outage cannot invalidate a committed Review; +- delivery acknowledgement and fulfillment are represented separately; +- callbacks are authenticated, authorized, idempotent, and exact-quantity; +- failed may become fulfilled, while fulfilled is terminal; +- fulfillment receipts are immutable; +- read projections are rebuildable; +- provider-specific payment and points internals are absent from Workstream; +- deterministic contribution-evidence bundles are stored only through the shared ART-owned contribution-evidence capability; +- LocalStorage, MinIO, and AWS S3 satisfy the same Workstream evidence contract at their approved environment boundaries; +- public responses expose Workstream ArtifactBinding references, never raw provider authority; +- authorized evidence reads verify integrity, recheck scope and create attributable access records; +- storage failure and uncertain recovery cannot rewrite canonical Review, contribution or compensation facts; +- human tokens are never forwarded to Artifact Storage or compensation adapters; +- all conformance tests pass; +- the live drill captures authorization, API, database, event, artifact, retry, recovery, callback, and audit evidence. + +--- + +## 31. Explicitly Out of Scope + +The coding agent MUST NOT implement any of the following under WS-CON-001: + +- payment-request objects; +- payment-attempt objects; +- payment-provider SDK logic; +- bank, wallet, card, stablecoin, x402, or settlement execution; +- payout batching; +- balances or account statements; +- KYC or beneficiary onboarding; +- finance-approval workflow inside Workstream; +- provider retry or provider reconciliation logic; +- project-points ledger; +- point balances or transfers; +- Workstream-wide points; +- credits or credit ledger; +- token issuance; +- compensation tiers; +- task-specific compensation overrides; +- contributor-specific rates; +- skill- or reputation-derived rates; +- bonuses, penalties, multipliers, or dynamic formulas; +- partial fulfillment; +- currency conversion; +- reputation score calculation; +- reputation aggregate maintenance; +- automated reviewer-role grants; +- adjudication or second-level review; +- contribution reversal, voiding, or adjustment; +- retroactive policy application; +- mutation or deletion of canonical Contribution Records, awards, or receipts; +- a second contribution-specific artifact store; +- direct Local Storage, Flow Node, filesystem or CID calls outside ART-owned contribution-evidence capability; +- treating Artifact Storage as the canonical source for a ContributionRecord, Review, award or fulfillment result; +- public raw provider URLs, CIDs, filesystem paths or provider capability tokens; +- forwarding human Identity Issuer tokens to Artifact Storage or compensation adapters; +- adding a semantic-search disclosure path in v0.1; +- changing canonical contribution history because ART verification or evidence + read failed; +- Operator ownership or cross-Operator takeover of artifact-recovery execution leases; +- unrelated product architectures. + +External adapters may later connect to those systems, but this specification defines only the Workstream-facing contract. + +--- + +## 32. Future Additive Directions + +The following may be designed later through separate specifications: + +- provider-specific money adapters; +- project-points service and ledger; +- credits and other compensation instruments; +- finance approval adapters; +- task-category and compensation-tier policy rules; +- bonuses or quality incentives based on independently verified evidence; +- partial fulfillment; +- compensation adjustment and reversal records; +- adjudication and audit review; +- Workstream-wide economic reporting; +- reputation scoring and project-to-global aggregation; +- automated ProjectRoleGrant policy; +- external evidence publication. + +Future additions MUST preserve: + +- original Contribution Records; +- original CompensationAwards; +- frozen policy references; +- original fulfillment receipts; +- decision-neutral base reviewer compensation; +- project scope; +- event idempotency. + +--- + +## 33. Coding-Agent Handoff Rules + +The coding agent MUST follow these rules without reinterpretation: + +1. Implement this specification as an extension of WS-REV-001, not as a separate competing lifecycle. +2. Replace the temporary ContributionRecordRequested seam with direct atomic creation. +3. Keep the combined Review transaction short and database-local. +4. Do not call external adapters inside the Review transaction. +5. Do not use current project policy when a frozen assignment or lease version exists. +6. Do not derive reviewer compensation from Review.decision. +7. Do not create submitter contribution for needs_revision or reject. +8. Do not create contribution for an incomplete lease. +9. Do not store fulfillment state on ContributionRecord or CompensationAward. +10. Do not build payment, point-ledger, credit, or provider domain models. +11. Use exact decimal types and decimal-string API fields. +12. Enforce uniqueness in PostgreSQL, not only application code. +13. Require idempotency for Review decisions, event consumers, adapter delivery, and callbacks. +14. Treat external adapter payloads as untrusted. +15. Preserve project scope on every economic record and event. +16. Keep global contribution views as queries/read models, not a second global ledger. +17. Use append-only receipts and rebuildable projections. +18. Never silently repair immutable history. +19. Add no adjudication, appeal, reversal, or adjustment path. +20. Add no conditional compensation rule beyond exact contribution_type matching. +21. If existing code conflicts with a MUST rule, stop and raise the conflict before weakening the specification. +22. Completion requires conformance tests and a live API drill report; code compilation alone is insufficient. +23. Use WS-AUTH-001 AuthorizationService for every protected action; do not add local role-name checks or a second permission system. +24. Finance Authority alone manages compensation policy and adapter bindings in v0.1. +25. Require `compensation.fulfillment.report` from the exact frozen adapter service actor; no human role can satisfy a callback. +26. Load canonical resource ownership before authorization and revalidate sensitive writes inside the transaction. +27. Create one pending ContributionEvidenceProjection and event with every ContributionRecord. +28. Generate evidence asynchronously from canonical committed records; never trust the projection event as independent truth. +29. Use the shared ART-owned contribution-evidence capability and generic ArtifactBinding contract; do not import provider internals or create another byte store. +30. Never forward human tokens to Artifact Storage or compensation adapters. +31. Never expose raw provider CIDs, paths, URLs, credentials or search candidates as authority. +32. Treat LocalStorage as focused dev/test, MinIO as local/CI S3 protocol proof, and AWS S3 as production; keep R2 and Flow Node deferred. +33. Keep artifact projection/retrieval failure separate from contribution and compensation validity. +34. Delegate artifact recovery to ART: one recovery attempt creates a new retry verification job, exact replay returns the same ids, and the source job never changes. +35. Link policy, binding, callback, read, recovery and projection operations to immutable AuthorizationDecision and audit records without storing bearer tokens. +36. Register granular ActionIds in WS-AUTH-001 and map them to the canonical stable PermissionIds, including `compensation.policy.manage`, `compensation.adapter_binding.manage`, `operations.reconcile.run`, `operations.outbox.retry`, and `review.decision`; do not treat those PermissionIds as removed aliases. + +--- + +## 34. Final Implementation Contract + +The complete v0.1 contract is: + +> Workstream records every valid completed Review as one immutable reviewer contribution, regardless of decision. An accepted Review additionally records one immutable submitter contribution. Each contribution is evaluated against compensation terms frozen before work began. Workstream creates immutable, project-scoped money or project-points awards and emits transactional fulfillment instructions. Exact bound service actors perform provider and ledger work and report immutable fulfilled or failed results. In the same canonical transaction, Workstream schedules one deterministic evidence-bundle projection per contribution; after commit, the shared ART-owned contribution-evidence capability retains and verifies the bundle under a Workstream ArtifactBinding. WS-AUTH-001 governs every human and service action. Contribution and award history never changes; API views compose fulfillment and evidence status from append-only facts and rebuildable projections without exposing raw provider authority. From d9fe3e574af6e4122804eb3b1f0dc61f218b2ffa Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Wed, 15 Jul 2026 18:09:38 +0100 Subject: [PATCH 02/22] Bind WS-CON plan review evidence --- .../STATUS.md | 23 +++-- ...S-CON-001-PLAN-internal-review-evidence.md | 96 +++++++++++++++++-- 2 files changed, 102 insertions(+), 17 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 70e0c703..da1d5bfb 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,9 +2,11 @@ ## Current status -Planning amendment under internal review. Application code is unchanged. The supplied revised Markdown/PDF, -original archival PDF, current backend, active docs, parallel WS-AUTH -authorization catalogue, and parallel WS-REV plan have been mapped. +Base planning and the latest merged AUTH-07A/active REV-12A delta +reconciliation have passed internal re-review. Application code is unchanged. +The reconciled working Markdown transcription, supplied generation-2 PDF, +original archival PDF, current backend, active docs, merged WS-AUTH +authorization catalogue, and active parallel WS-REV plan delta have been mapped. The candidate cannot be canonically adopted as written because it conflicts with `/api/v1`, the ActionId/PermissionId model, artifact-storage ownership and @@ -13,14 +15,14 @@ providers, existing versioned `Submission`, and active payment architecture. ## Active chunk `WS-CON-001-PLAN` only. The human approved complete PaymentPolicy removal on -2026-07-15; the resulting plan amendment requires reviewer closure. No -implementation is active. +2026-07-15. The latest AUTH/REV reconciliation and scanner-contract repair are +internally reviewed and bound to local evidence. No implementation is active. ## Chunk status | Chunk | Status | Branch | PR | Notes | |---|---|---|---:|---| -| `WS-CON-001-PLAN` | D2 removal amendment review pending | `codex/ws-con-001-plan` | - | Prior review predates the approved removal direction. | +| `WS-CON-001-PLAN` | Internally reviewed | `codex/ws-con-001-plan` | - | Approved D2 removal is split into 05A/05B; the reviewed refresh records merged AUTH-07A/ADR 0014 foundations, exact archive-scanner ownership, and the active non-consumable REV-12A working delta atop `3e09e99`. | | `WS-CON-001-01` | Proposed | - | - | No runtime work. | | `WS-CON-001-02A` through `11` | Proposed | - | - | Each requires separate explicit start; REV-13 owns final activation. | @@ -29,19 +31,20 @@ implementation is active. | Blocker | Owner | Next action | |---|---|---| | Active-contract/archive handling approval | Human | Approve D1. | -| PaymentPolicy/CompensationPolicy authority relationship | Human | D2 approved: complete removal; only legacy reset/backfill rule remains. | +| Legacy PaymentPolicy/task/assignment row handling | Human | Choose pre-production rebuild or an explicit classified backfill before 05A/05B; PaymentPolicy removal itself is approved. | | Exact WS-CON action registrations plus callback and shared-outbox service permissions | WS-AUTH + human | Approve dependency proposal; implement only in AUTH-owned chunk. | | Contribution evidence typed capability | WS-ART + human | Create and approve the named `WS-ART-001-CON-EVIDENCE` prerequisite before CON-09A. | | ReviewLease/Review contracts | WS-REV | Merge owning persistence/behavior chunks at declared gates. | | Shared outbox | WS-CON-001-02A/B after approval | Land persistence and dispatcher before asynchronous integration. | -| Current REV-13 scope omits the joint CON surface/docs/drill | WS-REV owner + human | Incorporate and review `JOINT_RELEASE_HANDOFF.md`; both surfaces stay hidden until then. | -| Exact-head evidence gate requires a committed candidate | Primary agent after human publication direction | Do not claim PR readiness; commit only when authorized, rerun reviewers, and require the gate to pass. | +| REV-12A/13 joint scope is content-reviewed only as an uncommitted sibling delta atop `3e09e99` | WS-REV owner + human | Commit the exact repaired snapshot, run commit-bound freshness review, refresh against trusted main without losing the handoff, and merge; both surfaces stay hidden until its contract and later implementation gates land on trusted `main`. | +| REV-12A draft assigns shared-outbox claim wording to the CON handler | WS-REV owner | Consume an already-claimed command and return a typed outcome; preserve CON-02B as sole outbox transition owner before sibling review/merge. | +| External publication | Human | Push or open a PR only after explicit direction; local review evidence does not authorize publication. | ## Follow-ups | Item | Source | Priority | |---|---|---:| -| Re-read AUTH-07A/07B and later merged catalogue at each activation. | Parallel worktree | P1 | +| Re-read merged AUTH-07A catalogue plus later AUTH-07B/kernel/grant/service-actor state at each activation. | Trusted `main` | P1 | | Re-read REV contracts at CON-03C/06/07 activation. | Parallel worktree | P1 | | Re-read ART v2/capability ports before CON-09A. | ADR 0013/spec | P1 | | Decide pre-production row rebuild vs classified backfill. | Migration risk | P1 | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index c95cb35a..ed84cc04 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -1,5 +1,84 @@ # Internal Review Evidence: WS-CON-001-PLAN +## 2026-07-15 Final Trusted-Main And Parallel-Dependency Review + +This addendum is the current authoritative review state and supersedes older +statements below about D2, AUTH-07A merge status, REV joint-release adoption, or +an uncommitted planning candidate. D2 is approved: +`CompensationPolicyVersion` completely supersedes `PaymentPolicy`; only the +legacy-row reset-versus-classified-backfill rule remains a human gate. + +Reviewed code SHA: ebdd21d231207845d44832a502de9dc56f237fd9 + +Reviewed planning-tree SHA-256: +`c3a82c1d5db19038709ff844a3bbde6cc77b21d525f408f2768d71c34883181d` + +The tree digest excludes this evidence file and is reproduced from the +initiative directory with: + +```bash +find . -type f ! -path './reviews/WS-CON-001-PLAN-internal-review-evidence.md' -print0 | sort -z | xargs -0 sha256sum | sha256sum +``` + +Reviewed at: 2026-07-15T17:08:45Z + +Reviewer run IDs: architecture/senior/reuse=`/root/plan_arch_senior`; +QA/test/product/ops/docs=`/root/plan_qa_product_docs`; +security/auth/privacy=`/root/plan_security_auth` + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | The chunk map, ownership seams, stop conditions, and long-term boundaries are coherent. | +| QA/test | PASS | None | Gates, races, failure cases, evidence retention, and the exact scanner regression contract are executable. | +| security/auth | PASS | None | Merged AUTH has 74 PermissionIds/50 ActionIds; 23 WS-CON actions and two service permissions remain absent/proposed; all 12 reused permissions exist. | +| product/ops | PASS | None | Complete PaymentPolicy removal, legacy-row gate, fulfillment lifecycle, drain, and joint release behavior are explicit. | +| architecture | PASS | None | CON-02B solely owns outbox transitions; CON owns narrow ports; REV supplies only hidden release-control composition. | +| CI integrity | N/A - with approved reason | None | This reviewed delta changes planning Markdown only; CON-01 itself requires CI-integrity review when its script/test files change. | +| docs | PASS | None | Source provenance, active/archive precedence, current REV status, and PaymentPolicy removal are truthful. | +| reuse/dedup | PASS | None | Claim validation, drain observation, and lifecycle fences reuse sole owners through narrow ports without repository duplication. | +| test delta | N/A - with approved reason | None | No test file changes in this planning delta; CON-01 requires test-delta review for its planned gate regression. | + +Open sub-agent sessions: none + +Valid findings addressed: yes + +- Rebased onto trusted `main` `e9d72a1`, including merged ADR 0014 and AUTH-07A + catalogue/audit foundations, and validated exact AUTH counts/mappings. +- Preserved complete PaymentPolicy removal in split semantic-cutover and physical + removal chunks; no advisory, compatibility, or execution fallback survives. +- Made merged REV-02 exact `Submission.task_assignment_id` lineage a hard + CON-05A prerequisite. +- Preserved CON-02B as the sole OutboxEvent claim/retry/finalization owner. A + feature handler only validates immutable claim generation through + `OutboxClaimValidationPort`, never locks or mutates OutboxEvent, and returns a + typed outcome after CON work. +- Added canonical lifecycle-fence lock ordering, durable pre-I/O state, and the + prohibition on provider I/O under a database transaction, lifecycle fence, + or OutboxEvent lock. +- Assigned `FulfillmentDispatchFence`, `FulfillmentCallbackFence`, and + `FulfillmentLifecycleDrainObservationPort` to CON-owned chunks while limiting + REV-12A to hidden composition and REV-13 to sole activation/live drill. +- Recorded the content-reviewed but dirty REV snapshot atop `3e09e99` as + non-consumable. Its stale handler-claim wording must be repaired, committed, + commit-freshness reviewed, refreshed, and merged before use. +- Made CON-01 own the exact authorization-scanner history entry created by its + hash-proven archival rename plus fail-closed tests. The cross-scanner equality + assertion subtracts only that named auth-only path and separately proves the + unchanged artifact scanner already excludes reference specs by prefix. +- Preserved AUTH ownership: WS-CON proposes identifiers and supplies resource + facts/guards only; it does not implement the authorization service. + +Deterministic evidence passed: Markdown links for 38 changed Markdown files, +general stale wording, artifact-contract state, loop-memory state, 71 agent-gate +tests, reference hashes, and `git diff --check`. The authorization stale-doc +scan continues to flag ten human-worker vocabulary occurrences only in the +explicitly non-canonical working transcription. CON-01 now owns its exact +byte-preserving archive rename/classification and the reconciled active spec; +this is not a waiver for an active document. + +Application/runtime code changed: no. The original PDF deletion remains an +unstaged user-worktree change and was excluded from both reviewed commits. + ## 2026-07-15 End-to-End Reference Reconciliation Addendum The supplied generation-2 Markdown was audited against AUTH head `3ab25cf`, @@ -47,7 +126,7 @@ changed. | senior engineering | PASS AFTER FIXES | None | Cross-initiative ownership, PR sizing, reusable infrastructure, and executable contracts repaired. | | QA/test | PASS AFTER FIXES | None | Traceability, isolated PostgreSQL evidence, separate subsystem coverage, retained attempts, and release handoff repaired. | | security/auth | PASS AFTER FIXES | None | Proposed action/resource contracts, service actor, binding states, rate controls, retirement and privacy repaired. | -| product/ops | SUPERSEDED | Re-review required | This row predates approved complete PaymentPolicy removal and the end-to-end reference reconciliation. | +| product/ops | PASS AFTER FIXES | None | Current re-review confirms complete PaymentPolicy removal, the open legacy-row gate, REV-02 ordering, fence ownership, and joint activation operations. | | architecture | PASS AFTER FIXES | None | REV ownership, sole activation, outbox/audit/factory boundaries and ART/AUTH ownership are coherent. | | CI integrity | N/A - with approved reason | None | Planning Markdown only; no workflow, script, dependency, test, or coverage gate changed. | | docs | PASS AFTER FIXES | None | Archive provenance, active-doc inventory and generated-companion release ownership are explicit. | @@ -62,8 +141,10 @@ changed. exact evidence-driven release handoff without editing the sibling worktree. - Split shared outbox truth from its dispatcher, added a shared lifecycle-audit participant owner, and kept feature handlers separate. -- Reconciled trusted-main 73 PermissionIds versus unmerged AUTH-07A 74/50 state; - every WS-CON ActionId remains proposed with exact target/principal/facts/ +- At the original pre-merge review point, reconciled trusted-main 73 + PermissionIds versus AUTH-07A's 74/50 candidate state. The current addendum + records AUTH-07A merged through `e9d72a1`; every WS-CON ActionId remains + proposed with exact target/principal/facts/ guard/revalidation/registry/resource/activation ownership. - Added canonical service ActorProfile binding, exact callback assignment, actor/link/binding state distinctions, per actor+binding rate control, and @@ -120,13 +201,14 @@ Results: ## Remaining Risks -- D1/D2/D7/D8 and the callback PermissionId require explicit human approval. +- D1/D7/D8 and the callback/outbox service PermissionIds require explicit human + approval. D2 removal is approved; only legacy-row handling remains open. - Original PDF disposition remains a pre-existing user-worktree concern; generation-2 PDF preservation and working-Markdown provenance remain CON-01 gates. -- AUTH, ART and REV prerequisites are unmerged. The WS-REV owner must adopt and - internally review `JOINT_RELEASE_HANDOFF.md` before either public surface can - activate. +- AUTH, ART and REV prerequisites are unmerged. The active REV working delta + incorporates `JOINT_RELEASE_HANDOFF.md` but must become a branch-reachable + reviewed commit, rebase, and merge before either public surface can activate. - Exact migration numbers, merged symbols, production adapter/provider and live values must be refreshed at each approved implementation chunk. - This uncommitted reviewed plan still requires a committed exact-head review From 6a03546c3b31536b857fcd017e24706238a98c5f Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Wed, 15 Jul 2026 21:21:59 +0100 Subject: [PATCH 03/22] Reconcile WS-CON plan with AUTH-07B --- .../ARTIFACT_STORAGE_HANDOFF.md | 34 ++- .../AUTHORIZATION_HANDOFF.md | 195 +++++++++++++++--- .../CHUNK_MAP.md | 47 +++-- .../CONFORMANCE_MATRIX.md | 1 + .../DECISIONS.md | 38 +++- .../DISCOVERY.md | 28 ++- .../INTENT.md | 10 +- .../JOINT_RELEASE_HANDOFF.md | 46 +++-- .../PLAN.md | 103 ++++++--- .../RISKS.md | 3 + .../SOURCE_MANIFEST.md | 39 ++-- .../STATUS.md | 21 +- ...-CON-001-01-canonical-contract-adoption.md | 6 + ...WS-CON-001-02B-shared-outbox-dispatcher.md | 19 ++ ...-001-04A-hidden-adapter-binding-service.md | 26 ++- ...-04B-hidden-compensation-policy-service.md | 19 +- ...policy-semantic-cutover-and-task-freeze.md | 11 +- ...001-06-review-lease-compensation-freeze.md | 7 +- ...c-review-contribution-award-participant.md | 7 +- ...-001-08A-outbound-compensation-delivery.md | 6 + ...ON-001-08B-inbound-fulfillment-callback.md | 10 +- ...CON-001-09A-contribution-evidence-write.md | 26 +++ ...B-authorized-contribution-evidence-read.md | 7 +- ...01-10A-contribution-award-product-reads.md | 7 +- ...1-10B-operations-reconciliation-rebuild.md | 10 +- .../WS-CON-001-11-hidden-release-readiness.md | 7 +- ...PLAN-contribution-compensation-planning.md | 6 +- 27 files changed, 567 insertions(+), 172 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md index 78ec7fc4..706f60d3 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md @@ -10,10 +10,17 @@ projection status, canonical owner facts, and disclosure guards. ## Required typed capabilities -- `ContributionEvidenceWritePort.write(request)` accepts contribution/project/ - schema identity, media type, expected digest, stable idempotency identity, and - bounded deterministic bytes or byte source. It returns bounded verified - ArtifactBinding/receipt data and never a provider reference. +- `ContributionEvidenceWritePort.write(request)` accepts the caller + `AsyncSession`, D10 prepared handle, contribution/project/schema identity, + media type, expected digest, stable idempotency identity, and bounded + deterministic bytes or byte source. In durable Transaction A it locks ART + admission state after AUTH and CON locks, composes the full typed context, + completes the handle's single final AUTH evaluation, stages the decision and + admission/put-attempt continuation, and never commits or performs provider + I/O. After the caller commits, only ART-owned continuation/executor authority + may perform provider I/O, verification and binding. The high-level capability + eventually returns bounded verified ArtifactBinding/receipt data and never a + provider reference. - `ContributionEvidenceReadPort.read(request)` accepts a Workstream ArtifactBinding id and already-authorized contribution context. It verifies binding/digest and returns bounded bytes or a stream, never provider authority. @@ -26,11 +33,24 @@ projection status, canonical owner facts, and disclosure guards. ## Authorization dependency AUTH registers `artifact.contribution_evidence.binding.create` mapped to the -existing `artifact.binding.create` PermissionId. ART provisions the fixed -service actor and activates exact contribution/project/role/schema/digest facts. -Public reads continue to use `contribution.read_self` or +existing `artifact.binding.create` PermissionId, reuses the canonical fixed +`workstream.artifact.binding` ActorProfile/link, adds only this exact action to +that principal's closed assignment set, adds the typed service evaluator and +prepared `T` protocol, and alone changes availability to active. A new generic +CON/ART worker identity or broader artifact assignment is not allowed without a +reviewed AUTH amendment. ART owns the canonical contribution/project/role/ +schema/digest resource composer and capability behavior consumed by that +evaluator. Public reads continue to use `contribution.read_self` or `contribution.read_project`; there is no `artifact.retrieve` action. +CON prepares the AUTH handle from a server-resolved contribution/evidence-role +target before it locks its projection/contribution rows. It passes only that +opaque handle, canonical CON facts and deterministic bytes through the typed +port. ART then locks its own admission rows, adds ART-owned facts and completes +the one final evaluation in Transaction A. Missing/reused/mismatched handles or +fact drift fail before any durable provider attempt is executable. CON never +loads an ART row, composes ART admission facts or calls the evaluator itself. + ## Provider and proof boundary LocalStorage is focused dev/test, MinIO is local/CI S3-protocol proof, AWS S3 is diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md index 9789d6c9..1c1d4190 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -2,28 +2,110 @@ ## Status and ownership -Every ActionId below is **proposed and currently absent**. AUTH-07A commit -`3ab25cf` merged to trusted `main` through `e9d72a1`; the canonical catalogue -now contains 74 PermissionIds and 50 planned non-WS-CON ActionIds. Its additive -permission is `review.queue.override`. Neither proposed WS-CON service-only -PermissionId is registered, and none of the proposed WS-CON ActionIds is in the -merged closed enum. - -AUTH owns ActionId/ActionOwner registration, PermissionId registration, -typed/PostgreSQL parity, grants, service ActorProfiles and exact service-action -assignments, and kernel behavior. The feature owner below owns canonical -resource composition, lifecycle guards, transaction-time revalidation, -behavioral proof, and activation after AUTH registration merges. WS-CON must not -edit AUTH persistence, catalogue, grant, or kernel files. +Every WS-CON-specific ActionId below is **proposed and currently absent**. +Trusted `main` `90eca12` includes AUTH-07B. The canonical catalogue now contains +74 PermissionIds and 50 non-WS-CON ActionIds: only +`actor.profile.read_self` and `actor.profile.update_self` are active; the other +48 are planned. Neither proposed WS-CON service-only PermissionId is registered, +and none of the 23 proposed WS-CON ActionIds is in the merged closed enum. + +AUTH-07B also makes the runtime boundary concrete. `AuthorizationService` +currently evaluates only the two actor-self actions; +`AuthorizationResourceContext` accepts only actor-self and system variants; +`MatchedAuthorityKind` contains only `actor_self`; and the current FastAPI +composition dependency rejects service subjects. Registering an ActionId as +planned is therefore intentionally insufficient: every WS-CON surface would +continue to fail with `action_unavailable` until AUTH supplies its typed +context, evaluator, principal/grant or exact service assignment, transaction +protocol, and active availability. + +AUTH owns ActionId/ActionOwner and PermissionId registration, +typed/PostgreSQL/audit parity, availability transitions, central evaluator +dispatch, matched-authority types, grant loading, actor/link/grant +revalidation, service ActorProfiles, exact service-action assignments, and the +request/worker/callback authorization composition roots. WS-CON owns canonical +product-row loading, construction of AUTH-approved typed resource facts, +product lifecycle guards, and feature behavior proof. WS-CON never edits AUTH +persistence, catalogue, runtime, grant, evaluator, or kernel files and never +changes an action from planned to active. + +## Required AUTH delivery contract + +Authorization delivery uses two AUTH-owned checkpoints around one feature-owned +chunk. Before the feature chunk starts, an AUTH registration checkpoint provides +the planned identifier/mapping, typed context contract, principal prerequisites +and prepared protocol. The feature chunk then lands hidden authorization-ready +behavior and its canonical resource composer while the action still fails +closed. Only after that feature commit is merged may an AUTH activation +checkpoint integrate the evaluator, prove end-to-end behavior and change +availability. The feature is not executable production authorization between +those checkpoints. + +Across those checkpoints AUTH must provide all applicable items below: + +1. Register the exact ActionId, ActionOwner, PermissionId mapping and audit/SQL + parity. Add only the two approved new PermissionIds, + `outbox.dispatch` and `compensation.fulfillment.report`; all other rows reuse + the existing PermissionId in the table. +2. Add closed typed resource-context variants for the target families below and + extend the decision resource type without accepting generic dictionaries, + client-supplied grants, raw PermissionIds, or CON persistence objects. +3. Replace the current two-action-only evaluator branch with an explicit closed + evaluator registry or equivalent AUTH-owned dispatch. No runtime plugin + discovery, service locator, fallback allow path, CON repository import, or + action string construction is permitted. +4. Extend matched authority for exact actor-self, AdminRoleGrant, + ProjectRoleGrant, and service-action-assignment authority as applicable. + AUTH-08 grant definitions, AUTH-09 service actor/assignment truth, and + AUTH-10 project contributor grants must be merged before dependent + evaluators activate. +5. For `T` mutations, provide one caller-session-bound prepared-authorization + protocol. It accepts the action plus a server-resolved preliminary target, + locks/revalidates AUTH actor/link/grant or service-assignment rows first, + returns an opaque non-serializable handle bound to the request, session, + actor, action and target, then evaluates exactly once against the final + typed context recomposed from locked product rows. This preserves the PLAN + lock order and stages one decision without AUTH committing. A prepare-time + lifecycle/availability/authority denial terminates with that one denial and + returns no handle; a successful prepare stages no allow until final + evaluation. Missing, + mismatched, reused, cross-session or cross-action handles fail closed. +6. For `Q` reads, retain request-scoped `require(action_id, + typed_resource_context)` while loading canonical authority and applying + pre-filter/concealment rules. No decision or grant cache survives a request. +7. Add a service-capable composition dependency for fixed workers and bound + callbacks. Human grants never satisfy a service-only action, service + assignments never imply a human role, and suspended/revoked/deactivated + actor or link state fails closed. +8. Change availability to active only after the named CON/ART resource composer + and hidden behavior implementation is merged. The AUTH activation change + owns central integration tests against that exact merged implementation. + Startup parity must reject missing or extra + identifiers, mappings, evaluators, service identities, assignments, or + active actions without executable behavior. + +These are AUTH implementation requirements, not authorization behavior that a +CON chunk may reproduce locally. A CON feature chunk may use an explicit test +decision/fake below its authorization boundary to prove domain behavior, but no +test or production fallback may make a planned action executable through the +real kernel. + +The current WS-AUTH chunk map has no WS-CON registration or activation chunks. +The AUTH owner must first add and internally review bounded chunk contracts for +the registration checkpoint, the shared prepared protocol if not delivered by +an earlier AUTH foundation, and each activation wave below. Do not silently +fold WS-CON permissions/actions into AUTH-08 through AUTH-16 or an unrelated +feature PR without an allowed-file/acceptance/reviewer amendment. ## Proposed closed handoff -`T` means authority must be revalidated in the same caller transaction after -the relevant canonical rows are locked. `Q` means request-scoped authorization -is sufficient because the operation is read-only, but resource facts still come -from canonical rows. +`T` means the AUTH-owned prepared protocol locks authority first and the feature +then evaluates against facts recomposed from its locked product rows in the same +caller transaction. `Q` means request-scoped authorization is sufficient +because the operation is read-only, but resource facts still come from +canonical rows. -| Proposed ActionId | PermissionId | Target | Candidate principal | Canonical facts/mandatory guards | Revalidation | Registry / activation owner | +| Proposed ActionId | PermissionId | Target | Candidate principal | Canonical facts/mandatory guards | Revalidation | AUTH activation / feature resource owner | |---|---|---|---|---|---:|---| | `contribution.read_self` | existing `contribution.read_self` | ContributionRecord | human contributor | contribution, project, contributor; caller is exact contributor; minimal self disclosure | Q | AUTH / CON-09B; reused by CON-10A | | `contribution.read_project` | existing `contribution.read_project` | Project contribution collection | Project Manager, Finance Authority, Operator/Audit as separately eligible | exact project role/operational scope; pre-filtered pagination and concealment; Reviewer is self-only and gains no project-wide history | Q | AUTH / CON-09B; reused by CON-10A | @@ -46,8 +128,46 @@ from canonical rows. | `audit.read` | existing `audit.read` | WS-CON audit projection | Audit/Operator candidate | exact project/ops scope; redaction and pagination; append-only truth | Q | AUTH / CON-10B | | `audit.export` | existing `audit.export` | bounded WS-CON audit export | Audit candidate | exact scope, purpose, maximum range, redaction, export evidence | T | AUTH / CON-10B | | `compensation.fulfillment.report` | **new service-only `compensation.fulfillment.report`** | frozen CompensationAdapterBinding + Award | exact bound service ActorProfile only | actor/link/action assignment active; route identity, award, project, instrument, frozen binding and receipt state all match | T | AUTH / CON-08B | -| `outbox.dispatch` | **new service-only `outbox.dispatch`** | claimed shared OutboxEvent | fixed `workstream.outbox.dispatcher` ActorProfile only | current claim/lease/generation; immutable event, payload and idempotency identity; handler side effects occur only under this claimed command | T | AUTH + shared outbox / CON-02B prerequisite; consumed by CON-08A | -| `artifact.contribution_evidence.binding.create` | existing `artifact.binding.create` | ContributionRecord evidence role | fixed ART/CON worker service actor | exact contribution/project/role/schema/digest; ART admission/verification receipt; no raw provider ref | T | AUTH + ART / ART prerequisite then CON-09A | +| `outbox.dispatch` | **new service-only `outbox.dispatch`** | claimed shared OutboxEvent | fixed `workstream.outbox.dispatcher` ActorProfile only | current claim/lease/generation; immutable event, payload and idempotency identity; handler side effects occur only under this claimed command | T | AUTH / CON-02B shared-outbox prerequisite; consumed by CON-08A | +| `artifact.contribution_evidence.binding.create` | existing `artifact.binding.create` | ContributionRecord evidence role | existing fixed `workstream.artifact.binding` service ActorProfile only | exact contribution/project/role/schema/digest; ART admission/verification receipt; no raw provider ref | T | AUTH / ART capability + CON-09A composer | + +## Existing product-action dependency + +`task.claim` is not one of the 23 WS-CON-specific actions, but current trusted +`main` contains only its PermissionId; no `ActionId.TASK_CLAIM` exists. Before +CON-05A can integrate compensation freezing, AUTH-13 or a reviewed AUTH-owned +successor must register and activate ActionId `task.claim` mapped to existing +PermissionId `task.claim`, using the canonical project/task target, +exact-project submitter-or-both grant, actor/link/grant revalidation, and the +prepared `T` protocol. CON-05A adds only the compensation-policy product guard +and frozen-version participant to the already authorized task-owned claim +transaction. + +Likewise, registered review actions such as `review.claim` and +`review.decision` remain unusable while planned. Their sequence is AUTH +registration/typed/prepared contract -> CON capability/participant -> REV +hidden resource composition and final-context integration while the real kernel +still denies -> AUTH evaluator integration/activation. Only then may the +already-merged hidden composition execute outside explicit test boundaries. +WS-CON and WS-REV do not activate them. + +## Activation waves + +| Authority family | AUTH registration checkpoint | Feature-owned hidden implementation | AUTH activation must merge before | +|---|---|---|---| +| Shared-outbox service | planned `outbox.dispatch`, new permission, typed contract, fixed actor/link/assignment and prepared protocol | CON-02B dispatcher integrates the prepared seam but remains disabled/fail-closed | CON-08A or any dispatcher enablement | +| Binding management | planned binding read/create/suspend/resume actions, typed contracts, applicable grant definitions and prepared protocol; retire may be registered but stays planned; plus the planned callback ActionId/new PermissionId and active callback service actor/link/exact assignment needed to validate a binding (the callback action remains unavailable) | CON-04A read/create/suspend/resume only | CON-04B; retire activates only in the operations wave after CON-10B | +| Policy management | planned policy actions, typed contracts, Finance grant definition, prepared protocol | CON-04B | CON-05A | +| Task claim | planned `task.claim` registration plus typed/prepared contract | AUTH-13 task resource composer, guards and behavior | AUTH evaluator/activation in AUTH-13 or a reviewed successor before CON-05A | +| Review authority | existing planned `review.claim`/`review.decision` plus typed/prepared prerequisites | CON-06 + REV-06 hidden claim composition; CON-07 + REV-10 hidden decision composition, all real-kernel fail-closed | any production execution, CON-11 or REV-13 | +| Bound callback service | callback identity/action registration already required before CON-04A; typed callback context and prepared protocol complete before CON-08B | CON-08B | CON-11 | +| Contribution evidence service | planned evidence-binding action/service contract, prepared protocol plus ART capability | ART prerequisite + CON-09A composer/handler integrates the prepared seam | CON-11 | +| Contribution reads | planned self/project read actions and typed contexts | CON-09B | CON-10A | +| Award reads | planned self/project award actions and typed contexts | CON-10A | CON-10B | +| Operations | planned retire/reconcile/status/rebuild/audit actions, typed contexts, grants and prepared protocol | CON-10B | CON-11 | + +No row authorizes public route registration. CON-11 proves the hidden action +manifest and REV-13 remains the sole joint public activation owner. ## Adapter service-identity invariant @@ -58,6 +178,13 @@ non-secret route identity. AUTH creates the exact AdminRoleGrant or ProjectRoleGrant records can never satisfy this action, and WS-CON never fabricates such grants. +That callback identity is a binding-creation prerequisite, not an executable +callback. Before CON-04A, AUTH must register the planned ActionId and new +PermissionId and create an active service ActorProfile/link with the exact +assignment so CON can validate canonical identity. The action remains planned +and fail-closed until CON-08B supplies the callback composer/behavior and the +later AUTH activation gate passes. + Under the canonical lock order a callback revalidates actor state, identity-link state, exact service-action assignment, route identity, award, project, instrument, frozen binding, binding state, and delivery/receipt state. Controls @@ -79,9 +206,27 @@ distinct from adapter-binding suspension. ## Shared-outbox and ART prerequisites CON-08A is an outbox handler, not an independently authorized compensation -command. The shared-outbox owner must register and provision `outbox.dispatch` -for the fixed dispatcher before CON-08A activates; human +command. After CON-02B merges its hidden dispatcher, AUTH must integrate and +activate `outbox.dispatch` for the fixed dispatcher before CON-08A activates; +human `operations.outbox.retry` authority can request recovery but can never execute -delivery. CON-09A similarly consumes a narrow ART-owned capability after ART -registers `artifact.contribution_evidence.binding.create`; CON never receives a -raw storage port or an artifact-recovery execution authority. +delivery. CON-09A similarly consumes a narrow ART-owned capability after AUTH +registers the planned `artifact.contribution_evidence.binding.create` and adds +that exact assignment to the existing fixed `workstream.artifact.binding` +principal; a separately invented evidence worker is forbidden absent a reviewed +AUTH amendment. AUTH may activate it only after the ART capability and CON +composer merge. CON never receives a raw storage port or an artifact-recovery +execution authority. + +Both service mutations use D10 at their owning call sites. CON-02B prepares +`outbox.dispatch` from a server-resolved event target before locking the claimed +OutboxEvent, then evaluates exactly once against final locked claim facts. +CON-09A prepares the evidence-binding action before locking its CON-owned +projection/contribution rows, then passes the handle and canonical CON facts to +the narrow ART capability. ART locks/composes its own admission facts and +performs the handle's one final evaluation in durable Transaction A before that +transaction stages admission/put-attempt state and commits; CON never imports +ART persistence or evaluates ART facts. Provider I/O and verification occur +only after Transaction A commits under ART-owned continuation/executor +authority. Later AUTH activation integrates the evaluators against those seams; +it does not retrofit or edit feature code. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md index 670d94d8..cd74df22 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -11,29 +11,29 @@ and same-invocation coverage evidence defined in `PLAN.md`. | Chunk | Title | Risk | Gate | Status | |---|---|---:|---|---| -| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Internally reviewed; human approval pending | +| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Reviewed; human approval gate | | `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Plan/human decisions approved | Proposed | | `WS-CON-001-02A` | Shared Transactional Outbox Persistence | L1 | 01; event ownership approved | Proposed | -| `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; worker/operations contract and AUTH `outbox.dispatch` registration approved | Proposed | +| `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; worker/operations contract; AUTH planned `outbox.dispatch` registration/context/fixed actor/assignment/prepared protocol merged; dispatcher remains disabled pending later AUTH activation | Proposed | | `WS-CON-001-02C` | Shared Lifecycle Audit Participant | L1 | 02B; existing AuditEvent contract refreshed | Proposed | | `WS-CON-001-03A` | Compensation Adapter-Binding Persistence | L1 | 02C; migration head refreshed | Proposed | | `WS-CON-001-03B` | Compensation Policy Persistence | L1 | 03A; legacy-data rule | Proposed | | `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; merged REV-03 and REV-04 exact FK targets | Proposed | | `WS-CON-001-03D` | Delivery, Receipt, And Status Persistence | L1 | 03C | Proposed | -| `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; AUTH registrations/kernel merged | Proposed | -| `WS-CON-001-04B` | Hidden Compensation-Policy Service | L1 | 03B,04A; AUTH registrations/kernel merged | Proposed | -| `WS-CON-001-05A` | PaymentPolicy Semantic Consumer Cutover And Task Freeze | L1 | 04B; merged REV-02 exact `Submission.task_assignment_id` lineage; D2 approved; legacy rule; AUTH task-claim cutover | Proposed | +| `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; AUTH planned binding registrations/typed contracts/grants/prepared protocol plus planned callback action/new permission and active callback actor/link/exact assignment merged; callback remains unavailable | Proposed | +| `WS-CON-001-04B` | Hidden Compensation-Policy Service | L1 | 03B,04A; post-04A AUTH binding activation merged; AUTH planned policy registrations/typed contracts/grants/prepared protocol merged | Proposed | +| `WS-CON-001-05A` | PaymentPolicy Semantic Consumer Cutover And Task Freeze | L1 | 04B; merged REV-02 exact `Submission.task_assignment_id` lineage; D2 approved; legacy rule; AUTH `task.claim` registration/evaluator/prepared protocol/activation | Proposed | | `WS-CON-001-05B` | PaymentPolicy Physical Schema Removal | L1 | 05A; zero-consumer scan; removal migration approval | Proposed | -| `WS-CON-001-06` | Review-Lease Freeze Capability | L1 | REV-03 schema; 05B; exact caller facts stable | Proposed | -| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D; REV-09B; shared audit/outbox | Proposed | -| `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07; 02B; ADR 0014 adapter foundation; joint lifecycle-fence port contract | Proposed | +| `WS-CON-001-06` | Review-Lease Freeze Capability | L1 | REV-03 schema; 05B; AUTH planned `review.claim` typed/prepared contract; exact caller facts stable | Proposed | +| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D; REV-09B; shared audit/outbox; AUTH planned `review.decision` typed/prepared contract | Proposed | +| `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07; 02B; post-02B AUTH `outbox.dispatch` evaluator/activation and exact service-assignment proof merged; ADR 0014 adapter foundation; joint lifecycle-fence port contract | Proposed | | `WS-CON-001-08R` | Bound-Service Callback Rate Control | L1 | 08A; shared API-control contract | Proposed | -| `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; AUTH callback permission/service assignment; joint callback-fence port contract | Proposed | -| `WS-CON-001-09A` | Contribution Evidence Projection Write | L1 | 07; named `WS-ART-001-CON-EVIDENCE` capability/action prerequisite | Proposed | -| `WS-CON-001-09B` | Authorized Contribution Evidence Read | L1 | 09A; disclosure schema; AUTH read actions | Proposed | -| `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B,09B; AUTH read actions | Proposed | -| `WS-CON-001-10B` | Operations, Reconciliation, Rebuild, And Fulfillment Drain Observation | L1 | 10A; AUTH ops/audit actions; shared-outbox observation capability | Proposed | -| `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10B; REV-10 integration; AUTH/ART/outbox readiness; required CON-owned dispatch/callback fence hooks and drain port | Proposed | +| `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; callback identity/action registration already merged before 04A; AUTH typed callback context and prepared protocol merged; joint callback-fence port contract | Proposed | +| `WS-CON-001-09A` | Contribution Evidence Projection Write | L1 | 07; named `WS-ART-001-CON-EVIDENCE` capability; AUTH planned evidence action/context/prepared protocol and exact assignment on existing `workstream.artifact.binding` | Proposed | +| `WS-CON-001-09B` | Authorized Contribution Evidence Read | L1 | 09A; disclosure schema; AUTH planned contribution-read registrations/typed contexts | Proposed | +| `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B,09B; post-09B AUTH contribution-read activation; AUTH planned award-read registrations/typed contexts | Proposed | +| `WS-CON-001-10B` | Operations, Reconciliation, Rebuild, And Fulfillment Drain Observation | L1 | 10A; post-10A AUTH award-read activation; AUTH planned binding-retire/ops/audit registrations/typed contexts/grants/prepared protocol; shared-outbox observation capability | Proposed | +| `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10B; REV-10 integration; exact AUTH evaluator/action/service manifest, ART/outbox readiness, required CON-owned dispatch/callback fence hooks and drain port | Proposed | ## Dependency order @@ -44,13 +44,22 @@ PLAN -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D -> 04A -> 04B -> 05A Cross-initiative ownership and merge gates: ```text +CON-02A -> AUTH outbox registration/service assignment -> CON-02B hidden dispatcher -> AUTH outbox evaluator/activation -> CON-08A +CON-03A -> AUTH binding registration/contracts + planned callback action/permission + active callback actor/link/assignment -> CON-04A hidden binding behavior -> AUTH binding evaluator/activation +CON-04A + AUTH policy registration/contracts -> CON-04B hidden policy behavior -> AUTH policy evaluator/activation -> CON-05A CON-03B policy persistence -> REV-03 lease persistence (REV owns lease FK) REV-02 exact Submission.task_assignment_id lineage -> CON-05A semantic cutover/freeze -> CON-05B physical removal -> new task claims under compensation policy only +AUTH-13 ordered task.claim registration/typed-prepared contract -> task resource behavior -> evaluator/activation (or the same ordered work in a reviewed AUTH successor) -> CON-05A CON-02C shared audit participant -> REV-04 review-chain persistence REV-03 lease persistence + CON-05B -> CON-06 capability -CON-06 -> REV-06 claim injection/integrated freeze proof +AUTH review.claim registration/contracts -> CON-06 -> REV-06 hidden claim composition while planned -> AUTH review.claim evaluator/activation REV-04 exact Review target -> CON-03C foreign keys -REV-09B + CON-07 participant -> REV-10 sole review-composition integration +AUTH review.decision registration/contracts + REV-09B + CON-07 participant -> REV-10 hidden decision composition while planned -> AUTH review.decision evaluator/activation +AUTH callback identity/action registration before CON-04A + remaining typed/prepared callback contracts -> CON-08B hidden callback -> AUTH callback evaluator/activation -> CON-11 +AUTH evidence action/typed/prepared/exact-service-assignment registration + ART capability -> CON-09A hidden handler -> AUTH evidence evaluator/activation -> CON-11 +AUTH contribution-read registration/contracts -> CON-09B hidden reads -> AUTH contribution-read activation -> CON-10A +AUTH award-read registration/contracts -> CON-10A hidden reads -> AUTH award-read activation -> CON-10B +AUTH operations registration/contracts -> CON-10B hidden operations -> AUTH operations activation -> CON-11 CON-08A/B,09A/B,10A/B + REV-12 + AUTH/ART/outbox -> CON-11 hidden readiness CON-08A/08B/10B/11 required CON-owned dispatch/callback fence ports and fulfillment-drain observation + CON-11 hidden manifest + REV-12 -> REV-12A hidden joint release-control composition -> REV-13 sole route activation and joint live drill ``` @@ -70,6 +79,12 @@ CON-08A/08B/10B/11 required CON-owned dispatch/callback fence ports and fulfillm - 03A/03B split binding and policy schema; 03C/03D split canonical economic truth from delivery/receipt/projection schema. - 04A/04B split hidden binding and policy services; routes remain unregistered. +- Every authorized feature family follows AUTH registration -> hidden CON + implementation -> AUTH activation. Registration alone stays fail-closed; the + CON chunk may prove domain behavior below an explicit test boundary but owns + no production allow fallback. AUTH owns availability/evaluators/principal + truth and the prepared mutation protocol. A later CON consumer and CON-11 + wait for the preceding AUTH activation gate. - 05A owns the cross-module semantic cutover because the old locked fields span project, task, submission and checker contracts; 05B is schema cleanup only. - 06 exposes only a CON-owned capability; REV-06 owns review claim wiring. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md index 7b7b41fc..1fcbb003 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -12,6 +12,7 @@ evidence, not executable authority. | Requirement family | Owner | Minimum executable cases before owner completes | Final live evidence owner | |---|---|---|---| +| Central authorization integration | AUTH executable gates + each CON resource owner | all absent/planned actions deny; each active action has exact ActionId/PermissionId/owner/context/evaluator parity; human grant and service assignment never substitute; `T` prepared handles reject missing/reuse/cross-session/cross-action/target drift; authority-loss versus product mutation runs in both orders; no CON AUTH-repository import or local role fallback | AUTH conformance + REV-13 | | Contribution identity and review lineage | CON-03C/07 + REV-10 | one completed-review contribution per valid Review; accept adds one accepted-submission contribution; second revision review creates a distinct reviewer contribution; automated checker outcomes create none; at-most-one DB constraints and mandatory-participant at-least-one proof | REV-13 | | Policy publication and freezing | CON-04B/05/06 + REV-06 | absent/incomplete setup denies; unpaid is explicit; retired frozen version remains valid for started work; later activation changes new assignments/leases only; publish versus both claims in both lock orders | REV-13 | | Binding lifecycle | CON-04A/08A/08B/10B | suspended blocks new freeze/delivery but accepts valid existing-work callback; retirement denies dependencies then permits exact accepted-receipt replay only; actor/link revocation denies; project/instrument mismatch denies | REV-13 | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md index c93e9851..7d29541b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -49,12 +49,17 @@ Use `backend/app/modules/tasks/models.py::Submission` and its `version`/ ## D4 - ActionIds Do Not Replace PermissionIds **Status:** separation accepted; all WS-CON actions and service permissions are -proposed dependencies requiring human approval and AUTH registration. +proposed dependencies requiring human approval and AUTH-owned executable +integration. WS-CON declares granular proposed ActionIds mapped to existing stable PermissionIds when semantically safe. AUTH owns registration, audit migration, -grants/service actors, and kernel behavior; the named feature chunk owns -resource composition, behavioral proof, and activation after registration. +availability, evaluator dispatch, grants/service actors, authority +revalidation, and kernel behavior; the named feature chunk owns product-row +loading, approved typed resource composition and hidden behavioral proof below +an explicit test seam while the action remains planned. AUTH later integrates +the evaluator against that exact merged seam, proves real-kernel behavior and +alone activates the action. Shared outbox dispatch and the external fulfillment callback require the proposed service-only PermissionIds `outbox.dispatch` and `compensation.fulfillment.report`; neither can borrow human authority. CON-08A @@ -67,6 +72,10 @@ No WS-CON code edits the AUTH catalogue. `AUTHORIZATION_HANDOFF.md` is the exact proposal, and every mapping is re-read from merged trusted `main` before its implementation chunk. +Current trusted `main` proves why registration and activation cannot be +collapsed: AUTH-07B has 50 registered actions but only two active evaluators; +all planned and unsupported actions fail closed. + ## D5 - Derived Contribution/Award Writes Are Review Participants **Status:** accepted by the parallel WS-REV plan and candidate invariant. @@ -112,3 +121,26 @@ Workstream persists awards, exact outbound instructions, adapter delivery evidence, immutable fulfillment receipts, and rebuildable status. External adapters own payment requests/attempts, approvals, provider reconciliation, beneficiary accounts, balances, and project-points ledger entries. + +## D10 - AUTH Owns Prepared Cross-Domain Mutation Authorization + +**Status:** required architecture correction after merged AUTH-07B review; +human/AUTH approval required before any `T` action implementation. + +The current actor-self kernel can revalidate entirely inside AUTH-owned rows. +WS-CON mutations cross AUTH and product rows, so one `require()` call against an +unlocked product snapshot is insufficient, while locking product rows before +AUTH rows violates the canonical lock order. + +AUTH must provide one caller-session-bound prepared authorization protocol. It +locks actor/link/grant or service-assignment authority first from a +server-resolved preliminary target, returns an opaque single-use handle, and +evaluates that handle exactly once against the final typed context recomposed +from locked product rows. The handle is bound to request, session, actor, +action, target and authority snapshot; it cannot be serialized, cached, reused, +or substituted. AUTH stages one decision and never commits. WS-CON supplies +facts and product guards but cannot implement the handle or query AUTH state. + +Rejected: product-row locks before AUTH locks, evaluating an unlocked snapshot, +calling AUTH twice and emitting competing decisions, or letting feature code +flip catalogue availability. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md index a6e6b76e..46884ee7 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -55,8 +55,11 @@ generation rather than replacing the first. | Finding | Evidence | Required correction in active contract | |---|---|---| | Wrong public prefix | Candidate section 18 uses `/v1`; router and ADR 0012 use `/api/v1`. | Use `/api/v1` only; no alias. | -| ActionId/PermissionId conflation | Candidate calls granular `compensation.policy.*` values permissions and says broad IDs were removed. Merged AUTH-07A preserves 74 approved PermissionIds and separately registers 50 planned ActionIds. | Publish an exact proposed ActionId -> PermissionId handoff. Never call an ActionId a permission or a merely planned identifier active. | -| Wrong Review action | Candidate uses `review.decision.record`; merged AUTH-07A and WS-REV use planned ActionId `review.decision` mapped to PermissionId `review.decision`. | Consume `review.decision` only after its AUTH/REV activation gate. | +| ActionId/PermissionId conflation | Candidate calls granular `compensation.policy.*` values permissions and says broad IDs were removed. Merged AUTH-07B preserves 74 approved PermissionIds and separately registers 50 ActionIds: two active actor-self actions and 48 planned actions. | Publish an exact proposed ActionId -> PermissionId handoff. Never call an ActionId a permission or a registered/planned identifier executable. | +| Registration treated as activation | AUTH-07B's runtime accepts only actor-self/system contexts and explicitly evaluates only its two active actor-self actions; planned or unsupported actions deny. | AUTH must own typed-context/evaluator/principal/transaction integration and active availability. CON owns product facts/guards only and cannot flip the AUTH catalogue. | +| Cross-domain mutation lock gap | Current `require()` can revalidate actor-self wholly inside AUTH, but WS-CON mutations need AUTH rows before product rows and final evaluation against locked product facts. | AUTH supplies the prepared, caller-session-bound, single-use `T` protocol in D10; no unlocked-snapshot decision or product-before-AUTH lock order. | +| Missing upstream task action | PermissionId `task.claim` exists, but current ActionId has no `task.claim` member. | AUTH-13 or reviewed AUTH successor registers/evaluates/activates `task.claim` before CON-05A integrates compensation freeze. | +| Wrong Review action | Candidate uses `review.decision.record`; merged AUTH catalogue and WS-REV use registered planned ActionId `review.decision` mapped to PermissionId `review.decision`. | Consume `review.decision` only after its AUTH evaluator/availability and REV resource-composition gates. | | Invented WS-AUTH source | Candidate names `WS-AUTH-001-A`, which is not a canonical repository artifact. | Cite merged `docs/spec_authorization_service.md`, ADR 0012, and the closed catalogue. | | Invented artifact permissions | Candidate uses `artifact.recovery.request`, `artifact.recovery.execute`, and `artifact.retrieve`. AUTH explicitly rejected the first; none is a registered PermissionId. | Use `artifact.verification_job.retry` through `ArtifactOperatorRecoveryPort`; require ART-owned typed storage/read capabilities and approved action mappings. | | Wrong artifact port | Candidate injects `ArtifactStorePort` with store/projection/retain/retrieve methods. ADR 0013's target `ArtifactStore` has only provider-byte behavior and cannot enter product services. | WS-CON consumes narrow ART capability ports. Only ART orchestration receives the raw store. | @@ -76,9 +79,9 @@ generation rather than replacing the first. | `backend/app/modules/tasks/service.py` | Claim, submission, task lifecycle | WS-CON may integrate only through task-owned participants; auth cutover stays WS-AUTH-owned. | | `backend/app/modules/projects/models.py` | Project and guide-bound `PaymentPolicy` | Approved for complete semantic removal in CON-05A and physical removal in CON-05B; the legacy-row rebuild/classification rule remains a human gate. | | `backend/app/modules/projects/service.py` | Guide activation and policy locking | Must not become a second compensation-policy engine. | -| `backend/app/modules/authorization/*` | Current authority idempotency/audit foundation | WS-CON imports only the future public service/types, never repositories or grants. | -| `backend/app/modules/authorization/catalogue.py` from AUTH-07A `3ab25cf`, merged through `e9d72a1` | Canonical merged closed catalogue | 74 PermissionIds and 50 planned ActionIds; the additive permission is `review.queue.override`, not either proposed WS-CON service permission. All WS-CON ActionIds remain absent/proposed. | -| sibling `workstream-rev-001/.../` working delta atop `3e09e99` | Content-reviewed, uncommitted parallel review integration amendment | The branch has integrated trusted `main` `e9d72a1`; its delta defines hidden composition, lock order, contribution participant gates, PaymentPolicy removal dependencies, WS-CON-11 preflight, REV-12A hidden release control, and joint REV-13 activation. Required content tracks pass, but its handler-claim wording must be repaired to preserve CON-02B ownership. It cannot be consumed until the exact repaired snapshot is committed, commit-freshness reviewed, refreshed against trusted main, and merged. | +| `backend/app/modules/authorization/{catalogue,kernel,runtime}.py` from merged AUTH-07B | Canonical closed registry and first executable kernel | 74 PermissionIds, 50 ActionIds, exactly two active actor-self actions and 48 planned; actor-self/system are the only runtime contexts and actor-self is the only matched authority. All WS-CON-specific actions and both service permissions remain absent. | +| `backend/app/api/deps/authorization.py` | Current actor-self composition root | Human self only; it rejects service subjects and owns actor-self denial rollback/restaging. WS-CON needs AUTH-owned general human/project/service composition, not a copied dependency. | +| sibling `workstream-rev-001/.../` branch head `e59e2bb` | Parallel review integration plan refreshed with trusted main `90eca12` | The branch includes committed REV-12A hidden release control and REV-13 sole activation, but its status/evidence still describes older AUTH/CON heads and its REV-12A contract still says the CON handler claims the event. Treat it as non-consumable until that ownership wording and freshness evidence are repaired and merged. | | `backend/app/modules/artifacts/*` | Current artifact metadata/orchestration foundation | Target v2 is still being delivered by WS-ART; WS-CON cannot import provider internals. | | `backend/app/interfaces/artifacts.py` | Current v1 raw provider port | Not a WS-CON dependency; it is being clean-cut to ADR 0013 v2. | | `docs/spec_artifact_storage_service.md` | Canonical target artifact contract | Owns narrow product capability ports, recovery, verification, quotas, and provider policy. | @@ -93,7 +96,7 @@ generation rather than replacing the first. |---|---|---| | `backend/tests/test_tasks.py` | Task policy locks, assignment uniqueness, immutable Submission versions, checker admission, concurrency | No compensation freeze, review effects, contribution, or award tests. | | `backend/tests/test_projects.py` | Guide/policy activation including `PaymentPolicy` | No CompensationPolicy lifecycle or Finance Authority behavior. | -| `backend/tests/test_authorization.py` | Authority foundations plus merged closed catalogue/audit parity | The deny-by-default kernel, grants, service actors, and feature action activation remain later AUTH-owned work. | +| `backend/tests/test_authorization.py` | Closed catalogue plus AUTH-07B deny-by-default kernel/runtime | Actor-self allow/deny, unknown/planned/unsupported denial, immutable decisions, denial restaging and request-local state are covered. Grants, service composition, WS-CON contexts/evaluators and prepared cross-domain mutation authorization remain AUTH-owned work. | | `backend/tests/test_audit.py` | Typed append-only authority evidence | No contribution/compensation lifecycle audit contract. | | `backend/tests/test_artifacts.py` | Current artifact port, local adapter, content/binding/receipt foundation | Target v2, S3/MinIO, typed contribution projection capability, and evidence reads are not merged. | | `backend/tests/test_checkers.py` | Durable checker run and `allow_review` routing | Stops before Review persistence. | @@ -102,9 +105,11 @@ generation rather than replacing the first. ## Dependencies/integrations -- WS-AUTH: executable kernel, grants, service actors, exact WS-CON ActionId - registrations/mappings, immutable `AuthorizationDecision`, and final bypass - removal. WS-CON does not edit those owned surfaces. +- WS-AUTH: merged actor-self kernel plus future grants, service actors, exact + WS-CON ActionId/PermissionId/ActionOwner/audit registration, typed resource + contexts, closed evaluators, matched authorities, prepared `T` protocol, + service-capable composition, active availability and final bypass removal. + WS-CON does not edit those owned surfaces. - WS-REV: `Review`, `ReviewLease`, findings/resolutions, decision idempotency, task effects, hidden composition, and final public review cutover. - WS-ART: v2 store, LocalStorage/MinIO conformance, AWS proof, narrow system- @@ -126,6 +131,8 @@ generation rather than replacing the first. |---|---|---| | Dual payment truth | `PaymentPolicy`/future `PaymentRecord` and new compensation versions/awards can disagree. | ADR-backed sole execution authority and clean documentation/schema cutover. | | Permission replacement | Treating ActionIds as replacement permissions would break merged audit/grants. | Exact mapping table; AUTH-owned additive registration; typed manifest tests. | +| Registered-but-inexecutable AUTH action | Planned availability or a missing evaluator causes every WS-CON command to deny; a feature-local workaround would bypass central AUTH. | Separate AUTH registration and executable activation gates; startup parity rejects active-without-evaluator and CON never edits AUTH. | +| AUTH/product lock inversion | One-step authorization after product locks reverses canonical order; authorization before product locks can evaluate stale facts. | AUTH-owned prepared handle locks authority first and evaluates once against final locked product facts. | | Circular REV/CON dependency | Leases need policy FKs; claims need freeze; decisions need contribution participant. | Explicit interleaving gates in chunk map. | | Cross-domain deadlock/partial commit | Review, authority, tasks, artifacts, CON, audit, and outbox share one transaction. | One canonical lock order, caller-owned session, fault injection, real Postgres concurrency tests. | | Economic overreach | Payment-provider or points-ledger logic could leak into Workstream. | Typed outbound instruction/receipt boundary and architecture import tests. | @@ -141,7 +148,8 @@ generation rather than replacing the first. |---|---|---| | Preserve both candidate generations and reconcile into active spec? | Maintains archival provenance and follows repository precedent. | Before 01. | | May pre-production payment/task rows be rebuilt, or must they be classified/backfilled? | Determines migration safety and atomic claim cutover. | Before 05. | -| Approve two new service-only PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`? | Human outbox recovery/reconciliation authority must not execute async side effects; no existing permission safely names the external adapter callback entitlement. | Before shared-outbox prerequisite/08A. | +| Approve two new service-only PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`? | Human outbox recovery/reconciliation authority must not execute async side effects; no existing permission safely names the external adapter callback entitlement. | Before CON-02B for dispatch and before CON-04A for callback binding identity. | +| Approve the AUTH-owned WS-CON registration/evaluator/activation work and D10 prepared mutation protocol? | Current AUTH-07B intentionally supports only two self actions; CON cannot safely or physically activate its own actions. | Before any authorized CON service chunk. | | Does the ART initiative add the contribution evidence capability, or should it be a separate ART-owned prerequisite chunk? | WS-CON cannot own raw storage orchestration. | Before 10. | ## Existing conventions to preserve diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md index 5f453a73..932a7ea6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md @@ -35,8 +35,9 @@ contribution/award participant before it can expose review decisions. - Contribution evidence is produced after commit through an ART-owned typed capability and Workstream `ArtifactBinding`, never through a raw artifact provider in contribution code. -- Every public or service operation consumes the merged WS-AUTH - `AuthorizationService.require(ActionId, typed ResourceContext)` boundary. +- Every public or service operation consumes the merged WS-AUTH boundary: + request-scoped `require(ActionId, typed ResourceContext)` for `Q` reads and + the AUTH-owned prepared, caller-session-bound protocol for `T` mutations. - Public APIs use `/api/v1` only. ## Non-goals @@ -73,8 +74,9 @@ reputation policy. existing broad PermissionIds wherever safe, while the exact bound adapter shared outbox dispatch and inbound callbacks require two new service-only PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`, - owned and implemented by WS-AUTH. The shared-outbox owner activates dispatch; - CON-08A only consumes the claimed command. + owned and implemented by WS-AUTH. CON-02B first lands the hidden dispatcher; + AUTH then integrates its evaluator and activates dispatch. CON-08A only + consumes the already-claimed command. 4. Approve the cross-initiative sequence, including REV-13 as the sole joint production-route activation/live-drill owner after AUTH, ART, REV, shared outbox, and WS-CON participants are mandatory and proven. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md index 39527e74..0614fc11 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -2,24 +2,31 @@ ## Incorporation status -The inspected sibling working delta atop `3e09e99` has incorporated -contribution/compensation router registration, the WS-CON-11 preflight -manifest, the complete joint live matrix, PaymentPolicy removal dependencies, -the active generated/document companions, and a new REV-12A hidden -release-control chunk. The delta also corrects REV-12A to consume the CON-owned +The inspected sibling branch now has committed merge head `e59e2bb`, which +integrates trusted `main` `90eca12` and includes contribution/compensation +router registration, the WS-CON-11 preflight manifest, the complete joint live +matrix, PaymentPolicy removal dependencies, active generated/document +companions, and REV-12A hidden release control. It consumes the CON-owned dispatch and callback fences plus fulfillment-drain observation through -composition instead of editing CON product files or importing CON/outbox -repositories. Its required content-review tracks pass, but the snapshot remains -uncommitted and lacks commit-bound freshness evidence as recorded in -`SOURCE_MANIFEST.md`; it is working discovery evidence, not a dependency. -The current REV-12A draft still says the CON handler claims the shared-outbox -event; before review/merge it must instead accept the dispatcher's already- -claimed command and return a typed outcome, leaving every outbox transition to -CON-02B's shared dispatcher. -WS-CON does not edit the parallel worktree. The WS-REV owner must commit the -exact content-reviewed delta, run commit-bound freshness review, and merge -before CON-11, REV-12A, or REV-13 can activate. Until the later implementation -gates land, both initiatives remain hidden. +composition instead of importing CON/outbox repositories. + +The sibling is still not a consumable dependency: its status/evidence cites +older AUTH/CON heads and its REV-12A contract still says the CON handler claims +the shared-outbox event. Before review/merge it must instead accept the +dispatcher's already-claimed command and return a typed outcome, leaving every +outbox transition to CON-02B. It must also adopt AUTH-07B's executable-gate and +prepared-authorization requirements. WS-CON does not edit the parallel +worktree; the WS-REV owner must repair, commit-bind, internally review and merge +that exact contract. Until later implementation gates land, both initiatives +remain hidden. + +The refresh must also repair REV-06/10 authorization choreography. AUTH first +registers the planned review action and typed/prepared contract; CON supplies +its capability/participant; REV then merges hidden resource composition and +final-context integration while the real kernel still denies; AUTH alone +integrates the evaluator and activates the action before production execution. +REV must not require active review actions before building the hidden +composition that AUTH activation depends on. ## Required REV-13 allowed-file additions @@ -70,8 +77,9 @@ historical reviews, and generated loop memory remain excluded. award/evidence reads, fulfillment callback, and bounded operations routers in the same PR under `/api/v1`; no `/v1` alias and no partial prior surface. - Consume CON-11's exact merged-SHA/migration/action/service-assignment/ART/ - outbox/worker/handler/fence manifest and fail startup/preflight on any - mismatch. + outbox/worker/handler/fence manifest plus AUTH context/evaluator/matched- + authority/prepared-protocol/availability parity, and fail startup/preflight + on any mismatch or active action without executable behavior. - Use REV-12A only for hidden persisted joint lifecycle control and explicit composition. Consume the required CON-owned `FulfillmentDispatchFence`, `FulfillmentCallbackFence`, and `FulfillmentLifecycleDrainObservationPort`; diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md index 08b2d261..ad320915 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -36,19 +36,43 @@ WS-CON never reads grants, roles, or AUTH repositories. Every protected command or query declares one ActionId and consumes a request-scoped, caller-session- bound `AuthorizationService`. -Every WS-CON ActionId is currently absent and proposed. AUTH-07A is merged on -trusted `main` through `e9d72a1`; its closed catalogue contains 74 PermissionIds -and 50 planned non-WS-CON ActionIds. The exact handoff is in -`AUTHORIZATION_HANDOFF.md`. It enumerates each proposed action separately, -its existing or proposed PermissionId, canonical target, candidate principal -class, typed resource facts and guards, transaction revalidation requirement, -registry owner, resource-context owner, and activation owner. - -WS-AUTH owns identifier/owner-enum registration, typed/PostgreSQL parity, -service ActorProfile/action-assignment construction, grant semantics, and -kernel behavior. The feature chunk named in the handoff owns resource -composition, lifecycle guards, behavioral proof, and activation only after the -AUTH registration prerequisite is merged. WS-CON never edits AUTH-owned files. +Every WS-CON ActionId is currently absent and proposed. Trusted `main` +`90eca12` includes AUTH-07B's request-scoped deny-by-default kernel. Its closed +catalogue contains 74 PermissionIds and 50 non-WS-CON ActionIds: two actor-self +actions are active and 48 actions remain planned. The exact handoff is in +`AUTHORIZATION_HANDOFF.md`. It enumerates each proposed action separately, its +existing or proposed PermissionId, canonical target, candidate principal class, +typed resource facts and guards, transaction protocol, AUTH activation gate, +and feature resource owner. + +AUTH-07B currently evaluates only actor-self contexts/actions and rejects +service subjects at its actor-self dependency. WS-AUTH therefore owns not only +identifier/owner-enum registration and typed/PostgreSQL parity, but also action +availability, closed evaluator dispatch, matched-authority expansion, grant +semantics, service-capable composition, service ActorProfile/action-assignment +construction, and transaction-local authority revalidation. The feature chunk +named in the handoff owns product-row loading, construction of AUTH-approved +typed resource facts, lifecycle guards, and behavioral proof. WS-CON never +edits AUTH-owned files or activates an AUTH action. + +For mutations crossing AUTH and product rows, AUTH must add the prepared +authorization protocol specified in the handoff. The preliminary target lets +AUTH lock actor/link/grant or service-assignment rows first; the opaque handle is +then evaluated exactly once against facts recomposed from product rows locked by +the feature in canonical order. AUTH stages one decision and never commits. +This prevents both product-before-AUTH lock inversion and authorization based on +an unlocked resource snapshot. + +Current trusted `main` also lacks an ActionId for upstream `task.claim`, even +though PermissionId `task.claim` exists. AUTH-13 or an approved AUTH-owned +successor must register and activate that action before CON-05A adds the +compensation freeze participant. Review choreography is deliberately staged: +AUTH first registers the planned `review.claim` and `review.decision` contracts; +CON-06/07 then supply their hidden capability/participant; REV-06/10 compose and +prove the final typed resource behavior while the real kernel remains +fail-closed; only then may AUTH integrate the evaluators and activate those +actions. Production execution and public routes remain blocked until the later +readiness/REV-13 gates. Derived contribution/award writes are mandatory participants of the already authorized `review.decision` transaction. They are not separately callable @@ -84,7 +108,9 @@ composition and proves end-to-end atomicity. The active contract extends, and may not replace, WS-REV's accepted order: -1. AUTH-owned current actor/identity/grant/control rows in AUTH internal order; +1. AUTH-owned current actor/identity/grant/service-assignment/control rows in + AUTH internal order, locked by the prepared authorization handle for `T` + operations; 2. the operation idempotency row; 3. for lifecycle-controlled commands, the shared lifecycle advisory fence and captured phase snapshot; this is held through the database transaction but @@ -109,9 +135,12 @@ The active contract extends, and may not replace, WS-REV's accepted order: Multiple same-type rows are locked by ascending primary key/UUID. Operations skip absent classes but never reorder shared classes. -No feature may reverse this order. Publish, retire, binding suspend/resume/ -retire, assignment claim, review claim, delivery, callback, reconciliation, and -projection rebuild revalidate authority after acquiring their relevant locks. +No feature may reverse this order. For `T` operations, AUTH prepares and locks +authority first; publish, retire, binding suspend/resume/retire, assignment +claim, review claim, delivery, callback, reconciliation, and projection rebuild +then evaluate the same prepared handle against final facts recomposed from their +locked product rows. The handle is request/session/action/target bound and +single-use. `Q` reads remain request-scoped. Freezing requires a published version whose referenced bindings are active. Suspension blocks new freezes and new delivery but does not erase already-frozen obligations; exact callback/replay behavior is state-matrix controlled. Real @@ -162,9 +191,18 @@ Markdown build. Preserve generations and create an active reconciled spec. ### Replace broad PermissionIds with granular strings Rejected because the merged AUTH contract preserves 74 stable PermissionIds -and separately stages 50 planned ActionIds. Granular action names do not replace +and separately registers 50 ActionIds, of which only two actor-self actions are +active on current trusted `main`. Granular action names do not replace permissions. +### Let WS-CON flip AUTH catalogue availability + +Rejected because availability without an AUTH-owned typed evaluator, grant or +service-assignment path, audit parity, and transaction protocol is either +deny-only or an authorization bypass. AUTH owns registration, evaluator +dispatch, principal truth and activation; CON owns canonical product facts and +behavior only. + ### Reuse `PaymentPolicy` directly as the award policy Rejected because it is guide-version-bound, submitter-oriented, and cannot @@ -220,10 +258,15 @@ backend contract. artifact scanner itself is unchanged. 2. Merge outbox persistence then its feature-neutral dispatcher; add split, inactive binding/policy/contribution/award/delivery/receipt persistence. -3. Merge required AUTH ActionId/PermissionId registrations and exact service - action assignments in the AUTH initiative; merge required ART capabilities - in ART. Feature chunks then activate only their own registered actions with - resource composers and behavioral proof. +3. Interleave each AUTH registration -> feature implementation -> AUTH + activation wave in `AUTHORIZATION_HANDOFF.md`. The registration checkpoint + provides planned ActionId/PermissionId/owner/audit parity, typed context + contracts, principal prerequisites and prepared mutation protocol. The + CON/ART chunk then merges hidden authorization-ready behavior while the real + kernel still denies. Only a later AUTH-owned checkpoint integrates the + evaluator, proves the exact merged feature and changes availability. CON/ART + never edits AUTH or supplies a production allow fallback. Merge required ART + capabilities in ART. 4. Activate hidden binding/policy services. CON-05A atomically removes every PaymentPolicy semantic consumer and enables only task claims that freeze a CompensationPolicyVersion, only after merged REV-02 establishes the exact @@ -240,11 +283,11 @@ backend contract. required CON-owned dispatch/callback fence ports while consuming the read-only fulfillment-drain observation port; it may not edit CON product files or import CON/outbox repositories. - The content-reviewed sibling working delta atop `3e09e99` currently matches - this boundary except for the recorded shared-outbox claim-wording repair. The - exact repaired snapshot must become a branch-reachable commit, pass - commit-bound freshness review, preserve the boundary through refresh, and - merge before it is a consumable dependency. Do not change archival sources. + Sibling merge head `e59e2bb` now includes the joint plan atop trusted main + `90eca12`, but its status/evidence still cites older heads and REV-12A still + assigns claim wording to the handler. The exact repaired snapshot must adopt + the AUTH-07B executable gates, pass commit-bound freshness review, and merge + before it is a consumable dependency. Do not change archival sources. At every chunk activation, rebase discovery on trusted `main`, refresh exact migration numbers and dependency symbols, and stop if an expected port/action @@ -264,6 +307,12 @@ is absent or materially changed. repository coverage at or above 78 percent. - OpenAPI action inventory requires one ActionId per protected surface and proves hidden routes remain absent before final activation. +- Authorization contract tests prove every planned WS-CON action denies, every + active action has exactly one AUTH evaluator and one approved typed context, + and no active action exists without its owning feature behavior. Mutation + tests reject missing/reused/cross-session prepared handles and exercise + actor/link/grant or service-assignment revocation against product mutation in + both lock permutations. - Static architecture tests reject AUTH persistence imports, local role checks, provider-specific compensation adapters, concrete-adapter imports or construction outside the explicit composition root, raw ArtifactStore diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md index 50152ce8..0d6af66d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -12,6 +12,9 @@ | Direct provider call bypasses ART controls | Critical | Named `WS-ART-001-CON-EVIDENCE` capability prerequisite; import/composition tests reject raw store/provider access. | WS-ART / WS-CON-001-09A | Open | | Outbox duplication or loss | High | 02A owns truth/append; 02B alone owns dispatch/retry/replay with stable identities. | WS-CON-001-02A/B | Open | | Human role or token claims leak into feature authorization | Critical | Central AUTH service only; no grant queries/local role checks; deny/race tests. | WS-AUTH / all WS-CON | Open | +| Registered WS-CON action has no executable AUTH evaluator | Critical | AUTH owns typed contexts, closed evaluator dispatch, matched authority and active availability; CON cannot flip catalogue state; startup parity rejects active-without-evaluator and evaluator-without-feature behavior. | WS-AUTH | Open | +| Cross-domain mutation authorizes unlocked facts or reverses locks | Critical | D10 AUTH-owned prepared handle locks authority first and evaluates once against final locked product facts; missing/reused/cross-session handles deny. | WS-AUTH + each `T` CON owner | Open | +| Task compensation freeze assumes nonexistent `task.claim` ActionId | Critical | AUTH-13 or reviewed AUTH successor registers/evaluates/activates exact `task.claim` -> existing `task.claim` before CON-05A. | WS-AUTH / WS-CON-001-05A | Open | | Provider payment logic leaks into Workstream | High | Typed instruction/ack/receipt contract; provider attempts/balances/ledger prohibited. | WS-CON-001-08A/B | Open | | Fulfilled state regresses or duplicates | High | Immutable receipts, unique fulfilled row, row locks, exact callback idempotency. | WS-CON-001-08B | Open | | Lifecycle disable races adapter I/O or authenticated callback | Critical | CON-owned mandatory dispatch/callback fence ports, durable pre-I/O in-flight state, same-session drain observations, REV-12A exclusive transition lock, and both-order PostgreSQL tests. | WS-CON-001-03D/08A/08B/10B/11 + WS-REV-001-12A | Open | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md index 8ec5d151..1bf23b6f 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -32,30 +32,25 @@ ## Parallel dependency sources inspected - trusted authorization worktree and `origin/main` at - `e9d72a16d95e704f2af514a97d37623940854d95`, which merges AUTH-07A through - PR #126 -- merged AUTH-07A catalogue implementation `3ab25cf`, now canonical on trusted - `main` with 74 PermissionIds, 50 planned ActionIds, and no WS-CON ActionIds or - service-only delivery/fulfillment permissions + `90eca12f6398f2ef168e634244d912765572c3e5`, which merges AUTH-07B through PR + #130 +- merged AUTH-07B implementation `9fd3bb4` plus CI repair `da0230c`, now + canonical on trusted `main`: 74 PermissionIds, 50 ActionIds, exactly two + active actor-self actions, 48 planned actions, actor-self/system runtime + contexts only, and no WS-CON ActionIds or service-only + delivery/fulfillment permissions - `/home/abiorh/flow/workstream-auth-001-07/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/` - active sibling REV worktree `/home/abiorh/flow/workstream-rev-001/`, observed - at branch-reachable head `3e09e994d500cd45916b449d7bc4f13b7623cdcc` - on `2026-07-15T17:48:19+01:00`, plus an uncommitted initiative delta. The - branch head integrates trusted `main` `e9d72a1`. The - delta introduces REV-12A hidden joint release control, preserves REV-13 as - sole production activation, consumes the proposed CON-owned dispatch and - callback fences plus fulfillment-drain observation only through composition, - and retains the complete PaymentPolicy removal/CON-11 gates. All required - content-review tracks pass in the sibling evidence, but the reviewed snapshot - and reference changes remain dirty. No dependency SHA is claimed. The exact - reviewed delta must become a branch-reachable commit, pass commit-bound - freshness review, refresh against trusted main, and merge before it is - consumable. The sibling's revised reference Markdown/PDF remain separate - worktree-only discovery inputs alongside pre-existing original-reference - deletions. -- trusted `main` at `e9d72a16d95e704f2af514a97d37623940854d95`, including the - merged ADR 0014 `ExternalServiceAdapterFactory[TAdapter]` foundation from PR - #127 and the AUTH-07A catalogue/audit foundation from PR #126. + at branch-reachable merge head + `e59e2bbe823bc0ee2b0e59ff35f8352349618b2e` on + `2026-07-15T20:22:41+01:00`. It integrates trusted `main` `90eca12` and + committed REV-12A/13 planning, while user reference-file renames remain dirty. + Its status/evidence still cites older AUTH/CON heads and REV-12A still says + the CON handler claims the outbox event. It remains non-consumable until that + ownership wording and commit-bound freshness are repaired and the plan merges. +- trusted `main` at `90eca12f6398f2ef168e634244d912765572c3e5`, including merged + ADR 0014 from PR #127, AUTH-07A catalogue/audit foundation from PR #126, and + AUTH-07B deny-by-default actor-self kernel from PR #130. These sibling worktrees are discovery evidence, not dependencies by path. Every implementation chunk consumes only contracts merged into trusted `main`. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index da1d5bfb..39c1e231 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,8 +2,9 @@ ## Current status -Base planning and the latest merged AUTH-07A/active REV-12A delta -reconciliation have passed internal re-review. Application code is unchanged. +Base planning passed its earlier review. The latest merged AUTH-07B executable +kernel reconciliation and resulting AUTH/CON activation-boundary repair are +under fresh internal review. Application code is unchanged. The reconciled working Markdown transcription, supplied generation-2 PDF, original archival PDF, current backend, active docs, merged WS-AUTH authorization catalogue, and active parallel WS-REV plan delta have been mapped. @@ -15,14 +16,16 @@ providers, existing versioned `Submission`, and active payment architecture. ## Active chunk `WS-CON-001-PLAN` only. The human approved complete PaymentPolicy removal on -2026-07-15. The latest AUTH/REV reconciliation and scanner-contract repair are -internally reviewed and bound to local evidence. No implementation is active. +2026-07-15. AUTH-07B proves that registration alone is not activation, so the +plan now makes typed evaluators, principal truth, active availability and a +prepared cross-domain mutation protocol AUTH-owned prerequisites. No +implementation is active. ## Chunk status | Chunk | Status | Branch | PR | Notes | |---|---|---|---:|---| -| `WS-CON-001-PLAN` | Internally reviewed | `codex/ws-con-001-plan` | - | Approved D2 removal is split into 05A/05B; the reviewed refresh records merged AUTH-07A/ADR 0014 foundations, exact archive-scanner ownership, and the active non-consumable REV-12A working delta atop `3e09e99`. | +| `WS-CON-001-PLAN` | AUTH-07B boundary re-review pending | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; current refresh records merged AUTH-07B at `90eca12`, exact AUTH executable gates, archive-scanner ownership, and non-consumable REV head `e59e2bb`. | | `WS-CON-001-01` | Proposed | - | - | No runtime work. | | `WS-CON-001-02A` through `11` | Proposed | - | - | Each requires separate explicit start; REV-13 owns final activation. | @@ -32,11 +35,13 @@ internally reviewed and bound to local evidence. No implementation is active. |---|---|---| | Active-contract/archive handling approval | Human | Approve D1. | | Legacy PaymentPolicy/task/assignment row handling | Human | Choose pre-production rebuild or an explicit classified backfill before 05A/05B; PaymentPolicy removal itself is approved. | -| Exact WS-CON action registrations plus callback and shared-outbox service permissions | WS-AUTH + human | Approve dependency proposal; implement only in AUTH-owned chunk. | +| Exact WS-CON executable authorization integration | WS-AUTH + human | Approve and implement registration, typed contexts/evaluators, matched authorities, grants/service assignments, prepared `T` protocol and active availability only in AUTH-owned chunks. | +| Upstream `task.claim` ActionId is absent | WS-AUTH-001-13 or reviewed AUTH successor | Register/evaluate/activate `task.claim` against existing PermissionId before CON-05A integrates compensation freeze. | | Contribution evidence typed capability | WS-ART + human | Create and approve the named `WS-ART-001-CON-EVIDENCE` prerequisite before CON-09A. | | ReviewLease/Review contracts | WS-REV | Merge owning persistence/behavior chunks at declared gates. | +| REV-06/10 authorization choreography predates AUTH-07B repair | WS-REV + WS-AUTH | Refresh sibling contracts to AUTH registration -> CON participant -> REV hidden planned-action composition -> AUTH activation; commit-bind and review before consumption. | | Shared outbox | WS-CON-001-02A/B after approval | Land persistence and dispatcher before asynchronous integration. | -| REV-12A/13 joint scope is content-reviewed only as an uncommitted sibling delta atop `3e09e99` | WS-REV owner + human | Commit the exact repaired snapshot, run commit-bound freshness review, refresh against trusted main without losing the handoff, and merge; both surfaces stay hidden until its contract and later implementation gates land on trusted `main`. | +| REV-12A/13 joint plan is committed at sibling merge head `e59e2bb` but stale | WS-REV owner + human | Repair outbox claim ownership and AUTH/CON freshness evidence against `90eca12`, rerun commit-bound review, and merge; both surfaces stay hidden meanwhile. | | REV-12A draft assigns shared-outbox claim wording to the CON handler | WS-REV owner | Consume an already-claimed command and return a typed outcome; preserve CON-02B as sole outbox transition owner before sibling review/merge. | | External publication | Human | Push or open a PR only after explicit direction; local review evidence does not authorize publication. | @@ -44,7 +49,7 @@ internally reviewed and bound to local evidence. No implementation is active. | Item | Source | Priority | |---|---|---:| -| Re-read merged AUTH-07A catalogue plus later AUTH-07B/kernel/grant/service-actor state at each activation. | Trusted `main` | P1 | +| Re-read merged AUTH kernel plus later AUTH-08/09/10 grants/service-actor state and each WS-CON evaluator gate at activation. | Trusted `main` | P1 | | Re-read REV contracts at CON-03C/06/07 activation. | Parallel worktree | P1 | | Re-read ART v2/capability ports before CON-09A. | ADR 0013/spec | P1 | | Decide pre-production row rebuild vs classified backfill. | Migration risk | P1 | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index 58b88402..3bcf2dc9 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -98,6 +98,12 @@ roadmap or broad operational-doc rewrite `ArtifactStorePort`, production Flow Node/R2, or broad-permission removal. - [ ] Active spec declares AUTH/ART/REV/outbox prerequisites and no local auth implementation. +- [ ] Active spec reflects merged AUTH-07B: 74 PermissionIds, 50 ActionIds, two + active actor-self actions and 48 planned actions on reviewed main; every + WS-CON action remains absent until an AUTH-owned registration plus typed + evaluator/principal/transaction/availability gate merges. It defines D10's + prepared `T` protocol and the absent upstream `task.claim` ActionId gate + without authorizing CON to edit AUTH. - [ ] Required specification reviewers pass. - [ ] `CONFORMANCE_MATRIX.md` maps every retained normative invariant to its owning chunk, concrete behavioral case, and final evidence owner; no blanket diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md index 41d1162a..2eabdbec 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md @@ -30,6 +30,22 @@ dependency, workflow, test or coverage weakening ## Acceptance criteria +- [ ] AUTH has registered planned `outbox.dispatch` with its new service-only + PermissionId, typed context contract, fixed `workstream.outbox.dispatcher` + ActorProfile/link, exact action assignment, and D10 prepared-mutation + protocol. This chunk keeps dispatcher execution disabled and proves the real + kernel denies while planned; only a later AUTH-owned evaluator/activation + change may enable it, and no human grant can execute dispatch. +- [ ] The dispatcher prepares authority from a server-resolved preliminary + event target before locking/claiming OutboxEvent, then evaluates the opaque + handle exactly once against final typed event/claim/lease/generation facts + recomposed from locked rows. It retains the one AuthorizationDecision in the + dispatch causation/audit path, never asks AUTH to commit, and rejects missing, + reused, mismatched, cross-session or cross-action handles. +- [ ] While the action is planned, success-path domain tests use only an + explicit decision/fake below that prepared seam. Real-kernel and worker tests + remain fail-closed; transaction tests cover prepare denial, stale claim, + final-context mismatch and both AUTH-first/product-lock race orders. - [ ] One explicit handler registry, stable Celery task IDs, fenced claim, attempt, retry schedule, dead-letter, replay, retention and bounded recovery preserve immutable event identity. @@ -60,6 +76,9 @@ dependency, workflow, test or coverage weakening query outbox persistence directly. - [ ] Handler invocation occurs after commit; no feature event semantics or compensation adapter is implemented here. +- [ ] The post-CON AUTH activation gate owns end-to-end central evaluator and + service-assignment proof against this merged seam without editing dispatcher + code. CON-08A and any worker enablement remain blocked until that gate merges. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md index 8d3a8c76..42079553 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md @@ -2,9 +2,10 @@ ## Goal and risk -Implement authorized binding create/read/suspend/resume commands behind -unregistered composition. Retirement stays planned until dependency rows exist. -L1 payment/auth risk. +Implement authorization-ready binding create/read/suspend/resume domain behavior +and canonical resource composition while production routes remain unregistered +and AUTH actions remain planned. Retirement stays planned until dependency rows +exist. L1 payment/auth risk. ## Allowed files @@ -27,16 +28,27 @@ concrete adapter, provider secret/ref, dependency or CI weakening ## Acceptance criteria -- [ ] Proposed actions follow AUTHORIZATION_HANDOFF after AUTH registration. +- [ ] AUTH's registration checkpoint is merged: exact planned binding actions, + typed context contracts, applicable AdminRoleGrant definitions and prepared + `T` protocol, plus the planned `compensation.fulfillment.report` ActionId/new + PermissionId and an active canonical callback service ActorProfile/link with + its exact action assignment. Both binding and callback actions remain planned + and fail-closed. This chunk changes no AUTH file and uses only an explicit + test decision/fake below the authorization boundary for domain-success tests. - [ ] Create validates canonical active service ActorProfile, exact AUTH-owned action assignment and non-secret route identity. - [ ] Mutations follow PLAN locks and transaction-revalidate authority; own-state - concurrent suspend/resume is deterministic. + concurrent suspend/resume is deterministic. They use the AUTH-prepared handle + and evaluate it once against facts recomposed from locked binding/project rows. - [ ] Retire remains registered/planned but non-executable; any attempt fails - closed with stable not-active behavior. CON-10B activates dependency-aware - retirement after assignment/lease/award/delivery rows exist. + closed with stable not-active behavior. CON-10B later implements its + dependency-aware resource behavior after assignment/lease/award/delivery rows + exist; the post-CON-10B AUTH gate alone activates the action. - [ ] Claims/delivery/callback races remain owned by 05/06/08A/08B/REV-13. - [ ] Production OpenAPI remains unchanged. +- [ ] A later AUTH-owned gate integrates the central evaluators against this + merged composer and alone changes availability. CON-04B cannot start until + that activation passes. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md index bf1d1976..80ae6cf5 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md @@ -2,8 +2,9 @@ ## Goal and risk -Implement authorized draft/read/update/publish/retire behavior behind -unregistered composition. L1 payment/auth risk. +Implement authorization-ready draft/read/update/publish/retire domain behavior +and canonical resource composition while routes remain unregistered and AUTH +actions remain planned. L1 payment/auth risk. ## Allowed files @@ -27,16 +28,24 @@ PaymentPolicy fallback, dependency or CI weakening ## Acceptance criteria -- [ ] Proposed actions follow AUTHORIZATION_HANDOFF; read maps to - `compensation.policy.manage`, never broad `project.read`. +- [ ] AUTH's registration checkpoint is merged: exact planned policy actions, + typed context contracts, Finance Authority grant definitions and prepared + `T` protocol. Read maps to `compensation.policy.manage`, never broad + `project.read`. This chunk changes no AUTH file, keeps the real kernel + fail-closed while planned, and uses only an explicit test decision/fake below + the authorization boundary for domain-success tests. - [ ] Publish locks project/selector/version/bindings, revalidates authority, validates closed rules/active bindings, and atomically changes selector with - audit/outbox. + audit/outbox. It evaluates one AUTH-prepared handle against facts recomposed + from those locked rows. - [ ] Explicit unpaid is valid; absent/incomplete/contradictory setup is stable remediation failure; removed PaymentPolicy never executes or acts as fallback. - [ ] Own-state concurrent draft/publish/retire/selector/binding changes are deterministic. Claim races remain 05/06; delivery/callback races remain 08. - [ ] Production OpenAPI remains unchanged. +- [ ] A later AUTH-owned gate integrates the central evaluators against this + merged composer and alone changes availability. CON-05A remains blocked until + that activation passes. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md index 669095c6..2a01fbb9 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md @@ -78,11 +78,14 @@ review behavior or unrelated checker behavior the active specification inventory and REV-13 owns final joint release docs. - [ ] A zero-consumer scanner proves the remaining PaymentPolicy model/table is unreachable compatibility residue pending 05B, not an executable fallback. -- [ ] Existing task-claim ActionId/authority is allowed and revalidated before - assignment/freeze commit; WS-CON introduces no local role checks. +- [ ] AUTH-13 or an approved AUTH successor has registered and activated the + currently absent ActionId `task.claim` mapped to existing PermissionId + `task.claim`, with its exact-project contributor evaluator and prepared `T` + protocol. WS-CON introduces no local role checks or AUTH edits. - [ ] Claim follows the PLAN lock order, locks every referenced binding by UUID, - revalidates task-claim authority after relevant locks, and copies one - published same-project version whose bindings are active. + evaluates the AUTH-prepared task-claim handle once against final locked task/ + project/assignment facts, and copies one published same-project version whose + bindings are active. - [ ] Missing/suspended/invalid policy fails with stable compensation error and creates no assignment/task/audit/outbox partial state. - [ ] Concurrent publish vs claim freezes one committed old or new version, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md index 81065d87..d8baa1d8 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md @@ -57,8 +57,11 @@ provider/artifact/adapter calls - [ ] Missing/inactive/invalid policy or binding returns stable typed failure with no WS-CON/audit/outbox partial state. - [ ] Contract explicitly requires REV-03's immutable non-null ReviewLease FK - and REV-06's `review.claim` revalidation, injection, lease write, audit/outbox, - release/expiry behavior, and integrated tests; CON-06 implements none of them. + plus AUTH's planned `review.claim` typed/prepared contract and REV-06's hidden + resource composition, final-context integration, injection, lease write, + audit/outbox, release/expiry behavior, and planned-action fail-closed tests; + CON-06 implements none of them. After both merge, AUTH alone integrates the + evaluator and activates the action before production execution. - [ ] Policy publish vs claim concurrency freezes one committed version and passes both lock permutations without deadlock. - [ ] Binding suspend/retire versus lookup is covered in both permutations. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md index 52733828..a62af8d2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md @@ -70,8 +70,11 @@ reputation scoring - [ ] Participant accepts only a typed allowed `review.decision` whose actor, action, Review/lease/Submission/project resource, request, and correlation facts match the locked caller transaction; denied, stale, unrelated, or - mismatched evidence is rejected. REV-10 owns final transaction-time authority - revalidation and mandatory injection. + mismatched evidence is rejected. AUTH first supplies the planned + `review.decision` typed/prepared contract; REV-10 then owns hidden resource + composition, final-context integration and mandatory injection while the real + kernel remains fail-closed. After both merge, AUTH alone integrates the + evaluator and activates the action before production execution. - [ ] Each contribution creates one pending evidence projection and one stable projection request event in the same transaction. - [ ] Versioned `ContributionRecorded`, `CompensationAwardCreated`, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md index 16fced58..9d912e67 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md @@ -35,6 +35,12 @@ optional/no-op/fallback dispatch fence or REV edits to CON product files ## Acceptance criteria +- [ ] The post-CON-02B AUTH checkpoint has integrated and activated the real + `outbox.dispatch` evaluator for the fixed dispatcher, including exact active + actor/link/action-assignment revalidation and end-to-end proof through the + merged prepared-dispatch seam. Real-kernel dispatch succeeds only for that + service identity; every human, stale assignment and mismatched event fails + closed. This chunk does not edit AUTH or activate a public route. - [ ] Reuse shared dispatcher/hashing/idempotency/worker/session/task-settings; preserve event/payload/binding/idempotency identity. - [ ] Execute only as a handler of a currently claimed `outbox.dispatch` diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md index 67bc8880..1648bdf1 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -29,8 +29,12 @@ optional/no-op/fallback callback fence or REV edits to CON callback policy ## Acceptance criteria -- [ ] AUTH callback PermissionId/ActionId/parity/exact assignment is merged; - human AdminRoleGrant/ProjectRoleGrant never satisfies it. +- [ ] The callback PermissionId/ActionId/audit parity, canonical service + ActorProfile/link and exact assignment prerequisite already merged before + CON-04A. AUTH has now also merged the typed context, service-capable dependency + and prepared `T` contracts needed by this handler. The real kernel remains + fail-closed while planned; human AdminRoleGrant/ProjectRoleGrant never + satisfies it. - [ ] Locks revalidate actor/link/assignment/route/award/project/instrument/ binding/state; durable rate control is per actor+binding. - [ ] After signature verification and AUTH/idempotency locking, callback @@ -55,6 +59,8 @@ optional/no-op/fallback callback fence or REV edits to CON callback policy - [ ] Behavior tests prove failed then fulfilled is allowed, fulfilled then failed/changed-fulfilled is denied, and partial fulfillment is rejected. - [ ] Production OpenAPI remains unchanged and secrets/refs are never stored. +- [ ] A later AUTH-owned gate integrates the callback evaluator against this + merged implementation and alone changes availability; CON-11 waits for it. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md index 65323531..908c2856 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md @@ -28,6 +28,28 @@ duplicate canonicalizer/worker/session/idempotency, dependency/CI weakening ## Acceptance criteria +- [ ] AUTH has registered the planned + `artifact.contribution_evidence.binding.create` action with existing + `artifact.binding.create` PermissionId, typed context, D10 prepared-mutation + protocol and only the exact added assignment on the existing fixed + `workstream.artifact.binding` ActorProfile/link; ART has merged its capability. + A new or broader worker principal is forbidden. The real kernel remains + fail-closed while planned and CON adds no AUTH or ART bypass. +- [ ] The handler prepares authority from a server-resolved contribution and + evidence-role target before locking its CON-owned projection/contribution + rows, then passes the opaque handle, deterministic bytes and canonical + project/contribution/role/schema/digest facts into the ART-owned caller- + transaction capability. ART locks/composes ART-owned admission facts after + those rows, completes the handle's one final evaluation, stages the one + AuthorizationDecision plus admission/put-attempt continuation, and never + commits or performs provider I/O in that transaction. CON never imports ART + persistence, evaluates ART facts or invokes the final evaluator itself. +- [ ] While planned, success-path evidence tests use only an explicit fake below + that seam and real-kernel/worker tests fail closed. Transaction tests cover + prepare denial, CON/ART final-fact drift, handle misuse, ART Transaction-A + rollback, post-commit provider continuation, and AUTH -> CON -> ART lock races + in both relevant orders. Provider I/O is impossible before Transaction A + commits. - [ ] Versioned minimal schema/disclosure matrix excludes reviewer-private, compensation/provider, credential, external-receipt and unnecessary actor data. - [ ] Versioned `ContributionEvidenceProjectionRequested` reuses shared hashing, @@ -36,6 +58,10 @@ duplicate canonicalizer/worker/session/idempotency, dependency/CI weakening only projection state and verified binding reference. - [ ] LocalStorage/MinIO capability conformance passes; new-schema rebuild retains prior immutable bundles. +- [ ] A later AUTH-owned activation gate, after the ART capability and CON + composer are merged, integrates the evaluator against the merged seams + without editing CON feature code and alone changes availability; CON-11 + waits. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md index 70ec4822..d4ef7638 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -27,8 +27,11 @@ dependency, test, coverage or CI weakening ## Acceptance criteria -- [ ] Exact proposed actions/canonical facts, pre-filter pagination and - cross-project concealment are required. +- [ ] AUTH has registered the exact planned contribution self/project read + actions, typed contexts and applicable actor-self/AdminRoleGrant definitions. + CON composes canonical facts; pre-filter pagination and cross-project + concealment are required. The real kernel remains fail-closed while planned; + a later AUTH gate owns evaluator integration and availability before CON-10A. - [ ] Matrix proves self, Project Manager, Finance, Operator/Audit views and Reviewer project-wide denial/self-only behavior without private/provider data. - [ ] ART result matches immutable projection identity; evidence failure never diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md index 386d0608..09b3fca4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md @@ -29,8 +29,11 @@ dependency, test, coverage or CI weakening ## Acceptance criteria -- [ ] Exact proposed actions/canonical facts, stable pre-filter pagination and - cross-project concealment are enforced. +- [ ] The post-CON-09B AUTH contribution-read activation is merged. AUTH has + registered the exact planned award self/project actions, typed contexts and + applicable actor-self/AdminRoleGrant definitions. CON composes canonical + facts; stable pre-filter pagination and cross-project concealment are + enforced. A later AUTH gate activates award reads before CON-10B. - [ ] Self, Finance/project/Operator/Audit disclosure is separated; Reviewer is self-only absent a later approved assigned-review action. - [ ] Contribution, money, points, delivery acknowledgement and fulfillment diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md index c6eab0b4..bd024394 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -29,14 +29,20 @@ dependency, test, coverage or CI weakening ## Acceptance criteria -- [ ] Ops/audit actions follow handoff and revalidate after locks. +- [ ] The post-CON-10A AUTH award-read activation is merged. AUTH has registered + planned binding-retire, delivery-reconcile, status, reconciliation, rebuild + and audit actions with exact AdminRoleGrant definitions, typed contexts and + prepared `T` handling where required. CON proves domain behavior below the + authorization boundary and changes no AUTH file; a later AUTH gate integrates + these evaluators and activates them before CON-11. - [ ] Finance project and reason-bound Operator reconciliation use distinct guards; Project Manager/contributor denials are explicit. - [ ] Reconcile preserves original identities; rebuild changes projection only; bounded range/reason/audit/idempotency is durable. - [ ] Audit read/export purpose/scope/redaction/max range is proved without provider or sensitive failure leakage; OpenAPI remains hidden. -- [ ] Dependency-aware binding retirement now activates: it locks policy, +- [ ] Dependency-aware binding retirement is implemented as hidden behavior and + remains planned until the later AUTH gate activates it. It locks policy, assignment, lease, award, delivery and receipt dependencies, denies any active/unfinished/unfulfilled reference, races all dependency changes in both orders, and afterward permits only exact accepted-receipt replay. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index 51ee8450..9588021d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -38,8 +38,11 @@ archival reference edits ## Acceptance criteria - [ ] Startup/preflight fails closed unless exact migrations, AUTH action - definitions/owners/availability/service assignments, ART capabilities, outbox - dispatcher, REV-10 integration and provider readiness are present. + definitions/owners/PermissionId mappings/availability/typed + contexts/evaluators/matched authorities/prepared protocol/service + dependencies and assignments, ART capabilities, outbox dispatcher, REV-10 + integration and provider readiness are present. An active action without its + executable evaluator or feature behavior fails startup. - [ ] Hidden integration proves `/api/v1` target paths are absent from production OpenAPI before release and no partial direct construction path exists. - [ ] `CONFORMANCE_MATRIX.md` has collected node IDs/evidence for every adopted diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md index c5c84921..74f9210d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md @@ -53,6 +53,10 @@ active runtime documentation adoption - [x] First implementation/spec chunk remains proposed until human approval. - [x] Required plan reviewers complete and all valid findings are resolved or recorded for human decision. +- [x] AUTH-07B refresh records the two-active/48-planned runtime, separates AUTH + registration from post-feature AUTH activation, adds the prepared `T` + protocol and absent upstream `task.claim` gate, and receives fresh required + review/evidence against current trusted main. ## Verification commands @@ -71,7 +75,7 @@ only planning Markdown and no CI/tests. ## Human review focus -Review unresolved D1/D4/D7/D8, confirm accepted D3/D5/D6/D9 and approved D2, +Review unresolved D1/D4/D7/D8/D10, confirm accepted D3/D5/D6/D9 and approved D2, and assess D2's unresolved legacy-row handling rule, exact authorization dependencies, artifact boundary, cross-initiative gates, and whether every runtime chunk is independently reviewable. From fda0a0498d61d66122f903d1059232512c6a520f Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Wed, 15 Jul 2026 21:23:20 +0100 Subject: [PATCH 04/22] Bind WS-CON AUTH-07B plan review evidence --- .../STATUS.md | 6 +- ...S-CON-001-PLAN-internal-review-evidence.md | 100 ++++++++++++++++++ 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 39c1e231..8a611a61 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -3,8 +3,8 @@ ## Current status Base planning passed its earlier review. The latest merged AUTH-07B executable -kernel reconciliation and resulting AUTH/CON activation-boundary repair are -under fresh internal review. Application code is unchanged. +kernel reconciliation and resulting AUTH/CON activation-boundary repair passed +fresh internal review. Application code is unchanged. The reconciled working Markdown transcription, supplied generation-2 PDF, original archival PDF, current backend, active docs, merged WS-AUTH authorization catalogue, and active parallel WS-REV plan delta have been mapped. @@ -25,7 +25,7 @@ implementation is active. | Chunk | Status | Branch | PR | Notes | |---|---|---|---:|---| -| `WS-CON-001-PLAN` | AUTH-07B boundary re-review pending | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; current refresh records merged AUTH-07B at `90eca12`, exact AUTH executable gates, archive-scanner ownership, and non-consumable REV head `e59e2bb`. | +| `WS-CON-001-PLAN` | Reviewed; human approval gate | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; reviewed refresh records merged AUTH-07B at `90eca12`, exact AUTH executable gates, archive-scanner ownership, and non-consumable REV head `e59e2bb`. | | `WS-CON-001-01` | Proposed | - | - | No runtime work. | | `WS-CON-001-02A` through `11` | Proposed | - | - | Each requires separate explicit start; REV-13 owns final activation. | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index ed84cc04..35a512f2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -1,5 +1,105 @@ # Internal Review Evidence: WS-CON-001-PLAN +## 2026-07-15 AUTH-07B Executable-Boundary Reconciliation + +This addendum is the current authoritative review state. It supersedes the +older trusted-main SHA, AUTH runtime assumptions, activation choreography and +parallel-REV freshness statements below. The reviewed plan is based on trusted +`main` `90eca12f6398f2ef168e634244d912765572c3e5` (merged AUTH-07B). + +Reviewed code SHA: 31f7350be4a964faed4f3f0487a53de65c3f6840 + +Reviewed planning-tree SHA-256: +`07f8ed891ff15302b7b1a8e223cc122d98298d99ab0dd35660699866fff63cac` + +The tree digest excludes this evidence file and includes the final initiative +status. It is reproduced from the initiative directory with: + +```bash +find . -type f ! -path './reviews/WS-CON-001-PLAN-internal-review-evidence.md' -print0 | sort -z | xargs -0 sha256sum | sha256sum +``` + +Reviewed at: 2026-07-15T20:22:23Z + +Reviewer run IDs: architecture/senior/reuse=`/root/plan_arch_senior`; +QA/test/product/ops/docs=`/root/plan_qa_product_docs`; +security/auth/privacy=`/root/plan_security_auth` + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | Activation waves, prepared mutation seams, transaction ownership and chunk boundaries are executable. | +| QA/test | PASS | None | Local gates, failure cases, races, real-kernel denial and post-activation proof are explicit. | +| security/auth | PASS | None | Canonical identifiers, grants, fixed service identities, one-decision semantics and AUTH-only activation are coherent. | +| product/ops | PASS | None | Complete PaymentPolicy removal, legacy-row human gate, callback/delivery behavior and release dependencies remain explicit. | +| architecture | PASS | None | Review choreography is non-circular; outbox, ART, REV, AUTH and CON ownership boundaries do not cross. | +| CI integrity | N/A - with approved reason | None | This delta changes planning Markdown only and does not modify CI, dependencies, tests or coverage gates. | +| docs | PASS | None | Trusted-main facts, sibling freshness, source provenance, blockers and ownership language are truthful. | +| reuse/dedup | PASS | None | The plan reuses the central prepared protocol, shared dispatcher, ART capability, `workstream.artifact.binding` and existing grants/permissions. | +| test delta | N/A - with approved reason | None | No runtime test file changed; every later runtime chunk still requires test-delta review and retained evidence. | + +Open sub-agent sessions: none + +Valid findings addressed: yes + +- Recorded the exact merged AUTH-07B state: 74 PermissionIds, 50 ActionIds, + two active and 48 planned actions. All 23 proposed WS-CON ActionIds remain + absent. The two proposed service-only PermissionIds remain absent. +- Kept authorization implementation entirely AUTH-owned: catalogue/owner/audit + parity, closed typed contexts, evaluator dispatch, matched authority, grant + loading/revalidation, service actors/assignments, composition dependencies and + availability changes. +- Added an AUTH-owned D10 prepared-mutation protocol for every `T` operation: + authority rows lock first, an opaque caller-session-bound handle is finalized + once against locked product facts, one decision is staged, and AUTH never + commits. Missing, reused, mismatched and cross-session/action handles deny. +- Repaired activation into registration -> hidden fail-closed feature behavior + -> AUTH evaluator/activation waves. Review actions add the required REV-owned + composition stage: AUTH registration -> CON capability/participant -> REV + hidden composition while planned -> AUTH activation -> later readiness/public + activation. +- Added the missing upstream dependency that `task.claim` has an existing + PermissionId but no ActionId. AUTH-13 or a reviewed AUTH successor must order + registration/typed-prepared contract, task resource behavior and evaluator/ + activation before CON-05A. +- Required the callback ActionId/new PermissionId and active binding-specific + service actor/link/exact assignment before CON-04A so binding creation is + executable while the callback action remains planned. Binding retirement + remains planned until its CON-10B dependency guards exist and a later AUTH + gate activates it. +- Put the D10 call site in CON-02B before OutboxEvent claim and made the active + `outbox.dispatch` evaluator/assignment proof a local CON-08A gate. +- Repaired evidence ownership: CON prepares authority and locks only CON facts; + ART locks/composes admission facts and performs the one final evaluation in + durable Transaction A without commit/provider I/O. Provider continuation is + post-commit under ART authority. The exact action reuses the existing fixed + `workstream.artifact.binding` principal and existing + `artifact.binding.create` PermissionId. +- Recorded sibling REV head `e59e2bbe823bc0ee2b0e59ff35f8352349618b2e` + as non-consumable until its AUTH-07B choreography, outbox claim wording, + source SHA and commit-bound evidence are refreshed and reviewed. +- Preserved the approved complete PaymentPolicy semantic cutover and physical + removal. Only the legacy-row rebuild-versus-classified-backfill choice remains + a human decision. + +Deterministic evidence passed: `git diff --check`; Markdown links for 38 changed +Markdown files; stale Workstream wording; artifact-contract state; loop-memory +state; 71 agent-gate tests; and direct AUTH catalogue/runtime assertions for the +counts, availability, absent WS-CON IDs, absent service permissions, +`task.claim`, resource variants and matched-authority state. The authorization +stale-doc scan continues to flag exactly ten `HUMAN_WORKER_VOCABULARY` +occurrences in the explicitly non-canonical working transcription; CON-01 owns +its exact byte-preserving archival rename/classification and active-spec +reconciliation. This is not a waiver for an active document. + +The focused async AUTH test environment was unavailable at final rerun because +this worktree's `backend/.venv` lacked an interpreter/plugin installation. That +does not weaken the planning proof: runtime files are byte-unchanged from +trusted main, the catalogue assertion passed with the available interpreter, +and no runtime completion is claimed. + +Application/runtime code changed: no. The original PDF deletion remains an +unstaged user-worktree change and is excluded from both reviewed commits. + ## 2026-07-15 Final Trusted-Main And Parallel-Dependency Review This addendum is the current authoritative review state and supersedes older From 7f999d10ef1f772da44b23add307ccca655da953 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Thu, 16 Jul 2026 10:17:05 +0100 Subject: [PATCH 05/22] Reconcile WS-CON plan with AUTH-08 --- .../AUTHORIZATION_HANDOFF.md | 144 ++++++++++++++---- .../CHUNK_MAP.md | 15 +- .../CONFORMANCE_MATRIX.md | 6 +- .../DECISIONS.md | 65 +++++++- .../DISCOVERY.md | 32 ++-- .../JOINT_RELEASE_HANDOFF.md | 43 ++++-- .../PLAN.md | 65 ++++++-- .../RISKS.md | 3 + .../SOURCE_MANIFEST.md | 49 +++--- .../STATUS.md | 23 +-- ...-CON-001-01-canonical-contract-adoption.md | 11 +- ...-001-04A-hidden-adapter-binding-service.md | 5 + ...-04B-hidden-compensation-policy-service.md | 5 + ...ON-001-08B-inbound-fulfillment-callback.md | 6 + ...B-authorized-contribution-evidence-read.md | 8 +- ...01-10A-contribution-award-product-reads.md | 11 +- ...1-10B-operations-reconciliation-rebuild.md | 20 ++- .../WS-CON-001-11-hidden-release-readiness.md | 10 ++ ...PLAN-contribution-compensation-planning.md | 79 +++++++++- 19 files changed, 475 insertions(+), 125 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md index 1c1d4190..1ba1d1a7 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -3,21 +3,24 @@ ## Status and ownership Every WS-CON-specific ActionId below is **proposed and currently absent**. -Trusted `main` `90eca12` includes AUTH-07B. The canonical catalogue now contains -74 PermissionIds and 50 non-WS-CON ActionIds: only -`actor.profile.read_self` and `actor.profile.update_self` are active; the other -48 are planned. Neither proposed WS-CON service-only PermissionId is registered, -and none of the 23 proposed WS-CON ActionIds is in the merged closed enum. - -AUTH-07B also makes the runtime boundary concrete. `AuthorizationService` -currently evaluates only the two actor-self actions; -`AuthorizationResourceContext` accepts only actor-self and system variants; -`MatchedAuthorityKind` contains only `actor_self`; and the current FastAPI -composition dependency rejects service subjects. Registering an ActionId as -planned is therefore intentionally insufficient: every WS-CON surface would -continue to fail with `action_unavailable` until AUTH supplies its typed -context, evaluator, principal/grant or exact service assignment, transaction -protocol, and active availability. +Trusted `main` `aa0fdcd` includes AUTH-08 through PR #131. The canonical +catalogue contains 74 PermissionIds and 57 non-WS-CON ActionIds: the two +actor-self actions and seven AUTH-08 administrative actions are active; 48 +actions remain planned. Neither proposed WS-CON service-only PermissionId is +registered, and none of the 23 proposed WS-CON ActionIds is in the merged +closed enum. + +AUTH-08 materially advances, but does not complete, the runtime boundary. +`AuthorizationResourceContext` now has eight closed variants; +`MatchedAuthorityKind` has `actor_self` and `admin_role_grant`; decisions carry +the complete resource-context digest plus matched grant/scope evidence; and the +kernel evaluates the self and administrative families. The current FastAPI +actor dependency still rejects service subjects, ProjectRoleGrant and service +assignment authority are not implemented, and no WS-CON evaluator exists. +Registering an ActionId as planned is therefore intentionally insufficient: +every WS-CON surface still fails with `action_unavailable` until AUTH supplies +its action-specific context, exact candidate-role filter/evaluator, remaining +principal or service assignment, transaction protocol, and active availability. AUTH owns ActionId/ActionOwner and PermissionId registration, typed/PostgreSQL/audit parity, availability transitions, central evaluator @@ -43,22 +46,31 @@ those checkpoints. Across those checkpoints AUTH must provide all applicable items below: -1. Register the exact ActionId, ActionOwner, PermissionId mapping and audit/SQL - parity. Add only the two approved new PermissionIds, +1. After D12 approval, register the exact ActionId, one ActionOwner/activation- + custody mapping, PermissionId mapping and audit/SQL parity. No feature owner + or registration PR is a second activation authority. If the human approves + D4's service expansion, add only the two + proposed new PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`; all other rows reuse the existing PermissionId in the table. 2. Add closed typed resource-context variants for the target families below and extend the decision resource type without accepting generic dictionaries, client-supplied grants, raw PermissionIds, or CON persistence objects. -3. Replace the current two-action-only evaluator branch with an explicit closed +3. Extend the current self/admin family dispatch into an explicit closed evaluator registry or equivalent AUTH-owned dispatch. No runtime plugin discovery, service locator, fallback allow path, CON repository import, or action string construction is permitted. 4. Extend matched authority for exact actor-self, AdminRoleGrant, ProjectRoleGrant, and service-action-assignment authority as applicable. - AUTH-08 grant definitions, AUTH-09 service actor/assignment truth, and - AUTH-10 project contributor grants must be merged before dependent - evaluators activate. + AUTH-08's durable AdminRoleGrant definitions and scope evidence are now + merged and must be reused; AUTH-09 service actor/assignment truth and + AUTH-10 project contributor grants must merge before dependent evaluators + activate. Permission membership alone is not an allow: each action evaluator + must enforce the exact candidate-role allowlist in the table below. AUTH + extends its repository/kernel candidate lookup with an evaluator-owned closed + AdminRole set intersected with `permissions_for(role)` before query; neither + CON nor request data may supply that set. An actor holding both an excluded + and eligible role must match the eligible grant deterministically. 5. For `T` mutations, provide one caller-session-bound prepared-authorization protocol. It accepts the action plus a server-resolved preliminary target, locks/revalidates AUTH actor/link/grant or service-assignment rows first, @@ -69,10 +81,18 @@ Across those checkpoints AUTH must provide all applicable items below: lifecycle/availability/authority denial terminates with that one denial and returns no handle; a successful prepare stages no allow until final evaluation. Missing, - mismatched, reused, cross-session or cross-action handles fail closed. + mismatched, reused, cross-session or cross-action handles fail closed. The + final decision preserves AUTH-08's complete `resource_context_digest`, exact + `matched_grant_id` and covered project scope when grant-backed. 6. For `Q` reads, retain request-scoped `require(action_id, typed_resource_context)` while loading canonical authority and applying pre-filter/concealment rules. No decision or grant cache survives a request. + Every route explicitly commits its own read/mutation plus decision evidence; + the AUTH dependency rolls back an abandoned transaction and never rescues a + missing feature commit. Hidden CON domain services only flush and never + commit; REV-13's actual route owners prove the commit/rollback behavior. + AUTH evidence failure remains the typed retryable service-unavailable path + introduced by AUTH-08. 7. Add a service-capable composition dependency for fixed workers and bound callbacks. Human grants never satisfy a service-only action, service assignments never imply a human role, and suspended/revoked/deactivated @@ -94,9 +114,47 @@ The current WS-AUTH chunk map has no WS-CON registration or activation chunks. The AUTH owner must first add and internally review bounded chunk contracts for the registration checkpoint, the shared prepared protocol if not delivered by an earlier AUTH foundation, and each activation wave below. Do not silently -fold WS-CON permissions/actions into AUTH-08 through AUTH-16 or an unrelated +fold WS-CON permissions/actions into AUTH-09 through AUTH-16 or an unrelated feature PR without an allowed-file/acceptance/reviewer amendment. +## Proposed AUTH-owned ActionOwner custody + +Canonical `ActionOwner` currently means the implementation chunk allowed to +activate a reserved action. Because the user requires authorization activation +to remain in the authorization service, a CON/REV feature chunk cannot also be +the ActionOwner. D12 proposes the following exact AUTH-owned activation chunks; +the AUTH owner and human must approve/add these enum members and chunk contracts +before any registration checkpoint uses them. + +| Proposed enum member | Exact ActionOwner value / AUTH activation chunk | Exact ActionIds | +|---|---|---| +| `AUTH_CON_OUTBOX` | `WS-AUTH-001-CON-OUTBOX` | `outbox.dispatch` | +| `AUTH_CON_BINDING` | `WS-AUTH-001-CON-BINDING` | `compensation.adapter_binding.read`, `compensation.adapter_binding.create`, `compensation.adapter_binding.suspend`, `compensation.adapter_binding.resume` | +| `AUTH_CON_POLICY` | `WS-AUTH-001-CON-POLICY` | `compensation.policy.read`, `compensation.policy.create_draft`, `compensation.policy.update_draft`, `compensation.policy.publish`, `compensation.policy.retire` | +| `AUTH_CON_CALLBACK` | `WS-AUTH-001-CON-CALLBACK` | `compensation.fulfillment.report` | +| `AUTH_CON_EVIDENCE` | `WS-AUTH-001-CON-EVIDENCE` | `artifact.contribution_evidence.binding.create` | +| `AUTH_CON_CONTRIBUTION_READS` | `WS-AUTH-001-CON-CONTRIBUTION-READS` | `contribution.read_self`, `contribution.read_project` | +| `AUTH_CON_AWARD_READS` | `WS-AUTH-001-CON-AWARD-READS` | `compensation.award.read_self`, `compensation.award.read_project` | +| `AUTH_CON_OPERATIONS` | `WS-AUTH-001-CON-OPERATIONS` | `compensation.adapter_binding.retire`, `compensation.delivery.reconcile`, `compensation.status.read`, `compensation.reconcile.run`, `contribution.projection.rebuild`, `audit.read`, `audit.export` | + +This table maps all 23 proposed WS-CON ActionIds exactly once. A registration +PR may reserve an action for its named future activation chunk, but only that +exact ActionOwner may later change availability after the feature gate. The +feature resource owner remains the CON/ART owner in the handoff table below and +does not gain catalogue custody. + +The same semantic conflict already exists for the two review actions consumed +here: merged `review.claim` is owned by `REV_06` and `review.decision` by +`REV_08`, while the repaired choreography requires AUTH-owned activation after +REV composition. D12 therefore also proposes `AUTH_REV_CLAIM = +WS-AUTH-001-REV-CLAIM` and `AUTH_REV_DECISION = +WS-AUTH-001-REV-DECISION`, with a reviewed AUTH registration amendment that +transfers those planned actions before activation. Alternatively, the human may +choose a global, reviewed redefinition of ActionOwner as feature/resource +owner—but then AUTH must introduce a separate closed activation-custody type. +Leaving the current dual meaning or allowing both AUTH and product chunks to +activate is forbidden. + ## Proposed closed handoff `T` means the AUTH-owned prepared protocol locks authority first and the feature @@ -120,17 +178,47 @@ canonical rows. | `compensation.adapter_binding.resume` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | actor/link/action assignment and adapter capability are active; no silent backlog mutation | T | AUTH / CON-04A | | `compensation.adapter_binding.retire` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | no active-policy reference, unfinished frozen assignment/lease, or unfulfilled award; after retirement only exact replay of a previously accepted receipt remains | T | AUTH / CON-10B | | `compensation.award.read_self` | existing `contribution.read_self` | CompensationAward | human beneficiary | award/project/beneficiary; exact subject match; safe status only | Q | AUTH / CON-10A | -| `compensation.award.read_project` | existing `compensation.award.read` | Project award collection | Finance Authority, Operator/Audit as separately eligible | exact project/ops scope; pre-filtered pagination; no provider refs | Q | AUTH / CON-10A | -| `compensation.delivery.reconcile` | existing `compensation.delivery.reconcile` | CompensationDelivery | Finance Authority or reason-bound Operator candidate | exact project/delivery; immutable event/payload/binding/idempotency identity; distinct finance/operator guards | T | AUTH / CON-10B | +| `compensation.award.read_project` | existing `compensation.award.read` | Project award collection | D11 candidate: Finance Authority and Operator/Audit; Project Manager inclusion unresolved | exact project/ops scope; pre-filtered pagination; no provider refs | Q | AUTH / CON-10A | +| `compensation.delivery.reconcile` | existing `compensation.delivery.reconcile` | CompensationDelivery | D11 candidate: Finance Authority plus reason-bound Operator if approved | exact project/delivery; immutable event/payload/binding/idempotency identity; distinct finance/operator guards | T | AUTH / CON-10B | | `compensation.status.read` | existing `operations.status.read` | Compensation operations projection | Operator candidate | bounded operational scope; redacted failure class; no beneficiary/provider secret | Q | AUTH / CON-10B | | `compensation.reconcile.run` | existing `operations.reconcile.run` | Compensation reconciliation request | reason-bound Operator candidate | bounded project/range; durable request only; immutable truth comparison; never repair canonical awards/receipts; async execution is a shared-outbox handler under fixed dispatch authority | T | AUTH / CON-10B | | `contribution.projection.rebuild` | existing `operations.projection.rebuild` | Contribution projection rebuild request | reason-bound Operator candidate | bounded project/version; durable request only; rebuild projection only; immutable truth unchanged; async execution is a shared-outbox handler under fixed dispatch authority | T | AUTH / CON-10B | -| `audit.read` | existing `audit.read` | WS-CON audit projection | Audit/Operator candidate | exact project/ops scope; redaction and pagination; append-only truth | Q | AUTH / CON-10B | -| `audit.export` | existing `audit.export` | bounded WS-CON audit export | Audit candidate | exact scope, purpose, maximum range, redaction, export evidence | T | AUTH / CON-10B | +| `audit.read` | existing `audit.read` | WS-CON audit projection | D11 candidate set unresolved against broader merged roles | exact project/ops scope; redaction and pagination; append-only truth | Q | AUTH / CON-10B | +| `audit.export` | existing `audit.export` | bounded WS-CON audit export | D11 candidate set unresolved against Access Administrator/Audit permission candidates | exact scope, purpose, maximum range, redaction, export evidence | T | AUTH / CON-10B | | `compensation.fulfillment.report` | **new service-only `compensation.fulfillment.report`** | frozen CompensationAdapterBinding + Award | exact bound service ActorProfile only | actor/link/action assignment active; route identity, award, project, instrument, frozen binding and receipt state all match | T | AUTH / CON-08B | | `outbox.dispatch` | **new service-only `outbox.dispatch`** | claimed shared OutboxEvent | fixed `workstream.outbox.dispatcher` ActorProfile only | current claim/lease/generation; immutable event, payload and idempotency identity; handler side effects occur only under this claimed command | T | AUTH / CON-02B shared-outbox prerequisite; consumed by CON-08A | | `artifact.contribution_evidence.binding.create` | existing `artifact.binding.create` | ContributionRecord evidence role | existing fixed `workstream.artifact.binding` service ActorProfile only | exact contribution/project/role/schema/digest; ART admission/verification receipt; no raw provider ref | T | AUTH / ART capability + CON-09A composer | +## Merged AUTH-08 role-matrix reconciliation + +AUTH-08 proves the five AdminRole definitions and exact permission candidates, +but one merged row conflicts with the reconciled candidate WS-CON human +authority matrix. `finance_authority` contains +`compensation.delivery.reconcile`; `operator` does not. The candidate proposes +both a covered Finance Authority and a reason-bound system-scoped Operator for +the exact `compensation.delivery.reconcile` action, but only D2 has explicit +human approval. D11 therefore remains a human decision. If the Operator +behavior is approved, a reviewed AUTH-owned successor must add the **existing** +`compensation.delivery.reconcile` PermissionId to the closed Operator +definition, update definition/API/kernel matrix tests, and retain the action- +specific reason/scope guards. If it is rejected, the active WS-CON contract and +handoff must remove the Operator candidate before registration. No new +PermissionId is needed in either case, and CON must not query roles or emulate +the missing candidate locally. + +The inverse constraint is equally important, but is also unresolved rather than +implicitly approved. The merged Project Manager definition contains +`compensation.award.read`, while the candidate WS-CON matrix excludes Project +Manager from monetary award/fulfillment detail. Merged audit permissions also +cover broader roles than the candidate Audit/Operator and Audit-only surfaces. +D11 must choose the exact action-specific role sets. If a narrower set is +approved, AUTH evaluators filter candidate AdminRole values before resource +guards, preserve the exact matched grant/scope, and prove every excluded, +foreign-project, revoked-grant, wrong-scope and mixed excluded+eligible case. If +the merged role candidates are preserved, CON-01 updates the active matrix and +tests that exact wider set. Neither outcome may be inferred from PermissionId +membership or implemented as CON role logic. + ## Existing product-action dependency `task.claim` is not one of the 23 WS-CON-specific actions, but current trusted @@ -164,7 +252,7 @@ WS-CON and WS-REV do not activate them. | Contribution evidence service | planned evidence-binding action/service contract, prepared protocol plus ART capability | ART prerequisite + CON-09A composer/handler integrates the prepared seam | CON-11 | | Contribution reads | planned self/project read actions and typed contexts | CON-09B | CON-10A | | Award reads | planned self/project award actions and typed contexts | CON-10A | CON-10B | -| Operations | planned retire/reconcile/status/rebuild/audit actions, typed contexts, grants and prepared protocol | CON-10B | CON-11 | +| Operations | full D11 human decision plus any required AUTH role-matrix/evaluator amendment; planned retire/reconcile/status/rebuild/audit actions, typed contexts, prepared protocol and exact chosen candidate-role filters | CON-10B | CON-11 | No row authorizes public route registration. CON-11 proves the hidden action manifest and REV-13 remains the sole joint public activation owner. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md index cd74df22..52945272 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -5,13 +5,16 @@ One chunk maps to one reviewable PR. No runtime chunk starts until its exact AUTH, ART, REV, outbox, migration, and human gates are satisfied on current trusted `main`. Every runtime chunk uses the fresh isolated PostgreSQL runner -and same-invocation coverage evidence defined in `PLAN.md`. +and same-invocation coverage evidence defined in `PLAN.md`. D12 must resolve +one exact activation owner/custodian for every action before any AUTH +registration checkpoint starts; feature ownership never supplies a second +availability writer. ## Chunks | Chunk | Title | Risk | Gate | Status | |---|---|---:|---|---| -| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Reviewed; human approval gate | +| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Reviewed; D11/D12 human gates | | `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Plan/human decisions approved | Proposed | | `WS-CON-001-02A` | Shared Transactional Outbox Persistence | L1 | 01; event ownership approved | Proposed | | `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; worker/operations contract; AUTH planned `outbox.dispatch` registration/context/fixed actor/assignment/prepared protocol merged; dispatcher remains disabled pending later AUTH activation | Proposed | @@ -31,8 +34,8 @@ and same-invocation coverage evidence defined in `PLAN.md`. | `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; callback identity/action registration already merged before 04A; AUTH typed callback context and prepared protocol merged; joint callback-fence port contract | Proposed | | `WS-CON-001-09A` | Contribution Evidence Projection Write | L1 | 07; named `WS-ART-001-CON-EVIDENCE` capability; AUTH planned evidence action/context/prepared protocol and exact assignment on existing `workstream.artifact.binding` | Proposed | | `WS-CON-001-09B` | Authorized Contribution Evidence Read | L1 | 09A; disclosure schema; AUTH planned contribution-read registrations/typed contexts | Proposed | -| `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B,09B; post-09B AUTH contribution-read activation; AUTH planned award-read registrations/typed contexts | Proposed | -| `WS-CON-001-10B` | Operations, Reconciliation, Rebuild, And Fulfillment Drain Observation | L1 | 10A; post-10A AUTH award-read activation; AUTH planned binding-retire/ops/audit registrations/typed contexts/grants/prepared protocol; shared-outbox observation capability | Proposed | +| `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B,09B; post-09B AUTH contribution-read activation; D11 award/audit role outcome approved; AUTH planned award-read registrations/typed contexts/exact chosen role contract | Proposed | +| `WS-CON-001-10B` | Operations, Reconciliation, Rebuild, And Fulfillment Drain Observation | L1 | 10A; post-10A AUTH award-read activation; full D11 outcome approved and any chosen AUTH role-matrix amendment merged; AUTH planned binding-retire/ops/audit registrations/typed contexts/exact chosen role contract/prepared protocol; shared-outbox observation capability | Proposed | | `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10B; REV-10 integration; exact AUTH evaluator/action/service manifest, ART/outbox readiness, required CON-owned dispatch/callback fence hooks and drain port | Proposed | ## Dependency order @@ -58,8 +61,8 @@ AUTH review.decision registration/contracts + REV-09B + CON-07 participant -> RE AUTH callback identity/action registration before CON-04A + remaining typed/prepared callback contracts -> CON-08B hidden callback -> AUTH callback evaluator/activation -> CON-11 AUTH evidence action/typed/prepared/exact-service-assignment registration + ART capability -> CON-09A hidden handler -> AUTH evidence evaluator/activation -> CON-11 AUTH contribution-read registration/contracts -> CON-09B hidden reads -> AUTH contribution-read activation -> CON-10A -AUTH award-read registration/contracts -> CON-10A hidden reads -> AUTH award-read activation -> CON-10B -AUTH operations registration/contracts -> CON-10B hidden operations -> AUTH operations activation -> CON-11 +D11 award-role decision + AUTH award-read registration/contracts -> CON-10A hidden reads -> AUTH exact-role award activation -> CON-10B +D11 delivery/audit decisions + any required AUTH matrix amendment + operations registration/typed/prepared/exact-role contracts -> CON-10B hidden operations -> AUTH exact-role operations activation -> CON-11 CON-08A/B,09A/B,10A/B + REV-12 + AUTH/ART/outbox -> CON-11 hidden readiness CON-08A/08B/10B/11 required CON-owned dispatch/callback fence ports and fulfillment-drain observation + CON-11 hidden manifest + REV-12 -> REV-12A hidden joint release-control composition -> REV-13 sole route activation and joint live drill ``` diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md index 1fcbb003..25a8f1e6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -12,7 +12,7 @@ evidence, not executable authority. | Requirement family | Owner | Minimum executable cases before owner completes | Final live evidence owner | |---|---|---|---| -| Central authorization integration | AUTH executable gates + each CON resource owner | all absent/planned actions deny; each active action has exact ActionId/PermissionId/owner/context/evaluator parity; human grant and service assignment never substitute; `T` prepared handles reject missing/reuse/cross-session/cross-action/target drift; authority-loss versus product mutation runs in both orders; no CON AUTH-repository import or local role fallback | AUTH conformance + REV-13 | +| Central authorization integration | AUTH executable gates + each CON resource owner | post-AUTH-08 74/57 baseline exact; D12 maps each action to exactly one approved owner/custodian and rejects dual activation; all absent/planned actions deny; each active action has exact ActionId/PermissionId/owner/context/evaluator parity; evaluator-owned per-action AdminRole allowlist precedes query/guards and mixed excluded+eligible grants select only the eligible grant; decisions bind complete resource digest plus matched grant/project; human grant and service assignment never substitute; `T` prepared handles reject missing/reuse/cross-session/cross-action/target drift; authority-loss versus product mutation runs in both orders; feature routes explicitly commit and abandoned/evidence-failed work rolls back; no CON AUTH-repository import or local role fallback | AUTH conformance + REV-13 | | Contribution identity and review lineage | CON-03C/07 + REV-10 | one completed-review contribution per valid Review; accept adds one accepted-submission contribution; second revision review creates a distinct reviewer contribution; automated checker outcomes create none; at-most-one DB constraints and mandatory-participant at-least-one proof | REV-13 | | Policy publication and freezing | CON-04B/05/06 + REV-06 | absent/incomplete setup denies; unpaid is explicit; retired frozen version remains valid for started work; later activation changes new assignments/leases only; publish versus both claims in both lock orders | REV-13 | | Binding lifecycle | CON-04A/08A/08B/10B | suspended blocks new freeze/delivery but accepts valid existing-work callback; retirement denies dependencies then permits exact accepted-receipt replay only; actor/link revocation denies; project/instrument mismatch denies | REV-13 | @@ -20,8 +20,8 @@ evidence, not executable authority. | Outbox and delivery | CON-02A/02B/03D/08A + REV-12A | immutable event/payload/binding/idempotency identity; stale claim fencing; durable in-flight generation; retry/dead-letter/replay; reconciliation preserves original identity; provider I/O occurs outside every database transaction/lifecycle fence; dispatch-versus-admission fencing in both orders | REV-13 | | Callback and fulfillment | CON-08B + REV-12A | callback before acknowledgement suppresses later delivery; duplicate exact receipt idempotent; changed receipt conflicts; per-actor/binding limits; suspended/retired matrices; callback allowed through delivery drain and denied after disable; callback-versus-disable in both orders; no human authority | REV-13 | | Evidence artifact | CON-09A/09B | deterministic versioned schema; self/project disclosure matrix; no reviewer-private, provider, credential, external-receipt or unnecessary actor data; newer-schema rebuild retains prior immutable bundle; LocalStorage/MinIO capability conformance | REV-13 | -| Product reads | CON-10A | self/project role matrix, cross-project concealment, stable pagination, money/points/status separation, no provider refs | REV-13 | -| Operations and audit | CON-10B + REV-12A | Finance versus Operator reconciliation and PM/contributor denials; bounded rebuild; immutable truth unchanged; audit read/export scope and redaction; same-session drain observation never reports false zero or exposes repositories | REV-13 | +| Product reads | CON-10A | D11's approved award-role set exact; Project Manager contribution access remains separate from the chosen award-detail rule; AUTH activation proves allowed/excluded/mixed/revoked/foreign-project grants; CON proves matched decision facts, stable pagination, money/points/status separation and no provider refs | REV-13 | +| Operations and audit | CON-10B + REV-12A | D11's approved delivery/audit role sets and any AUTH matrix amendment exact; AUTH activation proves role/reason/scope candidates; CON proves bounded reconciliation/rebuild, immutable truth, decision-fact binding, audit redaction and same-session drain observation with no false zero or repository exposure | REV-13 | | Atomic review integration | CON-07 + REV-10 | allowed exact `review.decision` evidence matches actor/action/resource/project/request/correlation; denied/stale/mismatched evidence rejected; every injected failure rolls back review/task/contribution/award/audit/outbox together | REV-13 | | Public contract | CON-11 readiness + REV-12A control + REV-13 activation | hidden routes absent before release; `/api/v1` only; dependency/fence/drain manifest exact; startup/preflight fail closed; no partial surface; deterministic shutdown/reactivation phase matrix | REV-13 | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md index 7d29541b..06718e5e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -73,8 +73,11 @@ proposal, and every mapping is re-read from merged trusted `main` before its implementation chunk. Current trusted `main` proves why registration and activation cannot be -collapsed: AUTH-07B has 50 registered actions but only two active evaluators; -all planned and unsupported actions fail closed. +collapsed: AUTH-08 has 57 registered actions but only nine active self/admin +actions; all planned and unsupported actions fail closed. Its complete +resource-context digest, matched grant/scope evidence and route-owned commit +boundary become mandatory inputs to later WS-CON evaluators rather than a +feature-local replacement. ## D5 - Derived Contribution/Award Writes Are Review Participants @@ -124,7 +127,7 @@ beneficiary accounts, balances, and project-points ledger entries. ## D10 - AUTH Owns Prepared Cross-Domain Mutation Authorization -**Status:** required architecture correction after merged AUTH-07B review; +**Status:** required architecture correction after merged AUTH-07B/AUTH-08 review; human/AUTH approval required before any `T` action implementation. The current actor-self kernel can revalidate entirely inside AUTH-owned rows. @@ -144,3 +147,59 @@ facts and product guards but cannot implement the handle or query AUTH state. Rejected: product-row locks before AUTH locks, evaluating an unlocked snapshot, calling AUTH twice and emitting competing decisions, or letting feature code flip catalogue availability. + +## D11 - Reconcile AUTH-08 Role Candidates Per Action + +**Status:** unresolved human cross-spec decision before CON-10A/10B +authorization registration; any resulting AUTH correction remains AUTH-owned. + +Merged AUTH-08 is the canonical five-role permission-candidate matrix. It gives +Finance Authority the existing `compensation.delivery.reconcile` PermissionId +but omits it from Operator, while the reconciled candidate WS-CON human matrix +proposes a reason-bound system Operator for delivery reconciliation. Only D2 is +human-approved. The recommended D11 resolution is to preserve that candidate +behavior: a reviewed AUTH successor adds the existing PermissionId to Operator +and updates its closed definition/API/kernel tests. The human may instead +reject Operator delivery reconciliation; then CON-01 removes it from the active +matrix before AUTH registration. WS-CON adds no PermissionId, role query or +local exception under either resolution. + +The human must also resolve the inverse mismatches. Project Manager has the +merged `compensation.award.read` permission while the candidate WS-CON matrix +excludes it from monetary award/fulfillment detail; candidate audit read/export +sets are narrower than every merged role containing `audit.read` or +`audit.export`. D11 chooses whether to preserve each merged candidate or adopt +the narrower WS-CON action set. Any approved narrowing is implemented only by +AUTH through an evaluator-owned closed role intersection before grant query. +The role set is never request- or CON-supplied; an actor with both excluded and +eligible grants must match only the eligible grant. If the merged set is kept, +CON-01 updates the active product matrix before registration. No generic +"permission present means action allowed" branch or silent narrowing is +accepted. + +Rejected: silently choosing either side of a role-matrix conflict, changing a +candidate set after registration without review, or reproducing role policy in +CON. + +## D12 - ActionOwner And Activation Custody Have One Meaning + +**Status:** unresolved AUTH/human contract decision before any WS-CON action +registration or review-action activation amendment. + +The merged enum defines ActionOwner as the implementation chunk allowed to +activate an action. The user requires AUTH to own authorization activation, so +the recommended resolution keeps that meaning and adds the exact eight +AUTH-owned WS-CON activation owners plus two review activation owners listed in +`AUTHORIZATION_HANDOFF.md`. Every proposed action maps to one owner; CON/ART/REV +remain feature resource owners but never change availability. + +The alternative is a reviewed global semantic change: ActionOwner becomes the +feature/resource owner and AUTH adds a separate closed activation-custody type. +That change must update catalogue docs, typed/PostgreSQL parity where +applicable, startup checks and every existing owner test before use. It cannot +be inferred locally. Under either choice there is exactly one activation +authority and the handoff table keeps feature ownership separate. + +Rejected: leaving current REV owners while saying AUTH activates, assigning an +evidence action jointly to AUTH/ART, using a registration PR as a second owner, +or letting two chunks flip one action. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md index 46884ee7..2900f209 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -32,6 +32,13 @@ runtime implementation was performed. `ExternalServiceAdapterFactory[TAdapter]` foundation. It does not supply a contribution-evidence capability or compensation provider adapter; those remain separately gated, explicit composition-root registrations. +- Trusted `main` `aa0fdcd` now includes AUTH-08. The authorization catalogue is + 74 PermissionIds/57 ActionIds with nine active and 48 planned actions. Durable + scoped AdminRoleGrants, the five-role permission matrix, typed grant resource + contexts, resource-context digests, matched grant/scope evidence, explicit + route-owned commits and retryable authorization-evidence failure handling are + merged. Service actors, ProjectRoleGrants, D10 and every WS-CON action remain + future AUTH-owned work. ## Reconciled working source and supplied generation-2 PDF @@ -55,9 +62,12 @@ generation rather than replacing the first. | Finding | Evidence | Required correction in active contract | |---|---|---| | Wrong public prefix | Candidate section 18 uses `/v1`; router and ADR 0012 use `/api/v1`. | Use `/api/v1` only; no alias. | -| ActionId/PermissionId conflation | Candidate calls granular `compensation.policy.*` values permissions and says broad IDs were removed. Merged AUTH-07B preserves 74 approved PermissionIds and separately registers 50 ActionIds: two active actor-self actions and 48 planned actions. | Publish an exact proposed ActionId -> PermissionId handoff. Never call an ActionId a permission or a registered/planned identifier executable. | -| Registration treated as activation | AUTH-07B's runtime accepts only actor-self/system contexts and explicitly evaluates only its two active actor-self actions; planned or unsupported actions deny. | AUTH must own typed-context/evaluator/principal/transaction integration and active availability. CON owns product facts/guards only and cannot flip the AUTH catalogue. | +| ActionId/PermissionId conflation | Candidate calls granular `compensation.policy.*` values permissions and says broad IDs were removed. Merged AUTH-08 preserves 74 approved PermissionIds and separately registers 57 ActionIds: nine active self/admin actions and 48 planned actions. | Publish an exact proposed ActionId -> PermissionId handoff. Never call an ActionId a permission or a registered/planned identifier executable. | +| Registration treated as activation | AUTH-08 evaluates only its self/admin action families; all planned, unsupported, wrong-context and unimplemented actions deny. No WS-CON evaluator exists. | AUTH must own typed-context/evaluator/principal/transaction integration and active availability. CON owns product facts/guards only and cannot flip the AUTH catalogue. | | Cross-domain mutation lock gap | Current `require()` can revalidate actor-self wholly inside AUTH, but WS-CON mutations need AUTH rows before product rows and final evaluation against locked product facts. | AUTH supplies the prepared, caller-session-bound, single-use `T` protocol in D10; no unlocked-snapshot decision or product-before-AUTH lock order. | +| Merged Operator permission gap | AUTH-08's closed `operator` definition omits existing PermissionId `compensation.delivery.reconcile`, but the reconciled candidate WS-CON matrix proposes a reason-bound Operator as well as Finance Authority to request delivery reconciliation. Only D2 is human-approved. | D11 human decision: an AUTH-owned reviewed successor adds the existing permission before CON-10B if Operator behavior is retained, otherwise CON-01 removes the candidate before registration. CON has no role-query/local fallback. | +| Cross-spec role-set conflict | AUTH-08 gives Project Manager `compensation.award.read` and broader roles `audit.read`/`audit.export`, while the unadopted WS-CON candidate proposes narrower monetary/audit sets. | D11 human choice freezes each active set. Any approved narrowing is AUTH evaluator policy with matched grant/scope proof; preserving merged candidates updates CON-01. Permission membership or candidate text alone never settles the action. | +| ActionOwner activation conflict | Canonical `ActionOwner` means the implementation chunk allowed to activate an action. Existing review actions name REV owners, while the reconciled AUTH boundary says only AUTH activates after feature composition; the 23 WS-CON actions had no exact owner mapping. | D12 human/AUTH decision plus the exact closed owner map in `AUTHORIZATION_HANDOFF.md`; never permit AUTH and a feature chunk to both change availability. | | Missing upstream task action | PermissionId `task.claim` exists, but current ActionId has no `task.claim` member. | AUTH-13 or reviewed AUTH successor registers/evaluates/activates `task.claim` before CON-05A integrates compensation freeze. | | Wrong Review action | Candidate uses `review.decision.record`; merged AUTH catalogue and WS-REV use registered planned ActionId `review.decision` mapped to PermissionId `review.decision`. | Consume `review.decision` only after its AUTH evaluator/availability and REV resource-composition gates. | | Invented WS-AUTH source | Candidate names `WS-AUTH-001-A`, which is not a canonical repository artifact. | Cite merged `docs/spec_authorization_service.md`, ADR 0012, and the closed catalogue. | @@ -79,16 +89,17 @@ generation rather than replacing the first. | `backend/app/modules/tasks/service.py` | Claim, submission, task lifecycle | WS-CON may integrate only through task-owned participants; auth cutover stays WS-AUTH-owned. | | `backend/app/modules/projects/models.py` | Project and guide-bound `PaymentPolicy` | Approved for complete semantic removal in CON-05A and physical removal in CON-05B; the legacy-row rebuild/classification rule remains a human gate. | | `backend/app/modules/projects/service.py` | Guide activation and policy locking | Must not become a second compensation-policy engine. | -| `backend/app/modules/authorization/{catalogue,kernel,runtime}.py` from merged AUTH-07B | Canonical closed registry and first executable kernel | 74 PermissionIds, 50 ActionIds, exactly two active actor-self actions and 48 planned; actor-self/system are the only runtime contexts and actor-self is the only matched authority. All WS-CON-specific actions and both service permissions remain absent. | -| `backend/app/api/deps/authorization.py` | Current actor-self composition root | Human self only; it rejects service subjects and owns actor-self denial rollback/restaging. WS-CON needs AUTH-owned general human/project/service composition, not a copied dependency. | -| sibling `workstream-rev-001/.../` branch head `e59e2bb` | Parallel review integration plan refreshed with trusted main `90eca12` | The branch includes committed REV-12A hidden release control and REV-13 sole activation, but its status/evidence still describes older AUTH/CON heads and its REV-12A contract still says the CON handler claims the event. Treat it as non-consumable until that ownership wording and freshness evidence are repaired and merged. | +| `backend/app/modules/authorization/{catalogue,kernel,runtime,policy}.py` from merged AUTH-08 | Canonical closed registry, grant policy and executable kernel | 74 PermissionIds, 57 ActionIds, nine active self/admin actions and 48 planned; eight resource-context variants and actor-self/AdminRoleGrant matched authority. All WS-CON-specific actions and both service permissions remain absent. | +| `backend/app/api/deps/authorization.py` | Current human composition root and transaction cleanup | Human self/admin only; it rejects service subjects, maps typed evidence failure to retryable 503 and rolls back any transaction a feature route leaves open. WS-CON routes must explicitly commit their own unit and need AUTH-owned project/service composition, not a copied dependency. | +| `backend/app/modules/authorization/policy.py::ADMIN_ROLE_PERMISSIONS` | Exact merged AdminRole permission candidates | Finance has delivery reconcile; Operator does not; Project Manager has award-read. D11 decides whether each candidate WS-CON difference changes AUTH or the active CON matrix. | +| sibling `workstream-rev-001/.../` clean branch head `a13bf35` | Parallel review plan's committed AUTH-08 dependency refresh | Counts, teardown/error/timestamp repairs and source SHAs now match AUTH-08, but publication evidence deliberately remains stale pending ART. REV-06/10 still use one-step current authorization rather than the registration -> CON -> REV hidden -> AUTH activation choreography; D12 owner custody is unresolved; REV-12A still says the CON handler claims the event. Treat it as non-consumable until those CON/AUTH ownership contracts are repaired, commit-bound reviewed and merged. | | `backend/app/modules/artifacts/*` | Current artifact metadata/orchestration foundation | Target v2 is still being delivered by WS-ART; WS-CON cannot import provider internals. | | `backend/app/interfaces/artifacts.py` | Current v1 raw provider port | Not a WS-CON dependency; it is being clean-cut to ADR 0013 v2. | | `docs/spec_artifact_storage_service.md` | Canonical target artifact contract | Owns narrow product capability ports, recovery, verification, quotas, and provider policy. | | `docs/spec_authorization_service.md` | Canonical target authorization contract | Preserves broad PermissionIds; ActionIds are separate. | | `docs/architecture_data_model.md` | Existing contribution/payment target | Conflicts with supplied candidate and needs ADR-backed reconciliation. | | `docs/operations_payment_reputation.md` | Existing manual payment/reputation workflow | Needs coordinated update only after architecture adoption. | -| `backend/alembic/versions/*` | Current schema through merged AUTH-07A migration `0021_authorization_action_evidence.py` | Every runtime chunk must refresh the next migration number from trusted `main`; no WS-CON contract pre-reserves `0022`. | +| `backend/alembic/versions/*` | Current schema through merged AUTH-08 migration `0022_bootstrap_admin_grants.py` | Every runtime chunk must refresh the next migration number from trusted `main`; no WS-CON contract pre-reserves `0023`. | ## Current tests @@ -96,7 +107,7 @@ generation rather than replacing the first. |---|---|---| | `backend/tests/test_tasks.py` | Task policy locks, assignment uniqueness, immutable Submission versions, checker admission, concurrency | No compensation freeze, review effects, contribution, or award tests. | | `backend/tests/test_projects.py` | Guide/policy activation including `PaymentPolicy` | No CompensationPolicy lifecycle or Finance Authority behavior. | -| `backend/tests/test_authorization.py` | Closed catalogue plus AUTH-07B deny-by-default kernel/runtime | Actor-self allow/deny, unknown/planned/unsupported denial, immutable decisions, denial restaging and request-local state are covered. Grants, service composition, WS-CON contexts/evaluators and prepared cross-domain mutation authorization remain AUTH-owned work. | +| `backend/tests/test_authorization.py` | Closed catalogue plus AUTH-08 self/admin kernel/runtime | Self/admin allow/deny, scope/grant revalidation, complete resource digests, unknown/planned/unsupported denial, evidence failure and request-local state are covered. ProjectRoleGrants, service composition, WS-CON contexts/evaluators and prepared cross-domain mutation authorization remain AUTH-owned work. | | `backend/tests/test_audit.py` | Typed append-only authority evidence | No contribution/compensation lifecycle audit contract. | | `backend/tests/test_artifacts.py` | Current artifact port, local adapter, content/binding/receipt foundation | Target v2, S3/MinIO, typed contribution projection capability, and evidence reads are not merged. | | `backend/tests/test_checkers.py` | Durable checker run and `allow_review` routing | Stops before Review persistence. | @@ -105,7 +116,8 @@ generation rather than replacing the first. ## Dependencies/integrations -- WS-AUTH: merged actor-self kernel plus future grants, service actors, exact +- WS-AUTH: merged actor-self/admin kernel and AdminRoleGrants plus future + ProjectRoleGrants/service actors, exact WS-CON ActionId/PermissionId/ActionOwner/audit registration, typed resource contexts, closed evaluators, matched authorities, prepared `T` protocol, service-capable composition, active availability and final bypass removal. @@ -131,6 +143,7 @@ generation rather than replacing the first. |---|---|---| | Dual payment truth | `PaymentPolicy`/future `PaymentRecord` and new compensation versions/awards can disagree. | ADR-backed sole execution authority and clean documentation/schema cutover. | | Permission replacement | Treating ActionIds as replacement permissions would break merged audit/grants. | Exact mapping table; AUTH-owned additive registration; typed manifest tests. | +| Merged AdminRole matrix conflicts with candidate WS-CON human matrix | Operator cannot currently satisfy candidate delivery reconciliation; award/audit candidate sets differ in the other direction. | D11 human decision, followed by only the required AUTH matrix/evaluator amendments or CON-01 active-matrix updates; no local role policy. | | Registered-but-inexecutable AUTH action | Planned availability or a missing evaluator causes every WS-CON command to deny; a feature-local workaround would bypass central AUTH. | Separate AUTH registration and executable activation gates; startup parity rejects active-without-evaluator and CON never edits AUTH. | | AUTH/product lock inversion | One-step authorization after product locks reverses canonical order; authorization before product locks can evaluate stale facts. | AUTH-owned prepared handle locks authority first and evaluates once against final locked product facts. | | Circular REV/CON dependency | Leases need policy FKs; claims need freeze; decisions need contribution participant. | Explicit interleaving gates in chunk map. | @@ -149,7 +162,8 @@ generation rather than replacing the first. | Preserve both candidate generations and reconcile into active spec? | Maintains archival provenance and follows repository precedent. | Before 01. | | May pre-production payment/task rows be rebuilt, or must they be classified/backfilled? | Determines migration safety and atomic claim cutover. | Before 05. | | Approve two new service-only PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`? | Human outbox recovery/reconciliation authority must not execute async side effects; no existing permission safely names the external adapter callback entitlement. | Before CON-02B for dispatch and before CON-04A for callback binding identity. | -| Approve the AUTH-owned WS-CON registration/evaluator/activation work and D10 prepared mutation protocol? | Current AUTH-07B intentionally supports only two self actions; CON cannot safely or physically activate its own actions. | Before any authorized CON service chunk. | +| Approve the AUTH-owned WS-CON registration/evaluator/activation work and D10 prepared mutation protocol? | Current AUTH-08 supports nine self/admin actions but no WS-CON action; CON cannot safely or physically activate its own actions. | Before any authorized CON service chunk. | +| Approve adding existing `compensation.delivery.reconcile` to the Operator role definition? | The reconciled candidate proposes reason-bound Operator delivery reconciliation, but merged AUTH-08 does not make that role a permission candidate. Rejecting the addition removes Operator from the active WS-CON action contract. | Before AUTH registration for CON-10B. | | Does the ART initiative add the contribution evidence capability, or should it be a separate ART-owned prerequisite chunk? | WS-CON cannot own raw storage orchestration. | Before 10. | ## Existing conventions to preserve diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md index 0614fc11..fde46e2e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -2,23 +2,27 @@ ## Incorporation status -The inspected sibling branch now has committed merge head `e59e2bb`, which -integrates trusted `main` `90eca12` and includes contribution/compensation -router registration, the WS-CON-11 preflight manifest, the complete joint live -matrix, PaymentPolicy removal dependencies, active generated/document -companions, and REV-12A hidden release control. It consumes the CON-owned -dispatch and callback fences plus fulfillment-drain observation through -composition instead of importing CON/outbox repositories. +The inspected sibling branch now has clean committed head `a13bf35`, based +on trusted `main` including AUTH-08. Its planning contracts assign future +contribution/compensation router registration, consumption of the WS-CON-11 +preflight manifest, the joint live matrix, PaymentPolicy removal dependencies, +active generated/document companions and REV-12A hidden release control. Those +runtime changes are not implemented. The planned composition consumes the +CON-owned dispatch/callback fences and fulfillment-drain observation instead of +importing CON/outbox repositories. -The sibling is still not a consumable dependency: its status/evidence cites -older AUTH/CON heads and its REV-12A contract still says the CON handler claims +The AUTH-08 dependency refresh now records correct merged counts and +transaction/error/timestamp repairs, but final publication evidence remains +intentionally stale pending ART. The sibling is still not consumable: REV-06/10 +predate the registration -> CON -> REV hidden -> AUTH activation choreography +and D12 owner-custody decision, and REV-12A still says the CON handler claims the shared-outbox event. Before review/merge it must instead accept the dispatcher's already-claimed command and return a typed outcome, leaving every -outbox transition to CON-02B. It must also adopt AUTH-07B's executable-gate and -prepared-authorization requirements. WS-CON does not edit the parallel -worktree; the WS-REV owner must repair, commit-bind, internally review and merge -that exact contract. Until later implementation gates land, both initiatives -remain hidden. +outbox transition to CON-02B. It must also adopt AUTH-08's current decision/ +transaction contract and the executable-gate/prepared-authorization +requirements. WS-CON does not edit the sibling. The WS-REV owner must repair, +commit-bind, internally review and merge the exact final contract. Until later +implementation gates land, both initiatives remain hidden. The refresh must also repair REV-06/10 authorization choreography. AUTH first registers the planned review action and typed/prepared contract; CON supplies @@ -76,6 +80,14 @@ historical reviews, and generated loop memory remain excluded. - Register review, contribution, compensation policy/binding, contribution/ award/evidence reads, fulfillment callback, and bounded operations routers in the same PR under `/api/v1`; no `/v1` alias and no partial prior surface. +- Every registered route explicitly commits its own complete read or mutation + plus AuthorizationDecision and business/audit/outbox/idempotency state. + Domain services remain flush-only. The service-authenticated fulfillment + callback explicitly commits its decision plus receipt/idempotency state in + the fenced transaction. Tests prove an omitted commit is rolled back by + dependency teardown, authorization-evidence failure is one retryable 503 with + zero partial state, callback commit failure leaves no partial receipt, and no + route relies on dependency ordering to commit. - Consume CON-11's exact merged-SHA/migration/action/service-assignment/ART/ outbox/worker/handler/fence manifest plus AUTH context/evaluator/matched- authority/prepared-protocol/availability parity, and fail startup/preflight @@ -92,7 +104,8 @@ historical reviews, and generated loop memory remain excluded. IDs and retained live evidence, including policy/binding setup, task/review freezes, accept/needs_revision/reject, second revision review, money+points, explicit unpaid, delivery/callback ordering, suspended/retired binding, - evidence privacy/rebuild, Finance-versus-Operator operations, denials, atomic + evidence privacy/rebuild, D11-approved delivery/operations role behavior, + denials, atomic rollback, storage/adapter outage, replay and reconciliation. - Update all active sources/generated companions in the same release so no mutable PaymentRecord, accept-only/voidable contribution, automatic diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md index ad320915..5333ad41 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -37,29 +37,56 @@ or query declares one ActionId and consumes a request-scoped, caller-session- bound `AuthorizationService`. Every WS-CON ActionId is currently absent and proposed. Trusted `main` -`90eca12` includes AUTH-07B's request-scoped deny-by-default kernel. Its closed -catalogue contains 74 PermissionIds and 50 non-WS-CON ActionIds: two actor-self -actions are active and 48 actions remain planned. The exact handoff is in +`aa0fdcd` includes AUTH-08's scoped administrative grants. Its closed catalogue +contains 74 PermissionIds and 57 non-WS-CON ActionIds: nine self/admin actions +are active and 48 actions remain planned. The exact handoff is in `AUTHORIZATION_HANDOFF.md`. It enumerates each proposed action separately, its existing or proposed PermissionId, canonical target, candidate principal class, typed resource facts and guards, transaction protocol, AUTH activation gate, and feature resource owner. -AUTH-07B currently evaluates only actor-self contexts/actions and rejects -service subjects at its actor-self dependency. WS-AUTH therefore owns not only -identifier/owner-enum registration and typed/PostgreSQL parity, but also action -availability, closed evaluator dispatch, matched-authority expansion, grant -semantics, service-capable composition, service ActorProfile/action-assignment -construction, and transaction-local authority revalidation. The feature chunk +AUTH-08 now evaluates actor-self and administrative grant families, carries a +complete resource-context digest plus matched grant/scope evidence, and rolls +back a transaction a feature route fails to commit. It still rejects service +subjects and has no ProjectRoleGrant, service-assignment, D10 or WS-CON action +evaluator. WS-AUTH therefore owns not only identifier/owner-enum registration +and typed/PostgreSQL parity, but also action availability, closed evaluator +dispatch, action-specific candidate-role filtering, matched-authority +expansion, remaining grant semantics, service-capable composition, service +ActorProfile/action-assignment construction, and transaction-local authority +revalidation. Every WS-CON route owns its explicit commit; the feature chunk named in the handoff owns product-row loading, construction of AUTH-approved typed resource facts, lifecycle guards, and behavioral proof. WS-CON never edits AUTH-owned files or activates an AUTH action. +Merged AUTH-08 also exposes a closed-role mismatch that must not be hidden in +CON. Finance Authority contains `compensation.delivery.reconcile`, but Operator +does not, while the reconciled candidate matrix proposes both. D11 requires a +human choice before CON-10B. If Operator delivery recovery is retained, a +reviewed AUTH-owned successor adds that existing PermissionId to Operator; if +not, the active WS-CON authority matrix removes the candidate before action +registration. D11 also decides whether Project Manager's broad +`compensation.award.read` candidate carries into WS-CON monetary detail and +which merged audit candidates remain eligible. CON-01 records the chosen sets; +AUTH activation proves them without CON role logic. + +D12 separately resolves activation custody. The merged ActionOwner type means +the implementation chunk permitted to activate an action; it cannot name a CON +feature chunk while this plan says AUTH alone flips availability. The handoff +therefore proposes exact AUTH-owned activation owners for all 23 WS-CON actions +and the two coupled review actions. Human/AUTH approval of that model—or a +global feature-owner semantic plus a separate closed activation-custody type—is +a registration gate. No action may have two activation authorities. + For mutations crossing AUTH and product rows, AUTH must add the prepared authorization protocol specified in the handoff. The preliminary target lets AUTH lock actor/link/grant or service-assignment rows first; the opaque handle is then evaluated exactly once against facts recomposed from product rows locked by the feature in canonical order. AUTH stages one decision and never commits. +The final decision retains AUTH-08's resource-context digest and exact matched +grant/project evidence. Hidden domain services flush and never commit; the +actual route/worker/callback transaction owner explicitly commits the complete +decision-plus-business transaction. REV-13 owns the public route proof. This prevents both product-before-AUTH lock inversion and authorization based on an unlocked resource snapshot. @@ -191,7 +218,7 @@ Markdown build. Preserve generations and create an active reconciled spec. ### Replace broad PermissionIds with granular strings Rejected because the merged AUTH contract preserves 74 stable PermissionIds -and separately registers 50 ActionIds, of which only two actor-self actions are +and separately registers 57 ActionIds, of which nine self/admin actions are active on current trusted `main`. Granular action names do not replace permissions. @@ -283,11 +310,14 @@ backend contract. required CON-owned dispatch/callback fence ports while consuming the read-only fulfillment-drain observation port; it may not edit CON product files or import CON/outbox repositories. - Sibling merge head `e59e2bb` now includes the joint plan atop trusted main - `90eca12`, but its status/evidence still cites older heads and REV-12A still - assigns claim wording to the handler. The exact repaired snapshot must adopt - the AUTH-07B executable gates, pass commit-bound freshness review, and merge - before it is a consumable dependency. Do not change archival sources. + Clean sibling head `a13bf35` now contains a separately reviewed AUTH-08 + dependency refresh with correct counts and teardown/error/timestamp facts. + Its publication evidence intentionally remains stale pending ART; REV-06/10 + still predate the registration -> CON -> REV hidden -> AUTH activation + choreography and D12 owner custody, while REV-12A still assigns claim wording + to the handler. The exact repaired snapshot must adopt those current CON/AUTH + handoffs, pass commit-bound publication review, and merge before it is + consumable. Do not change archival sources. At every chunk activation, rebase discovery on trusted `main`, refresh exact migration numbers and dependency symbols, and stop if an expected port/action @@ -312,7 +342,10 @@ is absent or materially changed. and no active action exists without its owning feature behavior. Mutation tests reject missing/reused/cross-session prepared handles and exercise actor/link/grant or service-assignment revocation against product mutation in - both lock permutations. + both lock permutations. AUTH role-matrix/evaluator tests prove D11's exact + human-approved delivery/award/audit sets, including only the amendments and + inclusion/exclusion cases that outcome requires, plus exact matched-grant/ + project evidence and resource-context digest equality. - Static architecture tests reject AUTH persistence imports, local role checks, provider-specific compensation adapters, concrete-adapter imports or construction outside the explicit composition root, raw ArtifactStore diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md index 0d6af66d..f89c0262 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -12,7 +12,10 @@ | Direct provider call bypasses ART controls | Critical | Named `WS-ART-001-CON-EVIDENCE` capability prerequisite; import/composition tests reject raw store/provider access. | WS-ART / WS-CON-001-09A | Open | | Outbox duplication or loss | High | 02A owns truth/append; 02B alone owns dispatch/retry/replay with stable identities. | WS-CON-001-02A/B | Open | | Human role or token claims leak into feature authorization | Critical | Central AUTH service only; no grant queries/local role checks; deny/race tests. | WS-AUTH / all WS-CON | Open | +| Merged AdminRole permission candidates conflict with candidate WS-CON roles | Critical | D11 chooses Operator delivery, Project Manager award-detail and audit/export candidates. AUTH amends only a chosen outcome that differs from its merged matrix; CON-01 updates the active matrix and AUTH activation proves exact roles. | Human + WS-AUTH + WS-CON-001-01/10A/B | Decision needed | | Registered WS-CON action has no executable AUTH evaluator | Critical | AUTH owns typed contexts, closed evaluator dispatch, matched authority and active availability; CON cannot flip catalogue state; startup parity rejects active-without-evaluator and evaluator-without-feature behavior. | WS-AUTH | Open | +| ActionOwner names a feature chunk while AUTH is said to activate | Critical | D12 approves exact AUTH-owned activation owners for all 23 WS-CON and two coupled review actions, or introduces a separately reviewed activation-custody type; startup/parity tests reject dual or missing owners. | Human + WS-AUTH | Decision needed | +| Feature route relies on authorization dependency teardown to commit | Critical | Preserve AUTH-08's rollback-only teardown: every route explicitly commits decision plus business/audit/outbox state; forgotten commit and evidence-failure tests prove zero partial state. | WS-AUTH + every WS-CON route owner | Open | | Cross-domain mutation authorizes unlocked facts or reverses locks | Critical | D10 AUTH-owned prepared handle locks authority first and evaluates once against final locked product facts; missing/reused/cross-session handles deny. | WS-AUTH + each `T` CON owner | Open | | Task compensation freeze assumes nonexistent `task.claim` ActionId | Critical | AUTH-13 or reviewed AUTH successor registers/evaluates/activates exact `task.claim` -> existing `task.claim` before CON-05A. | WS-AUTH / WS-CON-001-05A | Open | | Provider payment logic leaks into Workstream | High | Typed instruction/ack/receipt contract; provider attempts/balances/ledger prohibited. | WS-CON-001-08A/B | Open | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md index 1bf23b6f..76e6f734 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -32,25 +32,38 @@ ## Parallel dependency sources inspected - trusted authorization worktree and `origin/main` at - `90eca12f6398f2ef168e634244d912765572c3e5`, which merges AUTH-07B through PR - #130 -- merged AUTH-07B implementation `9fd3bb4` plus CI repair `da0230c`, now - canonical on trusted `main`: 74 PermissionIds, 50 ActionIds, exactly two - active actor-self actions, 48 planned actions, actor-self/system runtime - contexts only, and no WS-CON ActionIds or service-only - delivery/fulfillment permissions -- `/home/abiorh/flow/workstream-auth-001-07/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/` + `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3`, which merges AUTH-08 through PR + #131 +- merged AUTH-08 implementation lineage through `0832358`, now canonical on + trusted `main`: 74 PermissionIds, 57 ActionIds, exactly nine active self/admin + actions, 48 planned actions, eight closed resource-context variants, + actor-self/AdminRoleGrant matched authority, complete resource-context digest + and matched grant/scope decision evidence, explicit feature-route commit + ownership, and no WS-CON ActionIds or service-only dispatch/fulfillment + permissions +- merged `backend/app/modules/authorization/policy.py`, whose exact role matrix + confirms Finance Authority has `compensation.delivery.reconcile`, Operator + does not, and Project Manager has the broader `compensation.award.read` + candidate. These facts create the unresolved D11 human decision and only its + chosen AUTH amendment/evaluator or CON-01 matrix-update gates; they are not + copied into CON runtime. +- clean trusted authorization worktree `/home/abiorh/flow/workstream-authorization-service/` + at `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3` - active sibling REV worktree `/home/abiorh/flow/workstream-rev-001/`, observed - at branch-reachable merge head - `e59e2bbe823bc0ee2b0e59ff35f8352349618b2e` on - `2026-07-15T20:22:41+01:00`. It integrates trusted `main` `90eca12` and - committed REV-12A/13 planning, while user reference-file renames remain dirty. - Its status/evidence still cites older AUTH/CON heads and REV-12A still says - the CON handler claims the outbox event. It remains non-consumable until that - ownership wording and commit-bound freshness are repaired and the plan merges. -- trusted `main` at `90eca12f6398f2ef168e634244d912765572c3e5`, including merged - ADR 0014 from PR #127, AUTH-07A catalogue/audit foundation from PR #126, and - AUTH-07B deny-by-default actor-self kernel from PR #130. + at branch-reachable head + `a13bf352147cbb2c65742802e7c74a9478e5013b` after its parallel agent committed + `Refresh REV plan for merged AUTH-08`; the worktree is clean. Its separate + AUTH-08 dependency review now records correct 74/57, 9/48 and transaction/ + error/timestamp facts. Final publication evidence deliberately remains stale + pending ART, REV-06/10 still predate the repaired CON/AUTH choreography and + D12 custody, and REV-12A retains incorrect handler-claims-OutboxEvent wording. + The sibling remains non-consumable until those contracts are repaired, + commit-bound reviewed and merged. +- trusted `main` at `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3`, including merged + ADR 0014 from PR #127, AUTH-07A/07B from PRs #126/#130, and AUTH-08 scoped + administrative grants from PR #131. Authored loop-state/queue text in that + merge still records pre-publication AUTH-08 state; the merge commit and code + are authoritative while signed post-merge automation catches up. These sibling worktrees are discovery evidence, not dependencies by path. Every implementation chunk consumes only contracts merged into trusted `main`. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 8a611a61..cf6648f7 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,9 +2,10 @@ ## Current status -Base planning passed its earlier review. The latest merged AUTH-07B executable -kernel reconciliation and resulting AUTH/CON activation-boundary repair passed -fresh internal review. Application code is unchanged. +Base planning and its AUTH-07B reconciliation passed earlier review. The branch +is now rebased onto merged AUTH-08 at `aa0fdcd`; the resulting catalogue, +AdminRoleGrant, decision-evidence, transaction, ActionOwner and role-matrix +delta passed fresh internal review. Application code is unchanged. The reconciled working Markdown transcription, supplied generation-2 PDF, original archival PDF, current backend, active docs, merged WS-AUTH authorization catalogue, and active parallel WS-REV plan delta have been mapped. @@ -16,16 +17,16 @@ providers, existing versioned `Submission`, and active payment architecture. ## Active chunk `WS-CON-001-PLAN` only. The human approved complete PaymentPolicy removal on -2026-07-15. AUTH-07B proves that registration alone is not activation, so the -plan now makes typed evaluators, principal truth, active availability and a -prepared cross-domain mutation protocol AUTH-owned prerequisites. No -implementation is active. +2026-07-15. AUTH-08 proves that durable grant and permission candidacy still do +not activate a WS-CON action, so the plan keeps typed evaluators, exact per- +action role filters, principal truth, active availability and a prepared cross- +domain mutation protocol AUTH-owned. No implementation is active. ## Chunk status | Chunk | Status | Branch | PR | Notes | |---|---|---|---:|---| -| `WS-CON-001-PLAN` | Reviewed; human approval gate | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; reviewed refresh records merged AUTH-07B at `90eca12`, exact AUTH executable gates, archive-scanner ownership, and non-consumable REV head `e59e2bb`. | +| `WS-CON-001-PLAN` | Reviewed; D11/D12 human gates | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; reviewed refresh records merged AUTH-08 at `aa0fdcd`, unresolved D11/D12 decisions, exact AUTH executable gates, archive-scanner ownership, and clean but non-consumable REV head `a13bf35`. | | `WS-CON-001-01` | Proposed | - | - | No runtime work. | | `WS-CON-001-02A` through `11` | Proposed | - | - | Each requires separate explicit start; REV-13 owns final activation. | @@ -36,12 +37,14 @@ implementation is active. | Active-contract/archive handling approval | Human | Approve D1. | | Legacy PaymentPolicy/task/assignment row handling | Human | Choose pre-production rebuild or an explicit classified backfill before 05A/05B; PaymentPolicy removal itself is approved. | | Exact WS-CON executable authorization integration | WS-AUTH + human | Approve and implement registration, typed contexts/evaluators, matched authorities, grants/service assignments, prepared `T` protocol and active availability only in AUTH-owned chunks. | +| D11 AUTH/CON human-role conflicts | Human + WS-AUTH | Choose Operator delivery reconciliation, Project Manager award detail and WS-CON audit/export role sets. AUTH amends only chosen behavior that differs from its merged matrix; CON-01 updates the active contract before registration. | +| D12 ActionOwner/activation custody | Human + WS-AUTH | Approve the exact AUTH-owned activation owners in the handoff, or approve a global feature-owner semantic plus a separate activation-custody type. Do not register/activate with dual ownership. | | Upstream `task.claim` ActionId is absent | WS-AUTH-001-13 or reviewed AUTH successor | Register/evaluate/activate `task.claim` against existing PermissionId before CON-05A integrates compensation freeze. | | Contribution evidence typed capability | WS-ART + human | Create and approve the named `WS-ART-001-CON-EVIDENCE` prerequisite before CON-09A. | | ReviewLease/Review contracts | WS-REV | Merge owning persistence/behavior chunks at declared gates. | | REV-06/10 authorization choreography predates AUTH-07B repair | WS-REV + WS-AUTH | Refresh sibling contracts to AUTH registration -> CON participant -> REV hidden planned-action composition -> AUTH activation; commit-bind and review before consumption. | | Shared outbox | WS-CON-001-02A/B after approval | Land persistence and dispatcher before asynchronous integration. | -| REV-12A/13 joint plan is committed at sibling merge head `e59e2bb` but stale | WS-REV owner + human | Repair outbox claim ownership and AUTH/CON freshness evidence against `90eca12`, rerun commit-bound review, and merge; both surfaces stay hidden meanwhile. | +| REV committed head `a13bf35` remains non-consumable | WS-REV owner + human | Preserve its AUTH-08 refresh, then repair CON review choreography, D12 custody and outbox claim ownership; wait for ART, bind final publication review, and merge. | | REV-12A draft assigns shared-outbox claim wording to the CON handler | WS-REV owner | Consume an already-claimed command and return a typed outcome; preserve CON-02B as sole outbox transition owner before sibling review/merge. | | External publication | Human | Push or open a PR only after explicit direction; local review evidence does not authorize publication. | @@ -49,7 +52,7 @@ implementation is active. | Item | Source | Priority | |---|---|---:| -| Re-read merged AUTH kernel plus later AUTH-08/09/10 grants/service-actor state and each WS-CON evaluator gate at activation. | Trusted `main` | P1 | +| Re-read merged AUTH kernel plus later AUTH-09/10 service/project-grant state and each WS-CON evaluator gate at activation. | Trusted `main` | P1 | | Re-read REV contracts at CON-03C/06/07 activation. | Parallel worktree | P1 | | Re-read ART v2/capability ports before CON-09A. | ADR 0013/spec | P1 | | Decide pre-production row rebuild vs classified backfill. | Migration risk | P1 | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index 3bcf2dc9..38554d98 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -98,12 +98,17 @@ roadmap or broad operational-doc rewrite `ArtifactStorePort`, production Flow Node/R2, or broad-permission removal. - [ ] Active spec declares AUTH/ART/REV/outbox prerequisites and no local auth implementation. -- [ ] Active spec reflects merged AUTH-07B: 74 PermissionIds, 50 ActionIds, two - active actor-self actions and 48 planned actions on reviewed main; every +- [ ] Active spec reflects merged AUTH-08: 74 PermissionIds, 57 ActionIds, nine + active self/admin actions and 48 planned actions on reviewed main; every WS-CON action remains absent until an AUTH-owned registration plus typed evaluator/principal/transaction/availability gate merges. It defines D10's prepared `T` protocol and the absent upstream `task.claim` ActionId gate - without authorizing CON to edit AUTH. + without authorizing CON to edit AUTH. It also records D11's human-approved + delivery/award/audit role outcomes and any required AUTH amendment without + treating broad permission candidacy or candidate narrowing as executable. +- [ ] D12 is human/AUTH-approved and the active spec lists one exact owner for + all 23 proposed actions plus the review claim/decision custody amendment; it + never conflates feature resource ownership with catalogue activation. - [ ] Required specification reviewers pass. - [ ] `CONFORMANCE_MATRIX.md` maps every retained normative invariant to its owning chunk, concrete behavioral case, and final evidence owner; no blanket diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md index 42079553..488b96af 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md @@ -40,6 +40,11 @@ concrete adapter, provider secret/ref, dependency or CI weakening - [ ] Mutations follow PLAN locks and transaction-revalidate authority; own-state concurrent suspend/resume is deterministic. They use the AUTH-prepared handle and evaluate it once against facts recomposed from locked binding/project rows. +- [ ] The service accepts only an allowed decision whose complete resource- + context digest, matched AdminRoleGrant ID and covered project match the + locked binding facts; mismatched decision evidence is rejected. It flushes + and never commits. The later AUTH activation gate—not a CON role-aware + fake—proves Finance eligibility and every excluded/revoked/scope case. - [ ] Retire remains registered/planned but non-executable; any attempt fails closed with stable not-active behavior. CON-10B later implements its dependency-aware resource behavior after assignment/lease/award/delivery rows diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md index 80ae6cf5..d09a1ba8 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md @@ -38,6 +38,11 @@ PaymentPolicy fallback, dependency or CI weakening validates closed rules/active bindings, and atomically changes selector with audit/outbox. It evaluates one AUTH-prepared handle against facts recomposed from those locked rows. +- [ ] The service accepts only an allowed decision whose complete resource- + context digest, matched AdminRoleGrant ID and covered project match the + locked policy facts; mismatched decision evidence is rejected. It flushes + and never commits. The later AUTH activation gate—not a CON role-aware + fake—proves Finance eligibility and every excluded/revoked/scope case. - [ ] Explicit unpaid is valid; absent/incomplete/contradictory setup is stable remediation failure; removed PaymentPolicy never executes or acts as fallback. - [ ] Own-state concurrent draft/publish/retire/selector/binding changes are diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md index 1648bdf1..28e19d28 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -42,6 +42,12 @@ optional/no-op/fallback callback fence or REV edits to CON callback policy allowed lifecycle phase before any compensation-domain row, and holds the shared transaction fence through idempotent receipt commit. Missing injection fails closed; there is no optional/no-op/fallback production fence. +- [ ] The callback route/transaction owner explicitly commits the exact + AuthorizationDecision, receipt and idempotency result together; the AUTH + dependency remains rollback-only and never rescues an omitted commit. + Authorization-evidence or commit failure returns the typed retryable error + with no partial receipt/status/idempotency state. REV-13 repeats this proof on + the registered service route. - [ ] The callback fence allows authenticated callbacks through `delivery_draining` and denies them after `disabled`. Deterministic CON test doubles prove allow/deny semantics; REV-12A owns integrated callback-versus- diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md index d4ef7638..c79bc419 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -34,9 +34,15 @@ dependency, test, coverage or CI weakening a later AUTH gate owns evaluator integration and availability before CON-10A. - [ ] Matrix proves self, Project Manager, Finance, Operator/Audit views and Reviewer project-wide denial/self-only behavior without private/provider data. +- [ ] Grant-backed reads validate the allowed decision's complete resource- + context digest, matched AdminRoleGrant ID and matched project against the + canonical collection facts. CON tests disclosure with explicit allowed/ + denied decision seams only; the later AUTH activation gate proves exact role, + revoked-grant, mixed-grant and foreign-project candidate selection. - [ ] ART result matches immutable projection identity; evidence failure never changes ContributionRecord truth. -- [ ] All role/project denial cases map to CONFORMANCE_MATRIX; OpenAPI is hidden. +- [ ] All product-fact/project mismatch cases map to CONFORMANCE_MATRIX; + AUTH-owned role cases map to the activation gate; OpenAPI is hidden. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md index 09b3fca4..f9f8885e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md @@ -34,8 +34,15 @@ dependency, test, coverage or CI weakening applicable actor-self/AdminRoleGrant definitions. CON composes canonical facts; stable pre-filter pagination and cross-project concealment are enforced. A later AUTH gate activates award reads before CON-10B. -- [ ] Self, Finance/project/Operator/Audit disclosure is separated; Reviewer is - self-only absent a later approved assigned-review action. +- [ ] D11's human-approved award-detail role set is frozen in the active + contract before this chunk. CON implements only its disclosure projection; + Project Manager behavior follows that decision rather than the unadopted + candidate or broad PermissionId by inference. Reviewer remains self-only + absent a later approved assigned-review action. +- [ ] Reads validate the allowed decision's complete resource-context digest, + matched AdminRoleGrant ID and covered project against canonical award facts. + CON uses role-agnostic allowed/denied seams; the later AUTH activation gate + proves the chosen role set, mixed grants, revocation and scope denials. - [ ] Contribution, money, points, delivery acknowledgement and fulfillment remain distinct; no provider/balance/ledger data appears. - [ ] Query races never mutate truth; all matrix cases run; OpenAPI stays hidden. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md index bd024394..f855f2e9 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -31,12 +31,20 @@ dependency, test, coverage or CI weakening - [ ] The post-CON-10A AUTH award-read activation is merged. AUTH has registered planned binding-retire, delivery-reconcile, status, reconciliation, rebuild - and audit actions with exact AdminRoleGrant definitions, typed contexts and - prepared `T` handling where required. CON proves domain behavior below the - authorization boundary and changes no AUTH file; a later AUTH gate integrates - these evaluators and activates them before CON-11. -- [ ] Finance project and reason-bound Operator reconciliation use distinct - guards; Project Manager/contributor denials are explicit. + and audit actions with D11's chosen AdminRole contracts, typed contexts and + prepared `T` handling where required. Any human-approved outcome differing + from merged AUTH-08 has a reviewed AUTH-owned amendment; CON makes no local + role exception. CON proves domain behavior below the authorization boundary + and changes no AUTH file; a later AUTH gate proves roles and activates these + evaluators before CON-11. +- [ ] Finance/Operator/audit behavior follows D11's exact approved sets. CON + proves reason/scope/product guards only from allowed/denied decision seams; + AUTH activation proves role intersection, mixed grants, revocation and scope. +- [ ] Every allowed grant-backed decision carries the exact complete resource- + context digest, matched AdminRoleGrant ID and covered project scope. Stale, + wrong-scope or digest-mismatched decision evidence produces no operation, + audit export, outbox request or idempotency completion. AUTH owns revoked/ + wrong-role decision production and tests. - [ ] Reconcile preserves original identities; rebuild changes projection only; bounded range/reason/audit/idempotency is durable. - [ ] Audit read/export purpose/scope/redaction/max range is proved without diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index 9588021d..a29b4e8d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -43,6 +43,16 @@ archival reference edits dependencies and assignments, ART capabilities, outbox dispatcher, REV-10 integration and provider readiness are present. An active action without its executable evaluator or feature behavior fails startup. +- [ ] AUTH manifest proves the reviewed post-AUTH-08 baseline, full D11 human + outcome plus any required AUTH matrix amendment, exact chosen per-action + AdminRole allowlists, complete + resource-context digests, matched grant/project evidence, explicit feature- + route commits, rollback of abandoned transactions and typed retryable + authorization-evidence failure. No service action uses a human grant. +- [ ] D12 manifest maps all 23 WS-CON actions and the coupled review claim/ + decision actions to exactly one approved owner/activation custodian, matches + the registered enum and AUTH chunk map, and fails startup on dual, missing or + feature-side availability custody. - [ ] Hidden integration proves `/api/v1` target paths are absent from production OpenAPI before release and no partial direct construction path exists. - [ ] `CONFORMANCE_MATRIX.md` has collected node IDs/evidence for every adopted diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md index 74f9210d..c56722dc 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md @@ -57,14 +57,83 @@ active runtime documentation adoption registration from post-feature AUTH activation, adds the prepared `T` protocol and absent upstream `task.claim` gate, and receives fresh required review/evidence against current trusted main. +- [x] AUTH-08 refresh records the 74/57 and nine-active/48-planned runtime, + eight resource variants, two matched-authority kinds, resource/grant/scope + decision evidence and explicit feature commit ownership; reconciles D11's + cross-spec role choices and conditional AUTH changes; adds D12's exact + proposed ActionOwner/custody map; refreshes the clean/non-consumable REV + dependency; and receives fresh required review/evidence against `aa0fdcd`. ## Verification commands ```bash python3 scripts/check_markdown_links.py python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_artifact_contracts.py +python3 scripts/check_loop_memory_state.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py git diff --check -sha256sum docs/reference_specs/* +test "$(git rev-parse origin/main)" = aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3 +git merge-base --is-ancestor aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3 HEAD +test "$(sha256sum docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md | cut -d' ' -f1)" = cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640 +test "$(sha256sum 'docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf' | cut -d' ' -f1)" = ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457 +test "$(git show origin/main:docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf | sha256sum | cut -d' ' -f1)" = 34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1 +test "$(git -C /home/abiorh/flow/workstream-rev-001 rev-parse HEAD)" = a13bf352147cbb2c65742802e7c74a9478e5013b +test -z "$(git -C /home/abiorh/flow/workstream-rev-001 status --porcelain)" +(cd backend && python3 - <<'PY' +import re +from pathlib import Path + +from app.modules.authorization.catalogue import ( + ACTION_DEFINITIONS, ActionAvailability, ActionId, PermissionId, +) +from app.modules.authorization.policy import ADMIN_ROLE_PERMISSIONS +from app.modules.authorization.runtime import AuthorizationResourceContext, MatchedAuthorityKind +from app.modules.authorization.schemas import AdminRole + +actions = {item.value for item in ActionId} +permissions = {item.value for item in PermissionId} +active = { + row.action_id.value + for row in ACTION_DEFINITIONS + if row.availability is ActionAvailability.ACTIVE +} +ws_con_actions = { + "contribution.read_self", "contribution.read_project", + "compensation.policy.read", "compensation.policy.create_draft", + "compensation.policy.update_draft", "compensation.policy.publish", + "compensation.policy.retire", "compensation.adapter_binding.read", + "compensation.adapter_binding.create", "compensation.adapter_binding.suspend", + "compensation.adapter_binding.resume", "compensation.adapter_binding.retire", + "compensation.award.read_self", "compensation.award.read_project", + "compensation.delivery.reconcile", "compensation.status.read", + "compensation.reconcile.run", "contribution.projection.rebuild", + "audit.read", "audit.export", "compensation.fulfillment.report", + "outbox.dispatch", "artifact.contribution_evidence.binding.create", +} +operator = {item.value for item in ADMIN_ROLE_PERMISSIONS[AdminRole.OPERATOR]} +finance = {item.value for item in ADMIN_ROLE_PERMISSIONS[AdminRole.FINANCE_AUTHORITY]} +manager = {item.value for item in ADMIN_ROLE_PERMISSIONS[AdminRole.PROJECT_MANAGER]} +assert (len(permissions), len(actions), len(active)) == (74, 57, 9) +assert len(ACTION_DEFINITIONS) - len(active) == 48 +assert len(AuthorizationResourceContext.__args__) == 8 +assert {item.value for item in MatchedAuthorityKind} == {"actor_self", "admin_role_grant"} +assert not (ws_con_actions & actions) +assert "task.claim" in permissions and "task.claim" not in actions +assert not ({"outbox.dispatch", "compensation.fulfillment.report"} & permissions) +assert "compensation.delivery.reconcile" in finance +assert "compensation.delivery.reconcile" not in operator +assert "compensation.award.read" in manager +handoff = Path("../.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md").read_text() +owner_section = handoff.split("## Proposed AUTH-owned ActionOwner custody", 1)[1].split("## Proposed closed handoff", 1)[0] +owner_actions = [] +for line in owner_section.splitlines(): + if line.startswith("| `AUTH_CON_"): + owner_actions.extend(re.findall(r"`([^`]+)`", line.split("|")[3])) +assert len(owner_actions) == len(set(owner_actions)) == 23 +assert set(owner_actions) == ws_con_actions +PY +) ``` ## Required reviewers @@ -75,10 +144,10 @@ only planning Markdown and no CI/tests. ## Human review focus -Review unresolved D1/D4/D7/D8/D10, confirm accepted D3/D5/D6/D9 and approved D2, -and assess D2's unresolved legacy-row handling rule, exact authorization -dependencies, artifact boundary, cross-initiative gates, and whether every -runtime chunk is independently reviewable. +Review unresolved D1/D4/D7/D8/D10/D11/D12, confirm accepted D3/D5/D6/D9 and +approved D2, and assess D2's unresolved legacy-row handling rule, exact +authorization dependencies and role candidates, artifact boundary, cross- +initiative gates, and whether every runtime chunk is independently reviewable. ## Stop conditions From 38db0ffa8f75d05f6e738d2bbf231a3363c3c82d Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Thu, 16 Jul 2026 10:18:02 +0100 Subject: [PATCH 06/22] Bind WS-CON AUTH-08 review evidence --- ...S-CON-001-PLAN-internal-review-evidence.md | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index 35a512f2..376c2732 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -1,5 +1,97 @@ # Internal Review Evidence: WS-CON-001-PLAN +## 2026-07-16 AUTH-08 And Parallel-REV Reconciliation + +This addendum is the current authoritative review state and supersedes older +AUTH counts, trusted-main SHAs, ActionOwner assumptions, role-candidate outcomes +and REV freshness statements below. Trusted `main` +`aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3` includes AUTH-08 through PR #131. + +Reviewed code SHA: 9df6eace4921755cdd39759cece8e49c9a885382 + +Reviewed planning-tree SHA-256: +`7c49d006f505fe923e0194e1331e6e9ab7fb7da36ff506c8785f3c955ec2e372` + +The tree digest excludes this evidence file and is reproduced from the +initiative directory with: + +```bash +find . -type f ! -path './reviews/WS-CON-001-PLAN-internal-review-evidence.md' -print0 | sort -z | xargs -0 sha256sum | sha256sum +``` + +Reviewed at: 2026-07-16T09:17:13Z + +Reviewer run IDs: architecture/senior/reuse=`/root/auth08_arch_review`; +QA/test/product/ops/docs=`/root/auth08_qa_product_review`; +security/auth/privacy=`/root/auth08_security_review` + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | Chunk gates, conditional human decisions, exact ownership and operational commit boundaries are coherent. | +| QA/test | PASS | None | AUTH/source/REV freshness assertions, conditional role outcomes, chunk-local evidence and release proof are executable. | +| security/auth | PASS | None | D10, D11, D12, exact matched evidence, service separation and no-CON-auth boundaries are fail-closed. | +| product/ops | PASS | None | PaymentPolicy removal remains complete; delivery/award/audit role conflicts remain explicit human decisions rather than silent policy. | +| architecture | PASS | None | All 23 actions map once to proposed activation custody; feature ownership, AUTH activation, route commits, ART and outbox boundaries do not cross. | +| CI integrity | N/A - with approved reason | None | Planning Markdown only; no workflow, dependency, runner, threshold, test or coverage configuration changed. | +| docs | PASS | None | Main, source hashes, clean REV head, planning-versus-runtime language and blockers are truthful. | +| reuse/dedup | PASS | None | One prepared D10 protocol and existing AUTH grant, outbox, ART, session, fence and composition abstractions are reused. | +| test delta | N/A - with approved reason | None | No runtime test file changed; every later runtime chunk retains test-delta review and isolated evidence gates. | + +Open sub-agent sessions: none + +Valid findings addressed: yes + +- Rebased the branch onto merged AUTH-08. Canonical main now has 74 + PermissionIds, 57 ActionIds, nine active self/admin actions, 48 planned + actions, eight resource-context variants and actor-self/AdminRoleGrant matched + authorities. All 23 proposed WS-CON actions, both proposed service permissions + and the upstream `task.claim` ActionId remain absent. +- Reused AUTH-08's resource-context digest, matched grant/project evidence, + rollback-only dependency teardown and typed retryable evidence-failure path. + Hidden domain services flush without committing; every actual route owns its + complete decision/business transaction. The service callback commits its + decision, receipt and idempotency state atomically inside its fence. +- Kept D10 AUTH-owned and single-use: authority locks first, final product facts + are evaluated once, AUTH stages one decision and never commits, and CON never + queries AUTH state or supplies role policy. +- Added D11 as an unresolved human cross-spec decision. Merged AUTH gives + Finance—but not Operator—delivery-reconcile candidacy and gives Project + Manager the broad award-read candidate; audit candidates also differ. Later + gates support either human outcome and require only the AUTH amendments or + CON-01 active-matrix changes that outcome selects. +- Added D12 because canonical ActionOwner means the chunk allowed to activate. + The recommended model proposes eight exact AUTH activation owners mapping all + 23 WS-CON actions once plus two AUTH review-action custodians. The globally + reviewed alternative must add a separate closed activation-custody type. + Missing, dual or feature-side activation custody is forbidden. +- Moved role-selection and negative grant tests to AUTH activation. CON chunks + validate typed decision causation against canonical product facts and do not + grow role-aware fakes or a second policy engine. +- Refreshed the parallel REV dependency to clean committed head + `a13bf352147cbb2c65742802e7c74a9478e5013b`. Its AUTH-08 dependency review is + accurate, but it remains non-consumable pending ART/final evidence plus + review choreography, D12 custody and handler-claims-OutboxEvent repair. +- Preserved the human-approved complete PaymentPolicy semantic cutover in + CON-05A and physical removal in CON-05B. Only legacy-row treatment remains a + separate human decision. + +Deterministic evidence passed: `git diff --check`; Markdown links for 38 changed +Markdown files; stale Workstream wording; artifact-contract and loop-memory +state; 71 agent-gate tests; two focused synchronous AUTH catalogue/role-policy +tests; exact trusted-main ancestry; all three WS-CON source hashes including the +tracked original through `git show`; clean REV head assertion; direct AUTH +catalogue/runtime/role assertions; and exact D12 23/23 unique owner coverage. +The two focused AUTH tests emitted only expected environment warnings because +the local system interpreter lacks the async pytest plugin; no async test was +claimed. The authorization stale-doc scan continues to flag exactly ten +`HUMAN_WORKER_VOCABULARY` occurrences in the explicitly non-canonical working +transcription. CON-01 owns its byte-preserving archive classification and +active-spec reconciliation; this is not a waiver for active documentation. + +Application/runtime code changed: no. The original PDF deletion remains the +pre-existing unstaged user-worktree change and is excluded from the reviewed +content/evidence commits. + ## 2026-07-15 AUTH-07B Executable-Boundary Reconciliation This addendum is the current authoritative review state. It supersedes the From 6b35b1ec3f78524e50c3c17432dfd9c87df36637 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Thu, 16 Jul 2026 12:00:40 +0100 Subject: [PATCH 07/22] Reconcile WS-CON plan with ART PR 129 --- .../ARTIFACT_STORAGE_HANDOFF.md | 101 +++++++++++++--- .../AUTHORIZATION_HANDOFF.md | 39 ++++++- .../CHUNK_MAP.md | 11 +- .../CONFORMANCE_MATRIX.md | 4 +- .../DECISIONS.md | 8 +- .../DISCOVERY.md | 35 ++++-- .../JOINT_RELEASE_HANDOFF.md | 26 +++-- .../PLAN.md | 110 +++++++++++++----- .../RISKS.md | 6 + .../SOURCE_MANIFEST.md | 44 ++++--- .../STATUS.md | 23 ++-- ...-CON-001-01-canonical-contract-adoption.md | 8 +- ...CON-001-09A-contribution-evidence-write.md | 53 +++++++-- ...B-authorized-contribution-evidence-read.md | 11 +- .../WS-CON-001-11-hidden-release-readiness.md | 24 +++- ...PLAN-contribution-compensation-planning.md | 68 ++++++++++- 16 files changed, 443 insertions(+), 128 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md index 706f60d3..99caffb1 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md @@ -8,19 +8,74 @@ verification, ArtifactBinding/receipt persistence, retry recovery, and provider conformance. CON owns only the deterministic contribution-evidence schema, projection status, canonical owner facts, and disclosure guards. +Merged ART-02A2 PR #129 is a foundation, not this capability. It adds the +inactive `ArtifactPreparationService`, canonical `ArtifactScratchManager`, and +sealed `PreparedArtifact`/`CommittedArtifactSource` lifecycle while preserving +ArtifactStore v1 and all active runtime behavior. It adds no admission, +provider, verification, binding, contribution, action or permission behavior. +The named capability remains separately approved. Its exact gate is AUTH-09 +fixed verifier/scanner/resolver registration, service identities and assignments +-> merged ART 02A3, 02B1, 02C1, 02C2 and 02C3 -> ART-02D hidden resource/ +behavior composition -> AUTH-owned evaluator integration and activation of +`artifact.verification.execute`, `artifact.pending_work.scan` and +`artifact.put_attempt.resolve` -> `WS-ART-001-CON-EVIDENCE`. ART-02D proves and +consumes those authorities but never writes action availability; the later +contribution binding action cannot substitute for the internal executor actions. +Before ART-02D starts, D12 must transfer all eight existing ART-02D Operator +actions to `AUTH_ART_02D_OPERATOR` and the three internal actions to +`AUTH_ART_02D_INTERNAL`, or bind the same exact mappings in a separate closed +activation-custody type. Operator recovery separately requires AUTH activation +of `artifact.verification_job.retry`; the internal actions do not imply it. + ## Required typed capabilities -- `ContributionEvidenceWritePort.write(request)` accepts the caller - `AsyncSession`, D10 prepared handle, contribution/project/schema identity, - media type, expected digest, stable idempotency identity, and bounded - deterministic bytes or byte source. In durable Transaction A it locks ART - admission state after AUTH and CON locks, composes the full typed context, - completes the handle's single final AUTH evaluation, stages the decision and - admission/put-attempt continuation, and never commits or performs provider - I/O. After the caller commits, only ART-owned continuation/executor authority - may perform provider I/O, verification and binding. The high-level capability - eventually returns bounded verified ArtifactBinding/receipt data and never a - provider reference. +- `ContributionEvidenceWritePort.prepare_source(request)` runs before D10 and + before every database mutation lock. It accepts contribution/project/schema/ + logical-role identity, exact media type + `application/vnd.workstream.contribution-evidence+json;version=1`, + expected canonical `sha256:`, exact expected byte count, stable + idempotency identity, and a bounded deterministic async byte source. ART's + canonical `ArtifactPreparationService` writes the complete first pass once to + private scratch, computes the server commitment, and rejects an unsupported + media type, digest/size mismatch or source-limit breach before admission or + provider I/O. +- Preparation returns only a port-defined opaque + `PreparedContributionEvidenceWrite` async-context value with a read-only + commitment view. The ART implementation retains the raw `PreparedArtifact`; + the request/value contains no scratch path, descriptor, + `ArtifactScratchManager`, `PreparedArtifact`, `CommittedArtifactSource`, + provider reference or raw ArtifactStore and is never serialized to Celery or + persisted. +- The caller then starts Transaction A, asks AUTH to prepare D10 and lock its + authority rows, locks/reloads CON projection and immutable contribution rows, + regenerates the canonical evidence facts/digest from that locked snapshot, + and requires exact equality with the ART server commitment. Only then does + `ContributionEvidenceWritePort.stage(prepared, request)` accept the caller + `AsyncSession`, D10 handle and final canonical facts. ART locks admission + state after AUTH and CON, composes its full typed context, completes the + handle's single final AUTH evaluation, and stages the decision plus durable + admission/put-attempt. It flushes but never commits or performs provider I/O. +- `stage` returns an opaque same-process ART continuation. The caller explicitly + commits Transaction A and then calls + `ContributionEvidenceWritePort.execute_after_commit(continuation)`. ART opens + a fresh transaction to prove/claim the committed durable attempt before it + consumes the retained `CommittedArtifactSource.stream()` exactly once and + calls the provider outside every database transaction. No caller signal alone + authorizes I/O. +- Commit failure, rollback, pre-commit drift, caller cancellation and exact- + replay short-circuit close the ART-owned preparation cancellation-resistently. + A close/release failure retains explicit ART cleanup and quota custody until + retry succeeds. Process loss serializes no handle: the durable attempt remains + the only authority, stale scratch cleanup reclaims abandoned custody, and the + dispatcher/outbox replay regenerates deterministic bytes through + `prepare_source`, rechecks the exact commitment and either resumes the same + attempt or conflicts. Provider acknowledgement loss is resolved first by + read-only observation; it does not replay a write. CON never performs or + schedules scratch cleanup. +- The high-level ART flow eventually returns bounded verified + ArtifactBinding/receipt data. Before CON marks its projection `projected`, it + requires exact digest, byte count, media type, owner/project/logical-role, + schema and idempotency identity equality and never receives a provider ref. - `ContributionEvidenceReadPort.read(request)` accepts a Workstream ArtifactBinding id and already-authorized contribution context. It verifies binding/digest and returns bounded bytes or a stream, never provider authority. @@ -43,13 +98,14 @@ schema/digest resource composer and capability behavior consumed by that evaluator. Public reads continue to use `contribution.read_self` or `contribution.read_project`; there is no `artifact.retrieve` action. -CON prepares the AUTH handle from a server-resolved contribution/evidence-role -target before it locks its projection/contribution rows. It passes only that -opaque handle, canonical CON facts and deterministic bytes through the typed -port. ART then locks its own admission rows, adds ART-owned facts and completes -the one final evaluation in Transaction A. Missing/reused/mismatched handles or -fact drift fail before any durable provider attempt is executable. CON never -loads an ART row, composes ART admission facts or calls the evaluator itself. +CON resolves a read-only server snapshot and deterministic bytes, then ART +prepares them before D10 or any mutation lock. In Transaction A, CON asks AUTH +to prepare the handle first, locks/reloads its projection/contribution rows and +recomputes the exact evidence commitment before ART locks admission and performs +the final evaluation. Missing/reused/mismatched handles, commitment mismatch or +fact drift close the opaque preparation before any durable provider attempt is +executable. CON never loads an ART row, composes ART admission facts, calls the +evaluator, instantiates raw ART preparation, or handles a committed source. ## Provider and proof boundary @@ -58,3 +114,12 @@ production, and R2/Flow Node are deferred. Contract tests must reject raw store or provider imports in CON, raw provider-reference disclosure, changed bytes under one idempotency identity, cross-owner/project binding, and recovery rows or executor leases owned by CON. +They must also prove unsupported media and expected digest/size mismatch produce +zero admission/provider calls; no AUTH/CON/ART database lock is held during the +first pass; locked fact drift closes preparation; the second-pass source is +consumed once only after a committed durable-attempt claim; Transaction-A +rollback, provider failure, cancellation and replay either release scratch or +retain explicit ART cleanup custody until retry succeeds; process loss/replay +serializes no handle; verified output matches every identity/commitment fact; +and no CON API/model/event/persistence field exposes preparation details. +ART-02A2's focused tests do not replace this capability-level conformance. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md index 1ba1d1a7..89a350c2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -3,7 +3,8 @@ ## Status and ownership Every WS-CON-specific ActionId below is **proposed and currently absent**. -Trusted `main` `aa0fdcd` includes AUTH-08 through PR #131. The canonical +Trusted `main` `9a04434` includes AUTH-08 through PR #131 at `aa0fdcd` and the +later ART-02A2 merge, which changes no authorization contract. The canonical catalogue contains 74 PermissionIds and 57 non-WS-CON ActionIds: the two actor-self actions and seven AUTH-08 administrative actions are active; 48 actions remain planned. Neither proposed WS-CON service-only PermissionId is @@ -155,6 +156,42 @@ owner—but then AUTH must introduce a separate closed activation-custody type. Leaving the current dual meaning or allowing both AUTH and product chunks to activate is forbidden. +Under the recommended transfer model, AUTH atomically removes the now-unused +`ActionOwner.REV_08` after moving its only row, `review.decision`, to +`AUTH_REV_DECISION`. `REV_06` remains because it still owns the other review +release/decline/expiry actions. Closed enum/definition/SQL/audit parity tests +must reject an unused old owner or a missing new owner. + +The ART prerequisite exposes the same conflict: the merged catalogue assigns +all eleven 02D Operator/internal actions to `ActionOwner.ART_02D`, while this +plan and the user require AUTH to own availability. D12 therefore also proposes +the following complete transfer while every action is still planned. No +ActionId or PermissionId changes, and ART-02D remains the feature/resource +owner only. + +| Proposed enum member | Exact ActionOwner value / AUTH activation chunk | Existing ActionId -> PermissionId mappings transferred from `ART_02D` | +|---|---|---| +| `AUTH_ART_02D_OPERATOR` | `WS-AUTH-001-ART-02D-OPERATOR` | `artifact.binding.read` -> `artifact.binding.read`; `artifact.replica.read` -> `artifact.replica.read`; `artifact.receipt.read` -> `artifact.receipt.read`; `artifact.verification_job.read` -> `artifact.verification_job.read`; `artifact.verification_job.retry` -> `artifact.verification_job.retry`; `artifact.recovery_attempt.read` -> `artifact.recovery_attempt.read`; `artifact.audit.read` -> `artifact.audit.read`; `operations.artifact_storage_admission.read` -> `operations.status.read` | +| `AUTH_ART_02D_INTERNAL` | `WS-AUTH-001-ART-02D-INTERNAL` | `artifact.verification.execute` -> `artifact.verification.execute`; `artifact.pending_work.scan` -> `artifact.pending_work.scan`; `artifact.put_attempt.resolve` -> `artifact.put_attempt.resolve` | + +AUTH-09 owns the fixed internal ActorProfiles, links and exact assignments. After +ART-02D merges hidden resources, guards, calls and behavior proof, the two AUTH +activation chunks integrate the closed evaluators and alone change availability. +The Operator retry action is an independent human action; activating the three +service actions does not activate `artifact.verification_job.retry`. If D12 +instead adopts global feature-owner semantics, these same eleven mappings must +appear in the separate closed activation-custody type before ART-02D starts. +Partial transfer, `ART_02D` plus AUTH dual writers, or a generic ART activation +owner is forbidden. + +Under the recommended transfer model, AUTH atomically removes the now-unused +`ActionOwner.ART_02D` after all eleven definitions move to the two new AUTH +owners. The closed invariant remains +`{definition.owner} == set(ActionOwner)`. Under the global alternative, +`ART_02D` and `REV_08` remain feature owners in action definitions and the new +separate activation-custody catalogue—not `ActionOwner`—must independently have +exact closed coverage. The two models cannot be mixed. + ## Proposed closed handoff `T` means the AUTH-owned prepared protocol locks authority first and the feature diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md index 52945272..db52a7d0 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -32,8 +32,8 @@ availability writer. | `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07; 02B; post-02B AUTH `outbox.dispatch` evaluator/activation and exact service-assignment proof merged; ADR 0014 adapter foundation; joint lifecycle-fence port contract | Proposed | | `WS-CON-001-08R` | Bound-Service Callback Rate Control | L1 | 08A; shared API-control contract | Proposed | | `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; callback identity/action registration already merged before 04A; AUTH typed callback context and prepared protocol merged; joint callback-fence port contract | Proposed | -| `WS-CON-001-09A` | Contribution Evidence Projection Write | L1 | 07; named `WS-ART-001-CON-EVIDENCE` capability; AUTH planned evidence action/context/prepared protocol and exact assignment on existing `workstream.artifact.binding` | Proposed | -| `WS-CON-001-09B` | Authorized Contribution Evidence Read | L1 | 09A; disclosure schema; AUTH planned contribution-read registrations/typed contexts | Proposed | +| `WS-CON-001-09A` | Contribution Evidence Projection Write | L1 | 07; D12 exact AUTH custody for all eleven ART-02D actions; AUTH-09 internal executor registration/identities/assignments -> merged ART 02A2 -> 02A3 -> 02B1 -> 02C1 -> 02C2 -> 02C3 -> hidden 02D behavior -> AUTH Operator/internal evaluator activation; named `WS-ART-001-CON-EVIDENCE` write port; AUTH planned evidence action/context/prepared protocol and exact assignment on existing `workstream.artifact.binding` | Proposed | +| `WS-CON-001-09B` | Authorized Contribution Evidence Read | L1 | 09A; merged named `WS-ART-001-CON-EVIDENCE` read port; disclosure schema; AUTH planned contribution-read registrations/typed contexts | Proposed | | `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B,09B; post-09B AUTH contribution-read activation; D11 award/audit role outcome approved; AUTH planned award-read registrations/typed contexts/exact chosen role contract | Proposed | | `WS-CON-001-10B` | Operations, Reconciliation, Rebuild, And Fulfillment Drain Observation | L1 | 10A; post-10A AUTH award-read activation; full D11 outcome approved and any chosen AUTH role-matrix amendment merged; AUTH planned binding-retire/ops/audit registrations/typed contexts/exact chosen role contract/prepared protocol; shared-outbox observation capability | Proposed | | `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10B; REV-10 integration; exact AUTH evaluator/action/service manifest, ART/outbox readiness, required CON-owned dispatch/callback fence hooks and drain port | Proposed | @@ -59,6 +59,7 @@ AUTH review.claim registration/contracts -> CON-06 -> REV-06 hidden claim compos REV-04 exact Review target -> CON-03C foreign keys AUTH review.decision registration/contracts + REV-09B + CON-07 participant -> REV-10 hidden decision composition while planned -> AUTH review.decision evaluator/activation AUTH callback identity/action registration before CON-04A + remaining typed/prepared callback contracts -> CON-08B hidden callback -> AUTH callback evaluator/activation -> CON-11 +D12 AUTH custody for 8 ART-02D Operator + 3 internal actions -> AUTH-09 fixed executor registration/identities/assignments -> ART-02A2 preparation -> ART-02A3 v2 -> ART-02B1 MinIO/AWS -> ART-02C1 admission -> ART-02C2 verification/publication -> ART-02C3 recovery -> ART-02D hidden executor/Operator behavior -> AUTH Operator/internal evaluator activation -> ART-owned CON-EVIDENCE write/read ports AUTH evidence action/typed/prepared/exact-service-assignment registration + ART capability -> CON-09A hidden handler -> AUTH evidence evaluator/activation -> CON-11 AUTH contribution-read registration/contracts -> CON-09B hidden reads -> AUTH contribution-read activation -> CON-10A D11 award-role decision + AUTH award-read registration/contracts -> CON-10A hidden reads -> AUTH exact-role award activation -> CON-10B @@ -97,7 +98,11 @@ CON-08A/08B/10B/11 required CON-owned dispatch/callback fence ports and fulfillm joint composition and may not edit the CON handler. 08R extends the shared closed rate-control scopes; 08B owns the separately authenticated callback and its narrow mandatory callback-fence consumer port. -- 09A writes evidence projections through ART; 09B owns safe reads. +- 09A writes evidence projections through ART; 09B owns safe reads. PR #129's + 02A2 preparation is only a prerequisite: CON passes a bounded deterministic + byte source plus expected digest/size/media type through the named port, while + ART alone owns scratch preparation, sealed-source lifetime, admission, + provider I/O, verification and binding. - 10A owns product reads; 10B owns operations/reconciliation/rebuild plus the read-only fulfillment-drain observation port over CON and shared-outbox state. - 11 proves hidden readiness, including both required fence injection seams and diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md index 25a8f1e6..a0848ced 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -12,14 +12,14 @@ evidence, not executable authority. | Requirement family | Owner | Minimum executable cases before owner completes | Final live evidence owner | |---|---|---|---| -| Central authorization integration | AUTH executable gates + each CON resource owner | post-AUTH-08 74/57 baseline exact; D12 maps each action to exactly one approved owner/custodian and rejects dual activation; all absent/planned actions deny; each active action has exact ActionId/PermissionId/owner/context/evaluator parity; evaluator-owned per-action AdminRole allowlist precedes query/guards and mixed excluded+eligible grants select only the eligible grant; decisions bind complete resource digest plus matched grant/project; human grant and service assignment never substitute; `T` prepared handles reject missing/reuse/cross-session/cross-action/target drift; authority-loss versus product mutation runs in both orders; feature routes explicitly commit and abandoned/evidence-failed work rolls back; no CON AUTH-repository import or local role fallback | AUTH conformance + REV-13 | +| Central authorization integration | AUTH executable gates + each CON/ART resource owner | post-AUTH-08 74/57 baseline exact; D12 maps 23 WS-CON, two coupled review and eleven required ART-02D actions to exactly one approved owner/custodian and rejects dual activation while preserving exact ActionId/PermissionId mappings; all absent/planned actions deny; each active action has exact owner/context/evaluator parity; evaluator-owned per-action AdminRole allowlist precedes query/guards and mixed excluded+eligible grants select only the eligible grant; decisions bind complete resource digest plus matched grant/project; human grant and service assignment never substitute; `T` prepared handles reject missing/reuse/cross-session/cross-action/target drift; authority-loss versus product mutation runs in both orders; feature routes explicitly commit and abandoned/evidence-failed work rolls back; no CON AUTH-repository import or local role fallback | AUTH conformance + REV-13 | | Contribution identity and review lineage | CON-03C/07 + REV-10 | one completed-review contribution per valid Review; accept adds one accepted-submission contribution; second revision review creates a distinct reviewer contribution; automated checker outcomes create none; at-most-one DB constraints and mandatory-participant at-least-one proof | REV-13 | | Policy publication and freezing | CON-04B/05/06 + REV-06 | absent/incomplete setup denies; unpaid is explicit; retired frozen version remains valid for started work; later activation changes new assignments/leases only; publish versus both claims in both lock orders | REV-13 | | Binding lifecycle | CON-04A/08A/08B/10B | suspended blocks new freeze/delivery but accepts valid existing-work callback; retirement denies dependencies then permits exact accepted-receipt replay only; actor/link revocation denies; project/instrument mismatch denies | REV-13 | | Immutable award evaluation | CON-03C/07 | at most one money plus one points award; exact decimals; accept/needs_revision/reject rules; replay stable; changed facts fail; no PaymentPolicy fallback | REV-13 | | Outbox and delivery | CON-02A/02B/03D/08A + REV-12A | immutable event/payload/binding/idempotency identity; stale claim fencing; durable in-flight generation; retry/dead-letter/replay; reconciliation preserves original identity; provider I/O occurs outside every database transaction/lifecycle fence; dispatch-versus-admission fencing in both orders | REV-13 | | Callback and fulfillment | CON-08B + REV-12A | callback before acknowledgement suppresses later delivery; duplicate exact receipt idempotent; changed receipt conflicts; per-actor/binding limits; suspended/retired matrices; callback allowed through delivery drain and denied after disable; callback-versus-disable in both orders; no human authority | REV-13 | -| Evidence artifact | CON-09A/09B | deterministic versioned schema; self/project disclosure matrix; no reviewer-private, provider, credential, external-receipt or unnecessary actor data; newer-schema rebuild retains prior immutable bundle; LocalStorage/MinIO capability conformance | REV-13 | +| Evidence artifact | ART 02A2-02D + CON-EVIDENCE + CON-09A/09B | deterministic versioned schema and exact media type; self/project disclosure matrix; no reviewer-private/provider/credential/external-receipt/unnecessary actor data; ART prepares before DB locks; locked facts match server commitment; invalid media or digest/size mismatch causes zero admission/provider calls; committed-attempt proof precedes one-shot I/O; rollback/failure/cancellation/replay either release scratch or retain ART cleanup custody; process loss serializes no handle and deterministic replay regenerates bytes; returned binding/receipt matches digest/size/media/owner/project/role/schema/idempotency; LocalStorage/MinIO conformance | REV-13 | | Product reads | CON-10A | D11's approved award-role set exact; Project Manager contribution access remains separate from the chosen award-detail rule; AUTH activation proves allowed/excluded/mixed/revoked/foreign-project grants; CON proves matched decision facts, stable pagination, money/points/status separation and no provider refs | REV-13 | | Operations and audit | CON-10B + REV-12A | D11's approved delivery/audit role sets and any AUTH matrix amendment exact; AUTH activation proves role/reason/scope candidates; CON proves bounded reconciliation/rebuild, immutable truth, decision-fact binding, audit redaction and same-session drain observation with no false zero or repository exposure | REV-13 | | Atomic review integration | CON-07 + REV-10 | allowed exact `review.decision` evidence matches actor/action/resource/project/request/correlation; denied/stale/mismatched evidence rejected; every injected failure rolls back review/task/contribution/award/audit/outbox together | REV-13 | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md index 06718e5e..67e50fb4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -189,9 +189,11 @@ registration or review-action activation amendment. The merged enum defines ActionOwner as the implementation chunk allowed to activate an action. The user requires AUTH to own authorization activation, so the recommended resolution keeps that meaning and adds the exact eight -AUTH-owned WS-CON activation owners plus two review activation owners listed in -`AUTHORIZATION_HANDOFF.md`. Every proposed action maps to one owner; CON/ART/REV -remain feature resource owners but never change availability. +AUTH-owned WS-CON activation owners, two review activation owners, and two +AUTH-owned ART-02D activation owners covering all eight Operator plus three +internal actions listed in `AUTHORIZATION_HANDOFF.md`. Every required action +maps to one owner without changing its PermissionId; CON/ART/REV remain feature +resource owners but never change availability. The alternative is a reviewed global semantic change: ActionOwner becomes the feature/resource owner and AUTH adds a separate closed activation-custody type. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md index 2900f209..e3339388 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -24,15 +24,18 @@ runtime implementation was performed. checks. WS-AUTH owns their cutover; WS-CON must not reproduce or repair them. - The shared `AuditEvent` ledger and caller-owned `AsyncSession` are the transaction foundation. There is no shared transactional-outbox module yet. -- Current artifact runtime is the pre-v2 foundation. Accepted ADR 0013 and - `docs/spec_artifact_storage_service.md` define the target: only - `ArtifactStorageOrchestrator` receives `ArtifactStore`; product modules use - narrow typed capability ports. +- Merged ART-02A2 PR #129 adds the inactive provider-neutral + `ArtifactPreparationService`, sealed `PreparedArtifact`/ + `CommittedArtifactSource` values, canonical `ArtifactScratchManager`, and + cancellation/file-lock primitives. Active ArtifactStore v1, schema, provider + selection, product routes, admission, verification and binding behavior are + unchanged. Product modules still use only narrow ART-owned capability ports. - Trusted `main` now includes ADR 0014's generic typed `ExternalServiceAdapterFactory[TAdapter]` foundation. It does not supply a contribution-evidence capability or compensation provider adapter; those remain separately gated, explicit composition-root registrations. -- Trusted `main` `aa0fdcd` now includes AUTH-08. The authorization catalogue is +- Trusted `main` `9a04434` includes ART-02A2 PR #129 and AUTH-08 PR #131 at + `aa0fdcd`. The authorization catalogue remains 74 PermissionIds/57 ActionIds with nine active and 48 planned actions. Durable scoped AdminRoleGrants, the five-role permission matrix, typed grant resource contexts, resource-context digests, matched grant/scope evidence, explicit @@ -67,12 +70,13 @@ generation rather than replacing the first. | Cross-domain mutation lock gap | Current `require()` can revalidate actor-self wholly inside AUTH, but WS-CON mutations need AUTH rows before product rows and final evaluation against locked product facts. | AUTH supplies the prepared, caller-session-bound, single-use `T` protocol in D10; no unlocked-snapshot decision or product-before-AUTH lock order. | | Merged Operator permission gap | AUTH-08's closed `operator` definition omits existing PermissionId `compensation.delivery.reconcile`, but the reconciled candidate WS-CON matrix proposes a reason-bound Operator as well as Finance Authority to request delivery reconciliation. Only D2 is human-approved. | D11 human decision: an AUTH-owned reviewed successor adds the existing permission before CON-10B if Operator behavior is retained, otherwise CON-01 removes the candidate before registration. CON has no role-query/local fallback. | | Cross-spec role-set conflict | AUTH-08 gives Project Manager `compensation.award.read` and broader roles `audit.read`/`audit.export`, while the unadopted WS-CON candidate proposes narrower monetary/audit sets. | D11 human choice freezes each active set. Any approved narrowing is AUTH evaluator policy with matched grant/scope proof; preserving merged candidates updates CON-01. Permission membership or candidate text alone never settles the action. | -| ActionOwner activation conflict | Canonical `ActionOwner` means the implementation chunk allowed to activate an action. Existing review actions name REV owners, while the reconciled AUTH boundary says only AUTH activates after feature composition; the 23 WS-CON actions had no exact owner mapping. | D12 human/AUTH decision plus the exact closed owner map in `AUTHORIZATION_HANDOFF.md`; never permit AUTH and a feature chunk to both change availability. | +| ActionOwner activation conflict | Canonical `ActionOwner` means the implementation chunk allowed to activate an action. Existing review actions name REV owners and all eleven required ART-02D actions name `ART_02D`, while the reconciled boundary says only AUTH activates after feature composition; the 23 WS-CON actions had no owner mapping. | D12 human/AUTH decision plus the exact closed owners for 23 WS-CON, two review and eleven ART actions in `AUTHORIZATION_HANDOFF.md`; preserve all ActionId/PermissionId mappings and never permit dual availability writers. | | Missing upstream task action | PermissionId `task.claim` exists, but current ActionId has no `task.claim` member. | AUTH-13 or reviewed AUTH successor registers/evaluates/activates `task.claim` before CON-05A integrates compensation freeze. | | Wrong Review action | Candidate uses `review.decision.record`; merged AUTH catalogue and WS-REV use registered planned ActionId `review.decision` mapped to PermissionId `review.decision`. | Consume `review.decision` only after its AUTH evaluator/availability and REV resource-composition gates. | | Invented WS-AUTH source | Candidate names `WS-AUTH-001-A`, which is not a canonical repository artifact. | Cite merged `docs/spec_authorization_service.md`, ADR 0012, and the closed catalogue. | | Invented artifact permissions | Candidate uses `artifact.recovery.request`, `artifact.recovery.execute`, and `artifact.retrieve`. AUTH explicitly rejected the first; none is a registered PermissionId. | Use `artifact.verification_job.retry` through `ArtifactOperatorRecoveryPort`; require ART-owned typed storage/read capabilities and approved action mappings. | | Wrong artifact port | Candidate injects `ArtifactStorePort` with store/projection/retain/retrieve methods. ADR 0013's target `ArtifactStore` has only provider-byte behavior and cannot enter product services. | WS-CON consumes narrow ART capability ports. Only ART orchestration receives the raw store. | +| ART-02A2 mistaken for the contribution capability | PR #129 adds only inactive first-pass scratch preparation and a sealed one-shot second-pass source. It adds no admission, provider execution, verification, binding, contribution intake or authorization. | Keep `WS-ART-001-CON-EVIDENCE` as a separately approved ART-owned prerequisite. CON supplies deterministic bytes plus expected digest/size/media type to that port; ART alone prepares, consumes and closes the committed source. | | Wrong providers | Candidate requires Local Storage/Flow Node parity. ADR 0013 locks LocalStorage for dev/focused tests, MinIO for local/CI S3 proof, AWS S3 for v0.1 production, and defers Flow Node/R2. | Test LocalStorage and MinIO; AWS deployment proof gates production; Flow Node remains future. | | Wrong retention/search claims | Candidate assumes retain/pin and semantic indexing APIs that ADR 0013 deliberately excludes from v0.1 `ArtifactStore`. | Use ART's immutable completed-byte retention policy and typed lifecycle records; omit semantic indexing/search from WS-CON v0.1. | | Duplicate submission model language | Candidate defines `SubmissionVersion` as if separate. | Treat existing `Submission` as the versioned identity and use `submission_id` in repository schemas. | @@ -92,8 +96,9 @@ generation rather than replacing the first. | `backend/app/modules/authorization/{catalogue,kernel,runtime,policy}.py` from merged AUTH-08 | Canonical closed registry, grant policy and executable kernel | 74 PermissionIds, 57 ActionIds, nine active self/admin actions and 48 planned; eight resource-context variants and actor-self/AdminRoleGrant matched authority. All WS-CON-specific actions and both service permissions remain absent. | | `backend/app/api/deps/authorization.py` | Current human composition root and transaction cleanup | Human self/admin only; it rejects service subjects, maps typed evidence failure to retryable 503 and rolls back any transaction a feature route leaves open. WS-CON routes must explicitly commit their own unit and need AUTH-owned project/service composition, not a copied dependency. | | `backend/app/modules/authorization/policy.py::ADMIN_ROLE_PERMISSIONS` | Exact merged AdminRole permission candidates | Finance has delivery reconcile; Operator does not; Project Manager has award-read. D11 decides whether each candidate WS-CON difference changes AUTH or the active CON matrix. | -| sibling `workstream-rev-001/.../` clean branch head `a13bf35` | Parallel review plan's committed AUTH-08 dependency refresh | Counts, teardown/error/timestamp repairs and source SHAs now match AUTH-08, but publication evidence deliberately remains stale pending ART. REV-06/10 still use one-step current authorization rather than the registration -> CON -> REV hidden -> AUTH activation choreography; D12 owner custody is unresolved; REV-12A still says the CON handler claims the event. Treat it as non-consumable until those CON/AUTH ownership contracts are repaired, commit-bound reviewed and merged. | -| `backend/app/modules/artifacts/*` | Current artifact metadata/orchestration foundation | Target v2 is still being delivered by WS-ART; WS-CON cannot import provider internals. | +| sibling `workstream-rev-001/.../` reviewed baseline `6faccc0` plus later external-review repairs | Parallel review plan discovery | Head `6faccc0` was inspected after its commit-bound ART refresh; later in the same turn the sibling became dirty while its owner applied external-review repairs. Neither live sibling state is a dependency. Only a future reviewed merge on trusted `main` is consumable, and it must repair prepared authorization/D12/outbox ownership before WS-CON integration. | +| `backend/app/modules/artifacts/{preparation,sources}.py` | Merged inactive committed-source preparation | ART alone owns scratch allocation, first-pass hash/count, expected commitment comparison, sealed single-use second pass and cleanup. WS-CON must not import these implementation types or create a second scratch path. | +| `backend/app/modules/artifacts/*` | Current artifact metadata/orchestration foundation | ArtifactStore v1 remains active; v2, S3, admission, verification and named contribution capabilities are still WS-ART gates. | | `backend/app/interfaces/artifacts.py` | Current v1 raw provider port | Not a WS-CON dependency; it is being clean-cut to ADR 0013 v2. | | `docs/spec_artifact_storage_service.md` | Canonical target artifact contract | Owns narrow product capability ports, recovery, verification, quotas, and provider policy. | | `docs/spec_authorization_service.md` | Canonical target authorization contract | Preserves broad PermissionIds; ActionIds are separate. | @@ -110,6 +115,7 @@ generation rather than replacing the first. | `backend/tests/test_authorization.py` | Closed catalogue plus AUTH-08 self/admin kernel/runtime | Self/admin allow/deny, scope/grant revalidation, complete resource digests, unknown/planned/unsupported denial, evidence failure and request-local state are covered. ProjectRoleGrants, service composition, WS-CON contexts/evaluators and prepared cross-domain mutation authorization remain AUTH-owned work. | | `backend/tests/test_audit.py` | Typed append-only authority evidence | No contribution/compensation lifecycle audit contract. | | `backend/tests/test_artifacts.py` | Current artifact port, local adapter, content/binding/receipt foundation | Target v2, S3/MinIO, typed contribution projection capability, and evidence reads are not merged. | +| `backend/tests/test_artifact_preparation.py` | ART-02A2 scratch, commitment, cancellation, integrity and cleanup boundary | Proves preparation only; it does not prove contribution-evidence admission, provider execution, verification or binding. | | `backend/tests/test_checkers.py` | Durable checker run and `allow_review` routing | Stops before Review persistence. | | `backend/tests/test_alembic.py` | Migration upgrade/downgrade guards | No outbox, review, or WS-CON schema. | | `backend/tests/test_api_contract_e2e.py` | Current API contract drill | No review/contribution/compensation routes or events. | @@ -124,9 +130,13 @@ generation rather than replacing the first. WS-CON does not edit those owned surfaces. - WS-REV: `Review`, `ReviewLease`, findings/resolutions, decision idempotency, task effects, hidden composition, and final public review cutover. -- WS-ART: v2 store, LocalStorage/MinIO conformance, AWS proof, narrow system- - generated projection/read/bind capabilities, verification recovery, and - artifact action activation. +- WS-ART: merged 02A2 committed-source preparation; future 02A3 v2 store, 02B1 + LocalStorage/MinIO/AWS provider work, 02C1 admission, 02C2 verification/ + publication, 02C3 recovery, 02D hidden internal-executor/Operator recovery + behavior, AUTH-owned evaluator activation, and a separately approved narrow + system-generated contribution-evidence write/read capability. ART owns + preparation, scratch, provider execution and artifact records end to end; + AUTH alone owns registrations, assignments, evaluators and availability. - Shared outbox: caller-transaction append, stable event identity, post-commit publication, at-least-once dispatch, delivery attempts, dead-letter, replay, and idempotent consumer contract. @@ -150,6 +160,7 @@ generation rather than replacing the first. | Cross-domain deadlock/partial commit | Review, authority, tasks, artifacts, CON, audit, and outbox share one transaction. | One canonical lock order, caller-owned session, fault injection, real Postgres concurrency tests. | | Economic overreach | Payment-provider or points-ledger logic could leak into Workstream. | Typed outbound instruction/receipt boundary and architecture import tests. | | Artifact bypass | Direct store injection could bypass quotas, verification, binding, and audit. | ART-owned typed capability only; static import/composition tests. | +| Scratch/source custody leaks into CON | Importing PR #129 types or paths would make CON a second artifact orchestrator and can leak quota or cleanup ownership under cancellation. | The CON port request carries only bounded deterministic bytes and expected commitment facts; ART prepares/consumes the source and either releases scratch or retains explicit cleanup custody until retry succeeds. | | Premature public surface | Partial routes would create authorization or lifecycle gaps. | Hidden internal composition until final coherent activation. | | Legacy/pre-production rows | Existing PaymentPolicy/tasks/assignments cannot be safely guessed into new frozen terms. | Human-approved rebuild/classification/backfill rule before migration. | | Event/schema drift | The candidate names many events without a shared outbox registry. | Freeze envelope/ownership in the outbox chunk before persistence consumers. | @@ -164,7 +175,7 @@ generation rather than replacing the first. | Approve two new service-only PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`? | Human outbox recovery/reconciliation authority must not execute async side effects; no existing permission safely names the external adapter callback entitlement. | Before CON-02B for dispatch and before CON-04A for callback binding identity. | | Approve the AUTH-owned WS-CON registration/evaluator/activation work and D10 prepared mutation protocol? | Current AUTH-08 supports nine self/admin actions but no WS-CON action; CON cannot safely or physically activate its own actions. | Before any authorized CON service chunk. | | Approve adding existing `compensation.delivery.reconcile` to the Operator role definition? | The reconciled candidate proposes reason-bound Operator delivery reconciliation, but merged AUTH-08 does not make that role a permission candidate. Rejecting the addition removes Operator from the active WS-CON action contract. | Before AUTH registration for CON-10B. | -| Does the ART initiative add the contribution evidence capability, or should it be a separate ART-owned prerequisite chunk? | WS-CON cannot own raw storage orchestration. | Before 10. | +| Approve the separately named ART-owned `WS-ART-001-CON-EVIDENCE` capability after ART's remaining storage gates? | PR #129 deliberately excludes contribution intake and WS-CON cannot own raw storage orchestration. | Before 09A. | ## Existing conventions to preserve diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md index fde46e2e..233cae5e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -2,8 +2,9 @@ ## Incorporation status -The inspected sibling branch now has clean committed head `a13bf35`, based -on trusted `main` including AUTH-08. Its planning contracts assign future +The inspected sibling has reviewed baseline `6faccc0`, based on trusted `main` +including AUTH-08 and ART-02A2, plus later same-turn external-review repairs in +progress. Both are discovery until a reviewed merge. Its planning contracts assign future contribution/compensation router registration, consumption of the WS-CON-11 preflight manifest, the joint live matrix, PaymentPolicy removal dependencies, active generated/document companions and REV-12A hidden release control. Those @@ -11,9 +12,10 @@ runtime changes are not implemented. The planned composition consumes the CON-owned dispatch/callback fences and fulfillment-drain observation instead of importing CON/outbox repositories. -The AUTH-08 dependency refresh now records correct merged counts and -transaction/error/timestamp repairs, but final publication evidence remains -intentionally stale pending ART. The sibling is still not consumable: REV-06/10 +The AUTH-08 dependency refresh records correct merged counts and +transaction/error/timestamp repairs, and its reviewed ART refresh correctly says +PR #129 is inactive preparation only. The sibling is still not consumable: +REV-06/08 core authorization and REV-10 final CON composition predate the registration -> CON -> REV hidden -> AUTH activation choreography and D12 owner-custody decision, and REV-12A still says the CON handler claims the shared-outbox event. Before review/merge it must instead accept the @@ -24,13 +26,13 @@ requirements. WS-CON does not edit the sibling. The WS-REV owner must repair, commit-bind, internally review and merge the exact final contract. Until later implementation gates land, both initiatives remain hidden. -The refresh must also repair REV-06/10 authorization choreography. AUTH first -registers the planned review action and typed/prepared contract; CON supplies -its capability/participant; REV then merges hidden resource composition and -final-context integration while the real kernel still denies; AUTH alone -integrates the evaluator and activates the action before production execution. -REV must not require active review actions before building the hidden -composition that AUTH activation depends on. +The refresh must repair REV-06/08/10 authorization choreography. AUTH first +registers each planned review action and typed/prepared contract; CON supplies +the claim-freeze capability/decision participant; REV-06/08 build the hidden +core behavior and REV-10 supplies final CON composition/resource integration +while the real kernel still denies; AUTH alone integrates each evaluator and +activates the action before production execution. REV must not require an active +review action before building the hidden composition its activation depends on. ## Required REV-13 allowed-file additions diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md index 5333ad41..1ffdbabb 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -37,7 +37,8 @@ or query declares one ActionId and consumes a request-scoped, caller-session- bound `AuthorizationService`. Every WS-CON ActionId is currently absent and proposed. Trusted `main` -`aa0fdcd` includes AUTH-08's scoped administrative grants. Its closed catalogue +`9a04434` includes AUTH-08's scoped administrative grants at `aa0fdcd` and +ART-02A2 PR #129, which adds no authority. The closed AUTH catalogue contains 74 PermissionIds and 57 non-WS-CON ActionIds: nine self/admin actions are active and 48 actions remain planned. The exact handoff is in `AUTHORIZATION_HANDOFF.md`. It enumerates each proposed action separately, its @@ -74,9 +75,17 @@ D12 separately resolves activation custody. The merged ActionOwner type means the implementation chunk permitted to activate an action; it cannot name a CON feature chunk while this plan says AUTH alone flips availability. The handoff therefore proposes exact AUTH-owned activation owners for all 23 WS-CON actions -and the two coupled review actions. Human/AUTH approval of that model—or a -global feature-owner semantic plus a separate closed activation-custody type—is -a registration gate. No action may have two activation authorities. +and the two coupled review actions, plus all eleven existing ART-02D Operator/ +internal actions required by contribution evidence. The ART transfer preserves +every merged ActionId -> PermissionId mapping, including +`operations.artifact_storage_admission.read` -> `operations.status.read`. +Human/AUTH approval of that model—or a global feature-owner semantic plus a +separate closed activation-custody type containing the same mappings—is a +registration gate. In the recommended transfer, AUTH also removes the unused +`REV_08` and `ART_02D` enum members atomically; `REV_06` remains for its other +actions and closed owner-definition parity must still be exact. In the global +alternative those enums remain feature owners and the separate custody type is +closed independently. No action may have two activation authorities. For mutations crossing AUTH and product rows, AUTH must add the prepared authorization protocol specified in the handoff. The preliminary target lets @@ -95,11 +104,12 @@ though PermissionId `task.claim` exists. AUTH-13 or an approved AUTH-owned successor must register and activate that action before CON-05A adds the compensation freeze participant. Review choreography is deliberately staged: AUTH first registers the planned `review.claim` and `review.decision` contracts; -CON-06/07 then supply their hidden capability/participant; REV-06/10 compose and -prove the final typed resource behavior while the real kernel remains -fail-closed; only then may AUTH integrate the evaluators and activate those -actions. Production execution and public routes remain blocked until the later -readiness/REV-13 gates. +CON-06/07 then supply their hidden capability/participant; REV-06/08 build the +core claim/decision behavior and REV-10 proves the final contribution +composition and typed resource behavior while the real kernel remains fail- +closed; only then may AUTH integrate the evaluators and activate those actions. +Production execution and public routes remain blocked until the later readiness/ +REV-13 gates. Derived contribution/award writes are mandatory participants of the already authorized `review.decision` transaction. They are not separately callable @@ -187,11 +197,37 @@ outbox retry/finalization state. The Review transaction creates only a pending contribution-evidence projection row and a shared-outbox wake-up event. After commit, a worker loads canonical -PostgreSQL records, produces deterministic canonical JSON, and hands prepared -bytes plus exact contribution facts to an ART-owned typed capability. ART owns -admission, raw provider I/O, verification, content/binding/receipt records, and -recovery. WS-CON stores only its projection state and verified Workstream -binding reference. +PostgreSQL records, produces deterministic canonical JSON, computes its +expected SHA-256 and exact byte count, and passes a bounded async byte source, +media type `application/vnd.workstream.contribution-evidence+json;version=1` +and those expected facts to an ART-owned typed capability. + +Merged ART-02A2 PR #129 supplies only ART's inactive preparation foundation. +Before D10 or any database mutation lock, the future capability uses ART's +`ArtifactPreparationService` to write the complete first pass to canonical +bounded private scratch, compute digest/size, validate the exact media contract, +reject mismatch, and retain a sealed source behind an opaque ART operation. +Transaction A then locks AUTH -> CON -> ART, recomputes the canonical evidence +commitment from locked product facts, final-evaluates D10 and stages the durable +attempt. The caller commits explicitly; only then may an ART-owned same-process +continuation prove/claim that committed attempt in a fresh transaction and +consume the single second-pass stream outside every database transaction. + +Rollback, cancellation and exact replay close the preparation or retain +fail-closed ART cleanup custody until retry succeeds. Process loss persists no +handle/path: stale scratch cleanup reclaims custody and deterministic outbox +replay regenerates identical bytes against the durable attempt. CON never +imports or constructs `ArtifactScratchManager`, `PreparedArtifact` or +`CommittedArtifactSource`, receives a scratch path/descriptor, or owns cleanup. + +PR #129 does not implement the named contribution-evidence capability or the +remaining ArtifactStore v2, S3/MinIO, durable admission, provider execution, +verification/publication, recovery/authorization, binding or receipt gates. +02A3, 02B1, 02C1, 02C2, 02C3 and 02D must precede the separately approved +`WS-ART-001-CON-EVIDENCE` chunk, which delivers both named write and read ports. +It returns only bounded verified ArtifactBinding/receipt data. WS-CON validates +their digest/size/media/owner/project/role/schema/idempotency facts before it +stores projection state and the verified Workstream binding reference. LocalStorage and MinIO exercise the same product capability contract. AWS S3 deployment proof gates production. Flow Node, R2, semantic search, provider @@ -285,7 +321,20 @@ backend contract. artifact scanner itself is unchanged. 2. Merge outbox persistence then its feature-neutral dispatcher; add split, inactive binding/policy/contribution/award/delivery/receipt persistence. -3. Interleave each AUTH registration -> feature implementation -> AUTH +3. Complete the ART sequence needed by evidence intake: merged 02A2 committed- + source preparation -> 02A3 ArtifactStore v2 cutover -> 02B1 MinIO/AWS S3 -> + 02C1 durable admission/put-attempt -> 02C2 verification/publication -> 02C3 + recovery chain -> 02D hidden internal-executor/Operator recovery behavior -> + AUTH-owned evaluator integration/activation -> separately approved + `WS-ART-001-CON-EVIDENCE` write/read ports. AUTH-09 first owns the fixed + verifier/scanner/resolver registrations, identities and assignments; D12 + first transfers the eight ART-02D Operator and three internal actions to the + exact AUTH activation custodians (or a separate closed custody map); 02D + proves hidden resource/feature behavior but never changes availability; AUTH + separately activates Operator recovery and internal execution. None of these + gates moves scratch, provider, ART + persistence or authorization ownership into CON. +4. Interleave each AUTH registration -> feature implementation -> AUTH activation wave in `AUTHORIZATION_HANDOFF.md`. The registration checkpoint provides planned ActionId/PermissionId/owner/audit parity, typed context contracts, principal prerequisites and prepared mutation protocol. The @@ -294,30 +343,31 @@ backend contract. evaluator, proves the exact merged feature and changes availability. CON/ART never edits AUTH or supplies a production allow fallback. Merge required ART capabilities in ART. -4. Activate hidden binding/policy services. CON-05A atomically removes every +5. Activate hidden binding/policy services. CON-05A atomically removes every PaymentPolicy semantic consumer and enables only task claims that freeze a CompensationPolicyVersion, only after merged REV-02 establishes the exact `Submission.task_assignment_id` lineage. CON-05B drops the unreachable old model/table/columns/constraints after a zero-consumer scan. -5. Interleave with WS-REV: policy schema before REV lease schema; lease freeze +6. Interleave with WS-REV: policy schema before REV lease schema; lease freeze before claims; atomic participant after revision/decision persistence. -6. Add delivery/callback, evidence projection, reads, and operations behind +7. Add delivery/callback, evidence projection, reads, and operations behind unregistered production routes. -7. Finish WS-CON hidden readiness and an exact dependency manifest. WS-REV-13 +8. Finish WS-CON hidden readiness and an exact dependency manifest. WS-REV-13 is the sole production router activation and joint live-drill owner for the review/contribution/compensation release. Before it, REV-12A may own hidden persisted joint release control and inject its implementation through the required CON-owned dispatch/callback fence ports while consuming the read-only fulfillment-drain observation port; it may not edit CON product files or import CON/outbox repositories. - Clean sibling head `a13bf35` now contains a separately reviewed AUTH-08 - dependency refresh with correct counts and teardown/error/timestamp facts. - Its publication evidence intentionally remains stale pending ART; REV-06/10 - still predate the registration -> CON -> REV hidden -> AUTH activation - choreography and D12 owner custody, while REV-12A still assigns claim wording - to the handler. The exact repaired snapshot must adopt those current CON/AUTH - handoffs, pass commit-bound publication review, and merge before it is - consumable. Do not change archival sources. + Sibling reviewed baseline `6faccc0` correctly treats PR #129 as inactive + preparation; later same-turn external-review repairs are in progress. Both + are discovery only. The future merged snapshot must repair REV-06/08 one-step + authorization, REV-10 final CON composition, D12 custody and REV-12A's + handler-owned outbox transitions. It must adopt the current + registration -> CON -> REV hidden -> AUTH activation/prepared-handle + choreography and dispatcher-owned typed command/outcome contract, then pass + fresh review and merge before consumption. Do not pin the live sibling head/ + cleanliness or change archival sources. At every chunk activation, rebase discovery on trusted `main`, refresh exact migration numbers and dependency symbols, and stop if an expected port/action @@ -356,6 +406,12 @@ is absent or materially changed. catalogue and stable event payload/digest identity. - LocalStorage and MinIO evidence-capability conformance; AWS deployment proof remains owned by ART. +- ART capability tests prove expected digest/size mismatch causes zero durable + admission/provider calls; only ART preparation can mint the committed source; + the second pass is single-use; success/failure/cancellation either completes + close/release or leaves explicit ART-owned cleanup custody unavailable for + reuse until retry succeeds; and no scratch path/type crosses into CON. PR + #129's preparation tests alone do not satisfy this integration gate. - Final live drill covers paid accept, needs revision, reject, unpaid policy, frozen-version change, money+points, acknowledgement vs fulfillment, failure-then-fulfillment, replay, adapter outage, storage outage, recovery, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md index f89c0262..eaccf027 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -10,11 +10,17 @@ | Review/CON circular dependency | High | Interleaved gates: policy schema -> lease schema -> freeze -> claims -> participant -> integration. | WS-CON / WS-REV | Mitigated in plan | | Partial Review/contribution/economic commit | Critical | Caller-owned session, shared lock order, DB constraints, fault injection, exact replay. | WS-CON-001-07 / WS-REV | Open | | Direct provider call bypasses ART controls | Critical | Named `WS-ART-001-CON-EVIDENCE` capability prerequisite; import/composition tests reject raw store/provider access. | WS-ART / WS-CON-001-09A | Open | +| PR #129 scratch/source types leak into CON | Critical | ART alone invokes preparation, holds `PreparedArtifact`, consumes the sealed source and either releases scratch or retains explicit cleanup custody until retry succeeds. CON passes only bounded deterministic bytes plus expected commitment through the named capability; static and cancellation tests reject a second scratch path. | WS-ART / WS-CON-001-09A | Open | +| ART-02A2 is mistaken for contribution capability readiness | Critical | Keep AUTH-09 registration/assignments, ART 02A3-02C3, hidden 02D behavior, later AUTH evaluator activation, and `WS-ART-001-CON-EVIDENCE` write/read ports as explicit gates; 02D proves/consumes authority but never writes availability. | WS-ART / WS-AUTH / WS-CON-001-09A/B/11 | Open | +| First-pass preparation holds AUTH/product locks | Critical | ART prepares before D10 or any mutation lock; Transaction A revalidates locked canonical facts/commitment and stages only bounded database work. | WS-ART / WS-CON-001-09A | Open | +| Process-local prepared source is lost across transaction outcome | Critical | Opaque ART context retains the source; caller commit is followed by a fresh committed-attempt claim before I/O; rollback/cancellation closes, process loss uses stale cleanup, and outbox replay regenerates bytes without serializing a handle. | WS-ART / WS-CON-001-09A | Open | | Outbox duplication or loss | High | 02A owns truth/append; 02B alone owns dispatch/retry/replay with stable identities. | WS-CON-001-02A/B | Open | | Human role or token claims leak into feature authorization | Critical | Central AUTH service only; no grant queries/local role checks; deny/race tests. | WS-AUTH / all WS-CON | Open | | Merged AdminRole permission candidates conflict with candidate WS-CON roles | Critical | D11 chooses Operator delivery, Project Manager award-detail and audit/export candidates. AUTH amends only a chosen outcome that differs from its merged matrix; CON-01 updates the active matrix and AUTH activation proves exact roles. | Human + WS-AUTH + WS-CON-001-01/10A/B | Decision needed | | Registered WS-CON action has no executable AUTH evaluator | Critical | AUTH owns typed contexts, closed evaluator dispatch, matched authority and active availability; CON cannot flip catalogue state; startup parity rejects active-without-evaluator and evaluator-without-feature behavior. | WS-AUTH | Open | | ActionOwner names a feature chunk while AUTH is said to activate | Critical | D12 approves exact AUTH-owned activation owners for all 23 WS-CON and two coupled review actions, or introduces a separately reviewed activation-custody type; startup/parity tests reject dual or missing owners. | Human + WS-AUTH | Decision needed | +| Required ART-02D actions retain feature activation custody | Critical | D12 transfers all eight Operator and three internal ART-02D actions to exact AUTH owners without changing ActionId/PermissionId mappings, or records the same mappings in a separate closed custody type. Operator retry and internal executor activation remain distinct. | Human + WS-AUTH / WS-ART | Decision needed | +| Owner transfer leaves unused closed enum members | Critical | Recommended D12 atomically removes `REV_08` and `ART_02D` after their last rows transfer and proves owner-definition/SQL/audit parity; the global feature-owner alternative retains them only with a separate exact closed custody catalogue. | WS-AUTH | Decision needed | | Feature route relies on authorization dependency teardown to commit | Critical | Preserve AUTH-08's rollback-only teardown: every route explicitly commits decision plus business/audit/outbox state; forgotten commit and evidence-failure tests prove zero partial state. | WS-AUTH + every WS-CON route owner | Open | | Cross-domain mutation authorizes unlocked facts or reverses locks | Critical | D10 AUTH-owned prepared handle locks authority first and evaluates once against final locked product facts; missing/reused/cross-session handles deny. | WS-AUTH + each `T` CON owner | Open | | Task compensation freeze assumes nonexistent `task.claim` ActionId | Critical | AUTH-13 or reviewed AUTH successor registers/evaluates/activates exact `task.claim` -> existing `task.claim` before CON-05A. | WS-AUTH / WS-CON-001-05A | Open | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md index 76e6f734..440c91e1 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -32,8 +32,8 @@ ## Parallel dependency sources inspected - trusted authorization worktree and `origin/main` at - `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3`, which merges AUTH-08 through PR - #131 + `9a04434e2f23c5dec8939dadb943bba4d85110c0`, which merges ART-02A2 through PR + #129 and includes AUTH-08 merge `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3` - merged AUTH-08 implementation lineage through `0832358`, now canonical on trusted `main`: 74 PermissionIds, 57 ActionIds, exactly nine active self/admin actions, 48 planned actions, eight closed resource-context variants, @@ -47,26 +47,36 @@ candidate. These facts create the unresolved D11 human decision and only its chosen AUTH amendment/evaluator or CON-01 matrix-update gates; they are not copied into CON runtime. +- merged ART-02A2 final branch head + `32aab89262a3944f305e9e5dc4c65a2d31e2e144`: inactive + `ArtifactPreparationService`, `ArtifactScratchManager`, `PreparedArtifact` + and `CommittedArtifactSource`; no ArtifactStore v2 cutover, S3/MinIO, + admission, verification, contribution capability, action or permission +- merged AUTH catalogue assigns eight Operator-facing and three internal + artifact actions to `ActionOwner.ART_02D`; their existing PermissionId + mappings are unchanged. Because `ActionOwner` currently owns activation, + contribution-evidence readiness now extends D12 with exact proposed + `AUTH_ART_02D_OPERATOR` and `AUTH_ART_02D_INTERNAL` custody rather than + allowing ART/CON to write availability. - clean trusted authorization worktree `/home/abiorh/flow/workstream-authorization-service/` - at `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3` -- active sibling REV worktree `/home/abiorh/flow/workstream-rev-001/`, observed - at branch-reachable head - `a13bf352147cbb2c65742802e7c74a9478e5013b` after its parallel agent committed - `Refresh REV plan for merged AUTH-08`; the worktree is clean. Its separate - AUTH-08 dependency review now records correct 74/57, 9/48 and transaction/ - error/timestamp facts. Final publication evidence deliberately remains stale - pending ART, REV-06/10 still predate the repaired CON/AUTH choreography and - D12 custody, and REV-12A retains incorrect handler-claims-OutboxEvent wording. - The sibling remains non-consumable until those contracts are repaired, - commit-bound reviewed and merged. -- trusted `main` at `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3`, including merged + at `9a04434e2f23c5dec8939dadb943bba4d85110c0` +- active sibling REV worktree `/home/abiorh/flow/workstream-rev-001/`: reviewed + evidence-bound baseline `6faccc04e9dbad7c746b081e55a47750f678d37c` + was inspected, then later same-turn uncommitted external-review repairs were + observed. Its ART-02A2 classification is accurate, but no sibling path/head/ + dirty state is a durable dependency. Only a reviewed merge on trusted `main` + may be consumed, and it must repair REV-06/08 prepared authorization, REV-10 + final CON composition, D12 custody and dispatcher-owned outbox transitions. +- trusted `main` at `9a04434e2f23c5dec8939dadb943bba4d85110c0`, including merged ADR 0014 from PR #127, AUTH-07A/07B from PRs #126/#130, and AUTH-08 scoped - administrative grants from PR #131. Authored loop-state/queue text in that - merge still records pre-publication AUTH-08 state; the merge commit and code - are authoritative while signed post-merge automation catches up. + administrative grants from PR #131 plus ART-02A2 from PR #129. The merge + commits and code are authoritative where authored initiative status still + describes its pre-merge branch state. These sibling worktrees are discovery evidence, not dependencies by path. Every implementation chunk consumes only contracts merged into trusted `main`. +The verification contract deliberately does not pin a live sibling head or +cleanliness because its authorized owner is working concurrently. ## Adoption note diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index cf6648f7..e1e3453e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,10 +2,12 @@ ## Current status -Base planning and its AUTH-07B reconciliation passed earlier review. The branch -is now rebased onto merged AUTH-08 at `aa0fdcd`; the resulting catalogue, -AdminRoleGrant, decision-evidence, transaction, ActionOwner and role-matrix -delta passed fresh internal review. Application code is unchanged. +Base planning and its AUTH-07B/AUTH-08 reconciliations passed earlier review. +The branch is now rebased onto trusted main `9a04434`, which merges ART-02A2 PR +#129 and includes AUTH-08 at `aa0fdcd`. The ART delta reconciliation passed +fresh architecture/senior/reuse, QA/product/docs and security/auth review after +repairing preparation timing, continuation custody, exact ART/AUTH gates and +D12 closed-owner parity. Application code is unchanged. The reconciled working Markdown transcription, supplied generation-2 PDF, original archival PDF, current backend, active docs, merged WS-AUTH authorization catalogue, and active parallel WS-REV plan delta have been mapped. @@ -26,7 +28,7 @@ domain mutation protocol AUTH-owned. No implementation is active. | Chunk | Status | Branch | PR | Notes | |---|---|---|---:|---| -| `WS-CON-001-PLAN` | Reviewed; D11/D12 human gates | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; reviewed refresh records merged AUTH-08 at `aa0fdcd`, unresolved D11/D12 decisions, exact AUTH executable gates, archive-scanner ownership, and clean but non-consumable REV head `a13bf35`. | +| `WS-CON-001-PLAN` | Reviewed; D11/D12 human gates | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; reviewed refresh records PR #129 as inactive ART preparation only, exact ART/AUTH prerequisites and ownership, and treats concurrent REV work as non-consumable discovery until merged. | | `WS-CON-001-01` | Proposed | - | - | No runtime work. | | `WS-CON-001-02A` through `11` | Proposed | - | - | Each requires separate explicit start; REV-13 owns final activation. | @@ -38,13 +40,14 @@ domain mutation protocol AUTH-owned. No implementation is active. | Legacy PaymentPolicy/task/assignment row handling | Human | Choose pre-production rebuild or an explicit classified backfill before 05A/05B; PaymentPolicy removal itself is approved. | | Exact WS-CON executable authorization integration | WS-AUTH + human | Approve and implement registration, typed contexts/evaluators, matched authorities, grants/service assignments, prepared `T` protocol and active availability only in AUTH-owned chunks. | | D11 AUTH/CON human-role conflicts | Human + WS-AUTH | Choose Operator delivery reconciliation, Project Manager award detail and WS-CON audit/export role sets. AUTH amends only chosen behavior that differs from its merged matrix; CON-01 updates the active contract before registration. | -| D12 ActionOwner/activation custody | Human + WS-AUTH | Approve the exact AUTH-owned activation owners in the handoff, or approve a global feature-owner semantic plus a separate activation-custody type. Do not register/activate with dual ownership. | +| D12 ActionOwner/activation custody | Human + WS-AUTH | Approve exact AUTH-owned custody for 23 WS-CON, two coupled review and eleven existing ART-02D actions, or approve global feature-owner semantics plus a separate closed custody type with the same mappings. Do not register/activate with dual ownership. | | Upstream `task.claim` ActionId is absent | WS-AUTH-001-13 or reviewed AUTH successor | Register/evaluate/activate `task.claim` against existing PermissionId before CON-05A integrates compensation freeze. | -| Contribution evidence typed capability | WS-ART + human | Create and approve the named `WS-ART-001-CON-EVIDENCE` prerequisite before CON-09A. | +| Contribution evidence typed capabilities | WS-ART + human | Create and approve the named `WS-ART-001-CON-EVIDENCE` write/read ports after 02D; write gates CON-09A, read gates CON-09B, and both gate CON-11. | +| ART provider/admission/verification/recovery chain remains incomplete | WS-ART + WS-AUTH | PR #129 supplies only 02A2 preparation. D12 must transfer all eleven ART-02D activation custodians; AUTH-09 must register fixed internal identities/assignments; ART must merge 02A3-02D hidden behavior; AUTH then separately activates Operator recovery and the three internal actions before the named contribution ports are ready. | | ReviewLease/Review contracts | WS-REV | Merge owning persistence/behavior chunks at declared gates. | -| REV-06/10 authorization choreography predates AUTH-07B repair | WS-REV + WS-AUTH | Refresh sibling contracts to AUTH registration -> CON participant -> REV hidden planned-action composition -> AUTH activation; commit-bind and review before consumption. | +| REV-06/08/10 authorization choreography predates the prepared-handle repair | WS-REV + WS-AUTH | Repair core claim/decision sites in REV-06/08 and final CON composition in REV-10 to AUTH registration -> CON capability/participant -> REV hidden planned-action composition -> AUTH activation; commit-bind and review before consumption. | | Shared outbox | WS-CON-001-02A/B after approval | Land persistence and dispatcher before asynchronous integration. | -| REV committed head `a13bf35` remains non-consumable | WS-REV owner + human | Preserve its AUTH-08 refresh, then repair CON review choreography, D12 custody and outbox claim ownership; wait for ART, bind final publication review, and merge. | +| REV reviewed baseline plus active external-review repairs remains non-consumable | WS-REV owner + human | Repair prepared authorization/activation choreography, D12 custody and dispatcher-owned outbox transitions, bind review, and merge; WS-CON does not pin the concurrent live worktree. | | REV-12A draft assigns shared-outbox claim wording to the CON handler | WS-REV owner | Consume an already-claimed command and return a typed outcome; preserve CON-02B as sole outbox transition owner before sibling review/merge. | | External publication | Human | Push or open a PR only after explicit direction; local review evidence does not authorize publication. | @@ -54,7 +57,7 @@ domain mutation protocol AUTH-owned. No implementation is active. |---|---|---:| | Re-read merged AUTH kernel plus later AUTH-09/10 service/project-grant state and each WS-CON evaluator gate at activation. | Trusted `main` | P1 | | Re-read REV contracts at CON-03C/06/07 activation. | Parallel worktree | P1 | -| Re-read ART v2/capability ports before CON-09A. | ADR 0013/spec | P1 | +| Re-read merged ART v2/admission/verification and named capability ports before CON-09A; do not treat 02A2 preparation as capability readiness. | ADR 0013/spec/trusted main | P1 | | Decide pre-production row rebuild vs classified backfill. | Migration risk | P1 | ## Stop condition diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index 38554d98..9d40a4e6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -107,8 +107,12 @@ roadmap or broad operational-doc rewrite delivery/award/audit role outcomes and any required AUTH amendment without treating broad permission candidacy or candidate narrowing as executable. - [ ] D12 is human/AUTH-approved and the active spec lists one exact owner for - all 23 proposed actions plus the review claim/decision custody amendment; it - never conflates feature resource ownership with catalogue activation. + all 23 proposed actions plus the review claim/decision and eleven required + ART-02D custody amendments; it preserves exact ActionId/PermissionId mappings + and never conflates feature resource ownership with catalogue activation. In + the recommended transfer model the contract requires atomic removal of unused + `REV_08`/`ART_02D`; the global alternative keeps them only as feature owners + under a separate closed custody type. - [ ] Required specification reviewers pass. - [ ] `CONFORMANCE_MATRIX.md` maps every retained normative invariant to its owning chunk, concrete behavioral case, and final evidence owner; no blanket diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md index 908c2856..fa1002aa 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md @@ -22,6 +22,8 @@ docs/spec_contribution_compensation.md ```text raw ArtifactStore/provider ref, ART implementation edit +ArtifactScratchManager/PreparedArtifact/CommittedArtifactSource import or construction +scratch path/descriptor/ledger/cleanup ownership in CON read route, semantic search, retain/pin or provider recovery invention duplicate canonicalizer/worker/session/idempotency, dependency/CI weakening ``` @@ -35,27 +37,54 @@ duplicate canonicalizer/worker/session/idempotency, dependency/CI weakening `workstream.artifact.binding` ActorProfile/link; ART has merged its capability. A new or broader worker principal is forbidden. The real kernel remains fail-closed while planned and CON adds no AUTH or ART bypass. -- [ ] The handler prepares authority from a server-resolved contribution and - evidence-role target before locking its CON-owned projection/contribution - rows, then passes the opaque handle, deterministic bytes and canonical - project/contribution/role/schema/digest facts into the ART-owned caller- - transaction capability. ART locks/composes ART-owned admission facts after - those rows, completes the handle's one final evaluation, stages the one - AuthorizationDecision plus admission/put-attempt continuation, and never - commits or performs provider I/O in that transaction. CON never imports ART - persistence, evaluates ART facts or invokes the final evaluator itself. +- [ ] Merged trusted main contains the required ART chain: 02A2 committed-source + preparation, 02A3 ArtifactStore v2, 02B1 MinIO/AWS provider, 02C1 durable + admission, 02C2 verification/publication and 02C3 recovery; fixed AUTH-09 + verifier/scanner/put-resolver registrations, identities and assignments; ART- + 02D hidden resource/behavior composition; D12 exact AUTH custody for all eight + ART-02D Operator and three internal actions without ActionId/PermissionId + drift; later AUTH-owned Operator/internal evaluator integration and separate + action activation; followed by the separately approved + `WS-ART-001-CON-EVIDENCE` write port. Presence of PR #129 symbols alone fails. +- [ ] From a read-only canonical snapshot the handler creates versioned JSON, + exact media type + `application/vnd.workstream.contribution-evidence+json;version=1`, expected + digest/size and stable identity. ART prepares the source before D10 and every database + mutation lock and retains the raw `PreparedArtifact` behind an opaque async- + context operation; no ART implementation type crosses into CON. +- [ ] Transaction A then asks AUTH to prepare D10 and lock authority, locks/ + reloads the CON projection/contribution rows, regenerates and compares the + final canonical facts/digest with the server commitment, and asks ART to lock + admission and stage the AuthorizationDecision plus durable attempt. ART + flushes but does not commit; no first-pass filesystem or provider I/O occurs + while AUTH/CON/ART rows are locked. +- [ ] After the caller explicitly commits, an opaque same-process ART + continuation uses a fresh transaction to prove/claim the committed attempt + before consuming the sealed stream once and calling the provider outside all + database transactions. Commit failure, rollback, drift, cancellation and + replay close/release or retain explicit ART cleanup custody until retry. + Process loss persists no handle/path; stale cleanup and deterministic outbox + replay regenerate identical bytes against the durable attempt. Observation + precedes any absent-object replay after ambiguous provider completion. - [ ] While planned, success-path evidence tests use only an explicit fake below that seam and real-kernel/worker tests fail closed. Transaction tests cover prepare denial, CON/ART final-fact drift, handle misuse, ART Transaction-A - rollback, post-commit provider continuation, and AUTH -> CON -> ART lock races - in both relevant orders. Provider I/O is impossible before Transaction A - commits. + rollback, unsupported/wrong media or digest/size mismatch with zero admission/ + provider calls, no DB locks during first pass, locked-fact drift, post-commit + durable-attempt proof, prepared-source close/cancellation/quota custody, + process loss/replay without handle serialization, single-use second pass, and + AUTH -> CON -> ART lock races in both relevant orders. Provider I/O is + impossible before Transaction A commits. - [ ] Versioned minimal schema/disclosure matrix excludes reviewer-private, compensation/provider, credential, external-receipt and unnecessary actor data. - [ ] Versioned `ContributionEvidenceProjectionRequested` reuses shared hashing, outbox, worker, idempotency and session utilities; replay is byte-stable. - [ ] ART owns admission/I/O/verification/binding/receipt/recovery; WS-CON stores only projection state and verified binding reference. +- [ ] Before marking the projection `projected`, CON validates returned binding/ + receipt digest, byte count, exact media type, owner, project, logical role, + schema version and operation/idempotency identity against its immutable + projection. Any mismatch is an artifact integrity failure, never success. - [ ] LocalStorage/MinIO capability conformance passes; new-schema rebuild retains prior immutable bundles. - [ ] A later AUTH-owned activation gate, after the ART capability and CON diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md index c79bc419..4157abf0 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -27,6 +27,10 @@ dependency, test, coverage or CI weakening ## Acceptance criteria +- [ ] Trusted main contains the separately approved + `WS-ART-001-CON-EVIDENCE` `ContributionEvidenceReadPort`; 09A's merged write + port does not imply read readiness unless the same ART chunk explicitly + delivers and proves both. - [ ] AUTH has registered the exact planned contribution self/project read actions, typed contexts and applicable actor-self/AdminRoleGrant definitions. CON composes canonical facts; pre-filter pagination and cross-project @@ -39,8 +43,11 @@ dependency, test, coverage or CI weakening canonical collection facts. CON tests disclosure with explicit allowed/ denied decision seams only; the later AUTH activation gate proves exact role, revoked-grant, mixed-grant and foreign-project candidate selection. -- [ ] ART result matches immutable projection identity; evidence failure never - changes ContributionRecord truth. +- [ ] ART result matches immutable projection binding, digest, byte count, + exact media type + `application/vnd.workstream.contribution-evidence+json;version=1`, owner/ + project/logical role and schema identity; evidence failure never changes + ContributionRecord truth. - [ ] All product-fact/project mismatch cases map to CONFORMANCE_MATRIX; AUTH-owned role cases map to the activation gate; OpenAPI is hidden. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index a29b4e8d..6ce59d83 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -43,6 +43,17 @@ archival reference edits dependencies and assignments, ART capabilities, outbox dispatcher, REV-10 integration and provider readiness are present. An active action without its executable evaluator or feature behavior fails startup. +- [ ] ART readiness names exact merged 02A2, 02A3, 02B1, 02C1, 02C2, 02C3 and + hidden 02D behavior SHAs; fixed AUTH-09 verifier/scanner/put-resolver + registrations, identities and assignments; exact D12 AUTH custody and + unchanged ActionId/PermissionId mappings for all eight Operator/three internal + ART-02D actions; later AUTH-owned evaluator/activation evidence for Operator + recovery separately from all three internal actions; both + `WS-ART-001-CON-EVIDENCE` write/read port + symbols; `ArtifactOperatorRecoveryPort`; LocalStorage/MinIO conformance; AWS + proof; pre-lock preparation, locked-commitment revalidation, committed-attempt + continuation, one-shot stream and retained-cleanup-custody evidence. PR #129 + symbols alone fail readiness. - [ ] AUTH manifest proves the reviewed post-AUTH-08 baseline, full D11 human outcome plus any required AUTH matrix amendment, exact chosen per-action AdminRole allowlists, complete @@ -50,9 +61,16 @@ archival reference edits route commits, rollback of abandoned transactions and typed retryable authorization-evidence failure. No service action uses a human grant. - [ ] D12 manifest maps all 23 WS-CON actions and the coupled review claim/ - decision actions to exactly one approved owner/activation custodian, matches - the registered enum and AUTH chunk map, and fails startup on dual, missing or - feature-side availability custody. + decision actions plus all eleven required ART-02D actions to exactly one + approved owner/activation custodian, matches the registered enum and AUTH + chunk map, preserves exact ActionId/PermissionId mappings, and fails startup + on dual, missing or feature-side availability custody. +- [ ] Under recommended D12, no `ActionOwner.REV_08` or + `ActionOwner.ART_02D` enum/definition/SQL/audit member remains after transfer, + `REV_06` remains for its other actions, and + `{definition.owner} == set(ActionOwner)`. Under the global alternative the + old feature owners remain and a separate closed custody catalogue has exact + one-per-action coverage; mixed models fail startup. - [ ] Hidden integration proves `/api/v1` target paths are absent from production OpenAPI before release and no partial direct construction path exists. - [ ] `CONFORMANCE_MATRIX.md` has collected node IDs/evidence for every adopted diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md index c56722dc..0bdd71b4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md @@ -63,6 +63,12 @@ active runtime documentation adoption cross-spec role choices and conditional AUTH changes; adds D12's exact proposed ActionOwner/custody map; refreshes the clean/non-consumable REV dependency; and receives fresh required review/evidence against `aa0fdcd`. +- [x] ART-02A2 PR #129 refresh records the inactive preparation-only boundary, + exact `ArtifactPreparationService`/sealed-source ownership, remaining ART + 02A3/02B1/02C1/02C2/02C3/02D/write-read-capability gates, concurrent + non-consumable REV discovery without a live-head pin, and D12's exact eight- + Operator/three-internal ART action custody without ActionId/PermissionId + drift; and receives fresh required review/evidence against `9a04434`. ## Verification commands @@ -72,14 +78,39 @@ python3 scripts/check_stale_workstream_wording.py python3 scripts/check_stale_artifact_contracts.py python3 scripts/check_loop_memory_state.py PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py +(cd backend && PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -p pytest_asyncio.plugin -q \ + tests/test_artifact_preparation.py::test_preparation_seals_exact_commitment_and_single_stream \ + tests/test_artifact_preparation.py::test_committed_sources_cannot_be_publicly_assembled \ + tests/test_artifact_preparation.py::test_client_commitment_mismatch_prevents_provider_call \ + tests/test_artifact_preparation.py::test_preparation_cancellation_releases_file_and_reservation \ + tests/test_artifact_preparation.py::test_closed_preparation_rejects_stream_and_is_idempotent \ + tests/test_artifact_preparation.py::test_cancelled_close_finishes_cleanup_and_closes_handle) git diff --check -test "$(git rev-parse origin/main)" = aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3 -git merge-base --is-ancestor aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3 HEAD +test "$(git rev-parse origin/main)" = 9a04434e2f23c5dec8939dadb943bba4d85110c0 +git merge-base --is-ancestor 9a04434e2f23c5dec8939dadb943bba4d85110c0 HEAD test "$(sha256sum docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md | cut -d' ' -f1)" = cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640 test "$(sha256sum 'docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf' | cut -d' ' -f1)" = ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457 test "$(git show origin/main:docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf | sha256sum | cut -d' ' -f1)" = 34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1 -test "$(git -C /home/abiorh/flow/workstream-rev-001 rev-parse HEAD)" = a13bf352147cbb2c65742802e7c74a9478e5013b -test -z "$(git -C /home/abiorh/flow/workstream-rev-001 status --porcelain)" +(cd backend && python3 - <<'PY' +from inspect import signature + +from app.modules.artifacts.preparation import ( + ArtifactPreparationService, + ArtifactScratchManager, +) +from app.modules.artifacts.sources import CommittedArtifactSource, PreparedArtifact + +parameters = signature(ArtifactPreparationService.prepare).parameters +assert list(parameters) == [ + "self", "stream", "media_type", "expected_sha256", "expected_size" +] +assert parameters["media_type"].kind.name == "KEYWORD_ONLY" +assert parameters["expected_sha256"].kind.name == "KEYWORD_ONLY" +assert parameters["expected_size"].kind.name == "KEYWORD_ONLY" +for value in (ArtifactScratchManager, PreparedArtifact, CommittedArtifactSource): + assert value.__module__.startswith("app.modules.artifacts.") +PY +) (cd backend && python3 - <<'PY' import re from pathlib import Path @@ -132,6 +163,35 @@ for line in owner_section.splitlines(): owner_actions.extend(re.findall(r"`([^`]+)`", line.split("|")[3])) assert len(owner_actions) == len(set(owner_actions)) == 23 assert set(owner_actions) == ws_con_actions +definitions = { + row.action_id.value: (row.permission_id.value, row.owner.value) + for row in ACTION_DEFINITIONS +} +art_02d_mappings = { + "artifact.binding.read": "artifact.binding.read", + "artifact.replica.read": "artifact.replica.read", + "artifact.receipt.read": "artifact.receipt.read", + "artifact.verification_job.read": "artifact.verification_job.read", + "artifact.verification_job.retry": "artifact.verification_job.retry", + "artifact.recovery_attempt.read": "artifact.recovery_attempt.read", + "artifact.audit.read": "artifact.audit.read", + "operations.artifact_storage_admission.read": "operations.status.read", + "artifact.verification.execute": "artifact.verification.execute", + "artifact.pending_work.scan": "artifact.pending_work.scan", + "artifact.put_attempt.resolve": "artifact.put_attempt.resolve", +} +assert { + action: permission + for action, (permission, owner) in definitions.items() + if owner == "WS-ART-001-02D" +} == art_02d_mappings +assert "`AUTH_ART_02D_OPERATOR`" in owner_section +assert "`AUTH_ART_02D_INTERNAL`" in owner_section +for action, permission in art_02d_mappings.items(): + assert f"`{action}` -> `{permission}`" in owner_section +assert "removes the now-unused\n`ActionOwner.ART_02D`" in owner_section +assert "removes the now-unused\n`ActionOwner.REV_08`" in owner_section +assert "`REV_06` remains" in owner_section PY ) ``` From c0f61ae67c3dff2f6e4a877da1c2f343f5796963 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Thu, 16 Jul 2026 12:01:47 +0100 Subject: [PATCH 08/22] Bind WS-CON ART PR 129 review evidence --- ...S-CON-001-PLAN-internal-review-evidence.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index 376c2732..f020addf 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -1,5 +1,101 @@ # Internal Review Evidence: WS-CON-001-PLAN +## 2026-07-16 ART-02A2 PR #129 And Exact Custody Reconciliation + +This addendum is the current authoritative review state and supersedes older +trusted-main, ART readiness, REV worktree and ActionOwner statements below. +Trusted `main` `9a04434e2f23c5dec8939dadb943bba4d85110c0` merges ART-02A2 PR #129 and +includes AUTH-08 merge `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3`. + +Reviewed code SHA: `5538e94a66718b867280f806c9beac97ac212972` + +Reviewed non-review planning-tree SHA-256: +`b44c0685e842c57694ba0e3b4af34cbcdcaa6a423f965af3cd8d71f9fad9ea92` + +The digest excludes `reviews/**` and is reproduced from the repository root: + +```bash +find .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary \ + -type f -name '*.md' ! -path '*/reviews/*' -print0 \ + | sort -z | xargs -0 sha256sum | sha256sum +``` + +Reviewed at: 2026-07-16T11:00:58Z + +Reviewer run IDs: architecture/senior/reuse=`/root/auth08_arch_review`; +QA/test/product/ops/docs=`/root/auth08_qa_product_review`; +security/auth/privacy=`/root/auth08_security_review` + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | Pre-lock preparation, bounded Transaction A, explicit caller commit and ART-owned post-commit execution form one executable protocol. | +| QA/test | PASS | None | Exact ART write/read/recovery/media/receipt gates and concurrent-sibling discovery rules are testable. | +| security/auth | PASS | None | All eleven ART-02D actions retain exact mappings and move to closed AUTH custody without dual availability writers. | +| product/ops | PASS | None | Contribution truth remains PostgreSQL-canonical and complete PaymentPolicy removal remains unchanged. | +| architecture | PASS | None | ART owns preparation/storage; AUTH owns registration/evaluators/availability; CON owns deterministic evidence facts only. | +| docs | PASS | None | PR #129 is described as inactive preparation only and later gates are named exactly. | +| reuse/dedup | PASS | None | Canonical ART scratch/preparation, AUTH D10, shared outbox, sessions and recovery paths are reused. | +| CI integrity | N/A - with approved reason | None | Planning Markdown only; no workflow, dependency, test, threshold or runner changed. | +| test delta | N/A - with approved reason | None | No runtime test file changed; focused merged-code tests are dependency evidence only. | + +Open sub-agent sessions: none + +Valid findings addressed: yes + +- Classified merged ART-02A2 final head `32aab89262a3944f305e9e5dc4c65a2d31e2e144` + correctly: inactive `ArtifactPreparationService`, canonical bounded scratch and + sealed one-shot source only. ArtifactStore v1, providers, schema, admission, + verification, binding, contribution behavior and authorization are unchanged. +- Replaced the unsafe long-lock draft with ART-owned pre-transaction + `prepare_source`; locked AUTH -> CON -> ART staging and commitment + revalidation; caller-owned commit; a fresh committed-attempt claim; and + one-shot provider I/O outside every database transaction. Rollback, + cancellation, process loss, stale cleanup, acknowledgement loss and + deterministic replay serialize no scratch handle and retain cleanup custody + fail closed when release cannot complete. +- Made the dependency chain exact: AUTH-09 fixed identities/assignments; ART + 02A2 -> 02A3 -> 02B1 -> 02C1 -> 02C2 -> 02C3 -> hidden 02D behavior; + AUTH-owned Operator/internal evaluator activation; then the separately + approved `WS-ART-001-CON-EVIDENCE` write/read ports. CON-09A, 09B and 11 gate + the exact owning symbols separately. +- Froze media type + `application/vnd.workstream.contribution-evidence+json;version=1`, zero-I/O + rejection for invalid media or digest/size mismatch, and exact returned + binding/receipt digest, size, media, owner, project, role, schema and + idempotency validation before projection success. +- Extended D12 without changing canonical identifiers. All eight current + Operator-facing `ART_02D` ActionIds retain their existing PermissionIds under + proposed `AUTH_ART_02D_OPERATOR`; all three internal ActionIds retain theirs + under `AUTH_ART_02D_INTERNAL`. In the recommended model, AUTH atomically + removes now-unused `ART_02D` and `REV_08`, retains `REV_06`, and preserves + `{definition.owner} == set(ActionOwner)` across typed/SQL/audit parity. The + global alternative must keep feature owners and add a separate exact closed + activation-custody catalogue; mixed models and dual writers are forbidden. +- Preserved AUTH ownership. ART-02D supplies hidden feature/resource behavior + only; AUTH-09 owns service identities/assignments and later AUTH chunks alone + integrate evaluators and change availability. The three internal actions do + not imply Operator `artifact.verification_job.retry`, and the later + contribution binding action cannot substitute for either authority family. +- Inspected REV evidence-bound baseline `6faccc0`, then observed its owner begin + later external-review repairs. The live sibling is discovery only and is not + pinned by WS-CON verification; only a reviewed merge on trusted `main` may be + consumed. + +Deterministic evidence passed: `git diff --check`; Markdown links for 38 changed +Markdown files; stale Workstream wording; artifact-contract and loop-memory +state; 71 agent-gate tests; seven focused ART commitment/single-stream/ +cancellation/cleanup tests; exact trusted-main ancestry; no backend diff; +direct proof of all eleven current `ART_02D` ActionId -> PermissionId mappings; +and exact proposed owner/removal/parity assertions. The authorization stale-doc +scanner continues to flag exactly ten `HUMAN_WORKER_VOCABULARY` occurrences in +the explicitly non-canonical generation-2 working transcription. CON-01 owns +its byte-preserving archive classification and active-spec reconciliation; no +active documentation waiver was added. + +Application/runtime code changed: no. The original PDF deletion remains the +pre-existing unstaged user-worktree change and is excluded from the reviewed +content/evidence commits. + ## 2026-07-16 AUTH-08 And Parallel-REV Reconciliation This addendum is the current authoritative review state and supersedes older From c4242e0b7c3441c23ce8b3a3facc45ae00de848a Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 06:16:38 +0100 Subject: [PATCH 09/22] Reconcile WS-CON plan with WS-XINT boundaries --- .../ARTIFACT_STORAGE_HANDOFF.md | 173 ++--- .../AUTHORIZATION_HANDOFF.md | 583 ++++++-------- .../CHUNK_MAP.md | 182 ++--- .../CONFORMANCE_MATRIX.md | 44 +- .../DECISIONS.md | 339 ++++---- .../DISCOVERY.md | 328 ++++---- .../INTENT.md | 123 ++- .../JOINT_RELEASE_HANDOFF.md | 172 ++-- .../PLAN.md | 734 ++++++++---------- .../RISKS.md | 49 +- .../RUNTIME_VERIFICATION.md | 15 +- .../SOURCE_MANIFEST.md | 99 +-- .../STATUS.md | 93 +-- ...-CON-001-01-canonical-contract-adoption.md | 175 ++--- ...WS-CON-001-02B-shared-outbox-dispatcher.md | 108 +-- ...-02C-shared-lifecycle-audit-participant.md | 2 +- ...CON-001-03A-adapter-binding-persistence.md | 29 +- ...001-03B-compensation-policy-persistence.md | 42 - ...001-03B-contribution-policy-persistence.md | 47 ++ ...-001-03C-contribution-award-persistence.md | 30 +- ...03D-delivery-receipt-status-persistence.md | 6 +- ...-001-04A-hidden-adapter-binding-service.md | 11 +- ...-04B-hidden-compensation-policy-service.md | 59 -- ...-04B-hidden-contribution-policy-service.md | 50 ++ ...-economic-terms-cutover-and-task-freeze.md | 70 ++ ...policy-semantic-cutover-and-task-freeze.md | 129 --- ...-001-05B-legacy-economic-schema-removal.md | 46 ++ ...-payment-policy-physical-schema-removal.md | 48 -- ...001-06-review-lease-compensation-freeze.md | 90 --- ...review-lease-contribution-policy-freeze.md | 52 ++ ...c-review-contribution-award-participant.md | 150 ++-- ...-001-08A-outbound-compensation-delivery.md | 117 ++- ...ON-001-08B-inbound-fulfillment-callback.md | 87 +-- ...CON-001-09A-contribution-evidence-write.md | 120 +-- ...B-authorized-contribution-evidence-read.md | 86 +- ...01-10A-contribution-award-product-reads.md | 56 +- ...1-10B-operations-reconciliation-rebuild.md | 78 +- .../WS-CON-001-10C-operations-executors.md | 65 ++ .../WS-CON-001-11-hidden-release-readiness.md | 136 +--- ...PLAN-contribution-compensation-planning.md | 245 ++---- docs/current_system_data_flow.html | 2 +- scripts/check_internal_review_evidence.py | 33 +- scripts/check_stale_artifact_contracts.py | 1 + scripts/check_stale_authorization_docs.py | 3 +- scripts/check_stale_workstream_wording.py | 8 +- scripts/test_agent_gates.py | 105 ++- 46 files changed, 2181 insertions(+), 3039 deletions(-) delete mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-contribution-policy-persistence.md delete mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md delete mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md delete mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md delete mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md index 99caffb1..590985b4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/ARTIFACT_STORAGE_HANDOFF.md @@ -1,125 +1,68 @@ -# Artifact Storage Handoff: WS-ART-001-CON-EVIDENCE +# Optional Artifact Projection Handoff: WS-CON-001 -## Ownership and gate +## Status -This is a proposed ART-owned prerequisite before CON-09A. ART owns the chunk, -raw ArtifactStore composition, prepared-byte admission, provider I/O, -verification, ArtifactBinding/receipt persistence, retry recovery, and provider -conformance. CON owns only the deterministic contribution-evidence schema, -projection status, canonical owner facts, and disclosure guards. +Deferred and not approved for implementation. Merged WS-XINT-001 D7 and +`REV_CON_HANDOFF.md` supersede the earlier mandatory contribution-evidence +design. -Merged ART-02A2 PR #129 is a foundation, not this capability. It adds the -inactive `ArtifactPreparationService`, canonical `ArtifactScratchManager`, and -sealed `PreparedArtifact`/`CommittedArtifactSource` lifecycle while preserving -ArtifactStore v1 and all active runtime behavior. It adds no admission, -provider, verification, binding, contribution, action or permission behavior. -The named capability remains separately approved. Its exact gate is AUTH-09 -fixed verifier/scanner/resolver registration, service identities and assignments --> merged ART 02A3, 02B1, 02C1, 02C2 and 02C3 -> ART-02D hidden resource/ -behavior composition -> AUTH-owned evaluator integration and activation of -`artifact.verification.execute`, `artifact.pending_work.scan` and -`artifact.put_attempt.resolve` -> `WS-ART-001-CON-EVIDENCE`. ART-02D proves and -consumes those authorities but never writes action availability; the later -contribution binding action cannot substitute for the internal executor actions. -Before ART-02D starts, D12 must transfer all eight existing ART-02D Operator -actions to `AUTH_ART_02D_OPERATOR` and the three internal actions to -`AUTH_ART_02D_INTERNAL`, or bind the same exact mappings in a separate closed -activation-custody type. Operator recovery separately requires AUTH activation -of `artifact.verification_job.retry`; the internal actions do not imply it. +## Core boundary -## Required typed capabilities +Core Review/ContributionRecord creation has no synchronous or asynchronous ART +prerequisite. REV supplies the stabilized versioned Submission/packet artifact +digest through locked canonical facts. CON copies that value into +`ContributionRecord.artifact_hash` and does not load, verify, rehash, bind, or +project artifact bytes. -- `ContributionEvidenceWritePort.prepare_source(request)` runs before D10 and - before every database mutation lock. It accepts contribution/project/schema/ - logical-role identity, exact media type - `application/vnd.workstream.contribution-evidence+json;version=1`, - expected canonical `sha256:`, exact expected byte count, stable - idempotency identity, and a bounded deterministic async byte source. ART's - canonical `ArtifactPreparationService` writes the complete first pass once to - private scratch, computes the server commitment, and rejects an unsupported - media type, digest/size mismatch or source-limit breach before admission or - provider I/O. -- Preparation returns only a port-defined opaque - `PreparedContributionEvidenceWrite` async-context value with a read-only - commitment view. The ART implementation retains the raw `PreparedArtifact`; - the request/value contains no scratch path, descriptor, - `ArtifactScratchManager`, `PreparedArtifact`, `CommittedArtifactSource`, - provider reference or raw ArtifactStore and is never serialized to Celery or - persisted. -- The caller then starts Transaction A, asks AUTH to prepare D10 and lock its - authority rows, locks/reloads CON projection and immutable contribution rows, - regenerates the canonical evidence facts/digest from that locked snapshot, - and requires exact equality with the ART server commitment. Only then does - `ContributionEvidenceWritePort.stage(prepared, request)` accept the caller - `AsyncSession`, D10 handle and final canonical facts. ART locks admission - state after AUTH and CON, composes its full typed context, completes the - handle's single final AUTH evaluation, and stages the decision plus durable - admission/put-attempt. It flushes but never commits or performs provider I/O. -- `stage` returns an opaque same-process ART continuation. The caller explicitly - commits Transaction A and then calls - `ContributionEvidenceWritePort.execute_after_commit(continuation)`. ART opens - a fresh transaction to prove/claim the committed durable attempt before it - consumes the retained `CommittedArtifactSource.stream()` exactly once and - calls the provider outside every database transaction. No caller signal alone - authorizes I/O. -- Commit failure, rollback, pre-commit drift, caller cancellation and exact- - replay short-circuit close the ART-owned preparation cancellation-resistently. - A close/release failure retains explicit ART cleanup and quota custody until - retry succeeds. Process loss serializes no handle: the durable attempt remains - the only authority, stale scratch cleanup reclaims abandoned custody, and the - dispatcher/outbox replay regenerates deterministic bytes through - `prepare_source`, rechecks the exact commitment and either resumes the same - attempt or conflicts. Provider acknowledgement loss is resolved first by - read-only observation; it does not replay a write. CON never performs or - schedules scratch cleanup. -- The high-level ART flow eventually returns bounded verified - ArtifactBinding/receipt data. Before CON marks its projection `projected`, it - requires exact digest, byte count, media type, owner/project/logical-role, - schema and idempotency identity equality and never receives a provider ref. -- `ContributionEvidenceReadPort.read(request)` accepts a Workstream - ArtifactBinding id and already-authorized contribution context. It verifies - binding/digest and returns bounded bytes or a stream, never provider authority. -- `ArtifactOperatorRecoveryPort.retry_verification(request)` remains the only - operator recovery entry. Only exhausted `provider_unavailable` verification - jobs are eligible; one recovery attempt creates a new retry job, leaves the - exhausted source job unchanged, and exact replay returns the same attempt and - retry-job ids. +ART outage or integrity uncertainty may block a Review only where REV's own +stabilized packet contract requires it before judgment. Once REV supplies the +canonical decision facts, CON does not call ART and cannot translate storage +failure into `needs_revision`, `reject`, a missing contribution, or a missing +award. -## Authorization dependency +## Optional future projection -AUTH registers `artifact.contribution_evidence.binding.create` mapped to the -existing `artifact.binding.create` PermissionId, reuses the canonical fixed -`workstream.artifact.binding` ActorProfile/link, adds only this exact action to -that principal's closed assignment set, adds the typed service evaluator and -prepared `T` protocol, and alone changes availability to active. A new generic -CON/ART worker identity or broader artifact assignment is not allowed without a -reviewed AUTH amendment. ART owns the canonical contribution/project/role/ -schema/digest resource composer and capability behavior consumed by that -evaluator. Public reads continue to use `contribution.read_self` or -`contribution.read_project`; there is no `artifact.retrieve` action. +A deterministic contribution-evidence document may be proposed later as a +post-commit asynchronous projection. If approved: -CON resolves a read-only server snapshot and deterministic bytes, then ART -prepares them before D10 or any mutation lock. In Transaction A, CON asks AUTH -to prepare the handle first, locks/reloads its projection/contribution rows and -recomputes the exact evidence commitment before ART locks admission and performs -the final evaluation. Missing/reused/mismatched handles, commitment mismatch or -fact drift close the opaque preparation before any durable provider attempt is -executable. CON never loads an ART row, composes ART admission facts, calls the -evaluator, instantiates raw ART preparation, or handles a committed source. +- projection status and failure lifecycle remain separate from Review, + ContributionRecord, CompensationAward, CompensationFulfillmentReceipt, and + CompensationStatusProjection truth; +- CON owns deterministic document semantics and the projection relation only; +- ART owns preparation, scratch, admission, provider execution, verification, + binding, receipts, recovery, retention, and provider abstraction; +- AUTH owns the exact optional action, fixed service admission, evaluator, and + activation; +- PostgreSQL remains canonical; the artifact is an export, not source truth; +- storage failure is retryable projection failure and never a product rollback. -## Provider and proof boundary +## Required fresh approval -LocalStorage is focused dev/test, MinIO is local/CI S3-protocol proof, AWS S3 is -production, and R2/Flow Node are deferred. Contract tests must reject raw store -or provider imports in CON, raw provider-reference disclosure, changed bytes -under one idempotency identity, cross-owner/project binding, and recovery rows -or executor leases owned by CON. -They must also prove unsupported media and expected digest/size mismatch produce -zero admission/provider calls; no AUTH/CON/ART database lock is held during the -first pass; locked fact drift closes preparation; the second-pass source is -consumed once only after a committed durable-attempt claim; Transaction-A -rollback, provider failure, cancellation and replay either release scratch or -retain explicit ART cleanup custody until retry succeeds; process loss/replay -serializes no handle; verified output matches every identity/commitment fact; -and no CON API/model/event/persistence field exposes preparation details. -ART-02A2's focused tests do not replace this capability-level conformance. +CON-09A/09B cannot start from this planning document alone. A future chunk must +refresh and internally review: + +- the then-current ArtifactStore v2/admission/verification/recovery contracts; +- one named ART write capability and, independently, any read capability; +- exact document schema, media type, retention, disclosure, and replay rules; +- one separately registered optional binding ActionId mapped to the stable + `artifact.binding.create` PermissionId; +- exact extension of the existing `workstream.artifact.binding` static service + row, controlled provisioning, AUTH-09E admission, and activation sequence; +- cancellation, commitment drift, idempotency, provider ambiguity, cleanup + custody, and cross-project disclosure proof. + +PR #129 supplies only inactive committed-source preparation. It does not +approve a contribution-evidence port, admission, provider execution, +verification, binding, read, or retention contract. + +## Prohibited coupling + +- No evidence row/event in CON-07. +- No CON-09A/09B prerequisite for CON-10A/B or CON-11. +- No ART prerequisite in the core chunk dependency order or joint live drill. +- No raw ArtifactStore, scratch manager, prepared/committed source, provider + reference, path, credential, or ART repository crossing into CON. +- No optional evidence action counted as a core WS-CON action. +- No storage outcome mutating canonical contribution or award truth. + +This handoff changes no runtime and starts no optional projection work. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md index 89a350c2..85d8a59e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -1,357 +1,232 @@ # Authorization Handoff: WS-CON-001 -## Status and ownership - -Every WS-CON-specific ActionId below is **proposed and currently absent**. -Trusted `main` `9a04434` includes AUTH-08 through PR #131 at `aa0fdcd` and the -later ART-02A2 merge, which changes no authorization contract. The canonical -catalogue contains 74 PermissionIds and 57 non-WS-CON ActionIds: the two -actor-self actions and seven AUTH-08 administrative actions are active; 48 -actions remain planned. Neither proposed WS-CON service-only PermissionId is -registered, and none of the 23 proposed WS-CON ActionIds is in the merged -closed enum. - -AUTH-08 materially advances, but does not complete, the runtime boundary. -`AuthorizationResourceContext` now has eight closed variants; -`MatchedAuthorityKind` has `actor_self` and `admin_role_grant`; decisions carry -the complete resource-context digest plus matched grant/scope evidence; and the -kernel evaluates the self and administrative families. The current FastAPI -actor dependency still rejects service subjects, ProjectRoleGrant and service -assignment authority are not implemented, and no WS-CON evaluator exists. -Registering an ActionId as planned is therefore intentionally insufficient: -every WS-CON surface still fails with `action_unavailable` until AUTH supplies -its action-specific context, exact candidate-role filter/evaluator, remaining -principal or service assignment, transaction protocol, and active availability. - -AUTH owns ActionId/ActionOwner and PermissionId registration, -typed/PostgreSQL/audit parity, availability transitions, central evaluator -dispatch, matched-authority types, grant loading, actor/link/grant -revalidation, service ActorProfiles, exact service-action assignments, and the -request/worker/callback authorization composition roots. WS-CON owns canonical -product-row loading, construction of AUTH-approved typed resource facts, -product lifecycle guards, and feature behavior proof. WS-CON never edits AUTH -persistence, catalogue, runtime, grant, evaluator, or kernel files and never -changes an action from planned to active. - -## Required AUTH delivery contract - -Authorization delivery uses two AUTH-owned checkpoints around one feature-owned -chunk. Before the feature chunk starts, an AUTH registration checkpoint provides -the planned identifier/mapping, typed context contract, principal prerequisites -and prepared protocol. The feature chunk then lands hidden authorization-ready -behavior and its canonical resource composer while the action still fails -closed. Only after that feature commit is merged may an AUTH activation -checkpoint integrate the evaluator, prove end-to-end behavior and change -availability. The feature is not executable production authorization between -those checkpoints. - -Across those checkpoints AUTH must provide all applicable items below: - -1. After D12 approval, register the exact ActionId, one ActionOwner/activation- - custody mapping, PermissionId mapping and audit/SQL parity. No feature owner - or registration PR is a second activation authority. If the human approves - D4's service expansion, add only the two - proposed new PermissionIds, - `outbox.dispatch` and `compensation.fulfillment.report`; all other rows reuse - the existing PermissionId in the table. -2. Add closed typed resource-context variants for the target families below and - extend the decision resource type without accepting generic dictionaries, - client-supplied grants, raw PermissionIds, or CON persistence objects. -3. Extend the current self/admin family dispatch into an explicit closed - evaluator registry or equivalent AUTH-owned dispatch. No runtime plugin - discovery, service locator, fallback allow path, CON repository import, or - action string construction is permitted. -4. Extend matched authority for exact actor-self, AdminRoleGrant, - ProjectRoleGrant, and service-action-assignment authority as applicable. - AUTH-08's durable AdminRoleGrant definitions and scope evidence are now - merged and must be reused; AUTH-09 service actor/assignment truth and - AUTH-10 project contributor grants must merge before dependent evaluators - activate. Permission membership alone is not an allow: each action evaluator - must enforce the exact candidate-role allowlist in the table below. AUTH - extends its repository/kernel candidate lookup with an evaluator-owned closed - AdminRole set intersected with `permissions_for(role)` before query; neither - CON nor request data may supply that set. An actor holding both an excluded - and eligible role must match the eligible grant deterministically. -5. For `T` mutations, provide one caller-session-bound prepared-authorization - protocol. It accepts the action plus a server-resolved preliminary target, - locks/revalidates AUTH actor/link/grant or service-assignment rows first, - returns an opaque non-serializable handle bound to the request, session, - actor, action and target, then evaluates exactly once against the final - typed context recomposed from locked product rows. This preserves the PLAN - lock order and stages one decision without AUTH committing. A prepare-time - lifecycle/availability/authority denial terminates with that one denial and - returns no handle; a successful prepare stages no allow until final - evaluation. Missing, - mismatched, reused, cross-session or cross-action handles fail closed. The - final decision preserves AUTH-08's complete `resource_context_digest`, exact - `matched_grant_id` and covered project scope when grant-backed. -6. For `Q` reads, retain request-scoped `require(action_id, - typed_resource_context)` while loading canonical authority and applying - pre-filter/concealment rules. No decision or grant cache survives a request. - Every route explicitly commits its own read/mutation plus decision evidence; - the AUTH dependency rolls back an abandoned transaction and never rescues a - missing feature commit. Hidden CON domain services only flush and never - commit; REV-13's actual route owners prove the commit/rollback behavior. - AUTH evidence failure remains the typed retryable service-unavailable path - introduced by AUTH-08. -7. Add a service-capable composition dependency for fixed workers and bound - callbacks. Human grants never satisfy a service-only action, service - assignments never imply a human role, and suspended/revoked/deactivated - actor or link state fails closed. -8. Change availability to active only after the named CON/ART resource composer - and hidden behavior implementation is merged. The AUTH activation change - owns central integration tests against that exact merged implementation. - Startup parity must reject missing or extra - identifiers, mappings, evaluators, service identities, assignments, or - active actions without executable behavior. - -These are AUTH implementation requirements, not authorization behavior that a -CON chunk may reproduce locally. A CON feature chunk may use an explicit test -decision/fake below its authorization boundary to prove domain behavior, but no -test or production fallback may make a planned action executable through the -real kernel. - -The current WS-AUTH chunk map has no WS-CON registration or activation chunks. -The AUTH owner must first add and internally review bounded chunk contracts for -the registration checkpoint, the shared prepared protocol if not delivered by -an earlier AUTH foundation, and each activation wave below. Do not silently -fold WS-CON permissions/actions into AUTH-09 through AUTH-16 or an unrelated -feature PR without an allowed-file/acceptance/reviewer amendment. - -## Proposed AUTH-owned ActionOwner custody - -Canonical `ActionOwner` currently means the implementation chunk allowed to -activate a reserved action. Because the user requires authorization activation -to remain in the authorization service, a CON/REV feature chunk cannot also be -the ActionOwner. D12 proposes the following exact AUTH-owned activation chunks; -the AUTH owner and human must approve/add these enum members and chunk contracts -before any registration checkpoint uses them. - -| Proposed enum member | Exact ActionOwner value / AUTH activation chunk | Exact ActionIds | -|---|---|---| -| `AUTH_CON_OUTBOX` | `WS-AUTH-001-CON-OUTBOX` | `outbox.dispatch` | -| `AUTH_CON_BINDING` | `WS-AUTH-001-CON-BINDING` | `compensation.adapter_binding.read`, `compensation.adapter_binding.create`, `compensation.adapter_binding.suspend`, `compensation.adapter_binding.resume` | -| `AUTH_CON_POLICY` | `WS-AUTH-001-CON-POLICY` | `compensation.policy.read`, `compensation.policy.create_draft`, `compensation.policy.update_draft`, `compensation.policy.publish`, `compensation.policy.retire` | -| `AUTH_CON_CALLBACK` | `WS-AUTH-001-CON-CALLBACK` | `compensation.fulfillment.report` | -| `AUTH_CON_EVIDENCE` | `WS-AUTH-001-CON-EVIDENCE` | `artifact.contribution_evidence.binding.create` | -| `AUTH_CON_CONTRIBUTION_READS` | `WS-AUTH-001-CON-CONTRIBUTION-READS` | `contribution.read_self`, `contribution.read_project` | -| `AUTH_CON_AWARD_READS` | `WS-AUTH-001-CON-AWARD-READS` | `compensation.award.read_self`, `compensation.award.read_project` | -| `AUTH_CON_OPERATIONS` | `WS-AUTH-001-CON-OPERATIONS` | `compensation.adapter_binding.retire`, `compensation.delivery.reconcile`, `compensation.status.read`, `compensation.reconcile.run`, `contribution.projection.rebuild`, `audit.read`, `audit.export` | - -This table maps all 23 proposed WS-CON ActionIds exactly once. A registration -PR may reserve an action for its named future activation chunk, but only that -exact ActionOwner may later change availability after the feature gate. The -feature resource owner remains the CON/ART owner in the handoff table below and -does not gain catalogue custody. - -The same semantic conflict already exists for the two review actions consumed -here: merged `review.claim` is owned by `REV_06` and `review.decision` by -`REV_08`, while the repaired choreography requires AUTH-owned activation after -REV composition. D12 therefore also proposes `AUTH_REV_CLAIM = -WS-AUTH-001-REV-CLAIM` and `AUTH_REV_DECISION = -WS-AUTH-001-REV-DECISION`, with a reviewed AUTH registration amendment that -transfers those planned actions before activation. Alternatively, the human may -choose a global, reviewed redefinition of ActionOwner as feature/resource -owner—but then AUTH must introduce a separate closed activation-custody type. -Leaving the current dual meaning or allowing both AUTH and product chunks to -activate is forbidden. - -Under the recommended transfer model, AUTH atomically removes the now-unused -`ActionOwner.REV_08` after moving its only row, `review.decision`, to -`AUTH_REV_DECISION`. `REV_06` remains because it still owns the other review -release/decline/expiry actions. Closed enum/definition/SQL/audit parity tests -must reject an unused old owner or a missing new owner. - -The ART prerequisite exposes the same conflict: the merged catalogue assigns -all eleven 02D Operator/internal actions to `ActionOwner.ART_02D`, while this -plan and the user require AUTH to own availability. D12 therefore also proposes -the following complete transfer while every action is still planned. No -ActionId or PermissionId changes, and ART-02D remains the feature/resource -owner only. - -| Proposed enum member | Exact ActionOwner value / AUTH activation chunk | Existing ActionId -> PermissionId mappings transferred from `ART_02D` | -|---|---|---| -| `AUTH_ART_02D_OPERATOR` | `WS-AUTH-001-ART-02D-OPERATOR` | `artifact.binding.read` -> `artifact.binding.read`; `artifact.replica.read` -> `artifact.replica.read`; `artifact.receipt.read` -> `artifact.receipt.read`; `artifact.verification_job.read` -> `artifact.verification_job.read`; `artifact.verification_job.retry` -> `artifact.verification_job.retry`; `artifact.recovery_attempt.read` -> `artifact.recovery_attempt.read`; `artifact.audit.read` -> `artifact.audit.read`; `operations.artifact_storage_admission.read` -> `operations.status.read` | -| `AUTH_ART_02D_INTERNAL` | `WS-AUTH-001-ART-02D-INTERNAL` | `artifact.verification.execute` -> `artifact.verification.execute`; `artifact.pending_work.scan` -> `artifact.pending_work.scan`; `artifact.put_attempt.resolve` -> `artifact.put_attempt.resolve` | - -AUTH-09 owns the fixed internal ActorProfiles, links and exact assignments. After -ART-02D merges hidden resources, guards, calls and behavior proof, the two AUTH -activation chunks integrate the closed evaluators and alone change availability. -The Operator retry action is an independent human action; activating the three -service actions does not activate `artifact.verification_job.retry`. If D12 -instead adopts global feature-owner semantics, these same eleven mappings must -appear in the separate closed activation-custody type before ART-02D starts. -Partial transfer, `ART_02D` plus AUTH dual writers, or a generic ART activation -owner is forbidden. - -Under the recommended transfer model, AUTH atomically removes the now-unused -`ActionOwner.ART_02D` after all eleven definitions move to the two new AUTH -owners. The closed invariant remains -`{definition.owner} == set(ActionOwner)`. Under the global alternative, -`ART_02D` and `REV_08` remain feature owners in action definitions and the new -separate activation-custody catalogue—not `ActionOwner`—must independently have -exact closed coverage. The two models cannot be mixed. - -## Proposed closed handoff - -`T` means the AUTH-owned prepared protocol locks authority first and the feature -then evaluates against facts recomposed from its locked product rows in the same -caller transaction. `Q` means request-scoped authorization is sufficient -because the operation is read-only, but resource facts still come from -canonical rows. - -| Proposed ActionId | PermissionId | Target | Candidate principal | Canonical facts/mandatory guards | Revalidation | AUTH activation / feature resource owner | -|---|---|---|---|---|---:|---| -| `contribution.read_self` | existing `contribution.read_self` | ContributionRecord | human contributor | contribution, project, contributor; caller is exact contributor; minimal self disclosure | Q | AUTH / CON-09B; reused by CON-10A | -| `contribution.read_project` | existing `contribution.read_project` | Project contribution collection | Project Manager, Finance Authority, Operator/Audit as separately eligible | exact project role/operational scope; pre-filtered pagination and concealment; Reviewer is self-only and gains no project-wide history | Q | AUTH / CON-09B; reused by CON-10A | -| `compensation.policy.read` | existing `compensation.policy.manage` | CompensationPolicyVersion | Finance Authority candidate only | exact project; version belongs to project; no provider secret or service route data | Q | AUTH / CON-04B | -| `compensation.policy.create_draft` | existing `compensation.policy.manage` | Project compensation policy collection | Finance Authority candidate | exact project; setup state; referenced bindings belong to project/instrument | T | AUTH / CON-04B | -| `compensation.policy.update_draft` | existing `compensation.policy.manage` | draft CompensationPolicyVersion | Finance Authority candidate | same project; draft only; optimistic version and immutable published fields | T | AUTH / CON-04B | -| `compensation.policy.publish` | existing `compensation.policy.manage` | draft CompensationPolicyVersion | Finance Authority candidate | project selector, version, all referenced bindings active; closed rules; no contradictory guide handoff | T | AUTH / CON-04B | -| `compensation.policy.retire` | existing `compensation.policy.manage` | published CompensationPolicyVersion | Finance Authority candidate | same project; preserve frozen work; no selector corruption | T | AUTH / CON-04B | -| `compensation.adapter_binding.read` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | exact project; redact route identity as required; never expose credentials | Q | AUTH / CON-04A | -| `compensation.adapter_binding.create` | existing `compensation.adapter_binding.manage` | Project adapter-binding collection | Finance Authority candidate | project, instrument, adapter capability, canonical active service actor and non-secret route identity | T | AUTH / CON-04A | -| `compensation.adapter_binding.suspend` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | project/binding state; block new freezes/delivery, preserve existing callback obligations | T | AUTH / CON-04A | -| `compensation.adapter_binding.resume` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | actor/link/action assignment and adapter capability are active; no silent backlog mutation | T | AUTH / CON-04A | -| `compensation.adapter_binding.retire` | existing `compensation.adapter_binding.manage` | CompensationAdapterBinding | Finance Authority candidate | no active-policy reference, unfinished frozen assignment/lease, or unfulfilled award; after retirement only exact replay of a previously accepted receipt remains | T | AUTH / CON-10B | -| `compensation.award.read_self` | existing `contribution.read_self` | CompensationAward | human beneficiary | award/project/beneficiary; exact subject match; safe status only | Q | AUTH / CON-10A | -| `compensation.award.read_project` | existing `compensation.award.read` | Project award collection | D11 candidate: Finance Authority and Operator/Audit; Project Manager inclusion unresolved | exact project/ops scope; pre-filtered pagination; no provider refs | Q | AUTH / CON-10A | -| `compensation.delivery.reconcile` | existing `compensation.delivery.reconcile` | CompensationDelivery | D11 candidate: Finance Authority plus reason-bound Operator if approved | exact project/delivery; immutable event/payload/binding/idempotency identity; distinct finance/operator guards | T | AUTH / CON-10B | -| `compensation.status.read` | existing `operations.status.read` | Compensation operations projection | Operator candidate | bounded operational scope; redacted failure class; no beneficiary/provider secret | Q | AUTH / CON-10B | -| `compensation.reconcile.run` | existing `operations.reconcile.run` | Compensation reconciliation request | reason-bound Operator candidate | bounded project/range; durable request only; immutable truth comparison; never repair canonical awards/receipts; async execution is a shared-outbox handler under fixed dispatch authority | T | AUTH / CON-10B | -| `contribution.projection.rebuild` | existing `operations.projection.rebuild` | Contribution projection rebuild request | reason-bound Operator candidate | bounded project/version; durable request only; rebuild projection only; immutable truth unchanged; async execution is a shared-outbox handler under fixed dispatch authority | T | AUTH / CON-10B | -| `audit.read` | existing `audit.read` | WS-CON audit projection | D11 candidate set unresolved against broader merged roles | exact project/ops scope; redaction and pagination; append-only truth | Q | AUTH / CON-10B | -| `audit.export` | existing `audit.export` | bounded WS-CON audit export | D11 candidate set unresolved against Access Administrator/Audit permission candidates | exact scope, purpose, maximum range, redaction, export evidence | T | AUTH / CON-10B | -| `compensation.fulfillment.report` | **new service-only `compensation.fulfillment.report`** | frozen CompensationAdapterBinding + Award | exact bound service ActorProfile only | actor/link/action assignment active; route identity, award, project, instrument, frozen binding and receipt state all match | T | AUTH / CON-08B | -| `outbox.dispatch` | **new service-only `outbox.dispatch`** | claimed shared OutboxEvent | fixed `workstream.outbox.dispatcher` ActorProfile only | current claim/lease/generation; immutable event, payload and idempotency identity; handler side effects occur only under this claimed command | T | AUTH / CON-02B shared-outbox prerequisite; consumed by CON-08A | -| `artifact.contribution_evidence.binding.create` | existing `artifact.binding.create` | ContributionRecord evidence role | existing fixed `workstream.artifact.binding` service ActorProfile only | exact contribution/project/role/schema/digest; ART admission/verification receipt; no raw provider ref | T | AUTH / ART capability + CON-09A composer | - -## Merged AUTH-08 role-matrix reconciliation - -AUTH-08 proves the five AdminRole definitions and exact permission candidates, -but one merged row conflicts with the reconciled candidate WS-CON human -authority matrix. `finance_authority` contains -`compensation.delivery.reconcile`; `operator` does not. The candidate proposes -both a covered Finance Authority and a reason-bound system-scoped Operator for -the exact `compensation.delivery.reconcile` action, but only D2 has explicit -human approval. D11 therefore remains a human decision. If the Operator -behavior is approved, a reviewed AUTH-owned successor must add the **existing** -`compensation.delivery.reconcile` PermissionId to the closed Operator -definition, update definition/API/kernel matrix tests, and retain the action- -specific reason/scope guards. If it is rejected, the active WS-CON contract and -handoff must remove the Operator candidate before registration. No new -PermissionId is needed in either case, and CON must not query roles or emulate -the missing candidate locally. - -The inverse constraint is equally important, but is also unresolved rather than -implicitly approved. The merged Project Manager definition contains -`compensation.award.read`, while the candidate WS-CON matrix excludes Project -Manager from monetary award/fulfillment detail. Merged audit permissions also -cover broader roles than the candidate Audit/Operator and Audit-only surfaces. -D11 must choose the exact action-specific role sets. If a narrower set is -approved, AUTH evaluators filter candidate AdminRole values before resource -guards, preserve the exact matched grant/scope, and prove every excluded, -foreign-project, revoked-grant, wrong-scope and mixed excluded+eligible case. If -the merged role candidates are preserved, CON-01 updates the active matrix and -tests that exact wider set. Neither outcome may be inferred from PermissionId -membership or implemented as CON role logic. - -## Existing product-action dependency - -`task.claim` is not one of the 23 WS-CON-specific actions, but current trusted -`main` contains only its PermissionId; no `ActionId.TASK_CLAIM` exists. Before -CON-05A can integrate compensation freezing, AUTH-13 or a reviewed AUTH-owned -successor must register and activate ActionId `task.claim` mapped to existing -PermissionId `task.claim`, using the canonical project/task target, -exact-project submitter-or-both grant, actor/link/grant revalidation, and the -prepared `T` protocol. CON-05A adds only the compensation-policy product guard -and frozen-version participant to the already authorized task-owned claim -transaction. - -Likewise, registered review actions such as `review.claim` and -`review.decision` remain unusable while planned. Their sequence is AUTH -registration/typed/prepared contract -> CON capability/participant -> REV -hidden resource composition and final-context integration while the real kernel -still denies -> AUTH evaluator integration/activation. Only then may the -already-merged hidden composition execute outside explicit test boundaries. -WS-CON and WS-REV do not activate them. - -## Activation waves - -| Authority family | AUTH registration checkpoint | Feature-owned hidden implementation | AUTH activation must merge before | +## Current baseline + +Trusted `main` is `5d353b6` from merged PR #139. The runtime catalogue still +contains 74 PermissionIds and 57 ActionIds: nine active and 48 planned. No +WS-CON-specific ActionId below is registered. WS-XINT changed planning and +canonical contracts, not runtime authorization. + +AUTH owns identifiers, stable mappings, activation custody, typed resource and +principal contexts, grants, fixed ServiceIdentity/static matrix, AUTH-09E +admission, prepared mutation handles, evaluator dispatch, decision evidence, +availability, and parity. CON owns canonical product loaders, typed resource +facts, lifecycle guards, hidden behavior, and feature tests. Neither side +imports the other's repositories or mutates the other's state. + +## Required delivery sequence + +Every protected CON surface follows: + +```text +AUTH registration checkpoint + planned ActionId + stable PermissionId + AUTH ActionOwner + principal class + typed context + prepared protocol when mutating +-> CON hidden-behavior checkpoint + canonical resource loader + guards + behavior, real kernel still denies +-> AUTH activation checkpoint + exact evaluator + matched authority + negative proof + active availability +-> joint release checkpoint +``` + +Registration, provisioning, matrix membership, feature behavior, and activation +are distinct. A provisioned service cannot execute a planned action. CON cannot +turn a fake/test decision into a production allow path. + +## Principal models + +### Human + +- task.claim: exact active same-project `submitter` ProjectRoleGrant; +- review.claim and review.decision: exact active same-project `reviewer` + ProjectRoleGrant plus no-self-review and lifecycle guards; +- contribution self/award self: exact actor-self relationship; +- administrative policy, binding, project reads, and operations: one exact + eligible AdminRoleGrant selected by the action evaluator. + +`submitter`, `reviewer`, and `adjudicator` are independent immutable grants. +There is no combined grant. Adjudicator does not substitute for submitter or +reviewer. One role's revocation leaves every other project/admin grant intact. + +### Fixed service + +The only service admission path is: + +```text +verified service token +-> active ActorIdentityLink +-> active service ActorProfile +-> immutable closed ServiceIdentity +-> exact static service-action matrix membership +-> AUTH-09E typed service AuthorizationContext +-> CON-composed canonical ResourceContext +-> decision +``` + +There is no database service grant or action-assignment row. AUTH locks the +profile/link and validates unchanged ServiceIdentity, static membership, and +active action. Human grants cannot satisfy service actions and services cannot +use human grant candidates. Missing provisioned rows deny the request and block +release readiness, but do not fail application startup or provisioning. + +## Prepared mutation protocol + +For `T` actions AUTH resolves a server-owned preliminary target, locks human +actor/link/grant or fixed-service actor/link authority first, and returns one +opaque non-serializable handle. The handle is bound to request, session, actor, +action, target, and authority snapshot. CON then locks product rows in the +canonical order, recomposes final typed facts, and AUTH evaluates once. AUTH +stages decision evidence and never commits; the route/executor/callback boundary +commits explicitly. Missing, reused, cross-session, cross-action, target- +drifted, or authority-drifted handles deny with zero product mutation. + +`Q` reads use request-scoped require plus canonical CON loaders, pre-filtered +pagination, and concealment. No authorization result or grant cache survives a +request. + +## Proposed core action mappings + +These 22 feature-surface mappings preserve existing stable PermissionIds except +for the two explicitly proposed service-only PermissionIds. They are a product +proposal, not registered runtime. Policy ActionIds use the canonical +`contribution.policy.*` namespace while retaining stable +`compensation.policy.manage` PermissionId compatibility. + +| Proposed AUTH custodian | ActionId | PermissionId | Principal / target | Revalidation | Feature owner | +|---|---|---|---|---:|---| +| `AUTH_CON_OUTBOX` | `outbox.dispatch` | proposed `outbox.dispatch` | fixed outbox dispatcher / claimed event | T | shared outbox 02B | +| `AUTH_CON_BINDING` | `compensation.adapter_binding.read` | `compensation.adapter_binding.manage` | Finance / ProjectCompensationAdapterBinding | Q | CON-04A | +| `AUTH_CON_BINDING` | `compensation.adapter_binding.create` | `compensation.adapter_binding.manage` | Finance / project binding collection | T | CON-04A | +| `AUTH_CON_BINDING` | `compensation.adapter_binding.suspend` | `compensation.adapter_binding.manage` | Finance / active binding | T | CON-04A | +| `AUTH_CON_BINDING` | `compensation.adapter_binding.resume` | `compensation.adapter_binding.manage` | Finance / suspended binding | T | CON-04A | +| `AUTH_CON_OPERATIONS` | `compensation.adapter_binding.retire` | `compensation.adapter_binding.manage` | Finance / dependency-free binding | T | CON-10B | +| `AUTH_CON_POLICY` | `contribution.policy.read` | `compensation.policy.manage` | Finance / ContributionPolicyVersion | Q | CON-04B | +| `AUTH_CON_POLICY` | `contribution.policy.create_draft` | `compensation.policy.manage` | Finance / project policy collection | T | CON-04B | +| `AUTH_CON_POLICY` | `contribution.policy.update_draft` | `compensation.policy.manage` | Finance / draft version | T | CON-04B | +| `AUTH_CON_POLICY` | `contribution.policy.publish` | `compensation.policy.manage` | Finance / complete draft version | T | CON-04B | +| `AUTH_CON_POLICY` | `contribution.policy.retire` | `compensation.policy.manage` | Finance / published version | T | CON-04B | +| `AUTH_CON_CALLBACK` | `compensation.fulfillment.report` | proposed `compensation.fulfillment.report` | exact bound service / award and binding | T | CON-08B | +| `AUTH_CON_CONTRIBUTION_READS` | `contribution.read_self` | `contribution.read_self` | contributor / own record | Q | CON-10A | +| `AUTH_CON_CONTRIBUTION_READS` | `contribution.read_project` | `contribution.read_project` | exact eligible AdminRole / project collection | Q | CON-10A | +| `AUTH_CON_AWARD_READS` | `compensation.award.read_self` | `contribution.read_self` | beneficiary / own award | Q | CON-10A | +| `AUTH_CON_AWARD_READS` | `compensation.award.read_project` | `compensation.award.read` | D11 role set / project award collection | Q | CON-10A | +| `AUTH_CON_OPERATIONS` | `compensation.delivery.reconcile` | `compensation.delivery.reconcile` | D11 role set / delivery request | T | CON-10B | +| `AUTH_CON_OPERATIONS` | `compensation.status.read` | `operations.status.read` | Operator / bounded status | Q | CON-10B | +| `AUTH_CON_OPERATIONS` | `compensation.reconcile.run` | `operations.reconcile.run` | reason-bound Operator / durable request | T | CON-10B | +| `AUTH_CON_OPERATIONS` | `contribution.projection.rebuild` | `operations.projection.rebuild` | reason-bound Operator / durable request | T | CON-10B | +| `AUTH_CON_OPERATIONS` | `audit.read` | `audit.read` | D11 role set / bounded WS-CON audit | Q | CON-10B | +| `AUTH_CON_OPERATIONS` | `audit.export` | `audit.export` | D11 role set / bounded export | T | CON-10B | + +The proposed AUTH custodian names are exact candidates for AUTH-owned chunk +contracts. AUTH may adjust chunk grouping before registration, but every action +must have exactly one AUTH ActionOwner and unchanged PermissionId mapping. + +## Core resource guards + +- Policy publish locks one active ContributionPolicy selector, draft version, + both exact ContributionRules, award definitions, and referenced active same- + project/instrument bindings. Published content is immutable. +- Binding create validates canonical service actor, approved adapter capability, + project/instrument, and non-secret route identity. Suspend blocks new freezes + and deliveries but preserves valid callbacks for already-issued awards. +- Binding retire denies any active policy reference, unfinished frozen + assignment/lease, or unfulfilled award. After retirement only exact replay of + a previously accepted receipt may be acknowledged. +- Contribution self/project and award self/project reads use canonical record + ownership, pre-filtered project scope, stable pagination, and concealment. + They expose no provider reference, secret, balance, or ledger data. +- Callback requires exact actor/link/ServiceIdentity/static row, binding route, + award, project, instrument, and receipt-state match. Rate limits bind actor + plus binding, not shared IP alone. +- Reconciliation/rebuild create bounded durable requests and never repair + immutable contribution, award, or receipt truth. + +## Service execution gaps that must be closed + +The 22 mappings above cover human/public queries, management requests, the +callback, and generic outbox dispatch. They do not authorize protected feature +handler execution. `workstream.outbox.dispatcher` with `outbox.dispatch` can +only claim, invoke, and finalize events; it cannot transitively receive every +handler's mutation/provider authority. + +Before CON-02B/08A/10C protected execution, AUTH and the human must approve +exact ServiceIdentity/ActionId/static-row contracts. CON-08B independently +requires the authenticated callback identity/action/static-row contract: + +| Boundary | Discovery candidate identity | Discovery candidate action | Required result | |---|---|---|---| -| Shared-outbox service | planned `outbox.dispatch`, new permission, typed contract, fixed actor/link/assignment and prepared protocol | CON-02B dispatcher integrates the prepared seam but remains disabled/fail-closed | CON-08A or any dispatcher enablement | -| Binding management | planned binding read/create/suspend/resume actions, typed contracts, applicable grant definitions and prepared protocol; retire may be registered but stays planned; plus the planned callback ActionId/new PermissionId and active callback service actor/link/exact assignment needed to validate a binding (the callback action remains unavailable) | CON-04A read/create/suspend/resume only | CON-04B; retire activates only in the operations wave after CON-10B | -| Policy management | planned policy actions, typed contracts, Finance grant definition, prepared protocol | CON-04B | CON-05A | -| Task claim | planned `task.claim` registration plus typed/prepared contract | AUTH-13 task resource composer, guards and behavior | AUTH evaluator/activation in AUTH-13 or a reviewed successor before CON-05A | -| Review authority | existing planned `review.claim`/`review.decision` plus typed/prepared prerequisites | CON-06 + REV-06 hidden claim composition; CON-07 + REV-10 hidden decision composition, all real-kernel fail-closed | any production execution, CON-11 or REV-13 | -| Bound callback service | callback identity/action registration already required before CON-04A; typed callback context and prepared protocol complete before CON-08B | CON-08B | CON-11 | -| Contribution evidence service | planned evidence-binding action/service contract, prepared protocol plus ART capability | ART prerequisite + CON-09A composer/handler integrates the prepared seam | CON-11 | -| Contribution reads | planned self/project read actions and typed contexts | CON-09B | CON-10A | -| Award reads | planned self/project award actions and typed contexts | CON-10A | CON-10B | -| Operations | full D11 human decision plus any required AUTH role-matrix/evaluator amendment; planned retire/reconcile/status/rebuild/audit actions, typed contexts, prepared protocol and exact chosen candidate-role filters | CON-10B | CON-11 | - -No row authorizes public route registration. CON-11 proves the hidden action -manifest and REV-13 remains the sole joint public activation owner. - -## Adapter service-identity invariant - -Each CompensationAdapterBinding persists an `adapter_actor_id` referencing a -canonical service ActorProfile, project, instrument, adapter capability, and a -non-secret route identity. AUTH creates the exact -`compensation.fulfillment.report` service-action assignment. Human -AdminRoleGrant or ProjectRoleGrant records can never satisfy this action, and -WS-CON never fabricates such grants. - -That callback identity is a binding-creation prerequisite, not an executable -callback. Before CON-04A, AUTH must register the planned ActionId and new -PermissionId and create an active service ActorProfile/link with the exact -assignment so CON can validate canonical identity. The action remains planned -and fail-closed until CON-08B supplies the callback composer/behavior and the -later AUTH activation gate passes. - -Under the canonical lock order a callback revalidates actor state, identity-link -state, exact service-action assignment, route identity, award, project, -instrument, frozen binding, binding state, and delivery/receipt state. Controls -are rate-limited and idempotent per actor plus binding, not by shared IP alone. - -- Active binding: new freeze, delivery, and valid callback are eligible. -- Suspended binding: no new freeze or delivery; a valid callback for an award - already frozen/issued to that binding may still fulfill it. -- Retirement is denied while an active policy references the binding or any - unfinished frozen assignment/lease or unfulfilled award depends on it. - Retired binding: no new freeze, delivery, or receipt; only byte-for-byte exact - replay of a receipt already accepted before retirement is acknowledged. -- Callback before local acknowledgement creates the terminal receipt/status and - suppresses later delivery without regressing state or changing identities. - -Actor suspension/revocation and identity-link revocation always deny; these are -distinct from adapter-binding suspension. - -## Shared-outbox and ART prerequisites - -CON-08A is an outbox handler, not an independently authorized compensation -command. After CON-02B merges its hidden dispatcher, AUTH must integrate and -activate `outbox.dispatch` for the fixed dispatcher before CON-08A activates; -human -`operations.outbox.retry` authority can request recovery but can never execute -delivery. CON-09A similarly consumes a narrow ART-owned capability after AUTH -registers the planned `artifact.contribution_evidence.binding.create` and adds -that exact assignment to the existing fixed `workstream.artifact.binding` -principal; a separately invented evidence worker is forbidden absent a reviewed -AUTH amendment. AUTH may activate it only after the ART capability and CON -composer merge. CON never receives a raw storage port or an artifact-recovery -execution authority. - -Both service mutations use D10 at their owning call sites. CON-02B prepares -`outbox.dispatch` from a server-resolved event target before locking the claimed -OutboxEvent, then evaluates exactly once against final locked claim facts. -CON-09A prepares the evidence-binding action before locking its CON-owned -projection/contribution rows, then passes the handle and canonical CON facts to -the narrow ART capability. ART locks/composes its own admission facts and -performs the handle's one final evaluation in durable Transaction A before that -transaction stages admission/put-attempt state and commits; CON never imports -ART persistence or evaluates ART facts. Provider I/O and verification occur -only after Transaction A commits under ART-owned continuation/executor -authority. Later AUTH activation integrates the evaluators against those seams; -it does not retrofit or edit feature code. +| outbox mechanics | `workstream.outbox.dispatcher` | `outbox.dispatch` | exact closed identity and singleton static row | +| outbound fulfillment delivery | `workstream.compensation.delivery` | `compensation.delivery.execute` | independent feature authority; never inherited from dispatcher | +| async compensation reconciliation | `workstream.compensation.reconciler` | `compensation.reconcile.execute` | exact bounded execution action or approved dual-principal evaluator | +| async contribution projection rebuild | `workstream.contribution.projection_rebuilder` | `contribution.projection.rebuild.execute` | exact bounded execution action or approved dual-principal evaluator | +| fulfillment callback | `workstream.compensation.fulfillment_reporter` | `compensation.fulfillment.report` | one approved fixed identity/static row or an explicitly specified closed set | + +Candidate strings are not approved identifiers. If AUTH reuses an existing +request ActionId for fixed-service execution, it must specify a closed dual- +principal evaluator and prove human/service isolation. CON must not infer that +design. Each new identity requires closed enum/static-matrix changes, controlled +ActorProfile/ActorIdentityLink provisioning, service_identity constraint +migration custody, AUTH-09E admission, exact cross-service negative tests, and +activation only after hidden behavior merges. + +## Upstream review and task actions + +`task.claim` is an upstream AUTH action mapped to existing `task.claim`; it +requires the exact submitter grant and task guards before CON-05A participates. +`review.claim` and `review.decision` are current planned actions; CON-06/07 +provide hidden participants, REV supplies canonical composition, and AUTH +activates only after the complete behavior merges. + +AUTH must reconcile all 19 current review actions as one complete activation- +custody transfer under `WS-XINT-001/AUTH_REV_HANDOFF.md`. WS-CON declares only +its two dependencies and must not remove or retain individual REV ActionOwner +members locally. The four proposed additive review actions remain absent until +their own registration contract. + +Likewise, the complete 25-action ART transfer belongs to +`WS-XINT-001/AUTH_ART_HANDOFF.md`. WS-CON has no core ART dependency and does not +repeat an eleven-action subset. + +## Optional evidence action + +If optional contribution-evidence projection is separately approved, one +additional action may be proposed: + +```text +artifact.contribution_evidence.binding.create + -> existing artifact.binding.create + -> existing workstream.artifact.binding ServiceIdentity +``` + +AUTH would extend that identity's static row by exactly this action only after a +reviewed ART capability contract exists. This optional action is outside the 22 +core proposal and outside release readiness. It cannot be used to authorize +core ContributionRecord creation or reads. + +## D11 AdminRole decisions + +Before CON-10A/10B registration, the human must choose exact candidates for: + +- Project Manager inclusion in project award detail; +- reason-bound Operator delivery recovery in addition to Finance Authority; +- audit read/export role sets. + +Any difference from merged AUTH definitions is implemented by AUTH through an +action-owned closed role intersection before grant query. Mixed eligible and +excluded grants select only the eligible grant. CON receives matched decision +evidence and contains no role branch. + +## Activation and release proof + +AUTH proof must cover planned denial, exactly one custodian per action, +PermissionId parity, evaluator/context completeness, exact human grants, +ServiceIdentity/static-matrix membership, AUTH-09E admission, cross-service +denial, same-token revocation, prepared-handle misuse, transaction-time +revalidation, and decision-evidence failure. Feature proof covers canonical +facts, lifecycle guards, commit/rollback, and no AUTH persistence import. + +Startup may fail on closed code/catalogue/static-matrix/evaluator/active- +behavior drift. Runtime and release readiness deny on missing provisioned +service rows. Administrative provisioning remains available. + +This handoff changes no AUTH runtime and starts no AUTH or CON chunk. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md index db52a7d0..7a9736ac 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -3,121 +3,121 @@ ## Rule One chunk maps to one reviewable PR. No runtime chunk starts until its exact -AUTH, ART, REV, outbox, migration, and human gates are satisfied on current -trusted `main`. Every runtime chunk uses the fresh isolated PostgreSQL runner -and same-invocation coverage evidence defined in `PLAN.md`. D12 must resolve -one exact activation owner/custodian for every action before any AUTH -registration checkpoint starts; feature ownership never supplies a second -availability writer. +AUTH, REV, outbox, migration, and human gates are satisfied on trusted `main`. +AUTH owns activation custody; feature ownership never supplies a second +availability writer. Optional evidence chunks are not part of the core order. ## Chunks | Chunk | Title | Risk | Gate | Status | |---|---|---:|---|---| -| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Reviewed; D11/D12 human gates | -| `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Plan/human decisions approved | Proposed | +| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Reconciled to PR #139; internal review pending | +| `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Reconciled plan and human decisions approved | Proposed | | `WS-CON-001-02A` | Shared Transactional Outbox Persistence | L1 | 01; event ownership approved | Proposed | -| `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; worker/operations contract; AUTH planned `outbox.dispatch` registration/context/fixed actor/assignment/prepared protocol merged; dispatcher remains disabled pending later AUTH activation | Proposed | -| `WS-CON-001-02C` | Shared Lifecycle Audit Participant | L1 | 02B; existing AuditEvent contract refreshed | Proposed | -| `WS-CON-001-03A` | Compensation Adapter-Binding Persistence | L1 | 02C; migration head refreshed | Proposed | -| `WS-CON-001-03B` | Compensation Policy Persistence | L1 | 03A; legacy-data rule | Proposed | -| `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; merged REV-03 and REV-04 exact FK targets | Proposed | +| `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; AUTH registers `outbox.dispatch`, approved `workstream.outbox.dispatcher` ServiceIdentity/static row, AUTH-09E admission, prepared protocol; dispatcher remains disabled until AUTH activation | Proposed | +| `WS-CON-001-02C` | Shared Lifecycle Audit Participant | L1 | 02B; current AuditEvent contract refreshed | Proposed | +| `WS-CON-001-03A` | Project Compensation Adapter-Binding Persistence | L1 | 02C; migration head refreshed | Proposed | +| `WS-CON-001-03B` | Contribution Policy Persistence | L1 | 03A; legacy-data rule | Proposed | +| `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; exact merged REV FK targets | Proposed | | `WS-CON-001-03D` | Delivery, Receipt, And Status Persistence | L1 | 03C | Proposed | -| `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; AUTH planned binding registrations/typed contracts/grants/prepared protocol plus planned callback action/new permission and active callback actor/link/exact assignment merged; callback remains unavailable | Proposed | -| `WS-CON-001-04B` | Hidden Compensation-Policy Service | L1 | 03B,04A; post-04A AUTH binding activation merged; AUTH planned policy registrations/typed contracts/grants/prepared protocol merged | Proposed | -| `WS-CON-001-05A` | PaymentPolicy Semantic Consumer Cutover And Task Freeze | L1 | 04B; merged REV-02 exact `Submission.task_assignment_id` lineage; D2 approved; legacy rule; AUTH `task.claim` registration/evaluator/prepared protocol/activation | Proposed | -| `WS-CON-001-05B` | PaymentPolicy Physical Schema Removal | L1 | 05A; zero-consumer scan; removal migration approval | Proposed | -| `WS-CON-001-06` | Review-Lease Freeze Capability | L1 | REV-03 schema; 05B; AUTH planned `review.claim` typed/prepared contract; exact caller facts stable | Proposed | -| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D; REV-09B; shared audit/outbox; AUTH planned `review.decision` typed/prepared contract | Proposed | -| `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07; 02B; post-02B AUTH `outbox.dispatch` evaluator/activation and exact service-assignment proof merged; ADR 0014 adapter foundation; joint lifecycle-fence port contract | Proposed | +| `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; planned AUTH binding actions/contexts/prepared protocol; callback ServiceIdentity/action/static row approved but inactive | Proposed | +| `WS-CON-001-04B` | Hidden Contribution-Policy Service | L1 | 03B, 04A; binding activation merged; planned `contribution.policy.*` actions/contexts/prepared protocol | Proposed | +| `WS-CON-001-05A` | Legacy Economic Terms Cutover And Task Freeze | L1 | 04B; exact Submission/TaskAssignment lineage; AUTH task.claim with exact submitter grant and prepared protocol active; legacy rule | Proposed | +| `WS-CON-001-05B` | Legacy Economic Schema Removal | L1 | 05A; zero-consumer scan; removal migration approval | Proposed | +| `WS-CON-001-06` | Review-Lease Contribution-Policy Freeze Capability | L1 | REV lease schema; 05B; planned review.claim typed/prepared contract; exact reviewer grant facts stable | Proposed | +| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D, 05A, 06; merged TaskAssignment freeze field and REV ReviewLease schema/hidden claim composition carrying non-null reviewer policy version; shared audit/outbox; planned review.decision typed/prepared contract | Proposed | +| `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07, 02B; exact delivery ServiceIdentity/ActionId/static row registered but planned; AUTH-09E typed context/prepared protocol; ADR 0014 adapter foundation; lifecycle-fence port | Proposed | | `WS-CON-001-08R` | Bound-Service Callback Rate Control | L1 | 08A; shared API-control contract | Proposed | -| `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; callback identity/action registration already merged before 04A; AUTH typed callback context and prepared protocol merged; joint callback-fence port contract | Proposed | -| `WS-CON-001-09A` | Contribution Evidence Projection Write | L1 | 07; D12 exact AUTH custody for all eleven ART-02D actions; AUTH-09 internal executor registration/identities/assignments -> merged ART 02A2 -> 02A3 -> 02B1 -> 02C1 -> 02C2 -> 02C3 -> hidden 02D behavior -> AUTH Operator/internal evaluator activation; named `WS-ART-001-CON-EVIDENCE` write port; AUTH planned evidence action/context/prepared protocol and exact assignment on existing `workstream.artifact.binding` | Proposed | -| `WS-CON-001-09B` | Authorized Contribution Evidence Read | L1 | 09A; merged named `WS-ART-001-CON-EVIDENCE` read port; disclosure schema; AUTH planned contribution-read registrations/typed contexts | Proposed | -| `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B,09B; post-09B AUTH contribution-read activation; D11 award/audit role outcome approved; AUTH planned award-read registrations/typed contexts/exact chosen role contract | Proposed | -| `WS-CON-001-10B` | Operations, Reconciliation, Rebuild, And Fulfillment Drain Observation | L1 | 10A; post-10A AUTH award-read activation; full D11 outcome approved and any chosen AUTH role-matrix amendment merged; AUTH planned binding-retire/ops/audit registrations/typed contexts/exact chosen role contract/prepared protocol; shared-outbox observation capability | Proposed | -| `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10B; REV-10 integration; exact AUTH evaluator/action/service manifest, ART/outbox readiness, required CON-owned dispatch/callback fence hooks and drain port | Proposed | +| `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; exact callback ServiceIdentity/ActionId/static row, AUTH-09E context, prepared protocol, and callback-fence port | Proposed | +| `WS-CON-001-09A` | Optional Contribution Evidence Projection Write | L1 | Separate human approval; refreshed ART/AUTH contract and chunk review | Deferred optional | +| `WS-CON-001-09B` | Optional Authorized Contribution Evidence Read | L1 | 09A plus separate approval; refreshed disclosure contract | Deferred optional | +| `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B; D11 award-role outcome; planned contribution/award read actions and typed contexts | Proposed | +| `WS-CON-001-10B` | Operations Requests, Reads, And Fulfillment Drain Observation | L1 | 10A; D11 complete; operations request/read actions/contexts/prepared protocol; outbox observation port | Proposed | +| `WS-CON-001-10C` | Reconciliation And Projection Executors | L1 | 10B; exact executor identities/actions/static rows; AUTH-09E; hidden behavior then AUTH activation | Proposed | +| `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10C; merged REV decision integration; exact AUTH evaluator/action/service manifest; outbox readiness; CON fence/drain ports | Proposed | -## Dependency order +## Core dependency order ```text -PLAN -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D -> 04A -> 04B -> 05A -> 05B -> 06 -> 07 -> 08A -> 08R -> 08B -> 09A -> 09B -> 10A -> 10B -> 11 +PLAN -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D +-> 04A -> 04B -> 05A -> 05B -> 06 -> 07 -> 08A -> 08R -> 08B +-> 10A -> 10B -> 10C -> 11 ``` -Cross-initiative ownership and merge gates: +Optional successor, not a branch in the core release: ```text -CON-02A -> AUTH outbox registration/service assignment -> CON-02B hidden dispatcher -> AUTH outbox evaluator/activation -> CON-08A -CON-03A -> AUTH binding registration/contracts + planned callback action/permission + active callback actor/link/assignment -> CON-04A hidden binding behavior -> AUTH binding evaluator/activation -CON-04A + AUTH policy registration/contracts -> CON-04B hidden policy behavior -> AUTH policy evaluator/activation -> CON-05A -CON-03B policy persistence -> REV-03 lease persistence (REV owns lease FK) -REV-02 exact Submission.task_assignment_id lineage -> CON-05A semantic cutover/freeze -> CON-05B physical removal -> new task claims under compensation policy only -AUTH-13 ordered task.claim registration/typed-prepared contract -> task resource behavior -> evaluator/activation (or the same ordered work in a reviewed AUTH successor) -> CON-05A -CON-02C shared audit participant -> REV-04 review-chain persistence -REV-03 lease persistence + CON-05B -> CON-06 capability -AUTH review.claim registration/contracts -> CON-06 -> REV-06 hidden claim composition while planned -> AUTH review.claim evaluator/activation -REV-04 exact Review target -> CON-03C foreign keys -AUTH review.decision registration/contracts + REV-09B + CON-07 participant -> REV-10 hidden decision composition while planned -> AUTH review.decision evaluator/activation -AUTH callback identity/action registration before CON-04A + remaining typed/prepared callback contracts -> CON-08B hidden callback -> AUTH callback evaluator/activation -> CON-11 -D12 AUTH custody for 8 ART-02D Operator + 3 internal actions -> AUTH-09 fixed executor registration/identities/assignments -> ART-02A2 preparation -> ART-02A3 v2 -> ART-02B1 MinIO/AWS -> ART-02C1 admission -> ART-02C2 verification/publication -> ART-02C3 recovery -> ART-02D hidden executor/Operator behavior -> AUTH Operator/internal evaluator activation -> ART-owned CON-EVIDENCE write/read ports -AUTH evidence action/typed/prepared/exact-service-assignment registration + ART capability -> CON-09A hidden handler -> AUTH evidence evaluator/activation -> CON-11 -AUTH contribution-read registration/contracts -> CON-09B hidden reads -> AUTH contribution-read activation -> CON-10A -D11 award-role decision + AUTH award-read registration/contracts -> CON-10A hidden reads -> AUTH exact-role award activation -> CON-10B -D11 delivery/audit decisions + any required AUTH matrix amendment + operations registration/typed/prepared/exact-role contracts -> CON-10B hidden operations -> AUTH exact-role operations activation -> CON-11 -CON-08A/B,09A/B,10A/B + REV-12 + AUTH/ART/outbox -> CON-11 hidden readiness -CON-08A/08B/10B/11 required CON-owned dispatch/callback fence ports and fulfillment-drain observation + CON-11 hidden manifest + REV-12 -> REV-12A hidden joint release-control composition -> REV-13 sole route activation and joint live drill +separate human approval -> refreshed ART/AUTH handoff -> 09A -> 09B ``` +## Cross-initiative gates + +```text +AUTH registration -> CON hidden behavior -> AUTH activation -> later consumer/release +``` + +- AUTH-09A through 09E must precede protected fixed-service execution. New CON + ServiceIdentity/static-row additions require separate reviewed AUTH contracts; + provisioning never activates a feature action. +- The outbox dispatcher owns only claim/invoke/finalize under + `outbox.dispatch`. Each protected handler has independent approved authority. +- Task claim requires one exact active same-project submitter grant and freezes + the published ContributionPolicyVersion through CON-05A. +- Review claim requires one exact active same-project reviewer grant. CON-06 + supplies only the freeze port; REV supplies hidden claim composition; AUTH + activates review.claim after both merge. +- Review decision requires the reviewer grant and no-self-review/lifecycle + guards. CON-07 starts only after the TaskAssignment submitter freeze and REV + ReviewLease reviewer freeze/hidden claim composition are merged with non-null + policy-version lineage. CON-07 supplies the flush-only participant with no + ART/evidence work; REV supplies hidden decision composition; AUTH activates + review.decision afterward. +- CON-07 creates contributions, applicable awards, audit, and shared-outbox rows + in the Review transaction. It copies stabilized artifact-hash lineage and + performs no ART call. +- CON-08A/B and 10C cannot reuse outbox dispatcher authority for delivery, + callback, reconciliation, or rebuild execution. +- CON-10A owns core PostgreSQL contribution/award reads directly; it does not + wait for optional evidence reads. +- CON-11 has no ART or evidence-projection prerequisite. It hands typed + fulfillment fence/drain seams to the reviewed REV release-control work and + registers no production route. +- AUTH's complete ART and REV activation-custody transfers are consumed by + reference to WS-XINT handoffs. WS-CON does not define partial subsets. + ## Chunk boundaries -- 01 reconciles specifications/ADR and owns only the exact fail-closed scanner - classification required by its byte-preserving archival rename; 05A - atomically removes all PaymentPolicy semantic consumers and freezes the - replacement policy on task claim; 05B physically drops the unreachable - model/table/columns/constraints. -- 02A owns generic persistence/append; 02B alone owns the feature-neutral - dispatcher, handler registry, retry/dead-letter/replay, operations, and typed - read-only drain observation. -- 02C extends the existing shared AuditEvent repository/service with one typed - caller-transaction lifecycle participant; it owns no review/CON semantics. -- 03A/03B split binding and policy schema; 03C/03D split canonical economic - truth from delivery/receipt/projection schema. -- 04A/04B split hidden binding and policy services; routes remain unregistered. -- Every authorized feature family follows AUTH registration -> hidden CON - implementation -> AUTH activation. Registration alone stays fail-closed; the - CON chunk may prove domain behavior below an explicit test boundary but owns - no production allow fallback. AUTH owns availability/evaluators/principal - truth and the prepared mutation protocol. A later CON consumer and CON-11 - wait for the preceding AUTH activation gate. -- 05A owns the cross-module semantic cutover because the old locked fields span - project, task, submission and checker contracts; 05B is schema cleanup only. -- 06 exposes only a CON-owned capability; REV-06 owns review claim wiring. -- 07 creates the database-local participant; REV-10 owns review wiring. -- 08A is an outbox feature handler and owns its narrow mandatory dispatch-fence - consumer port; REV-12A may supply the durable implementation only through - joint composition and may not edit the CON handler. 08R extends the shared - closed rate-control scopes; 08B owns the separately authenticated callback - and its narrow mandatory callback-fence consumer port. -- 09A writes evidence projections through ART; 09B owns safe reads. PR #129's - 02A2 preparation is only a prerequisite: CON passes a bounded deterministic - byte source plus expected digest/size/media type through the named port, while - ART alone owns scratch preparation, sealed-source lifetime, admission, - provider I/O, verification and binding. -- 10A owns product reads; 10B owns operations/reconciliation/rebuild plus the - read-only fulfillment-drain observation port over CON and shared-outbox state. -- 11 proves hidden readiness, including both required fence injection seams and - the drain-observation port, and produces the exact dependency manifest. It - registers no production routes. REV-12A owns hidden release-control - composition; REV-13 remains the sole joint activation owner. +- 01 owns current specification/ADR adoption and scanner-safe active wording; + it does not edit archival inputs. +- 02A owns persistence/append; 02B owns generic dispatcher mechanics only; 02C + owns the shared caller-transaction audit participant. +- 03A uses `ProjectCompensationAdapterBinding`; 03B owns ContributionPolicy, + versions, rules, and award definitions; 03C/D own contribution/award and + downstream fulfillment records respectively. +- 04A/04B add hidden binding and policy services while AUTH actions remain + planned. +- 05A removes semantic consumers and freezes task assignments; 05B removes dead + physical schema. +- 06 exposes only a CON policy-freeze capability; REV owns ReviewLease schema + and wiring. +- 07 exposes only the flush-only decision participant; REV owns Review and the + single commit. No evidence projection is staged. +- 08A is a feature handler with its own protected execution boundary; 08R owns + rate-control scope; 08B owns callback authentication/composition. +- 09A/09B are deferred optional projection chunks and must be re-reviewed if + activated later. +- 10A owns core PostgreSQL product reads; 10B owns bounded operations requests + and typed drain observation; 10C owns independently authorized executors. +- 11 proves hidden readiness and blocks runtime requests on missing provisioned + service rows while leaving application startup and provisioning available. ## Required reviewer tracks Every chunk: senior engineering, QA/test, security/auth, product/ops, architecture, docs, and reuse/dedup. Runtime/test chunks add test-delta. Add CI -integrity for workflow, scripts, dependency, package, test configuration, or -coverage changes. +integrity for workflows, scripts, dependencies, test configuration, or coverage. ## Stop condition -Planning ends after required plan review and human discussion. Do not start 01 -or any runtime chunk automatically. +Planning ends after required plan review and human discussion. Do not start 01, +09A, or any runtime chunk automatically. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md index a0848ced..aab14bbd 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -1,31 +1,21 @@ # Conformance Matrix: WS-CON-001 -## Rule - -This matrix is the traceability index for the reconciled active contract. Chunk -01 expands every retained candidate requirement into an exact row. Runtime -chunks replace proposed case names with collected pytest node IDs and retained -metadata at `.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/evidence/--isolated-tests.json` -plus live-evidence paths before activation. Failed attempts remain immutable; -the matrix records the one accepted attempt ID/path. Archival candidate text is -evidence, not executable authority. - -| Requirement family | Owner | Minimum executable cases before owner completes | Final live evidence owner | +| Family | Owning chunks | Required proof | Final gate | |---|---|---|---| -| Central authorization integration | AUTH executable gates + each CON/ART resource owner | post-AUTH-08 74/57 baseline exact; D12 maps 23 WS-CON, two coupled review and eleven required ART-02D actions to exactly one approved owner/custodian and rejects dual activation while preserving exact ActionId/PermissionId mappings; all absent/planned actions deny; each active action has exact owner/context/evaluator parity; evaluator-owned per-action AdminRole allowlist precedes query/guards and mixed excluded+eligible grants select only the eligible grant; decisions bind complete resource digest plus matched grant/project; human grant and service assignment never substitute; `T` prepared handles reject missing/reuse/cross-session/cross-action/target drift; authority-loss versus product mutation runs in both orders; feature routes explicitly commit and abandoned/evidence-failed work rolls back; no CON AUTH-repository import or local role fallback | AUTH conformance + REV-13 | -| Contribution identity and review lineage | CON-03C/07 + REV-10 | one completed-review contribution per valid Review; accept adds one accepted-submission contribution; second revision review creates a distinct reviewer contribution; automated checker outcomes create none; at-most-one DB constraints and mandatory-participant at-least-one proof | REV-13 | -| Policy publication and freezing | CON-04B/05/06 + REV-06 | absent/incomplete setup denies; unpaid is explicit; retired frozen version remains valid for started work; later activation changes new assignments/leases only; publish versus both claims in both lock orders | REV-13 | -| Binding lifecycle | CON-04A/08A/08B/10B | suspended blocks new freeze/delivery but accepts valid existing-work callback; retirement denies dependencies then permits exact accepted-receipt replay only; actor/link revocation denies; project/instrument mismatch denies | REV-13 | -| Immutable award evaluation | CON-03C/07 | at most one money plus one points award; exact decimals; accept/needs_revision/reject rules; replay stable; changed facts fail; no PaymentPolicy fallback | REV-13 | -| Outbox and delivery | CON-02A/02B/03D/08A + REV-12A | immutable event/payload/binding/idempotency identity; stale claim fencing; durable in-flight generation; retry/dead-letter/replay; reconciliation preserves original identity; provider I/O occurs outside every database transaction/lifecycle fence; dispatch-versus-admission fencing in both orders | REV-13 | -| Callback and fulfillment | CON-08B + REV-12A | callback before acknowledgement suppresses later delivery; duplicate exact receipt idempotent; changed receipt conflicts; per-actor/binding limits; suspended/retired matrices; callback allowed through delivery drain and denied after disable; callback-versus-disable in both orders; no human authority | REV-13 | -| Evidence artifact | ART 02A2-02D + CON-EVIDENCE + CON-09A/09B | deterministic versioned schema and exact media type; self/project disclosure matrix; no reviewer-private/provider/credential/external-receipt/unnecessary actor data; ART prepares before DB locks; locked facts match server commitment; invalid media or digest/size mismatch causes zero admission/provider calls; committed-attempt proof precedes one-shot I/O; rollback/failure/cancellation/replay either release scratch or retain ART cleanup custody; process loss serializes no handle and deterministic replay regenerates bytes; returned binding/receipt matches digest/size/media/owner/project/role/schema/idempotency; LocalStorage/MinIO conformance | REV-13 | -| Product reads | CON-10A | D11's approved award-role set exact; Project Manager contribution access remains separate from the chosen award-detail rule; AUTH activation proves allowed/excluded/mixed/revoked/foreign-project grants; CON proves matched decision facts, stable pagination, money/points/status separation and no provider refs | REV-13 | -| Operations and audit | CON-10B + REV-12A | D11's approved delivery/audit role sets and any AUTH matrix amendment exact; AUTH activation proves role/reason/scope candidates; CON proves bounded reconciliation/rebuild, immutable truth, decision-fact binding, audit redaction and same-session drain observation with no false zero or repository exposure | REV-13 | -| Atomic review integration | CON-07 + REV-10 | allowed exact `review.decision` evidence matches actor/action/resource/project/request/correlation; denied/stale/mismatched evidence rejected; every injected failure rolls back review/task/contribution/award/audit/outbox together | REV-13 | -| Public contract | CON-11 readiness + REV-12A control + REV-13 activation | hidden routes absent before release; `/api/v1` only; dependency/fence/drain manifest exact; startup/preflight fail closed; no partial surface; deterministic shutdown/reactivation phase matrix | REV-13 | +| Canonical policy model | 01,03B,04B | ContributionPolicy/version/rules/definitions; explicit unpaid; immutable publish; one active policy; stable binding references | CON-11 | +| Legacy clean cut | 05A,05B | zero semantic consumers before schema removal; deterministic row treatment; no alias/fallback; migration upgrade/downgrade | CON-11 | +| Authorization | AUTH + each feature | 74/57 baseline refreshed; proposed mappings exact; full ART/REV custody referenced; one AUTH custodian; planned denial; exact grant/static row; AUTH-09E; prepared handle misuse; no local role logic | AUTH activation + CON-11 | +| Contribution cardinality | 03C,07 + REV | one completed_review per valid Review; accept adds accepted_submission; revision Reviews distinct; automated outcomes create none | joint live drill | +| Policy freeze | 05A,06 + task/REV | exact submitter/reviewer fields; published version; no drift; publish/suspend races both orders | joint live drill | +| Award evaluation | 03C,07 | matching frozen ContributionRule; unpaid creates none; at most one money/points; exact decimal; replay stable | joint live drill | +| Atomic REV/CON | 07 + REV | exact locked request and stabilized digest; CON copies artifact_hash; zero ART calls; every injected failure rolls back Review/task/contribution/award/audit/outbox | joint live drill | +| Outbox isolation | 02A,02B | stable event/task IDs; claim fencing; retry/dead-letter/replay; dispatcher cannot inherit feature authority; handler returns typed outcome | CON-11 | +| Delivery and callback | 08A,08R,08B | exact feature service authority; no I/O under locks; callback/binding/award match; replay and callback-before-ack; immutable receipts | joint live drill | +| Product reads | 10A | PostgreSQL contribution/award truth; D11 exact role sets; stable pagination/concealment; no ART/provider data | AUTH activation + joint drill | +| Operations requests and observation | 10B | bounded durable requests; AdminRole and prepared-protocol proof; audit redaction; stable drain observation; no executor authority | AUTH activation + joint drill | +| Operations executors | 10C | exact independent fixed-service authority; dispatcher/cross-executor denial; retry/replay/finding proof; projection-only rebuild mutation; immutable contribution/award/receipt truth | AUTH activation + joint drill | +| Public release | 11 + REV | hidden before release; exact `/api/v1` manifest; provisioning-aware readiness; no optional evidence/ART gate | joint live drill | +| Optional evidence | 09A,09B only if approved | separately reviewed ART/AUTH capability; independent status/failure; no effect on canonical truth or core release | separate optional release | -The completed matrix must cover every normative invariant adopted into -`docs/spec_contribution_compensation.md`, including all candidate cases that are -retained after reconciliation. “All mismatch cases” is not an acceptable test -reference. +Executable node IDs and retained evidence are added by each implementation +chunk. Planning rows are contracts, not claims that tests already ran. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md index 67e50fb4..39ca84db 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -1,207 +1,174 @@ # Decisions: WS-CON-001 Contribution Record And Compensation Boundary -## D1 - Preserve Reference Generations; Reconcile Active Contract +## D1 - Canonical Contract Is Repository-Owned -**Status:** recommended; human approval required. +**Status:** accepted. + +The supplied reference files are archival inputs. The active implementation +contract is the repository specification produced by CON-01 and reconciled with +trusted `main`, including WS-XINT-001 from PR #139. Archival files are not edited +or treated as runtime authority. + +## D2 - ContributionPolicy Is The Only Award-Eligibility Policy + +**Status:** accepted; supersedes the older WS-CON naming. + +The canonical aggregate is `ContributionPolicy`, immutable +`ContributionPolicyVersion`, `ContributionRule`, and +`ContributionAwardDefinition`. It decides whether a ContributionRecord is +unpaid or creates money and/or project-points CompensationAwards. The retired +guide-bound economic schema is completely removed in CON-05A/05B. There is no +alias, automatic conversion, historical fallback, or second executable policy. + +## D3 - Existing Submission Is The Version Identity + +**Status:** accepted. + +Existing `Submission` plus its `version` and `supersedes_submission_id` is the +versioned identity. ContributionRecord uses `submission_id` and the stabilized +artifact-hash lineage supplied by REV. WS-CON does not add a +`SubmissionVersion` table or reload artifact bytes through ART. + +## D4 - AUTH Owns Registration, Evaluation, And Activation + +**Status:** accepted by WS-XINT-001 D1/D2. + +WS-CON proposes product actions and typed facts, but AUTH owns ActionId, +PermissionId mapping, ActionOwner activation custody, typed resource contexts, +principal admission, evaluator dispatch, decision evidence, grants, the fixed +service static matrix, and availability. Each action follows planned +registration -> hidden feature behavior -> AUTH evaluator integration and +activation. CON never changes availability or implements a local role fallback. + +The stable PermissionIds may retain older broad namespace strings. New policy +ActionIds use `contribution.policy.*` and map to existing +`compensation.policy.manage`; the PermissionId string does not rename the +canonical product model. + +## D5 - Derived Contributions And Awards Are Review Participants + +**Status:** accepted by WS-XINT-001 D7 and the REV/CON handoff. + +The authorized `review.decision` transaction invokes one mandatory CON +participant in the caller's AsyncSession. It creates a reviewer +`completed_review` for every committed Review and a submitter +`accepted_submission` only for `accept`, evaluates each applicable frozen +ContributionRule, and stages applicable awards/audit/outbox rows. It flushes +and never commits. There is no `contribution.materialize` or +`compensation.award.materialize` action and no no-op production participant. + +## D6 - ART Is Not A Core Contribution Dependency + +**Status:** accepted by WS-XINT-001 D7; supersedes the prior mandatory evidence +design. -Preserve supplied PDFs as immutable source generations. Treat the Markdown as -an explicitly editable reconciled working transcription derived from the -generation-2 PDF, record its current hash after every reviewed reconciliation, -and never claim it is byte-identical to the PDF. CON-01 creates -`docs/spec_contribution_compensation.md` plus an ADR as the active normative -repository contract. - -Rejected: silently replacing a PDF generation, claiming the reconciled -Markdown is archival, or treating a candidate as executable merely because it -says “locked.” - -## D2 - One Executable Compensation Authority - -**Status:** approved by the human on 2026-07-15. - -`CompensationPolicyVersion` supersedes and completely replaces `PaymentPolicy`. -The `PaymentPolicy` model/table, project-guide request/response fields, -repository/service methods, task/submission/checker locked-version fields, -copied amount/currency/payout fields, constraints, imports, tests, active docs, -templates, diagrams and operations language are removed. No compatibility -alias, dormant historical model, dual write/read, automatic conversion, or -fallback is retained. - -CON-05A atomically cuts every semantic consumer to the replacement: project -guide activation stops requiring PaymentPolicy, Finance-published -CompensationPolicyVersion becomes the only task-claim economic prerequisite, -and TaskAssignment freezes it. Old columns/table may remain physically present -but are unreachable and write-blocked only until CON-05B drops them. CON-05B -owns physical schema/model removal and a zero-consumer scanner. Ambiguous legacy -rows fail migration; the exact reset-versus-classified-backfill rule remains a -separate human gate before CON-05A. - -Rejected: advisory retention, historical quote APIs, dual execution, silent -unpaid behavior, or rewriting legacy values into compensation terms by guess. - -## D3 - Existing Submission Is The Versioned Identity - -**Status:** accepted by repository evidence and parallel WS-REV plan. - -Use `backend/app/modules/tasks/models.py::Submission` and its `version`/ -`supersedes_submission_id` chain. WS-CON creates no `SubmissionVersion` table. - -## D4 - ActionIds Do Not Replace PermissionIds - -**Status:** separation accepted; all WS-CON actions and service permissions are -proposed dependencies requiring human approval and AUTH-owned executable -integration. - -WS-CON declares granular proposed ActionIds mapped to existing stable -PermissionIds when semantically safe. AUTH owns registration, audit migration, -availability, evaluator dispatch, grants/service actors, authority -revalidation, and kernel behavior; the named feature chunk owns product-row -loading, approved typed resource composition and hidden behavioral proof below -an explicit test seam while the action remains planned. AUTH later integrates -the evaluator against that exact merged seam, proves real-kernel behavior and -alone activates the action. -Shared outbox dispatch and the external fulfillment callback require the -proposed service-only PermissionIds `outbox.dispatch` and -`compensation.fulfillment.report`; neither can borrow human authority. CON-08A -is a handler of the claimed shared-outbox command, not a separately authorized -delivery command. Keeping dispatch separate from human reconciliation or retry -authority prevents a Finance or Operator grant from authorizing an external -side effect. - -No WS-CON code edits the AUTH catalogue. `AUTHORIZATION_HANDOFF.md` is the exact -proposal, and every mapping is re-read from merged trusted `main` before its -implementation chunk. - -Current trusted `main` proves why registration and activation cannot be -collapsed: AUTH-08 has 57 registered actions but only nine active self/admin -actions; all planned and unsupported actions fail closed. Its complete -resource-context digest, matched grant/scope evidence and route-owned commit -boundary become mandatory inputs to later WS-CON evaluators rather than a -feature-local replacement. - -## D5 - Derived Contribution/Award Writes Are Review Participants - -**Status:** accepted by the parallel WS-REV plan and candidate invariant. - -The authorized `review.decision` transaction invokes mandatory task and WS-CON -participants using the same `AsyncSession`. Contribution/award creation has no -separate human API and no invented `materialize` permission. The participant -flushes but does not commit. - -## D6 - Artifact Ownership Follows ADR 0013/0014 - -**Status:** accepted repository decision. - -WS-CON owns the deterministic contribution evidence schema and projection -status. ART owns prepared-byte admission, raw provider operations, verification, -content/binding/receipt persistence, and recovery through a narrow typed -capability. LocalStorage is development/focused-test only; MinIO proves the -S3-compatible protocol locally/in CI; AWS S3 is v0.1 production. Flow Node and -R2 are deferred. +Core contribution creation performs no ART capability call, artifact +authorization, provider I/O, or evidence projection. CON copies the stabilized +Submission/packet digest supplied by REV into +`ContributionRecord.artifact_hash` and does not verify or rederive it. + +An evidence document may be proposed later only as an optional asynchronous +projection with independent status/failure semantics, a separately reviewed ART +capability, and a separate AUTH action. Its failure cannot alter Review, +ContributionRecord, CompensationAward, fulfillment receipt, or status truth. ## D7 - Shared Outbox Is A Prerequisite **Status:** recommended; human approval required with the chunk sequence. -One generic shared outbox owns delivery state and retry/dead-letter mechanics. -Review and WS-CON append events through a caller-transaction participant. No -review-private or compensation-private outbox is allowed. +One generic shared outbox owns append, claim, retry, dead-letter, replay, and +finalization mechanics. Feature handlers return typed outcomes and do not query +or mutate outbox persistence directly. No review-private or compensation- +private dispatcher is allowed. ## D8 - Coherent Public Activation **Status:** recommended; human approval required. -Policy, contribution, award, callback, evidence, read, and review lifecycle -routes remain behind unregistered production composition until AUTH, ART, REV, -outbox, audit, migrations, operations, and live preflight are complete. The -final chunk activates one coherent `/api/v1` surface and no `/v1` alias. +Contribution-policy, binding, contribution, award, callback, and operations +routes remain hidden until exact AUTH actions/evaluators/principals, required +REV participants, outbox/audit, migrations, and release proof are complete. +Optional contribution-evidence projection is not a release dependency. -## D9 - No Provider Payment Or Points Ledger In Workstream +## D9 - External Rails Fulfill Awards But Never Decide Eligibility -**Status:** accepted from the human scope and candidate boundary. +**Status:** accepted. -Workstream persists awards, exact outbound instructions, adapter delivery +Workstream persists immutable awards, exact outbound instructions, delivery evidence, immutable fulfillment receipts, and rebuildable status. External -adapters own payment requests/attempts, approvals, provider reconciliation, -beneficiary accounts, balances, and project-points ledger entries. +money settlement and project-points adapters own provider execution, accounts, +balances, and ledger entries. They cannot create, change, void, or infer award +eligibility. ## D10 - AUTH Owns Prepared Cross-Domain Mutation Authorization -**Status:** required architecture correction after merged AUTH-07B/AUTH-08 review; -human/AUTH approval required before any `T` action implementation. - -The current actor-self kernel can revalidate entirely inside AUTH-owned rows. -WS-CON mutations cross AUTH and product rows, so one `require()` call against an -unlocked product snapshot is insufficient, while locking product rows before -AUTH rows violates the canonical lock order. - -AUTH must provide one caller-session-bound prepared authorization protocol. It -locks actor/link/grant or service-assignment authority first from a -server-resolved preliminary target, returns an opaque single-use handle, and -evaluates that handle exactly once against the final typed context recomposed -from locked product rows. The handle is bound to request, session, actor, -action, target and authority snapshot; it cannot be serialized, cached, reused, -or substituted. AUTH stages one decision and never commits. WS-CON supplies -facts and product guards but cannot implement the handle or query AUTH state. - -Rejected: product-row locks before AUTH locks, evaluating an unlocked snapshot, -calling AUTH twice and emitting competing decisions, or letting feature code -flip catalogue availability. - -## D11 - Reconcile AUTH-08 Role Candidates Per Action - -**Status:** unresolved human cross-spec decision before CON-10A/10B -authorization registration; any resulting AUTH correction remains AUTH-owned. - -Merged AUTH-08 is the canonical five-role permission-candidate matrix. It gives -Finance Authority the existing `compensation.delivery.reconcile` PermissionId -but omits it from Operator, while the reconciled candidate WS-CON human matrix -proposes a reason-bound system Operator for delivery reconciliation. Only D2 is -human-approved. The recommended D11 resolution is to preserve that candidate -behavior: a reviewed AUTH successor adds the existing PermissionId to Operator -and updates its closed definition/API/kernel tests. The human may instead -reject Operator delivery reconciliation; then CON-01 removes it from the active -matrix before AUTH registration. WS-CON adds no PermissionId, role query or -local exception under either resolution. - -The human must also resolve the inverse mismatches. Project Manager has the -merged `compensation.award.read` permission while the candidate WS-CON matrix -excludes it from monetary award/fulfillment detail; candidate audit read/export -sets are narrower than every merged role containing `audit.read` or -`audit.export`. D11 chooses whether to preserve each merged candidate or adopt -the narrower WS-CON action set. Any approved narrowing is implemented only by -AUTH through an evaluator-owned closed role intersection before grant query. -The role set is never request- or CON-supplied; an actor with both excluded and -eligible grants must match only the eligible grant. If the merged set is kept, -CON-01 updates the active product matrix before registration. No generic -"permission present means action allowed" branch or silent narrowing is -accepted. - -Rejected: silently choosing either side of a role-matrix conflict, changing a -candidate set after registration without review, or reproducing role policy in -CON. - -## D12 - ActionOwner And Activation Custody Have One Meaning - -**Status:** unresolved AUTH/human contract decision before any WS-CON action -registration or review-action activation amendment. - -The merged enum defines ActionOwner as the implementation chunk allowed to -activate an action. The user requires AUTH to own authorization activation, so -the recommended resolution keeps that meaning and adds the exact eight -AUTH-owned WS-CON activation owners, two review activation owners, and two -AUTH-owned ART-02D activation owners covering all eight Operator plus three -internal actions listed in `AUTHORIZATION_HANDOFF.md`. Every required action -maps to one owner without changing its PermissionId; CON/ART/REV remain feature -resource owners but never change availability. - -The alternative is a reviewed global semantic change: ActionOwner becomes the -feature/resource owner and AUTH adds a separate closed activation-custody type. -That change must update catalogue docs, typed/PostgreSQL parity where -applicable, startup checks and every existing owner test before use. It cannot -be inferred locally. Under either choice there is exactly one activation -authority and the handoff table keeps feature ownership separate. - -Rejected: leaving current REV owners while saying AUTH activates, assigning an -evidence action jointly to AUTH/ART, using a registration PR as a second owner, -or letting two chunks flip one action. +**Status:** required architecture contract. + +AUTH locks and revalidates human actor/link/grant rows or fixed-service +actor/link rows first. Fixed services additionally require immutable +ServiceIdentity, exact static service-action matrix membership, AUTH-09E typed +admission, and active action. AUTH returns one opaque, request/session/action/ +target-bound, single-use handle. The feature locks product rows, recomposes +final typed facts, and AUTH evaluates exactly once. AUTH stages one decision and +never commits. + +Missing, reused, serialized, cross-session, cross-action, target-drifted, or +authority-drifted handles fail closed. Product-first locks, unlocked resource +snapshots, double decisions, and feature-side catalogue changes are rejected. + +## D11 - Project Roles Are Independent; Admin Candidate Differences Remain Exact + +**Status:** project-role model resolved by ADR 0015; AdminRole surface choices +remain human gates before CON-10A/10B. + +ProjectRoleGrant values are exactly `submitter`, `reviewer`, and `adjudicator`. +Task claim requires submitter; review claim/decision require reviewer plus +no-self-review. Adjudicator does not substitute. Revoking one role leaves the +others and AdminRoleGrants unchanged; the owning task/review lifecycle consumes +the exact invalidation. + +Merged AUTH currently gives Finance Authority +`compensation.delivery.reconcile` but not Operator, while the earlier WS-CON +candidate also proposed reason-bound Operator recovery. Merged Project Manager +has `compensation.award.read`, while the earlier candidate narrowed award +detail. Audit candidates also differ. The human must select each exact action +candidate set before registration. Any change is AUTH-owned and evaluator- +closed; CON never queries roles or infers access from PermissionId membership. + +## D12 - ActionOwner Is AUTH Activation Custody + +**Status:** resolved by WS-XINT-001 D1-D3; no local alternative remains. + +AUTH must provide one exact activation custodian for each proposed CON action +and complete, not partially repeat, the canonical transfers for all current ART +and REV actions. Every ActionId-to-PermissionId mapping is preserved, and closed +typed/SQL/audit/definition-owner parity rejects dual, missing, unused, or extra +owners. WS-CON depends on review.claim/review.decision but does not prescribe a +two-action REV transfer or an eleven-action ART subset. + +## D13 - Fixed Service Admission Uses Static Matrix Membership + +**Status:** accepted architecture; exact new identities/actions remain an +AUTH/human registration gate. + +There is no database service-grant or service-action-assignment model. A fixed +service uses verified token -> ActorIdentityLink -> service ActorProfile -> +immutable closed ServiceIdentity -> exact static ActionId row -> AUTH-09E typed +context -> feature resource facts -> decision. + +The shared outbox dispatcher may only claim/invoke/finalize outbox work under +`outbox.dispatch`; it does not inherit protected handler or provider authority. +Outbound delivery, asynchronous reconciliation, contribution projection +rebuild, and fulfillment callback each require an exact approved service +identity/action/static row or an explicitly approved closed dual-principal +evaluator before implementation. Missing provisioned rows deny runtime but do +not prevent application startup or administrative provisioning. + +## D14 - Optional Evidence Is A Deferred Successor + +**Status:** deferred and not approved for implementation. + +CON-09A/09B are outside the core dependency order. If the human later approves +them, their chunk contracts must be refreshed against then-current ART/AUTH +contracts and internally reviewed again. The optional evidence action is not +counted as a core release action and cannot gate product reads or release. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md index e3339388..c4164ae6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -1,194 +1,138 @@ # Discovery: WS-CON-001 Contribution Record And Compensation Boundary -Discovery was read-only for application code. No contribution or compensation -runtime implementation was performed. - -## Current behavior - -- `backend/app/api/router.py` exposes the current backend only under - `/api/v1` (plus the unversioned health compatibility route). -- `backend/app/modules/tasks/models.py::Submission` is already the immutable, - version-numbered submission record. There is no separate `SubmissionVersion` - table and WS-CON must not create one. -- `TaskService.claim_task` creates `TaskAssignment` but freezes no compensation - policy. The parallel WS-REV plan will create `ReviewLease`; no review models - exist on current `main`. -- `WorkstreamTask` and `Submission` lock guide-bound `PaymentPolicy` versions. - The task also copies `base_amount`, `currency`, and `payout_type`. No runtime - `ContributionRecord`, `PaymentRecord`, `CompensationPolicy`, award, receipt, - fulfillment, or reputation model exists. -- Durable checker execution advances a locked Submission through the automatic - gate to `review_pending`. The review/revision lifecycle is planned in the - sibling `workstream-rev-001` worktree and remains unimplemented. -- Current task/project services still contain explicitly temporary legacy role - checks. WS-AUTH owns their cutover; WS-CON must not reproduce or repair them. -- The shared `AuditEvent` ledger and caller-owned `AsyncSession` are the - transaction foundation. There is no shared transactional-outbox module yet. -- Merged ART-02A2 PR #129 adds the inactive provider-neutral - `ArtifactPreparationService`, sealed `PreparedArtifact`/ - `CommittedArtifactSource` values, canonical `ArtifactScratchManager`, and - cancellation/file-lock primitives. Active ArtifactStore v1, schema, provider - selection, product routes, admission, verification and binding behavior are - unchanged. Product modules still use only narrow ART-owned capability ports. -- Trusted `main` now includes ADR 0014's generic typed - `ExternalServiceAdapterFactory[TAdapter]` foundation. It does not supply a - contribution-evidence capability or compensation provider adapter; those - remain separately gated, explicit composition-root registrations. -- Trusted `main` `9a04434` includes ART-02A2 PR #129 and AUTH-08 PR #131 at - `aa0fdcd`. The authorization catalogue remains - 74 PermissionIds/57 ActionIds with nine active and 48 planned actions. Durable - scoped AdminRoleGrants, the five-role permission matrix, typed grant resource - contexts, resource-context digests, matched grant/scope evidence, explicit - route-owned commits and retryable authorization-evidence failure handling are - merged. Service actors, ProjectRoleGrants, D10 and every WS-CON action remain - future AUTH-owned work. - -## Reconciled working source and supplied generation-2 PDF - -The working tree contains an editable reconciled Markdown transcription derived -from the supplied generation-2 PDF, plus that immutable PDF companion: - -| File | SHA-256 | Observation | -|---|---|---| -| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md` | `cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640` | Editable reconciled working transcription derived from the revised PDF; not canonically adopted | -| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf` | `ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457` | Revised archival companion; text extracts successfully; not a reproducible Markdown build contract | - -The original tracked PDF is currently deleted in the user's working tree but -remains the immutable first archival generation at SHA-256 -`34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1`. -`docs/reference_specs/README.md` and `SHA256SUMS` require that original to remain -unchanged. The revised candidate should therefore be retained as a second -generation rather than replacing the first. - -## Reconciliation findings - -| Finding | Evidence | Required correction in active contract | -|---|---|---| -| Wrong public prefix | Candidate section 18 uses `/v1`; router and ADR 0012 use `/api/v1`. | Use `/api/v1` only; no alias. | -| ActionId/PermissionId conflation | Candidate calls granular `compensation.policy.*` values permissions and says broad IDs were removed. Merged AUTH-08 preserves 74 approved PermissionIds and separately registers 57 ActionIds: nine active self/admin actions and 48 planned actions. | Publish an exact proposed ActionId -> PermissionId handoff. Never call an ActionId a permission or a registered/planned identifier executable. | -| Registration treated as activation | AUTH-08 evaluates only its self/admin action families; all planned, unsupported, wrong-context and unimplemented actions deny. No WS-CON evaluator exists. | AUTH must own typed-context/evaluator/principal/transaction integration and active availability. CON owns product facts/guards only and cannot flip the AUTH catalogue. | -| Cross-domain mutation lock gap | Current `require()` can revalidate actor-self wholly inside AUTH, but WS-CON mutations need AUTH rows before product rows and final evaluation against locked product facts. | AUTH supplies the prepared, caller-session-bound, single-use `T` protocol in D10; no unlocked-snapshot decision or product-before-AUTH lock order. | -| Merged Operator permission gap | AUTH-08's closed `operator` definition omits existing PermissionId `compensation.delivery.reconcile`, but the reconciled candidate WS-CON matrix proposes a reason-bound Operator as well as Finance Authority to request delivery reconciliation. Only D2 is human-approved. | D11 human decision: an AUTH-owned reviewed successor adds the existing permission before CON-10B if Operator behavior is retained, otherwise CON-01 removes the candidate before registration. CON has no role-query/local fallback. | -| Cross-spec role-set conflict | AUTH-08 gives Project Manager `compensation.award.read` and broader roles `audit.read`/`audit.export`, while the unadopted WS-CON candidate proposes narrower monetary/audit sets. | D11 human choice freezes each active set. Any approved narrowing is AUTH evaluator policy with matched grant/scope proof; preserving merged candidates updates CON-01. Permission membership or candidate text alone never settles the action. | -| ActionOwner activation conflict | Canonical `ActionOwner` means the implementation chunk allowed to activate an action. Existing review actions name REV owners and all eleven required ART-02D actions name `ART_02D`, while the reconciled boundary says only AUTH activates after feature composition; the 23 WS-CON actions had no owner mapping. | D12 human/AUTH decision plus the exact closed owners for 23 WS-CON, two review and eleven ART actions in `AUTHORIZATION_HANDOFF.md`; preserve all ActionId/PermissionId mappings and never permit dual availability writers. | -| Missing upstream task action | PermissionId `task.claim` exists, but current ActionId has no `task.claim` member. | AUTH-13 or reviewed AUTH successor registers/evaluates/activates `task.claim` before CON-05A integrates compensation freeze. | -| Wrong Review action | Candidate uses `review.decision.record`; merged AUTH catalogue and WS-REV use registered planned ActionId `review.decision` mapped to PermissionId `review.decision`. | Consume `review.decision` only after its AUTH evaluator/availability and REV resource-composition gates. | -| Invented WS-AUTH source | Candidate names `WS-AUTH-001-A`, which is not a canonical repository artifact. | Cite merged `docs/spec_authorization_service.md`, ADR 0012, and the closed catalogue. | -| Invented artifact permissions | Candidate uses `artifact.recovery.request`, `artifact.recovery.execute`, and `artifact.retrieve`. AUTH explicitly rejected the first; none is a registered PermissionId. | Use `artifact.verification_job.retry` through `ArtifactOperatorRecoveryPort`; require ART-owned typed storage/read capabilities and approved action mappings. | -| Wrong artifact port | Candidate injects `ArtifactStorePort` with store/projection/retain/retrieve methods. ADR 0013's target `ArtifactStore` has only provider-byte behavior and cannot enter product services. | WS-CON consumes narrow ART capability ports. Only ART orchestration receives the raw store. | -| ART-02A2 mistaken for the contribution capability | PR #129 adds only inactive first-pass scratch preparation and a sealed one-shot second-pass source. It adds no admission, provider execution, verification, binding, contribution intake or authorization. | Keep `WS-ART-001-CON-EVIDENCE` as a separately approved ART-owned prerequisite. CON supplies deterministic bytes plus expected digest/size/media type to that port; ART alone prepares, consumes and closes the committed source. | -| Wrong providers | Candidate requires Local Storage/Flow Node parity. ADR 0013 locks LocalStorage for dev/focused tests, MinIO for local/CI S3 proof, AWS S3 for v0.1 production, and defers Flow Node/R2. | Test LocalStorage and MinIO; AWS deployment proof gates production; Flow Node remains future. | -| Wrong retention/search claims | Candidate assumes retain/pin and semantic indexing APIs that ADR 0013 deliberately excludes from v0.1 `ArtifactStore`. | Use ART's immutable completed-byte retention policy and typed lifecycle records; omit semantic indexing/search from WS-CON v0.1. | -| Duplicate submission model language | Candidate defines `SubmissionVersion` as if separate. | Treat existing `Submission` as the versioned identity and use `submission_id` in repository schemas. | -| Payment model collision | Active docs/model use guide-bound `PaymentPolicy`, a future mutable `PaymentRecord`, adjustments, and voidable contributions; candidate introduces immutable policies/awards/receipts and prohibits adjustments/voiding. | D2 approves `CompensationPolicyVersion` as the sole authority and complete PaymentPolicy removal; CON-01 records the ADR, 05A/05B perform the cutover, and only the legacy-row rule remains open. | -| Outbox assumed but absent | Candidate requires atomic outbox effects; repository has no shared outbox. WS-REV also blocks on it. | Land a shared caller-transaction outbox foundation before review-chain and contribution integration. | -| Direct system-action invention | Candidate adds `contribution.materialize`, `compensation.award.materialize`, and `outbox.dispatch` as if already registered permissions. | Derived contribution/award creation is a required participant of authorized `review.decision`. Shared outbox owns the proposed service-only dispatch action; CON adds no feature-local bypass action. | - -## Relevant files/modules - -| Path | Purpose | Notes | -|---|---|---| -| `backend/app/api/router.py` | API composition | Canonical `/api/v1`; future routes stay unregistered until coherent cutover. | -| `backend/app/modules/tasks/models.py` | Task, assignment, versioned Submission, shared audit | Must gain exact assignment compensation freeze; Submission remains canonical version identity. | -| `backend/app/modules/tasks/service.py` | Claim, submission, task lifecycle | WS-CON may integrate only through task-owned participants; auth cutover stays WS-AUTH-owned. | -| `backend/app/modules/projects/models.py` | Project and guide-bound `PaymentPolicy` | Approved for complete semantic removal in CON-05A and physical removal in CON-05B; the legacy-row rebuild/classification rule remains a human gate. | -| `backend/app/modules/projects/service.py` | Guide activation and policy locking | Must not become a second compensation-policy engine. | -| `backend/app/modules/authorization/{catalogue,kernel,runtime,policy}.py` from merged AUTH-08 | Canonical closed registry, grant policy and executable kernel | 74 PermissionIds, 57 ActionIds, nine active self/admin actions and 48 planned; eight resource-context variants and actor-self/AdminRoleGrant matched authority. All WS-CON-specific actions and both service permissions remain absent. | -| `backend/app/api/deps/authorization.py` | Current human composition root and transaction cleanup | Human self/admin only; it rejects service subjects, maps typed evidence failure to retryable 503 and rolls back any transaction a feature route leaves open. WS-CON routes must explicitly commit their own unit and need AUTH-owned project/service composition, not a copied dependency. | -| `backend/app/modules/authorization/policy.py::ADMIN_ROLE_PERMISSIONS` | Exact merged AdminRole permission candidates | Finance has delivery reconcile; Operator does not; Project Manager has award-read. D11 decides whether each candidate WS-CON difference changes AUTH or the active CON matrix. | -| sibling `workstream-rev-001/.../` reviewed baseline `6faccc0` plus later external-review repairs | Parallel review plan discovery | Head `6faccc0` was inspected after its commit-bound ART refresh; later in the same turn the sibling became dirty while its owner applied external-review repairs. Neither live sibling state is a dependency. Only a future reviewed merge on trusted `main` is consumable, and it must repair prepared authorization/D12/outbox ownership before WS-CON integration. | -| `backend/app/modules/artifacts/{preparation,sources}.py` | Merged inactive committed-source preparation | ART alone owns scratch allocation, first-pass hash/count, expected commitment comparison, sealed single-use second pass and cleanup. WS-CON must not import these implementation types or create a second scratch path. | -| `backend/app/modules/artifacts/*` | Current artifact metadata/orchestration foundation | ArtifactStore v1 remains active; v2, S3, admission, verification and named contribution capabilities are still WS-ART gates. | -| `backend/app/interfaces/artifacts.py` | Current v1 raw provider port | Not a WS-CON dependency; it is being clean-cut to ADR 0013 v2. | -| `docs/spec_artifact_storage_service.md` | Canonical target artifact contract | Owns narrow product capability ports, recovery, verification, quotas, and provider policy. | -| `docs/spec_authorization_service.md` | Canonical target authorization contract | Preserves broad PermissionIds; ActionIds are separate. | -| `docs/architecture_data_model.md` | Existing contribution/payment target | Conflicts with supplied candidate and needs ADR-backed reconciliation. | -| `docs/operations_payment_reputation.md` | Existing manual payment/reputation workflow | Needs coordinated update only after architecture adoption. | -| `backend/alembic/versions/*` | Current schema through merged AUTH-08 migration `0022_bootstrap_admin_grants.py` | Every runtime chunk must refresh the next migration number from trusted `main`; no WS-CON contract pre-reserves `0023`. | - -## Current tests - -| Test path | What it covers | Gaps relevant to WS-CON | -|---|---|---| -| `backend/tests/test_tasks.py` | Task policy locks, assignment uniqueness, immutable Submission versions, checker admission, concurrency | No compensation freeze, review effects, contribution, or award tests. | -| `backend/tests/test_projects.py` | Guide/policy activation including `PaymentPolicy` | No CompensationPolicy lifecycle or Finance Authority behavior. | -| `backend/tests/test_authorization.py` | Closed catalogue plus AUTH-08 self/admin kernel/runtime | Self/admin allow/deny, scope/grant revalidation, complete resource digests, unknown/planned/unsupported denial, evidence failure and request-local state are covered. ProjectRoleGrants, service composition, WS-CON contexts/evaluators and prepared cross-domain mutation authorization remain AUTH-owned work. | -| `backend/tests/test_audit.py` | Typed append-only authority evidence | No contribution/compensation lifecycle audit contract. | -| `backend/tests/test_artifacts.py` | Current artifact port, local adapter, content/binding/receipt foundation | Target v2, S3/MinIO, typed contribution projection capability, and evidence reads are not merged. | -| `backend/tests/test_artifact_preparation.py` | ART-02A2 scratch, commitment, cancellation, integrity and cleanup boundary | Proves preparation only; it does not prove contribution-evidence admission, provider execution, verification or binding. | -| `backend/tests/test_checkers.py` | Durable checker run and `allow_review` routing | Stops before Review persistence. | -| `backend/tests/test_alembic.py` | Migration upgrade/downgrade guards | No outbox, review, or WS-CON schema. | -| `backend/tests/test_api_contract_e2e.py` | Current API contract drill | No review/contribution/compensation routes or events. | - -## Dependencies/integrations - -- WS-AUTH: merged actor-self/admin kernel and AdminRoleGrants plus future - ProjectRoleGrants/service actors, exact - WS-CON ActionId/PermissionId/ActionOwner/audit registration, typed resource - contexts, closed evaluators, matched authorities, prepared `T` protocol, - service-capable composition, active availability and final bypass removal. - WS-CON does not edit those owned surfaces. -- WS-REV: `Review`, `ReviewLease`, findings/resolutions, decision idempotency, - task effects, hidden composition, and final public review cutover. -- WS-ART: merged 02A2 committed-source preparation; future 02A3 v2 store, 02B1 - LocalStorage/MinIO/AWS provider work, 02C1 admission, 02C2 verification/ - publication, 02C3 recovery, 02D hidden internal-executor/Operator recovery - behavior, AUTH-owned evaluator activation, and a separately approved narrow - system-generated contribution-evidence write/read capability. ART owns - preparation, scratch, provider execution and artifact records end to end; - AUTH alone owns registrations, assignments, evaluators and availability. -- Shared outbox: caller-transaction append, stable event identity, post-commit - publication, at-least-once dispatch, delivery attempts, dead-letter, replay, - and idempotent consumer contract. -- PostgreSQL: exact decimals, composite project ownership, uniqueness, row - locking, immutable history, and atomic cross-domain commit. -- Celery/Redis: post-commit dispatch/projection/reconciliation execution only; - correctness must remain PostgreSQL-backed. -- External compensation adapters: typed ADR 0014 capability, deterministic test - adapter for proof, no provider-specific runtime integration in WS-CON. - -## Risks discovered - -| Risk | Why it matters | Suggested handling | -|---|---|---| -| Dual payment truth | `PaymentPolicy`/future `PaymentRecord` and new compensation versions/awards can disagree. | ADR-backed sole execution authority and clean documentation/schema cutover. | -| Permission replacement | Treating ActionIds as replacement permissions would break merged audit/grants. | Exact mapping table; AUTH-owned additive registration; typed manifest tests. | -| Merged AdminRole matrix conflicts with candidate WS-CON human matrix | Operator cannot currently satisfy candidate delivery reconciliation; award/audit candidate sets differ in the other direction. | D11 human decision, followed by only the required AUTH matrix/evaluator amendments or CON-01 active-matrix updates; no local role policy. | -| Registered-but-inexecutable AUTH action | Planned availability or a missing evaluator causes every WS-CON command to deny; a feature-local workaround would bypass central AUTH. | Separate AUTH registration and executable activation gates; startup parity rejects active-without-evaluator and CON never edits AUTH. | -| AUTH/product lock inversion | One-step authorization after product locks reverses canonical order; authorization before product locks can evaluate stale facts. | AUTH-owned prepared handle locks authority first and evaluates once against final locked product facts. | -| Circular REV/CON dependency | Leases need policy FKs; claims need freeze; decisions need contribution participant. | Explicit interleaving gates in chunk map. | -| Cross-domain deadlock/partial commit | Review, authority, tasks, artifacts, CON, audit, and outbox share one transaction. | One canonical lock order, caller-owned session, fault injection, real Postgres concurrency tests. | -| Economic overreach | Payment-provider or points-ledger logic could leak into Workstream. | Typed outbound instruction/receipt boundary and architecture import tests. | -| Artifact bypass | Direct store injection could bypass quotas, verification, binding, and audit. | ART-owned typed capability only; static import/composition tests. | -| Scratch/source custody leaks into CON | Importing PR #129 types or paths would make CON a second artifact orchestrator and can leak quota or cleanup ownership under cancellation. | The CON port request carries only bounded deterministic bytes and expected commitment facts; ART prepares/consumes the source and either releases scratch or retains explicit cleanup custody until retry succeeds. | -| Premature public surface | Partial routes would create authorization or lifecycle gaps. | Hidden internal composition until final coherent activation. | -| Legacy/pre-production rows | Existing PaymentPolicy/tasks/assignments cannot be safely guessed into new frozen terms. | Human-approved rebuild/classification/backfill rule before migration. | -| Event/schema drift | The candidate names many events without a shared outbox registry. | Freeze envelope/ownership in the outbox chunk before persistence consumers. | -| Scope size | The candidate is a multi-initiative system, not one PR. | PR-sized L1 chunks with hard stop after each merge. | - -## Unknowns/questions for human - -| Question | Why it matters | Needed before chunk? | -|---|---|---| -| Preserve both candidate generations and reconcile into active spec? | Maintains archival provenance and follows repository precedent. | Before 01. | -| May pre-production payment/task rows be rebuilt, or must they be classified/backfilled? | Determines migration safety and atomic claim cutover. | Before 05. | -| Approve two new service-only PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`? | Human outbox recovery/reconciliation authority must not execute async side effects; no existing permission safely names the external adapter callback entitlement. | Before CON-02B for dispatch and before CON-04A for callback binding identity. | -| Approve the AUTH-owned WS-CON registration/evaluator/activation work and D10 prepared mutation protocol? | Current AUTH-08 supports nine self/admin actions but no WS-CON action; CON cannot safely or physically activate its own actions. | Before any authorized CON service chunk. | -| Approve adding existing `compensation.delivery.reconcile` to the Operator role definition? | The reconciled candidate proposes reason-bound Operator delivery reconciliation, but merged AUTH-08 does not make that role a permission candidate. Rejecting the addition removes Operator from the active WS-CON action contract. | Before AUTH registration for CON-10B. | -| Approve the separately named ART-owned `WS-ART-001-CON-EVIDENCE` capability after ART's remaining storage gates? | PR #129 deliberately excludes contribution intake and WS-CON cannot own raw storage orchestration. | Before 09A. | - -## Existing conventions to preserve - -- One caller-owned async SQLAlchemy session and explicit commit boundary. -- Router -> service -> repository separation with stable structured errors. -- `/api/v1`, no short-prefix alias. -- Existing `Submission` is the versioned submission identity. -- Canonical review decisions only: `accept`, `needs_revision`, `reject`. -- ActionId and PermissionId are distinct closed types. -- Authorization resource facts come from canonical rows, never request JSON. -- Provider-neutral external adapters follow ADR 0014 with explicit composition. -- Only ART orchestration receives raw `ArtifactStore`. -- AWS S3 production, MinIO local/CI protocol proof, LocalStorage focused - development/tests; Flow Node and R2 deferred. -- New/materially changed backend subsystems stay at or above 90 percent while - repository coverage stays at or above 78 percent. +## Baseline inspected + +- trusted `origin/main` at `5d353b6`, merged PR #139; +- complete WS-XINT intent, decisions, plan, REV/CON, AUTH/role-service, + AUTH/REV, AUTH/ART, and ART/REV handoffs; +- current WS-CON initiative package and archival reference inputs; +- canonical README, glossary, architecture lockdown/data model/lifecycle, + authorization spec, artifact spec, roles/operations docs, and ADRs 0012-0015; +- current backend project/task/submission/checker, AUTH, audit, artifact, and + migration code/tests; +- stale wording, authorization, artifact, link, loop-memory, and agent-gate + scanners/tests. + +## Current runtime observations + +- The backend stops before the human Review/ContributionRecord implementation. +- Project code still has the retired guide-bound economic schema. There is no + canonical ContributionPolicy aggregate, ContributionRecord, + CompensationAward, fulfillment receipt, or status projection runtime. +- Existing Submission rows carry `version` and supersession lineage. A separate + SubmissionVersion model would duplicate current identity. +- The merged AUTH catalogue has 74 PermissionIds and 57 ActionIds. Nine + self/admin actions are active and 48 are planned. No WS-CON ActionId is + registered. +- Current AUTH supports actor-self and AdminRoleGrant evaluation. Independent + ProjectRoleGrant runtime, fixed-service runtime admission, CON evaluators, + and the cross-domain prepared mutation protocol remain future AUTH work. +- AUTH's static service-action matrix is typed code; it is not a database grant + table. AUTH-09E is the required runtime admission path. +- PR #129 added inactive ART preparation/source values only. It added no + contribution-evidence capability, ART admission/provider execution, binding, + action, permission, or CON dependency. +- No shared transactional outbox exists with the required generic dispatcher, + claim fencing, replay, and typed handler outcome contract. + +## Canonical merged changes affecting CON + +1. `ContributionPolicy`, `ContributionPolicyVersion`, `ContributionRule`, and + `ContributionAwardDefinition` decide award eligibility. CompensationAward + is the evaluated downstream result. +2. Every valid Review creates reviewer `completed_review`; `accept` additionally + creates submitter `accepted_submission`. +3. Core contribution creation is a flush-only CON participant in the REV-owned + transaction. It performs no ART call or evidence projection. +4. CON copies the stabilized versioned Submission/packet digest supplied by REV + into `ContributionRecord.artifact_hash`; it does not verify or rederive it. +5. Project grants are exactly independent submitter, reviewer, and adjudicator. +6. ActionOwner is AUTH activation custody. ART and REV transfers must be + complete across their full current catalogues; WS-CON cannot prescribe + partial subsets. +7. Fixed services use provisioned ActorProfile/ActorIdentityLink, immutable + ServiceIdentity, exact static ActionId row, and AUTH-09E admission. +8. The shared outbox dispatcher cannot inherit protected feature-handler + authority. Delivery, reconciliation, rebuild, and callback boundaries need + exact approved service contracts. + +## Relevant files and symbols + +| Source | Observation | +|---|---| +| `docs/architecture_data_model.md` | Canonical policy/rule/definition, binding, contribution, award, receipt, and projection names/fields | +| `docs/decision_0015_project_contributor_roles_are_independent.md` | Exact project role values and independent revocation | +| `docs/spec_authorization_service.md` | Stable permissions, current actions, ActionOwner semantics, static service matrix, AUTH-09E order | +| `WS-XINT-001/REV_CON_HANDOFF.md` | Exact core participant sequence and optional-evidence boundary | +| `WS-XINT-001/AUTH_ROLE_SERVICE_HANDOFF.md` | Fixed service and project grant contract | +| `WS-XINT-001/AUTH_REV_HANDOFF.md` | Full review activation-custody/hidden behavior sequence | +| `WS-XINT-001/AUTH_ART_HANDOFF.md` | Full 25-action ART transfer; not a core CON gate | +| `backend/app/modules/projects/{models,schemas,repository,service}.py` | Current guide-bound economic fields and consumers to cut over/remove | +| `backend/app/modules/tasks/**` | TaskAssignment creation and future submitter policy freeze seam | +| `backend/app/modules/authorization/{catalogue,policy,kernel,schemas}.py` | Current 74/57/9/48 runtime and stable PermissionIds | +| `backend/app/modules/audit/**` | Shared append-only audit extension point | +| `backend/app/modules/artifacts/{preparation,sources}.py` | Inactive ART-only preparation; no core CON import | + +## Existing tests and gaps + +- Project/task tests cover current setup/claim/submission behavior but not + ContributionPolicy freezes or retirement of the legacy economic schema. +- AUTH tests cover catalogue parity, planned denial, actor-self/admin grants, + decision digest, scope evidence, and route commit/rollback. They do not cover + CON contexts, independent project grants at CON call sites, AUTH-09E CON + identities, or prepared cross-domain mutations. +- ART tests prove preparation only. No optional evidence projection capability + exists or is needed for core contribution tests. +- No tests yet cover ContributionRecord cardinality, frozen rule evaluation, + money/points award uniqueness, fulfillment callback, delivery replay, + shared-outbox handler isolation, or REV/CON atomic rollback. + +## Dependencies + +- AUTH: reviewed registration and later activation chunks, independent project + grants, prepared mutation protocol, fixed service admission, exact CON + service identities/static rows, and action-specific evaluators. +- REV: ReviewLease reviewer policy FK, canonical claim/decision composition, + stabilized artifact-hash facts, mandatory CON participant injection, single + route commit, and no no-op fallback. +- Task/Submission: submitter policy freeze and stable assignment/version lineage. +- Shared outbox/audit: caller-transaction append and feature-neutral dispatch. +- ADR 0014 adapters: typed capability port, factory, and composition-root + registration for external fulfillment. +- ART: no core dependency; optional projection only after separate approval. + +## Risks + +| Risk | Mitigation | +|---|---| +| Two award-eligibility models | Clean semantic then physical cutover; no fallback | +| Contribution missing after Review | Mandatory flush-only participant and one caller commit | +| ART outage suppresses contribution | No core ART/evidence operation | +| Wrong policy version | Assignment/lease freeze before work; immutable published versions | +| Cross-domain deadlock | AUTH-first lock order and two-order PostgreSQL tests | +| Dispatcher gains feature authority | Exact dispatcher-only action plus independent handler authorization | +| Dynamic/broad service access | Closed ServiceIdentity/static rows, AUTH-09E, cross-service denial | +| Role coupling | Independent grants and role-specific invalidation consumers | +| Partial activation transfer | Consume complete WS-XINT AUTH handoffs, never local subsets | +| Legacy row ambiguity | Human-approved deterministic rebuild/classification before migration | +| Premature public surface | Hidden behavior until AUTH activation and joint release proof | + +## Open questions + +- Exact D11 AdminRole candidates for award detail, delivery recovery, and audit. +- Exact ServiceIdentity/ActionId/static-row contracts for delivery, + reconciliation, projection rebuild, and callback execution. +- Deterministic treatment of pre-production legacy rows. +- Whether optional evidence projection is ever approved; it is not part of the + current core plan. + +## Conventions to preserve + +- Review decisions are only `accept`, `needs_revision`, and `reject`. +- PostgreSQL owns canonical contribution/award/receipt truth. +- External I/O occurs only after commit and outside lifecycle/database locks. +- Domain participants flush and never commit. +- AUTH and feature repositories never cross-import. +- Fixed service identity is authorization; Celery executor/generation is + separate execution fencing. +- `/api/v1` is the only public prefix. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md index 932a7ea6..4bc74b99 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md @@ -2,87 +2,74 @@ ## Human-level goal -Implement an evidence-backed contribution and compensation boundary that joins -the canonical human Review transaction without taking ownership of -authentication, authorization, provider payment execution, a points ledger, or -reputation scoring. +Implement the canonical contribution-policy, ContributionRecord, +CompensationAward, fulfillment, and operations boundary that participates +atomically in human Review without taking ownership of authentication, +authorization, review decisions, artifact storage, external settlement, a +points ledger, or reputation scoring. -The supplied revised WS-CON Markdown/PDF pair is an input to reconcile, not an -authority to accept blindly. The active contract must conform to the repository, -the live WS-AUTH action/permission catalogue, the parallel WS-REV plan, and the -accepted artifact-storage and external-adapter decisions. - -## Why now - -The backend currently stops at `review_pending`. The parallel review initiative -needs real compensation-policy persistence before ReviewLease creation, a -transaction participant that freezes compensation terms, and an atomic -contribution/award participant before it can expose review decisions. +The supplied WS-CON reference pair is input to reconcile, not authority to +accept blindly. The active contract follows trusted repository decisions and +the merged WS-XINT-001 boundary from PR #139. ## Success state -- Every valid Review records one immutable reviewer contribution. -- `accept` additionally records one immutable submitter contribution; the other - canonical decisions do not. -- Contributions and awards use compensation terms frozen before the work. -- Review, task/assignment effects, contributions, awards, audit, and shared - outbox events commit or roll back together. -- Money and project-points awards remain project-scoped obligations. Provider - payment attempts, balances, point ledgers, and settlement stay outside - Workstream. -- Fulfillment delivery, acknowledgement, callback receipts, and rebuildable - status projections are distinct. -- Contribution evidence is produced after commit through an ART-owned typed - capability and Workstream `ArtifactBinding`, never through a raw artifact - provider in contribution code. -- Every public or service operation consumes the merged WS-AUTH boundary: - request-scoped `require(ActionId, typed ResourceContext)` for `Q` reads and - the AUTH-owned prepared, caller-session-bound protocol for `T` mutations. +- Every valid recorded human Review creates one immutable reviewer + `completed_review` contribution. +- `accept` additionally creates one immutable submitter + `accepted_submission`; `needs_revision` and `reject` do not. +- TaskAssignment and ReviewLease freeze independent published + ContributionPolicyVersions before work is performed. +- Explicit unpaid rules create no award; compensated rules create at most one + money and one project-points CompensationAward. +- Review/task effects, contributions, awards, audit, and shared-outbox rows + commit or roll back in one caller-owned transaction. +- Core contribution creation copies stabilized artifact-hash lineage supplied + by REV and has no ART or provider dependency. +- Downstream adapters fulfill awards but never determine eligibility. +- Every protected human/service surface uses AUTH's exact grant or + ServiceIdentity/static-matrix path, prepared mutation protocol when needed, + and AUTH-owned activation. - Public APIs use `/api/v1` only. ## Non-goals - Workstream-owned login, sessions, passwords, or token-role authority. -- AUTH catalogue/kernel/grant/service-actor implementation in this initiative. -- Provider-specific payment SDKs, payment attempts, payout batching, settlement, - beneficiary onboarding, balances, point ledgers, credits, or blockchain work. -- Reputation scores, aggregates, adjudication, reversals, or contribution - mutation. -- A second artifact store, direct `ArtifactStore` injection into contribution - services, Flow Node, R2, semantic-search authority, or public provider refs. -- Frontend work before backend contracts and guards are proven. +- AUTH catalogue, grant, static-matrix, evaluator, or activation implementation. +- REV models, routes, lifecycle decisions, or commits. +- Mandatory contribution-evidence artifacts. A future projection is optional + and separately approved. +- Provider-specific settlement SDKs, attempts, payout batches, accounts, + balances, points ledgers, credits, or blockchain work. +- Reputation scores, aggregates, adjudication, reversals, or mutable + contribution/award truth. +- A second artifact store, raw provider references, or ArtifactStore injection. +- Frontend work before backend contracts and guards stabilize. -## Business/product/engineering context +## Context -Workstream must certify useful human work independently from whether an external -provider has paid or credited it. Reviewer work is itself a contribution for -every valid completed review. This creates a durable economic and reputation -input while preserving the separation between human judgment, contribution -recognition, compensation authorization, external fulfillment, and future -reputation policy. +Workstream certifies useful human work independently from external fulfillment. +Reviewer work is a contribution for every valid Review. ContributionPolicy +decides what that work earns; immutable awards record the result; adapters carry +out fulfillment later. ## Human judgment required -1. Approve the recommended active-contract model: preserve both supplied - reference generations byte-for-byte and create a separately reconciled - `docs/spec_contribution_compensation.md`, instead of editing archival input. -2. **Approved 2026-07-15:** remove `PaymentPolicy` completely because - `CompensationPolicyVersion` supersedes it. The removal must migrate every - project/task/submission/checker/schema/API/doc consumer, preserve no fallback - alias, and leave CompensationPolicyVersion as the only economic policy. -3. Approve the additive WS-AUTH dependency: granular WS-CON ActionIds map to - existing broad PermissionIds wherever safe, while the exact bound adapter - shared outbox dispatch and inbound callbacks require two new service-only - PermissionIds, `outbox.dispatch` and `compensation.fulfillment.report`, - owned and implemented by WS-AUTH. CON-02B first lands the hidden dispatcher; - AUTH then integrates its evaluator and activates dispatch. CON-08A only - consumes the already-claimed command. -4. Approve the cross-initiative sequence, including REV-13 as the sole joint - production-route activation/live-drill owner after AUTH, ART, REV, shared - outbox, and WS-CON participants are mandatory and proven. +1. Approve the repository-owned active specification while preserving archival + reference inputs. +2. The complete removal of the retired guide-bound economic schema remains + approved; choose only the deterministic pre-production row classification + for migration. +3. Resolve D11 action-specific AdminRole candidates for award detail, delivery + recovery, and audit. +4. Approve exact ServiceIdentity/ActionId/static-row boundaries for dispatcher, + delivery, reconciliation, projection rebuild, and callback execution. The + shared dispatcher cannot inherit handler authority. +5. Optional contribution-evidence projection remains deferred unless separately + approved. -## Initial risk class +## Risk class -L0 for architecture direction and contract adoption. Each approved runtime -chunk is L1 because it touches payment, permissions, lifecycle, audit, schema, -and cross-domain transactions. +L0 for planning/contract reconciliation. Each runtime chunk is L1 because it +touches authorization, economic records, schema, lifecycle, audit, or cross- +domain transactions. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md index 233cae5e..9affa7e1 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -1,125 +1,71 @@ -# Joint Release Handoff: WS-CON-001 To WS-REV-001-13 +# Joint REV/CON Release Handoff -## Incorporation status +## Boundary -The inspected sibling has reviewed baseline `6faccc0`, based on trusted `main` -including AUTH-08 and ART-02A2, plus later same-turn external-review repairs in -progress. Both are discovery until a reviewed merge. Its planning contracts assign future -contribution/compensation router registration, consumption of the WS-CON-11 -preflight manifest, the joint live matrix, PaymentPolicy removal dependencies, -active generated/document companions and REV-12A hidden release control. Those -runtime changes are not implemented. The planned composition consumes the -CON-owned dispatch/callback fences and fulfillment-drain observation instead of -importing CON/outbox repositories. +REV owns Review decisions, queue/lease/task effects, release-control state, and +the single route commit. CON owns ContributionPolicy, ContributionRecord, +CompensationAward, fulfillment, shared outbox participation, and CON +audit/projections. AUTH owns all authorization and activation. -The AUTH-08 dependency refresh records correct merged counts and -transaction/error/timestamp repairs, and its reviewed ART refresh correctly says -PR #129 is inactive preparation only. The sibling is still not consumable: -REV-06/08 core authorization and REV-10 final CON composition -predate the registration -> CON -> REV hidden -> AUTH activation choreography -and D12 owner-custody decision, and REV-12A still says the CON handler claims -the shared-outbox event. Before review/merge it must instead accept the -dispatcher's already-claimed command and return a typed outcome, leaving every -outbox transition to CON-02B. It must also adopt AUTH-08's current decision/ -transaction contract and the executable-gate/prepared-authorization -requirements. WS-CON does not edit the sibling. The WS-REV owner must repair, -commit-bind, internally review and merge the exact final contract. Until later -implementation gates land, both initiatives remain hidden. +The canonical cross-boundary source is merged +`WS-XINT-001/REV_CON_HANDOFF.md`. Sibling worktree state is discovery only until +reviewed and merged to trusted `main`. -The refresh must repair REV-06/08/10 authorization choreography. AUTH first -registers each planned review action and typed/prepared contract; CON supplies -the claim-freeze capability/decision participant; REV-06/08 build the hidden -core behavior and REV-10 supplies final CON composition/resource integration -while the real kernel still denies; AUTH alone integrates each evaluator and -activates the action before production execution. REV must not require an active -review action before building the hidden composition its activation depends on. - -## Required REV-13 allowed-file additions +## Required decision composition ```text -backend/app/api/router.py for one joint review/contribution/compensation registration -backend/app/modules/reviews/router.py -backend/app/modules/contributions/router.py -backend/app/modules/compensation/router.py -backend/tests/test_api_contract_e2e.py -backend/tests/test_authorization.py -backend/tests/test_reviews.py -backend/tests/test_contributions.py -backend/tests/test_compensation.py -README.md -docs/product_brief.md -docs/product_principles.md -docs/principles.md -docs/architecture_data_model.md -docs/operations_payment_reputation.md -docs/operations_operator_workflow.md -docs/operations_project_operating_manual.md -docs/template_project_guide.md -docs/template_task.md -docs/architecture_brief/workstream_architecture_brief.md -docs/architecture_brief/workstream_architecture_brief.pdf -docs/architecture_brief/task_lifecycle_sequence.puml -docs/architecture_brief/images/task_lifecycle_sequence.png -docs/architecture_brief/images/future_identity_payment_reputation.png -docs/architecture_brief/images/workstream_v01_container.png -docs/diagrams/task_lifecycle_sequence.md -docs/diagrams/workstream_v01_container.md -docs/diagrams/workstream_v01_container.puml -docs/diagrams/rendered/workstream_v01_container.svg -docs/diagrams/future_identity_payment_reputation.md -docs/diagrams/future_identity_payment_reputation.puml -docs/diagrams/rendered/future_identity_payment_reputation.svg +AUTH prepares review.decision with exact reviewer grant +-> REV locks and recomposes canonical facts +-> AUTH evaluates once +-> REV stages Review/lease/queue/task effects +-> CON flush-only participant creates reviewer contribution +-> on accept only, CON creates submitter contribution +-> CON evaluates frozen ContributionRules and creates applicable awards +-> CON stages audit/outbox rows +-> REV route commits once ``` -This is a seed list, not a closed substitute for discovery. REV-13 must replace -it with CON-01's exact generated active-document/companion inventory and may add -or remove paths only from that evidence. It must include every active/template/ -operations/generated file containing an affected claim. Archival inputs, -historical reviews, and generated loop memory remain excluded. +No no-op participant, post-commit repair, ART call, evidence projection, or +provider I/O exists in this transaction. CON copies stabilized artifact-hash +lineage from REV facts. + +## Release prerequisites + +- ContributionPolicy publish/freeze and adapter-binding behavior are merged. +- TaskAssignment and ReviewLease carry exact frozen policy-version IDs. +- Shared outbox/audit participants and CON-07 are mandatory and merged. +- REV hidden claim/decision composition consumes CON-06/07 and has no fallback. +- AUTH complete REV custody transfer, exact evaluators, reviewer grant path, + prepared protocol, and activation are merged. +- Every public/service CON action has exact AUTH registration, evaluator, + principal path, and activation after hidden behavior. +- Protected outbox handlers have their own exact service authority; dispatcher + authority is not inherited. +- CON-owned fulfillment dispatch/callback fence ports and same-session drain + observation are injected through composition without REV importing CON/outbox + repositories. +- Exact migrations, handler registry, task IDs, route inventory, and retained + tests are bound to merged SHAs. + +ART storage and optional contribution-evidence projection are not prerequisites. + +## Startup and readiness + +Startup fails on closed catalogue/static-matrix/context/evaluator/active-feature +parity drift. Missing provisioned fixed-service ActorProfile/link rows do not +stop startup or administrative provisioning, but runtime calls deny and release +readiness remains false until exact rows exist. -## Required joint activation criteria +## Joint live proof -- Register review, contribution, compensation policy/binding, contribution/ - award/evidence reads, fulfillment callback, and bounded operations routers in - the same PR under `/api/v1`; no `/v1` alias and no partial prior surface. -- Every registered route explicitly commits its own complete read or mutation - plus AuthorizationDecision and business/audit/outbox/idempotency state. - Domain services remain flush-only. The service-authenticated fulfillment - callback explicitly commits its decision plus receipt/idempotency state in - the fenced transaction. Tests prove an omitted commit is rolled back by - dependency teardown, authorization-evidence failure is one retryable 503 with - zero partial state, callback commit failure leaves no partial receipt, and no - route relies on dependency ordering to commit. -- Consume CON-11's exact merged-SHA/migration/action/service-assignment/ART/ - outbox/worker/handler/fence manifest plus AUTH context/evaluator/matched- - authority/prepared-protocol/availability parity, and fail startup/preflight - on any mismatch or active action without executable behavior. -- Use REV-12A only for hidden persisted joint lifecycle control and explicit - composition. Consume the required CON-owned `FulfillmentDispatchFence`, - `FulfillmentCallbackFence`, and `FulfillmentLifecycleDrainObservationPort`; - do not edit CON delivery/callback/outbox policy or import CON/outbox - repositories from REV. -- Preserve CON-02B as sole outbox claim/retry/finalization owner. REV-12A may - fence the CON handler and observe drain state, but neither REV nor the handler - claims or directly transitions the shared OutboxEvent. -- Prove the complete `CONFORMANCE_MATRIX.md` plus REV matrix with collected node - IDs and retained live evidence, including policy/binding setup, task/review - freezes, accept/needs_revision/reject, second revision review, money+points, - explicit unpaid, delivery/callback ordering, suspended/retired binding, - evidence privacy/rebuild, D11-approved delivery/operations role behavior, - denials, atomic - rollback, storage/adapter outage, replay and reconciliation. -- Update all active sources/generated companions in the same release so no - mutable PaymentRecord, accept-only/voidable contribution, automatic - reputation, executable PaymentPolicy or stale prefix claim remains. -- Preserve the one-sheet roadmap rule if the roadmap is touched; do not change - archival reference bytes. +The release drill covers accept, needs_revision, reject, explicit unpaid, +money+points, frozen-version changes, repeated/revision Reviews, no-self-review, +grant revocation, atomic rollback, adapter outage/replay, callback-before-ack, +failure then fulfillment, reconciliation, drain fencing, and hidden-to-active +route transition. It asserts zero ART calls in core contribution creation. -## Ownership +## Ownership and stop -WS-REV-001-12A owns only the hidden joint release-control foundation and typed -composition; WS-REV-001-13 remains the sole production activation/live-drill -PR. This file does not authorize WS-CON to edit the sibling plan or start REV -work. The incorporated sibling contract must be preserved through rebase, -receive any required delta review, and merge before an implementation chunk may -consume it. +CON-11 publishes the hidden dependency manifest but registers no route. The +reviewed REV release chunk consumes that manifest and owns public activation and +the joint live drill. This handoff starts neither chunk automatically. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md index 1ffdbabb..693e83e7 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -2,435 +2,317 @@ ## Proposed approach -Reconcile the supplied candidate into an active repository contract first, then -deliver the backend through small hidden-composition chunks. Land the shared -outbox and compensation policy ownership before Review persistence needs them; -interleave the remaining WS-CON participants with WS-REV at explicit gates; -activate public contribution/compensation APIs only after AUTH, ART, REV, and -outbox dependencies are mandatory and proven. - -## Design chosen - -### Canonical records - -- `ContributionRecord` is immutable and recognizes one exact contributor unit: - `completed_review` for every valid Review and `accepted_submission` only for - `accept`. -- Existing `Submission` is the versioned submission identity. Contribution - fields use `submission_id`, not a new `SubmissionVersion` table. -- `CompensationPolicyVersion` is the sole executable economic authority for new - assignments/leases. Rules match only contribution type and create at most one - money plus one project-points award. -- `CompensationAward` is immutable. Adapter delivery/acknowledgement and - immutable fulfillment receipts are separate; a rebuildable status projection - supports reads. -- `PaymentPolicy` is removed completely. `CompensationPolicyVersion` is the - only economic policy in persistence, APIs, task/review freezes, checker - context and active documentation; no alias or fallback survives. -- Provider payment attempts, balances, payout batches, points ledgers, and - settlement remain external. - -### Authorization dependency - -WS-CON never reads grants, roles, or AUTH repositories. Every protected command -or query declares one ActionId and consumes a request-scoped, caller-session- -bound `AuthorizationService`. - -Every WS-CON ActionId is currently absent and proposed. Trusted `main` -`9a04434` includes AUTH-08's scoped administrative grants at `aa0fdcd` and -ART-02A2 PR #129, which adds no authority. The closed AUTH catalogue -contains 74 PermissionIds and 57 non-WS-CON ActionIds: nine self/admin actions -are active and 48 actions remain planned. The exact handoff is in -`AUTHORIZATION_HANDOFF.md`. It enumerates each proposed action separately, its -existing or proposed PermissionId, canonical target, candidate principal class, -typed resource facts and guards, transaction protocol, AUTH activation gate, -and feature resource owner. - -AUTH-08 now evaluates actor-self and administrative grant families, carries a -complete resource-context digest plus matched grant/scope evidence, and rolls -back a transaction a feature route fails to commit. It still rejects service -subjects and has no ProjectRoleGrant, service-assignment, D10 or WS-CON action -evaluator. WS-AUTH therefore owns not only identifier/owner-enum registration -and typed/PostgreSQL parity, but also action availability, closed evaluator -dispatch, action-specific candidate-role filtering, matched-authority -expansion, remaining grant semantics, service-capable composition, service -ActorProfile/action-assignment construction, and transaction-local authority -revalidation. Every WS-CON route owns its explicit commit; the feature chunk -named in the handoff owns product-row loading, construction of AUTH-approved -typed resource facts, lifecycle guards, and behavioral proof. WS-CON never -edits AUTH-owned files or activates an AUTH action. - -Merged AUTH-08 also exposes a closed-role mismatch that must not be hidden in -CON. Finance Authority contains `compensation.delivery.reconcile`, but Operator -does not, while the reconciled candidate matrix proposes both. D11 requires a -human choice before CON-10B. If Operator delivery recovery is retained, a -reviewed AUTH-owned successor adds that existing PermissionId to Operator; if -not, the active WS-CON authority matrix removes the candidate before action -registration. D11 also decides whether Project Manager's broad -`compensation.award.read` candidate carries into WS-CON monetary detail and -which merged audit candidates remain eligible. CON-01 records the chosen sets; -AUTH activation proves them without CON role logic. - -D12 separately resolves activation custody. The merged ActionOwner type means -the implementation chunk permitted to activate an action; it cannot name a CON -feature chunk while this plan says AUTH alone flips availability. The handoff -therefore proposes exact AUTH-owned activation owners for all 23 WS-CON actions -and the two coupled review actions, plus all eleven existing ART-02D Operator/ -internal actions required by contribution evidence. The ART transfer preserves -every merged ActionId -> PermissionId mapping, including -`operations.artifact_storage_admission.read` -> `operations.status.read`. -Human/AUTH approval of that model—or a global feature-owner semantic plus a -separate closed activation-custody type containing the same mappings—is a -registration gate. In the recommended transfer, AUTH also removes the unused -`REV_08` and `ART_02D` enum members atomically; `REV_06` remains for its other -actions and closed owner-definition parity must still be exact. In the global -alternative those enums remain feature owners and the separate custody type is -closed independently. No action may have two activation authorities. - -For mutations crossing AUTH and product rows, AUTH must add the prepared -authorization protocol specified in the handoff. The preliminary target lets -AUTH lock actor/link/grant or service-assignment rows first; the opaque handle is -then evaluated exactly once against facts recomposed from product rows locked by -the feature in canonical order. AUTH stages one decision and never commits. -The final decision retains AUTH-08's resource-context digest and exact matched -grant/project evidence. Hidden domain services flush and never commit; the -actual route/worker/callback transaction owner explicitly commits the complete -decision-plus-business transaction. REV-13 owns the public route proof. -This prevents both product-before-AUTH lock inversion and authorization based on -an unlocked resource snapshot. - -Current trusted `main` also lacks an ActionId for upstream `task.claim`, even -though PermissionId `task.claim` exists. AUTH-13 or an approved AUTH-owned -successor must register and activate that action before CON-05A adds the -compensation freeze participant. Review choreography is deliberately staged: -AUTH first registers the planned `review.claim` and `review.decision` contracts; -CON-06/07 then supply their hidden capability/participant; REV-06/08 build the -core claim/decision behavior and REV-10 proves the final contribution -composition and typed resource behavior while the real kernel remains fail- -closed; only then may AUTH integrate the evaluators and activate those actions. -Production execution and public routes remain blocked until the later readiness/ -REV-13 gates. - -Derived contribution/award writes are mandatory participants of the already -authorized `review.decision` transaction. They are not separately callable -human/service commands and do not invent `contribution.materialize` or -`compensation.award.materialize` permissions. Shared outbox dispatch likewise -belongs to the outbox subsystem, not WS-CON. - -### Review composition - -`ContributionCompensationDecisionParticipant` accepts the caller's -`AsyncSession`, exact Review/lease/assignment/Submission facts, originating -AuthorizationDecision reference, and canonical request/correlation IDs. It -flushes contributions, awards, projections, audit, and outbox events but never -commits. WS-REV owns the decision and final commit. No optional/no-op production -participant exists. - -Policy lookup/freezing uses separate narrow participants: - -- task-owned assignment claim calls a WS-CON policy-freeze participant; -- review-owned lease claim calls the same policy lookup contract with a distinct - lease freeze operation; -- both lock the Project active compensation selector and copy exactly one - published version ID. - -`ReviewLease` schema and review-claim wiring remain wholly WS-REV-owned: -REV-03 adds the immutable policy-version FK/field, CON-06 supplies only the -narrow compensation lookup/freeze participant against caller-supplied canonical -facts, and REV-06 injects it and proves integrated claim behavior. Likewise, -CON-07 supplies the decision participant; REV-10 alone wires it into review -composition and proves end-to-end atomicity. - -### Canonical lock and revalidation order - -The active contract extends, and may not replace, WS-REV's accepted order: - -1. AUTH-owned current actor/identity/grant/service-assignment/control rows in - AUTH internal order, locked by the prepared authorization handle for `T` - operations; -2. the operation idempotency row; -3. for lifecycle-controlled commands, the shared lifecycle advisory fence and - captured phase snapshot; this is held through the database transaction but - never through remote I/O; -4. for an already-claimed outbox handler command only, read-only validation of - the immutable event/claim generation through the outbox-owned capability; - the handler acquires no OutboxEvent row lock and performs no outbox state - transition; -5. `Project`; -6. active/candidate ProjectGuide, GuideSourceSnapshot, submission-artifact, - effective, checker, review, revision and legacy payment-policy rows in the - existing REV order; then the active compensation selector, - CompensationPolicyVersion and referenced CompensationAdapterBinding rows; -7. WorkstreamTask, TaskAssignment, Submission, CheckerRun, - RevisionContextPreparation, ReviewQueueEntry, ReviewLease, - ReviewReconciliationFinding and prior Review/finding rows in REV order; -8. stabilized ArtifactBinding/Replica facts without remote provider I/O; -9. ContributionRecord, CompensationAward, delivery, receipt and projection rows - in WS-CON order; -10. append-only audit and shared-outbox rows after all state locks. - -Multiple same-type rows are locked by ascending primary key/UUID. Operations -skip absent classes but never reorder shared classes. - -No feature may reverse this order. For `T` operations, AUTH prepares and locks -authority first; publish, retire, binding suspend/resume/retire, assignment -claim, review claim, delivery, callback, reconciliation, and projection rebuild -then evaluate the same prepared handle against final facts recomposed from their -locked product rows. The handle is request/session/action/target bound and -single-use. `Q` reads remain request-scoped. -Freezing requires a published version whose referenced bindings are active. -Suspension blocks new freezes and new delivery but does not erase already-frozen -obligations; exact callback/replay behavior is state-matrix controlled. Real -PostgreSQL tests cover publish/suspend versus both claim types and suspend/ -retire versus dispatch/callback in both lock permutations. - -The dispatcher claim is a separate, previously committed CON-02B transaction. -It releases its session and every database lock before invoking a feature -handler. The handler starts a new caller transaction, acquires the lifecycle -fence/phase, validates the supplied claim generation through the typed outbox -capability without locking or mutating the OutboxEvent, and only then locks CON -rows. It commits durable pre-I/O state and releases the transaction/fence before -remote I/O. Only the dispatcher later applies the handler's typed outcome to -outbox retry/finalization state. - -### Artifact evidence - -The Review transaction creates only a pending contribution-evidence projection -row and a shared-outbox wake-up event. After commit, a worker loads canonical -PostgreSQL records, produces deterministic canonical JSON, computes its -expected SHA-256 and exact byte count, and passes a bounded async byte source, -media type `application/vnd.workstream.contribution-evidence+json;version=1` -and those expected facts to an ART-owned typed capability. - -Merged ART-02A2 PR #129 supplies only ART's inactive preparation foundation. -Before D10 or any database mutation lock, the future capability uses ART's -`ArtifactPreparationService` to write the complete first pass to canonical -bounded private scratch, compute digest/size, validate the exact media contract, -reject mismatch, and retain a sealed source behind an opaque ART operation. -Transaction A then locks AUTH -> CON -> ART, recomputes the canonical evidence -commitment from locked product facts, final-evaluates D10 and stages the durable -attempt. The caller commits explicitly; only then may an ART-owned same-process -continuation prove/claim that committed attempt in a fresh transaction and -consume the single second-pass stream outside every database transaction. - -Rollback, cancellation and exact replay close the preparation or retain -fail-closed ART cleanup custody until retry succeeds. Process loss persists no -handle/path: stale scratch cleanup reclaims custody and deterministic outbox -replay regenerates identical bytes against the durable attempt. CON never -imports or constructs `ArtifactScratchManager`, `PreparedArtifact` or -`CommittedArtifactSource`, receives a scratch path/descriptor, or owns cleanup. - -PR #129 does not implement the named contribution-evidence capability or the -remaining ArtifactStore v2, S3/MinIO, durable admission, provider execution, -verification/publication, recovery/authorization, binding or receipt gates. -02A3, 02B1, 02C1, 02C2, 02C3 and 02D must precede the separately approved -`WS-ART-001-CON-EVIDENCE` chunk, which delivers both named write and read ports. -It returns only bounded verified ArtifactBinding/receipt data. WS-CON validates -their digest/size/media/owner/project/role/schema/idempotency facts before it -stores projection state and the verified Workstream binding reference. - -LocalStorage and MinIO exercise the same product capability contract. AWS S3 -deployment proof gates production. Flow Node, R2, semantic search, provider -retain/pin APIs, and raw provider refs are excluded. - -### Shared outbox - -Land one generic PostgreSQL outbox before contribution integration. CON-02A -owns persistence/caller-transaction append. CON-02B owns the feature-neutral -Celery dispatcher, claim fencing, stable task IDs, retry/dead-letter/replay, -retention, operational recovery, a single explicit handler registry, and the -read-only same-session `OutboxDrainObservationPort` plus -`OutboxClaimValidationPort`. Feature handlers own deterministic delivery -semantics, never dispatch infrastructure or repository queries. - -## Alternatives considered - -### Edit the supplied reference pair in place - -Rejected because reference inputs are provenance evidence, the original PDF is -already checksum-bound, and the revised PDF is not a declared reproducible -Markdown build. Preserve generations and create an active reconciled spec. - -### Replace broad PermissionIds with granular strings - -Rejected because the merged AUTH contract preserves 74 stable PermissionIds -and separately registers 57 ActionIds, of which nine self/admin actions are -active on current trusted `main`. Granular action names do not replace -permissions. - -### Let WS-CON flip AUTH catalogue availability - -Rejected because availability without an AUTH-owned typed evaluator, grant or -service-assignment path, audit parity, and transaction protocol is either -deny-only or an authorization bypass. AUTH owns registration, evaluator -dispatch, principal truth and activation; CON owns canonical product facts and -behavior only. - -### Reuse `PaymentPolicy` directly as the award policy - -Rejected because it is guide-version-bound, submitter-oriented, and cannot -represent reviewer compensation, explicit unpaid rules, points, bindings, or -immutable publication lifecycle without becoming a second incompatible model. - -### Retain `PaymentPolicy` as advisory or historical context - -Rejected by the human. CompensationPolicyVersion supersedes it. A two-step -expand/contract removal keeps the semantic cutover atomic in CON-05A and drops -the unreachable physical schema in CON-05B; neither step exposes a fallback. - -### Call ArtifactStore from contribution workers - -Rejected by ADR 0013/0014 because it bypasses ART admission, verification, -binding, receipts, recovery, and composition ownership. - -### Implement ContributionRecordRequested first - -Rejected because the approved REV/CON seam is direct atomic participation in -the Review transaction. A temporary event would create a partial-history risk. - -### Publish partial APIs early - -Rejected because action activation, policy freeze, callback service identity, -review atomicity, and artifact capabilities must fail closed as one coherent -backend contract. - -## Boundaries preserved - -- Auth/session: external tokens are verified by existing issuer adapters; - WS-AUTH alone owns product authorization and service actors. -- Permission/policy: WS-CON supplies resource facts/guards but never edits - grants or implements an authorization kernel. -- Payment/execution: Workstream records awards/instructions/receipts; external - adapters own provider attempts, approvals, balances, and ledgers. -- Persistence/data: PostgreSQL owns canonical contribution/award/receipt truth; - provider bytes are never canonical product state. -- Presentation/API: `/api/v1`; deterministic concealment and pagination; no - provider refs, tokens, or credentials. -- CI/deployment: no threshold weakening; no new production provider or - dependency without explicit approval. - -## Rollout/migration strategy - -1. Adopt the ADR-backed active contract while preserving both archival - generations. The same chunk adds only the exact renamed generation-2 - Markdown path to the stale-authorization scanner's reviewed history map, - with near-miss/new-document fail-closed regression proof; the active spec - remains scanned. Its gate test repairs the existing cross-scanner set - comparison by subtracting only this authorization-only path and proves the - artifact scanner already excludes it through the reference-spec prefix; the - artifact scanner itself is unchanged. -2. Merge outbox persistence then its feature-neutral dispatcher; add split, - inactive binding/policy/contribution/award/delivery/receipt persistence. -3. Complete the ART sequence needed by evidence intake: merged 02A2 committed- - source preparation -> 02A3 ArtifactStore v2 cutover -> 02B1 MinIO/AWS S3 -> - 02C1 durable admission/put-attempt -> 02C2 verification/publication -> 02C3 - recovery chain -> 02D hidden internal-executor/Operator recovery behavior -> - AUTH-owned evaluator integration/activation -> separately approved - `WS-ART-001-CON-EVIDENCE` write/read ports. AUTH-09 first owns the fixed - verifier/scanner/resolver registrations, identities and assignments; D12 - first transfers the eight ART-02D Operator and three internal actions to the - exact AUTH activation custodians (or a separate closed custody map); 02D - proves hidden resource/feature behavior but never changes availability; AUTH - separately activates Operator recovery and internal execution. None of these - gates moves scratch, provider, ART - persistence or authorization ownership into CON. -4. Interleave each AUTH registration -> feature implementation -> AUTH - activation wave in `AUTHORIZATION_HANDOFF.md`. The registration checkpoint - provides planned ActionId/PermissionId/owner/audit parity, typed context - contracts, principal prerequisites and prepared mutation protocol. The - CON/ART chunk then merges hidden authorization-ready behavior while the real - kernel still denies. Only a later AUTH-owned checkpoint integrates the - evaluator, proves the exact merged feature and changes availability. CON/ART - never edits AUTH or supplies a production allow fallback. Merge required ART - capabilities in ART. -5. Activate hidden binding/policy services. CON-05A atomically removes every - PaymentPolicy semantic consumer and enables only task claims that freeze a - CompensationPolicyVersion, only after merged REV-02 establishes the exact - `Submission.task_assignment_id` lineage. CON-05B drops the unreachable old - model/table/columns/constraints after a zero-consumer scan. -6. Interleave with WS-REV: policy schema before REV lease schema; lease freeze - before claims; atomic participant after revision/decision persistence. -7. Add delivery/callback, evidence projection, reads, and operations behind - unregistered production routes. -8. Finish WS-CON hidden readiness and an exact dependency manifest. WS-REV-13 - is the sole production router activation and joint live-drill owner for the - review/contribution/compensation release. Before it, REV-12A may own hidden - persisted joint release control and inject its implementation through the - required CON-owned dispatch/callback fence ports while consuming the - read-only fulfillment-drain observation port; it may not edit CON product - files or import CON/outbox repositories. - Sibling reviewed baseline `6faccc0` correctly treats PR #129 as inactive - preparation; later same-turn external-review repairs are in progress. Both - are discovery only. The future merged snapshot must repair REV-06/08 one-step - authorization, REV-10 final CON composition, D12 custody and REV-12A's - handler-owned outbox transitions. It must adopt the current - registration -> CON -> REV hidden -> AUTH activation/prepared-handle - choreography and dispatcher-owned typed command/outcome contract, then pass - fresh review and merge before consumption. Do not pin the live sibling head/ - cleanliness or change archival sources. - -At every chunk activation, rebase discovery on trusted `main`, refresh exact -migration numbers and dependency symbols, and stop if an expected port/action -is absent or materially changed. +Adopt the merged WS-XINT-001 boundary from PR #139 before runtime work, then +deliver WS-CON through hidden, reviewable chunks. The core path is PostgreSQL- +local and has no ART dependency: + +```text +AUTH prepares review.decision and locks reviewer authority +-> REV locks and recomposes canonical Review/Submission facts +-> AUTH evaluates once and stages decision evidence +-> REV stages Review, lease/queue consumption, and task effects +-> CON flush-only participant creates contributions and applicable awards +-> CON stages audit and shared-outbox rows +-> REV route commits once +``` + +Public contribution, policy, award, fulfillment, and operations surfaces stay +hidden until their exact AUTH registration -> feature behavior -> AUTH +activation sequence and the joint REV/CON release gate pass. + +## Canonical product model + +- `ContributionRecord` is immutable. Every valid recorded human Review creates + one reviewer `completed_review`; only `accept` additionally creates one + submitter `accepted_submission`. +- Existing `Submission` plus its `version` and `supersedes_submission_id` is the + versioned submission identity. WS-CON does not add `SubmissionVersion`. +- `ContributionPolicy` is the stable project aggregate. It has one active + policy per project and points to an immutable published + `ContributionPolicyVersion`. +- Each published version has exactly one `ContributionRule` for + `accepted_submission` and one for `completed_review`. A rule is explicitly + `unpaid` or `compensated`. +- An unpaid rule creates no award. A compensated rule references one or two + immutable `ContributionAwardDefinition` rows: at most one `money` and one + `project_points` definition. +- `CompensationAward` is the immutable evaluated result. Delivery, + acknowledgement, immutable `CompensationFulfillmentReceipt`, and rebuildable + `CompensationStatusProjection` are downstream fulfillment concerns and never + decide eligibility. +- `ProjectCompensationAdapterBinding` binds one project/instrument to a + non-secret adapter route and canonical service actor. Credentials and + provider endpoints remain deployment configuration. +- The retired guide-bound economic schema and every semantic consumer are + removed in two fail-closed chunks. No alias, automatic conversion, or + executable fallback survives. + +## Review and contribution boundary + +`ContributionCompensationDecisionParticipant` receives the caller-owned +`AsyncSession` and a typed request containing: + +- exact Review, ReviewLease, queue/lifecycle fence, and decision; +- versioned Submission, TaskAssignment, task, and project identities; +- reviewer and submitter canonical ActorProfile IDs; +- lease-frozen reviewer and assignment-frozen submitter + `ContributionPolicyVersion` IDs; +- the stabilized reviewed-packet/submission artifact digest already established + by REV and Submission; +- the originating allowed `review.decision` AuthorizationDecision reference, + request ID, and correlation ID. + +CON validates the supplied locked facts, copies the stabilized digest into +`ContributionRecord.artifact_hash`, evaluates the matching frozen +`ContributionRule`, stages applicable awards/audit/outbox rows, flushes, and +never commits. It never reads REV or AUTH repositories, evaluates +`review.decision`, calls ART, rehashes artifact bytes, performs provider I/O, or +offers a no-op production participant. Any CON failure rolls back the complete +Review decision. + +`needs_revision` and `reject` still create the reviewer contribution and any +award earned by its frozen reviewer rule. They create no submitter contribution. +Automated checker outcomes create neither contribution type. + +## Contribution-policy freezing + +TaskAssignment freezes `submitter_contribution_policy_version_id` during an +authorized task claim. ReviewLease freezes +`reviewer_contribution_policy_version_id` during an authorized review claim. +Both use a narrow CON-owned lookup/freeze participant, lock the active +`ContributionPolicy` and current published version plus referenced award +definitions and adapter bindings, return one exact version ID, flush only their +own state, and never commit. + +Later policy publication changes only new assignments or leases. Retired frozen +versions remain valid for started work. Missing policy configuration is not an +implicit unpaid rule. + +TaskAssignment and task-claim wiring remain task-owned. ReviewLease and review- +claim wiring remain REV-owned. CON supplies typed participants, not foreign +models, routes, lifecycle decisions, or commits. + +## Authorization boundary + +Trusted `main` is `5d353b6`, merging WS-XINT-001 through PR #139. Runtime +catalogue counts remain 74 PermissionIds, 57 ActionIds, nine active actions, and +48 planned actions. No WS-CON ActionId is registered yet. + +WS-XINT D1/D2 is final for this plan: `ActionOwner` is the exact AUTH activation +custodian. Each protected surface follows: + +```text +AUTH registers planned ActionId, stable PermissionId mapping, typed context, +principal path, and activation custodian +-> CON merges hidden canonical resource composition, guards, and behavior +-> AUTH integrates the evaluator and alone changes planned to active +-> joint release exposes the surface +``` + +CON never reads grants, imports AUTH repositories, constructs PermissionIds or +roles, changes availability, or supplies a production allow fallback. AUTH +never imports CON repositories or mutates contribution/award state. + +The current complete ART and REV custody transfers are AUTH-owned coordination +work. WS-CON references the canonical WS-XINT `AUTH_ART_HANDOFF.md` and +`AUTH_REV_HANDOFF.md`; it does not prescribe a partial transfer. CON depends on +`review.claim` and `review.decision`, but AUTH must reconcile every current REV +action as one complete boundary. The four proposed additive REV actions remain +unregistered until their own reviewed registration contract. + +### Human project grants + +Project contributor grants are exactly independent `submitter`, `reviewer`, +and `adjudicator` rows. Task claim requires one active exact-project submitter +grant. Review claim/decision require one active exact-project reviewer grant +plus no-self-review and lifecycle guards. Adjudicator authority does not +substitute for either. Revoking one grant does not revoke the other two or any +AdminRoleGrant; the owning task/review lifecycle consumes its exact invalidation. + +### Prepared mutation protocol + +For mutations, AUTH first locks and revalidates either human actor/link/grant +rows or fixed-service actor/link rows. A fixed service additionally requires an +unchanged closed `ServiceIdentity`, exact static service-action matrix +membership, AUTH-09E typed service admission, and active action. AUTH returns a +single-use, non-serializable handle bound to request, session, actor, action, +target, and authority snapshot. The feature locks canonical rows, recomposes +final typed facts, and AUTH evaluates once. AUTH stages one decision and never +commits. Reads use request-scoped `require()` and canonical feature loaders. + +Missing provisioned service ActorProfile/ActorIdentityLink rows deny that +runtime request and block release readiness, but do not fail application startup +or the Access Administrator provisioning surface. Startup may fail on closed +catalogue/matrix/context/evaluator/active-behavior parity drift. + +### Fixed services and handler authority + +The shared outbox dispatcher is not a catch-all feature executor. +`workstream.outbox.dispatcher` with exact `outbox.dispatch` static membership +may claim, invoke, and finalize outbox work only. It cannot inherit compensation +delivery, reconciliation, contribution projection, callback, ART, or provider +authority from an event type. + +Before a protected feature handler is implemented, its owning specification and +AUTH must approve one exact ServiceIdentity/ActionId/static-row contract. The +current candidate boundaries requiring decisions are: + +- outbound compensation delivery execution; +- asynchronous compensation reconciliation; +- asynchronous contribution projection rebuild; +- fulfillment result reporting by the bound external service; +- optional contribution-evidence binding, if that projection is later adopted. + +Suggested semantic identifiers are discovery candidates only, not approved +catalogue strings: `workstream.compensation.delivery`, +`workstream.compensation.reconciler`, +`workstream.contribution.projection_rebuilder`, and +`workstream.compensation.fulfillment_reporter`. AUTH may instead approve a +closed dual-principal evaluator for an existing action, but CON must not infer +one. Therefore the previously proposed 22 core WS-CON ActionIds are not a final +closed runtime count until these service execution boundaries are decided. + +The callback path requires a verified service token, provisioned service +ActorProfile/ActorIdentityLink, immutable approved ServiceIdentity, its exact +static matrix row, matching `ProjectCompensationAdapterBinding`, and AUTH-09E. +It never uses a human role or dynamic service grant. + +## Operation-specific lock and commit order + +There is no global sequence that moves CON policy rows ahead of REV lifecycle +rows. Every mutation first locks AUTH human actor/link/grant or fixed-service +actor/link authority, then its idempotency row and applicable lifecycle fence. +After that common prefix, the owning operation uses one explicit order: + +- `review.decision`: REV task, assignment, Submission, queue/lease, Review and + finding rows in REV's canonical order; the assignment- and lease-frozen + ContributionPolicyVersion, matching rule/definition, and referenced binding; + stabilized reviewed-packet and Submission artifact-hash lineage; then + ContributionRecord, CompensationAward, audit, and shared-outbox rows; +- task/review claim freeze: the owning task/assignment/Submission or REV + queue/lease rows first, then the selected published policy version, + rule/definition and referenced binding, then the frozen lineage write; +- binding retirement or reconciliation that inspects task/assignment/lease + dependencies: affected lifecycle rows in the same task/REV order first, then + binding/policy and CON delivery/receipt/projection rows. If the bounded rows + cannot be enumerated before locking, the operation takes its approved + project-scoped advisory fence before either family and still locks lifecycle + rows before policy/binding rows; +- an outbox handler: immutable claim-generation validation without handler + ownership of outbox transitions, then its feature-owned award, binding, + delivery, receipt, request, finding, or rebuildable projection rows. + +Pure policy/binding administration that does not inspect lifecycle dependencies +locks Project and its own aggregate only. Rows of one type lock by ascending +primary key/UUID. Missing classes are skipped without reordering. Provider or +external I/O happens only after durable pre-I/O state commits and every database +transaction/fence is released. + +The dispatcher owns claim, retry, dead-letter, and finalization transitions. +Feature handlers validate the committed claim generation through a typed port, +stage feature state, perform post-commit I/O under their own exact authority, +and return a typed outcome. They do not lock or mutate OutboxEvent rows. + +## Optional contribution-evidence projection + +A deterministic contribution-evidence document is optional later work. It is +not written or requested by CON-07, does not gate ContributionRecord creation, +and is excluded from core reads, operations, release readiness, and the joint +live drill. + +If separately approved, CON-09A/09B may implement an asynchronous projection +with independent status/failure semantics through a separately reviewed ART +capability and AUTH action. Storage failure cannot change Review, +ContributionRecord, CompensationAward, fulfillment receipt, or status +projection truth. The future contract must revalidate the then-current ART and +AUTH boundaries, exact media/schema/retention/disclosure rules, and service +identity. CON never receives ArtifactStore, scratch/preparation types, provider +references, or ART repositories. PR #129's preparation foundation does not +approve this capability. + +Core contribution and award reads move directly to CON-10A and read PostgreSQL +truth. They do not depend on an evidence artifact or ART read port. + +## Shared outbox + +CON-02A provides generic PostgreSQL persistence and caller-transaction append. +CON-02B provides the feature-neutral dispatcher, stable task IDs, claim fencing, +retry/dead-letter/replay, retention, explicit handler registry, +`OutboxClaimValidationPort`, and same-session drain observation. The outbox +subsystem owns no contribution, award, adapter, review, or provider semantics. + +## Rollout + +1. CON-01 adopts the merged WS-XINT contract and publishes the active + contribution/compensation specification without altering archival inputs. +2. CON-02A/B/C land shared outbox persistence/dispatch and shared lifecycle + audit participation, with outbox execution still disabled until its AUTH + registration, static service identity, AUTH-09E admission, hidden behavior, + and activation gates pass. +3. CON-03A-D add inactive policy, binding, contribution, award, delivery, + receipt, and status persistence using the canonical names and boundaries. +4. CON-04A/B add hidden binding and ContributionPolicy behavior behind planned + AUTH actions. +5. CON-05A removes retired semantic consumers and freezes the published + ContributionPolicyVersion on new TaskAssignments; 05B drops unreachable + physical schema after a zero-consumer proof. +6. CON-06 supplies reviewer policy freeze; the REV owner wires it into hidden + review claim behavior before AUTH activates `review.claim`. +7. CON-07 supplies the flush-only decision participant; the REV owner wires it + into the complete hidden decision path before AUTH activates + `review.decision`. +8. CON-08A/R/B add fulfillment delivery and callback behavior only after exact + service execution/callback identities, actions, static rows, AUTH-09E, and + lifecycle fencing are approved. +9. CON-10A/B add PostgreSQL product reads and bounded operation requests; 10C + adds independently authorized reconciliation/rebuild executors. Optional + 09A/09B remain outside the core dependency sequence. +10. CON-11 proves hidden readiness. REV release-control composition consumes + only typed fence/drain ports; the reviewed REV release chunk owns the final + public route activation and joint live drill. + +Every chunk refreshes trusted-main SHA, migration custody, exact port/action +symbols, and merged dependency evidence. No cross-initiative successor starts +automatically. ## Verification strategy -- Ruff and focused unit/service tests for every chunk. -- Every runtime chunk uses `scripts/run_isolated_tests.py` with one unique, - attempt-specific metadata JSON retained under the initiative evidence - directory and same-invocation `pytest --cov=app --cov-fail-under=78`; stale - `.coverage` output is never evidence. Focused reports from that invocation - prove each new/materially changed subsystem is at least 90 percent. -- Fresh isolated real-PostgreSQL tests cover migrations, constraints, - transaction rollback, idempotency, and both concurrency permutations. -- New/materially changed module coverage at or above 90 percent; same-run - repository coverage at or above 78 percent. -- OpenAPI action inventory requires one ActionId per protected surface and - proves hidden routes remain absent before final activation. -- Authorization contract tests prove every planned WS-CON action denies, every - active action has exactly one AUTH evaluator and one approved typed context, - and no active action exists without its owning feature behavior. Mutation - tests reject missing/reused/cross-session prepared handles and exercise - actor/link/grant or service-assignment revocation against product mutation in - both lock permutations. AUTH role-matrix/evaluator tests prove D11's exact - human-approved delivery/award/audit sets, including only the amendments and - inclusion/exclusion cases that outcome requires, plus exact matched-grant/ - project evidence and resource-context digest equality. -- Static architecture tests reject AUTH persistence imports, local role checks, - provider-specific compensation adapters, concrete-adapter imports or - construction outside the explicit composition root, raw ArtifactStore - injection, provider refs, and duplicate outbox implementations. The - deterministic conformance adapter is allowed only through the shared typed - factory and explicit composition. -- Contract tests prove proposed ActionId -> PermissionId parity with the merged AUTH - catalogue and stable event payload/digest identity. -- LocalStorage and MinIO evidence-capability conformance; AWS deployment proof - remains owned by ART. -- ART capability tests prove expected digest/size mismatch causes zero durable - admission/provider calls; only ART preparation can mint the committed source; - the second pass is single-use; success/failure/cancellation either completes - close/release or leaves explicit ART-owned cleanup custody unavailable for - reuse until retry succeeds; and no scratch path/type crosses into CON. PR - #129's preparation tests alone do not satisfy this integration gate. -- Final live drill covers paid accept, needs revision, reject, unpaid policy, - frozen-version change, money+points, acknowledgement vs fulfillment, - failure-then-fulfillment, replay, adapter outage, storage outage, recovery, - authorization denials, atomic rollback, and reconciliation. -- `CONFORMANCE_MATRIX.md` maps every adopted candidate invariant to an owning - chunk, executable case, final live case, and retained evidence; activation - replaces proposed names with collected test node IDs. -- Stale wording scan, Markdown links, reference checksums, `git diff --check`, - and one-sheet roadmap checks when sheets are present. - -## Review strategy +- Isolated PostgreSQL migration, constraint, rollback, idempotency, and both- + order concurrency tests. +- Same-run repository coverage at or above 78 percent and each new/materially + changed subsystem at or above 90 percent. +- Exact contribution cardinality for all three decisions and repeated/revision + Reviews; automated checks create none. +- Policy publication/freeze races, explicit unpaid rules, immutable published + versions, and at most one award per contribution/instrument. +- Participant fault injection proving Review/task/contribution/award/audit/ + outbox atomic rollback and no ART call. +- AUTH tests for planned denial, exact grant/static-matrix candidates, prepared + handle misuse, role-specific revocation, cross-service denial, and one + activation custodian per action. +- Outbox tests proving the dispatcher cannot execute feature authority and each + protected handler has an approved independent authorization path. +- Callback/delivery/reconciliation tests with no provider I/O under database + locks and immutable receipt/award identities under replay. +- Hidden OpenAPI proof before release; exact `/api/v1` inventory at release. +- Stale wording, stale authorization/artifact contracts, Markdown links, loop + memory, `git diff --check`, and one-sheet roadmap checks when local sheets are + present. + +## Open human/AUTH decisions + +- D11 exact AdminRole candidate sets for award detail, delivery recovery, and + WS-CON audit actions. +- Exact ServiceIdentity/ActionId/static-row design for each protected feature + handler and fulfillment callback; proposed strings are not executable until + approved and registered by AUTH. +- Legacy pre-production row classification before CON-05A/05B migration. +- Optional evidence projection remains deferred unless separately approved. + +## Review and stop Planning and every specification/runtime chunk require senior engineering, QA/test, security/auth, product/ops, architecture, docs, and reuse/dedup. -Runtime/test chunks add test-delta. Outbox/worker/script/config/CI changes add CI -integrity. Critical/High findings block; Medium findings require human decision. - -## Sequencing - -See `CHUNK_MAP.md`. Only one WS-CON chunk is active at a time. Cross-initiative -gates do not authorize another initiative's work and no successor starts -without a new explicit human instruction. +Runtime/test chunks add test-delta; background-execution/script/config/CI changes add CI +integrity. Stop after planning reconciliation. Do not start CON-01 or another +initiative without explicit human instruction. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md index eaccf027..4b197f6e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -1,33 +1,20 @@ # Risks: WS-CON-001 Contribution Record And Compensation Boundary -| Risk | Severity | Mitigation | Owner | Status | -|---|---|---|---|---| -| Candidate spec replaces canonical API/permission/storage rules | Critical | Preserve as input; reconcile into active spec with ADR precedence and exact scans. | WS-CON-001-01 | Open | -| Dual `PaymentPolicy` and `CompensationPolicyVersion` truth | Critical | D2 approved complete removal; 05A cuts all consumers atomically and 05B drops schema under a zero-consumer scanner. | WS-CON-001-05A/B | Direction resolved; implementation open | -| Existing rows lack safe frozen compensation refs | High | CON-05A classifies/drains or approved-backfills; migration fails on ambiguity and never guesses conversion. | Human / WS-CON-001-05A | Legacy rule decision needed | -| Bound adapter callback lacks a safe current service permission | Critical | AUTH-owned additive service-only PermissionId/action, fixed actor, exact binding guards. | WS-AUTH | Open | -| Shared outbox dispatcher borrows human retry/reconciliation authority | Critical | Add service-only `outbox.dispatch`, fixed dispatcher assignment, and claimed-command generation guards in CON-02B; CON-08A is only a handler. | WS-AUTH / WS-CON-001-02B | Open | -| Review/CON circular dependency | High | Interleaved gates: policy schema -> lease schema -> freeze -> claims -> participant -> integration. | WS-CON / WS-REV | Mitigated in plan | -| Partial Review/contribution/economic commit | Critical | Caller-owned session, shared lock order, DB constraints, fault injection, exact replay. | WS-CON-001-07 / WS-REV | Open | -| Direct provider call bypasses ART controls | Critical | Named `WS-ART-001-CON-EVIDENCE` capability prerequisite; import/composition tests reject raw store/provider access. | WS-ART / WS-CON-001-09A | Open | -| PR #129 scratch/source types leak into CON | Critical | ART alone invokes preparation, holds `PreparedArtifact`, consumes the sealed source and either releases scratch or retains explicit cleanup custody until retry succeeds. CON passes only bounded deterministic bytes plus expected commitment through the named capability; static and cancellation tests reject a second scratch path. | WS-ART / WS-CON-001-09A | Open | -| ART-02A2 is mistaken for contribution capability readiness | Critical | Keep AUTH-09 registration/assignments, ART 02A3-02C3, hidden 02D behavior, later AUTH evaluator activation, and `WS-ART-001-CON-EVIDENCE` write/read ports as explicit gates; 02D proves/consumes authority but never writes availability. | WS-ART / WS-AUTH / WS-CON-001-09A/B/11 | Open | -| First-pass preparation holds AUTH/product locks | Critical | ART prepares before D10 or any mutation lock; Transaction A revalidates locked canonical facts/commitment and stages only bounded database work. | WS-ART / WS-CON-001-09A | Open | -| Process-local prepared source is lost across transaction outcome | Critical | Opaque ART context retains the source; caller commit is followed by a fresh committed-attempt claim before I/O; rollback/cancellation closes, process loss uses stale cleanup, and outbox replay regenerates bytes without serializing a handle. | WS-ART / WS-CON-001-09A | Open | -| Outbox duplication or loss | High | 02A owns truth/append; 02B alone owns dispatch/retry/replay with stable identities. | WS-CON-001-02A/B | Open | -| Human role or token claims leak into feature authorization | Critical | Central AUTH service only; no grant queries/local role checks; deny/race tests. | WS-AUTH / all WS-CON | Open | -| Merged AdminRole permission candidates conflict with candidate WS-CON roles | Critical | D11 chooses Operator delivery, Project Manager award-detail and audit/export candidates. AUTH amends only a chosen outcome that differs from its merged matrix; CON-01 updates the active matrix and AUTH activation proves exact roles. | Human + WS-AUTH + WS-CON-001-01/10A/B | Decision needed | -| Registered WS-CON action has no executable AUTH evaluator | Critical | AUTH owns typed contexts, closed evaluator dispatch, matched authority and active availability; CON cannot flip catalogue state; startup parity rejects active-without-evaluator and evaluator-without-feature behavior. | WS-AUTH | Open | -| ActionOwner names a feature chunk while AUTH is said to activate | Critical | D12 approves exact AUTH-owned activation owners for all 23 WS-CON and two coupled review actions, or introduces a separately reviewed activation-custody type; startup/parity tests reject dual or missing owners. | Human + WS-AUTH | Decision needed | -| Required ART-02D actions retain feature activation custody | Critical | D12 transfers all eight Operator and three internal ART-02D actions to exact AUTH owners without changing ActionId/PermissionId mappings, or records the same mappings in a separate closed custody type. Operator retry and internal executor activation remain distinct. | Human + WS-AUTH / WS-ART | Decision needed | -| Owner transfer leaves unused closed enum members | Critical | Recommended D12 atomically removes `REV_08` and `ART_02D` after their last rows transfer and proves owner-definition/SQL/audit parity; the global feature-owner alternative retains them only with a separate exact closed custody catalogue. | WS-AUTH | Decision needed | -| Feature route relies on authorization dependency teardown to commit | Critical | Preserve AUTH-08's rollback-only teardown: every route explicitly commits decision plus business/audit/outbox state; forgotten commit and evidence-failure tests prove zero partial state. | WS-AUTH + every WS-CON route owner | Open | -| Cross-domain mutation authorizes unlocked facts or reverses locks | Critical | D10 AUTH-owned prepared handle locks authority first and evaluates once against final locked product facts; missing/reused/cross-session handles deny. | WS-AUTH + each `T` CON owner | Open | -| Task compensation freeze assumes nonexistent `task.claim` ActionId | Critical | AUTH-13 or reviewed AUTH successor registers/evaluates/activates exact `task.claim` -> existing `task.claim` before CON-05A. | WS-AUTH / WS-CON-001-05A | Open | -| Provider payment logic leaks into Workstream | High | Typed instruction/ack/receipt contract; provider attempts/balances/ledger prohibited. | WS-CON-001-08A/B | Open | -| Fulfilled state regresses or duplicates | High | Immutable receipts, unique fulfilled row, row locks, exact callback idempotency. | WS-CON-001-08B | Open | -| Lifecycle disable races adapter I/O or authenticated callback | Critical | CON-owned mandatory dispatch/callback fence ports, durable pre-I/O in-flight state, same-session drain observations, REV-12A exclusive transition lock, and both-order PostgreSQL tests. | WS-CON-001-03D/08A/08B/10B/11 + WS-REV-001-12A | Open | -| Artifact outage changes contribution truth | High | Projection is post-commit/rebuildable; canonical records never depend on provider availability. | WS-CON-001-09A | Open | -| Sensitive financial/provider/token data leaks | Critical | Bounded schemas, redaction, no human-token forwarding, no provider refs in APIs/events. | Security review | Open | -| Public routes expose partial system | High | CON-11 proves hidden readiness; REV-13 alone registers the joint surface. | WS-CON-001-11 / WS-REV-001-13 | Open | -| Initiative becomes unreviewable | High | One PR-sized chunk, circuit-breaker, explicit stop after each. | Primary agent / human | Mitigated in plan | +| Risk | Impact | Mitigation | Owner | +|---|---|---|---| +| Competing award-eligibility models | Critical | ContributionPolicy is sole authority; semantic then physical clean cut with no fallback | CON-05A/B | +| Review commits without contribution | Critical | Mandatory flush-only participant and one REV-owned commit; fault-injection rollback | CON-07 + REV | +| Mandatory ART projection blocks product truth | Critical | No ART/evidence work in core transaction or release; optional successor only | CON-07/09/11 | +| Wrong frozen policy | Critical | Assignment/lease freeze before work; immutable versions; concurrency proof | CON-05A/06 | +| Dispatcher inherits handler authority | Critical | Dispatcher-only action; exact independent service authority for protected handlers | CON-02B/08A/10C + AUTH | +| Operations request authority leaks into execution | Critical | 10B persists bounded human requests only; 10C uses exact fixed-service actions, cross-executor denial, replay/finding proof, and projection-only mutation | CON-10B/10C + AUTH | +| Broad or dynamic service access | Critical | Closed ServiceIdentity/static rows, controlled provisioning, AUTH-09E, cross-service denial | AUTH + CON | +| Partial ART/REV custody transfer | High | Reference complete WS-XINT handoffs; no local subset or dual writer | AUTH | +| Cross-domain deadlock/partial commit | Critical | AUTH-first common prefix; operation-specific REV/task lifecycle-before-policy order; one session/commit; both-order PostgreSQL tests | AUTH + REV + CON | +| Role coupling or substitution | High | Independent submitter/reviewer/adjudicator grants and exact invalidation | AUTH + lifecycle owners | +| Provider I/O under locks | Critical | Durable pre-I/O state; release transaction/fence before adapter call | CON-08A/outbox | +| Callback spoofing/replay | Critical | Exact service identity/static row, binding match, prepared protocol, idempotent receipt | CON-08B + AUTH | +| Legacy row ambiguity | High | Human-approved deterministic rebuild/classification; migration fails closed | Human + CON-05 | +| Premature public release | High | Hidden OpenAPI, exact manifest, AUTH activation, joint REV/CON gate | CON-11 + REV | + +No runtime work starts while a blocking decision or prerequisite remains open. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md index 80aefb56..db18fa12 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md @@ -26,23 +26,24 @@ git diff --check | CON-02B | `app/modules/outbox/*`; `app/workers/outbox.py` | `app/modules/outbox app/workers/outbox.py app/workers/celery_app.py app/core/config.py tests/test_outbox.py tests/test_config.py` | | CON-02C | `app/modules/audit/*` | `app/modules/audit tests/test_audit.py` | | CON-03A | `app/modules/compensation/*` | `app/modules/compensation app/db/models.py tests/test_compensation.py alembic/versions/.py` | -| CON-03B | `app/modules/compensation/*` | `app/modules/compensation app/modules/projects/models.py app/db/models.py tests/test_compensation.py tests/test_projects.py alembic/versions/.py` | +| CON-03B | `app/modules/contributions/*` | `app/modules/contributions app/modules/projects/models.py app/db/models.py tests/test_contributions.py tests/test_projects.py alembic/versions/.py` | | CON-03C | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation app/db/models.py tests/test_contributions.py tests/test_compensation.py alembic/versions/.py` | | CON-03D | `app/modules/compensation/*` | `app/modules/compensation app/db/models.py tests/test_compensation.py alembic/versions/.py` | | CON-04A | `app/modules/compensation/*` | `app/modules/compensation app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | -| CON-04B | `app/modules/compensation/*` | `app/modules/compensation app/modules/projects/repository.py app/composition/compensation.py tests/test_compensation.py tests/test_projects.py tests/test_authorization.py tests/test_api_contract_e2e.py` | -| CON-05A | `app/modules/compensation/*`; `app/modules/projects/*`; `app/modules/tasks/*`; `app/modules/checkers/*` | `app/modules/compensation app/modules/projects app/modules/tasks app/modules/checkers app/db/models.py tests/test_compensation.py tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_authorization.py tests/test_alembic.py tests/test_api_contract_e2e.py alembic/versions/.py` | +| CON-04B | `app/modules/contributions/*` | `app/modules/contributions app/modules/projects/repository.py app/composition/contributions.py tests/test_contributions.py tests/test_projects.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-05A | `app/modules/contributions/*`; `app/modules/projects/*`; `app/modules/tasks/*`; `app/modules/checkers/*` | `app/modules/contributions app/modules/projects app/modules/tasks app/modules/checkers app/db/models.py tests/test_contributions.py tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_authorization.py tests/test_alembic.py tests/test_api_contract_e2e.py alembic/versions/.py` | | CON-05B | `app/modules/projects/models.py`; `app/modules/tasks/models.py`; `app/modules/checkers/models.py`; `app/db/models.py` | `app/modules/projects/models.py app/modules/tasks/models.py app/modules/checkers/models.py app/db/models.py tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_alembic.py alembic/versions/.py` | -| CON-06 | `app/modules/compensation/*` | `app/modules/compensation tests/test_compensation.py tests/test_authorization.py` | +| CON-06 | `app/modules/contributions/*` | `app/modules/contributions tests/test_contributions.py tests/test_authorization.py` | | CON-07 | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py` | | CON-08A | `app/modules/compensation/*`; `app/workers/compensation.py`; `app/interfaces/compensation.py`; `app/adapters/compensation/*` | `app/interfaces/compensation.py app/adapters/compensation app/modules/compensation app/modules/outbox/handlers.py app/workers/compensation.py app/workers/celery_app.py app/composition/compensation.py tests/test_compensation.py tests/test_outbox.py tests/test_external_service_adapters.py` | | CON-08R | `app/modules/api_controls/*`; `app/api/deps/api_controls.py`; `app/core/config.py` | `app/modules/api_controls app/api/deps/api_controls.py app/core/config.py tests/test_api_rate_controls.py tests/test_config.py tests/test_alembic.py alembic/versions/.py` | | CON-08B | `app/modules/compensation/*` | `app/modules/compensation app/api/internal_compensation.py app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | -| CON-09A | `app/modules/contributions/*`; `app/workers/contribution_evidence.py` | `app/modules/contributions app/modules/outbox/handlers.py app/workers/contribution_evidence.py app/workers/celery_app.py tests/test_contributions.py tests/test_artifacts.py tests/test_outbox.py` | -| CON-09B | `app/modules/contributions/*` | `app/modules/contributions app/api/internal_contributions.py app/composition/contributions.py tests/test_contributions.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-09A (optional) | Defined only by a separately approved refreshed contract | Do not execute from this table alone | +| CON-09B (optional) | Defined only by a separately approved refreshed contract | Do not execute from this table alone | | CON-10A | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation app/api/internal_contributions.py app/api/internal_compensation.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | | CON-10B | `app/modules/contributions/*`; `app/modules/compensation/*`; `app/modules/audit/*` | `app/modules/contributions app/modules/compensation app/modules/audit app/api/internal_operations.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py tests/test_audit.py` | -| CON-11 | `app/modules/contributions/*`; `app/modules/compensation/*`; `app/modules/outbox/*`; `app/modules/audit/*`; `app/modules/api_controls/*`; `app/api/deps/api_controls.py`; `app/core/config.py`; `app/modules/projects/*`; `app/modules/tasks/*`; `app/modules/checkers/*`; `app/interfaces/compensation.py`; `app/adapters/compensation/*`; `app/workers/outbox.py`; `app/workers/compensation.py`; `app/workers/contribution_evidence.py`; `app/composition/contributions.py`; `app/composition/compensation.py`; `app/composition/outbox.py`; `app/api/internal_contributions.py`; `app/api/internal_compensation.py`; `app/api/internal_operations.py` | `app/composition/contributions.py app/composition/compensation.py app/composition/outbox.py tests/test_api_contract_e2e.py tests/test_authorization.py tests/test_contributions.py tests/test_compensation.py tests/test_outbox.py tests/test_audit.py` | +| CON-10C | `app/modules/contributions/*`; `app/modules/compensation/*`; `app/workers/contributions.py`; `app/workers/compensation.py` | `app/modules/contributions app/modules/compensation app/modules/outbox/handlers.py app/workers/contributions.py app/workers/compensation.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_outbox.py tests/test_authorization.py` | +| CON-11 | `app/modules/contributions/*`; `app/modules/compensation/*`; `app/modules/outbox/*`; `app/modules/audit/*`; `app/modules/api_controls/*`; `app/api/deps/api_controls.py`; `app/core/config.py`; `app/modules/projects/*`; `app/modules/tasks/*`; `app/modules/checkers/*`; `app/interfaces/compensation.py`; `app/adapters/compensation/*`; `app/workers/outbox.py`; `app/workers/contributions.py`; `app/workers/compensation.py`; `app/composition/contributions.py`; `app/composition/compensation.py`; `app/composition/outbox.py`; `app/api/internal_contributions.py`; `app/api/internal_compensation.py`; `app/api/internal_operations.py` | `app/composition/contributions.py app/composition/compensation.py app/composition/outbox.py tests/test_api_contract_e2e.py tests/test_authorization.py tests/test_contributions.py tests/test_compensation.py tests/test_outbox.py tests/test_audit.py` | If a named path differs after prerequisite merges, the chunk stops and its contract is re-reviewed; it may not silently broaden a glob or skip the target. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md index 440c91e1..af43cc7f 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -1,23 +1,31 @@ # Source Manifest: WS-CON-001 Contribution Record And Compensation Boundary -## Primary revised inputs under review +## Reference inputs | File | SHA-256 | Status | |---|---|---| -| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md` | `cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640` | Editable reconciled working transcription derived from generation-2 PDF; not archival and not canonically adopted | -| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf` | `ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457` | Revised archival companion; text extracted and structurally inspected; not a reproducible Markdown build contract | +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md` | `cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640` | Working transcription; not canonical | +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf` | `ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457` | Revised archival input; not runtime authority | +| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf` | `34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1` | Original archival input; pre-existing user deletion remains untouched | -## Original immutable input +## Trusted baseline -| File | SHA-256 | Status | -|---|---|---| -| `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf` | `34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1` | First archival generation supplied 2026-07-11; currently deleted in the pre-existing user worktree and not modified/restored by this audit | +- `origin/main` / merged PR #139 at + `5d353b6d3f8a36b9b9ffdc1959487a150ac25fd1`. +- PR #139 title: `ws-xint-001-boundary-reconciliation` / AUTH, ART, REV, and + CON lifecycle boundary reconciliation. +- Runtime AUTH remains 74 PermissionIds, 57 ActionIds, nine active, 48 planned. +- PR #139 changed planning/canonical docs/scanners, not runtime CON behavior or + action availability. -## Normative repository constraints +## Normative repository sources - `AGENTS.md` - `README.md` +- `docs/glossary.md` - `docs/architecture_lockdown.md` +- `docs/architecture_data_model.md` +- `docs/architecture_lifecycle_state_machine.md` - `docs/decision_0005_postgres_is_the_record_database.md` - `docs/decision_0007_async_first_execution.md` - `docs/decision_0009_review_decisions_are_canonical.md` @@ -25,61 +33,38 @@ - `docs/decision_0012_workstream_authorization_service.md` - `docs/decision_0013_immutable_artifact_storage_boundary.md` - `docs/decision_0014_external_service_adapter_convention.md` +- `docs/decision_0015_project_contributor_roles_are_independent.md` - `docs/spec_authorization_service.md` - `docs/spec_artifact_storage_service.md` - `.agent-loop/policies/*` -## Parallel dependency sources inspected +## Normative WS-XINT handoffs + +- `WS-XINT-001/REV_CON_HANDOFF.md`: core contribution participant, frozen + ContributionPolicyVersion, no core ART dependency. +- `WS-XINT-001/AUTH_ROLE_SERVICE_HANDOFF.md`: independent project grants, + fixed-service static matrix, AUTH-09E admission. +- `WS-XINT-001/AUTH_REV_HANDOFF.md`: complete REV activation-custody and hidden + behavior choreography. +- `WS-XINT-001/AUTH_ART_HANDOFF.md`: complete 25-action ART custody transfer; + referenced only, not a core CON dependency. +- `WS-XINT-001/DECISIONS.md`: D1-D13 ownership and transaction rules. -- trusted authorization worktree and `origin/main` at - `9a04434e2f23c5dec8939dadb943bba4d85110c0`, which merges ART-02A2 through PR - #129 and includes AUTH-08 merge `aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3` -- merged AUTH-08 implementation lineage through `0832358`, now canonical on - trusted `main`: 74 PermissionIds, 57 ActionIds, exactly nine active self/admin - actions, 48 planned actions, eight closed resource-context variants, - actor-self/AdminRoleGrant matched authority, complete resource-context digest - and matched grant/scope decision evidence, explicit feature-route commit - ownership, and no WS-CON ActionIds or service-only dispatch/fulfillment - permissions -- merged `backend/app/modules/authorization/policy.py`, whose exact role matrix - confirms Finance Authority has `compensation.delivery.reconcile`, Operator - does not, and Project Manager has the broader `compensation.award.read` - candidate. These facts create the unresolved D11 human decision and only its - chosen AUTH amendment/evaluator or CON-01 matrix-update gates; they are not - copied into CON runtime. -- merged ART-02A2 final branch head - `32aab89262a3944f305e9e5dc4c65a2d31e2e144`: inactive - `ArtifactPreparationService`, `ArtifactScratchManager`, `PreparedArtifact` - and `CommittedArtifactSource`; no ArtifactStore v2 cutover, S3/MinIO, - admission, verification, contribution capability, action or permission -- merged AUTH catalogue assigns eight Operator-facing and three internal - artifact actions to `ActionOwner.ART_02D`; their existing PermissionId - mappings are unchanged. Because `ActionOwner` currently owns activation, - contribution-evidence readiness now extends D12 with exact proposed - `AUTH_ART_02D_OPERATOR` and `AUTH_ART_02D_INTERNAL` custody rather than - allowing ART/CON to write availability. -- clean trusted authorization worktree `/home/abiorh/flow/workstream-authorization-service/` - at `9a04434e2f23c5dec8939dadb943bba4d85110c0` -- active sibling REV worktree `/home/abiorh/flow/workstream-rev-001/`: reviewed - evidence-bound baseline `6faccc04e9dbad7c746b081e55a47750f678d37c` - was inspected, then later same-turn uncommitted external-review repairs were - observed. Its ART-02A2 classification is accurate, but no sibling path/head/ - dirty state is a durable dependency. Only a reviewed merge on trusted `main` - may be consumed, and it must repair REV-06/08 prepared authorization, REV-10 - final CON composition, D12 custody and dispatcher-owned outbox transitions. -- trusted `main` at `9a04434e2f23c5dec8939dadb943bba4d85110c0`, including merged - ADR 0014 from PR #127, AUTH-07A/07B from PRs #126/#130, and AUTH-08 scoped - administrative grants from PR #131 plus ART-02A2 from PR #129. The merge - commits and code are authoritative where authored initiative status still - describes its pre-merge branch state. +## Runtime observations -These sibling worktrees are discovery evidence, not dependencies by path. Every -implementation chunk consumes only contracts merged into trusted `main`. -The verification contract deliberately does not pin a live sibling head or -cleanliness because its authorized owner is working concurrently. +- Current code still contains the retired guide-bound economic schema; CON-05A + and 05B own semantic then physical removal after a human migration decision. +- No ContributionPolicy, ContributionRecord, CompensationAward, fulfillment, or + WS-CON action runtime exists yet. +- Existing `Submission` is the versioned identity; no new SubmissionVersion is + required. +- ART preparation from PR #129 is inactive foundation only and does not approve + optional contribution-evidence projection. +- Sibling worktrees are discovery evidence only. Implementation consumes only + reviewed contracts merged to trusted `main`. ## Adoption note -The revised pair contains valuable domain invariants but is not the repository's -active runtime contract. Chunk 01 will preserve both source generations and -write the reconciled active specification/ADR after explicit human approval. +The reference inputs contain useful invariants but do not override merged +repository decisions. CON-01 writes the active specification after explicit +approval and leaves archival inputs unchanged. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index e1e3453e..22ed14c4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,65 +2,54 @@ ## Current status -Base planning and its AUTH-07B/AUTH-08 reconciliations passed earlier review. -The branch is now rebased onto trusted main `9a04434`, which merges ART-02A2 PR -#129 and includes AUTH-08 at `aa0fdcd`. The ART delta reconciliation passed -fresh architecture/senior/reuse, QA/product/docs and security/auth review after -repairing preparation timing, continuation custody, exact ART/AUTH gates and -D12 closed-owner parity. Application code is unchanged. -The reconciled working Markdown transcription, supplied generation-2 PDF, -original archival PDF, current backend, active docs, merged WS-AUTH -authorization catalogue, and active parallel WS-REV plan delta have been mapped. - -The candidate cannot be canonically adopted as written because it conflicts -with `/api/v1`, the ActionId/PermissionId model, artifact-storage ownership and -providers, existing versioned `Submission`, and active payment architecture. +`WS-CON-001-PLAN` is being reconciled to trusted `main` `5d353b6`, which merged +WS-XINT-001 boundary reconciliation through PR #139. Runtime code is unchanged. +The prior plan is superseded where it used the older policy aggregate, made ART +evidence mandatory, described service action rows as persisted assignments, +allowed partial activation-custody transfer, or let outbox dispatch imply +feature-handler authority. + +## Corrected boundary + +- ContributionPolicyVersion and ContributionRule decide award eligibility. +- Core Review -> ContributionRecord/Award is one PostgreSQL transaction with no + ART call or evidence projection. +- Project grants are independently submitter/reviewer/adjudicator. +- Fixed services require closed ServiceIdentity, exact static matrix membership, + provisioned ActorProfile/link, AUTH-09E admission, and active action. +- ActionOwner is AUTH activation custody. Complete ART/REV transfers are + referenced from WS-XINT and not partially restated by CON. +- Outbox dispatch owns outbox mechanics only. Protected handlers need exact + independent authority. +- CON-09A/09B are deferred optional successors and do not gate the core release. ## Active chunk -`WS-CON-001-PLAN` only. The human approved complete PaymentPolicy removal on -2026-07-15. AUTH-08 proves that durable grant and permission candidacy still do -not activate a WS-CON action, so the plan keeps typed evaluators, exact per- -action role filters, principal truth, active availability and a prepared cross- -domain mutation protocol AUTH-owned. No implementation is active. - -## Chunk status - -| Chunk | Status | Branch | PR | Notes | -|---|---|---|---:|---| -| `WS-CON-001-PLAN` | Reviewed; D11/D12 human gates | `codex/ws-con-001-plan` | - | Approved D2 removal remains split into 05A/05B; reviewed refresh records PR #129 as inactive ART preparation only, exact ART/AUTH prerequisites and ownership, and treats concurrent REV work as non-consumable discovery until merged. | -| `WS-CON-001-01` | Proposed | - | - | No runtime work. | -| `WS-CON-001-02A` through `11` | Proposed | - | - | Each requires separate explicit start; REV-13 owns final activation. | +`WS-CON-001-PLAN` only. No implementation chunk is active. -## Blockers - -| Blocker | Owner | Next action | +| Chunk | Status | Notes | |---|---|---| -| Active-contract/archive handling approval | Human | Approve D1. | -| Legacy PaymentPolicy/task/assignment row handling | Human | Choose pre-production rebuild or an explicit classified backfill before 05A/05B; PaymentPolicy removal itself is approved. | -| Exact WS-CON executable authorization integration | WS-AUTH + human | Approve and implement registration, typed contexts/evaluators, matched authorities, grants/service assignments, prepared `T` protocol and active availability only in AUTH-owned chunks. | -| D11 AUTH/CON human-role conflicts | Human + WS-AUTH | Choose Operator delivery reconciliation, Project Manager award detail and WS-CON audit/export role sets. AUTH amends only chosen behavior that differs from its merged matrix; CON-01 updates the active contract before registration. | -| D12 ActionOwner/activation custody | Human + WS-AUTH | Approve exact AUTH-owned custody for 23 WS-CON, two coupled review and eleven existing ART-02D actions, or approve global feature-owner semantics plus a separate closed custody type with the same mappings. Do not register/activate with dual ownership. | -| Upstream `task.claim` ActionId is absent | WS-AUTH-001-13 or reviewed AUTH successor | Register/evaluate/activate `task.claim` against existing PermissionId before CON-05A integrates compensation freeze. | -| Contribution evidence typed capabilities | WS-ART + human | Create and approve the named `WS-ART-001-CON-EVIDENCE` write/read ports after 02D; write gates CON-09A, read gates CON-09B, and both gate CON-11. | -| ART provider/admission/verification/recovery chain remains incomplete | WS-ART + WS-AUTH | PR #129 supplies only 02A2 preparation. D12 must transfer all eleven ART-02D activation custodians; AUTH-09 must register fixed internal identities/assignments; ART must merge 02A3-02D hidden behavior; AUTH then separately activates Operator recovery and the three internal actions before the named contribution ports are ready. | -| ReviewLease/Review contracts | WS-REV | Merge owning persistence/behavior chunks at declared gates. | -| REV-06/08/10 authorization choreography predates the prepared-handle repair | WS-REV + WS-AUTH | Repair core claim/decision sites in REV-06/08 and final CON composition in REV-10 to AUTH registration -> CON capability/participant -> REV hidden planned-action composition -> AUTH activation; commit-bind and review before consumption. | -| Shared outbox | WS-CON-001-02A/B after approval | Land persistence and dispatcher before asynchronous integration. | -| REV reviewed baseline plus active external-review repairs remains non-consumable | WS-REV owner + human | Repair prepared authorization/activation choreography, D12 custody and dispatcher-owned outbox transitions, bind review, and merge; WS-CON does not pin the concurrent live worktree. | -| REV-12A draft assigns shared-outbox claim wording to the CON handler | WS-REV owner | Consume an already-claimed command and return a typed outcome; preserve CON-02B as sole outbox transition owner before sibling review/merge. | -| External publication | Human | Push or open a PR only after explicit direction; local review evidence does not authorize publication. | +| `WS-CON-001-PLAN` | Reconciliation and internal review in progress | Based on PR #139 / `5d353b6` | +| `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required | +| `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | -## Follow-ups +## Open gates -| Item | Source | Priority | -|---|---|---:| -| Re-read merged AUTH kernel plus later AUTH-09/10 service/project-grant state and each WS-CON evaluator gate at activation. | Trusted `main` | P1 | -| Re-read REV contracts at CON-03C/06/07 activation. | Parallel worktree | P1 | -| Re-read merged ART v2/admission/verification and named capability ports before CON-09A; do not treat 02A2 preparation as capability readiness. | ADR 0013/spec/trusted main | P1 | -| Decide pre-production row rebuild vs classified backfill. | Migration risk | P1 | +| Gate | Owner | Required action | +|---|---|---| +| Active specification/archive handling | Human | Approve CON-01 repository-owned specification | +| Pre-production legacy rows | Human | Choose deterministic rebuild or explicit classified migration before 05A/05B | +| D11 AdminRole candidates | Human + AUTH | Fix award-detail, delivery-recovery, and audit candidates before registration | +| Core WS-CON action registration/activation | AUTH | Add reviewed registration and later activation chunks; CON remains hidden | +| Fixed service runtime | AUTH | Complete AUTH-09A through 09E before protected service calls | +| Feature handler authority | Human + AUTH + CON | Approve exact identities/actions/static rows; no dispatcher inheritance | +| Repository loop-memory state | AUTH / merged-main owner | `check_loop_memory_state.py` currently fails on the unchanged AUTH status inherited from `origin/main`; WS-CON must not repair that external initiative file | +| task.claim | AUTH/task owner | Register/evaluate/activate with exact submitter grant before CON-05A | +| review.claim/review.decision | AUTH + REV + CON | Complete hidden participants/composition, full REV custody transfer, then AUTH activation | +| Shared outbox | CON-02A/B | Land generic persistence/dispatcher after approval | +| Joint release | REV + CON + AUTH | Consume exact hidden manifest; optional evidence and ART are not prerequisites | ## Stop condition -Do not edit runtime code or start `WS-CON-001-01` from this planning turn. -Present the plan, risks, and human decisions, then wait for explicit approval. +Do not edit runtime code, start CON-01, publish, push, or open a PR without +explicit human direction. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index 9d40a4e6..6b80c84e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -1,156 +1,73 @@ # Chunk Contract: WS-CON-001-01 - Canonical Contract Adoption And Architecture Decision -## Parent initiative - -`WS-CON-001` - Contribution Record And Compensation Boundary - ## Goal -Preserve both WS-CON archival generations and adopt one ADR-backed active -repository specification reconciled with AUTH, ART, REV, `/api/v1`, existing -Submission identity, and payment-policy reality. - -## Why this chunk exists - -The revised candidate contains correct domain intent and incorrect executable -contracts. Runtime chunks need one active source of truth before schema work. - -## Approved plan reference - -- `../INTENT.md` -- `../PLAN.md` -- `../CHUNK_MAP.md` +Publish one repository-owned active contribution/compensation specification and +Decision 0016 reconciled with WS-XINT, without editing or restoring archival +inputs. -## Risk class +## Risk -L0 architecture direction executed as an L1 specification chunk; SLA P1. +L0 direction executed as L1 specification work; SLA P1. ## Allowed files ```text -docs/reference_specs/README.md -docs/reference_specs/SHA256SUMS -docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf -docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md only for a byte-preserving rename -docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).md -docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf docs/spec_contribution_compensation.md -docs/decision_0015_contribution_compensation_boundary.md -README.md only for one active-spec link/precedence note -scripts/check_stale_authorization_docs.py only for the exact generation-2 - archival Markdown classification -scripts/test_agent_gates.py only for the exact archival-classification - fail-closed regression and the existing cross-scanner history-set assertion +docs/decision_0016_contribution_compensation_boundary.md +README.md only active-spec link/precedence note +active docs/templates explicitly inventoried by the chunk before review .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-01.json ``` -The original and second-generation reference bytes are allowed only for -restoration/filename normalization that preserves their recorded hashes; their -contents are not editable. - ## Not allowed ```text -backend runtime, migrations, backend tests, workflows, dependencies -AUTH/ART/REV owned specifications or catalogues -permission/action activation -roadmap or broad operational-doc rewrite +reference-spec bytes, names, checksums, or restoration +backend runtime, migrations, tests, workflows, dependencies +AUTH/ART/REV owned specifications/catalogues or action activation +roadmap changes without synchronized local XLSX/CSV exports ``` ## Acceptance criteria -- [ ] Original PDF is restored at exact hash `34c433...66c1`. -- [ ] Revised candidate pair has distinct generation-2 names and exact recorded - hashes; the original eight checksum entries remain unchanged and additive - generation-2 provenance/checksums describe the pair without calling it - executable. The current Markdown path may only be deleted as one side of a - byte-preserving Git rename. -- [ ] Only after the byte-preserving rename and hash proof, the exact renamed - path - `docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).md` - is added to `HISTORICAL_PATHS` with an explicit immutable/reconciled archival - candidate rationale. The active `docs/spec_contribution_compensation.md` - remains scanned; the deleted unsuffixed working path is not allowlisted; and - arbitrary new documents or near-miss sibling filenames continue to fail - closed under gate regression tests. -- [ ] The existing authorization/artifact historical-set regression subtracts - only that named authorization-only path before comparing exact sets, then - separately proves the artifact scanner already classifies the renamed path as - historical through its `docs/reference_specs/` prefix. Do not edit the - artifact scanner or duplicate this path in its exact-path set. -- [ ] ADR 0015 resolves immutable contribution/award/receipt meaning, - PaymentPolicy versus CompensationPolicyVersion authority, external - fulfillment, shared outbox, review atomicity, and artifact ownership. -- [ ] ADR/spec defines the exact project setup handoff: Project Manager records - guide/business terms; Finance Authority creates a canonical adapter binding - and publishes the executable policy; new assignment/lease fails with stable - remediation when setup is absent, suspended, retired, contradictory, or - incomplete. Missing setup is never silently unpaid. -- [ ] ADR adopts complete PaymentPolicy removal: CON-05A atomically removes all - semantic consumers while cutting task claims to the frozen replacement; - CON-05B physically removes dead schema after the zero-consumer and approved - legacy-data gates pass. No advisory runtime/API fallback survives. -- [ ] Active spec uses `/api/v1`, existing `Submission`, AWS/MinIO/LocalStorage - roles, typed ART capabilities, and exact ActionId -> PermissionId language. -- [ ] Active spec contains no `WS-AUTH-001-A`, `review.decision.record`, - `artifact.recovery.request`, `artifact.recovery.execute`, `artifact.retrieve`, - `ArtifactStorePort`, production Flow Node/R2, or broad-permission removal. -- [ ] Active spec declares AUTH/ART/REV/outbox prerequisites and no local auth +- [ ] Decision number is 0016; 0015 remains independent project contributor + roles. +- [ ] Active spec defines ContributionPolicy/version/rules/award definitions, + ProjectCompensationAdapterBinding, ContributionRecord, CompensationAward, + fulfillment receipts/status, and shared outbox ownership. +- [ ] Retired guide-bound schema removal is complete and split across 05A/05B; + no alias/fallback survives. Missing ContributionPolicy setup is not silently + unpaid. +- [ ] Existing versioned Submission is retained. CON copies stabilized + artifact_hash lineage and performs no core ART/evidence operation. +- [ ] Optional evidence is clearly deferred with separate ART/AUTH approval and + is absent from the core release path. +- [ ] AUTH boundary matches PR #139: independent project grants, fixed-service + static matrix/AUTH-09E, prepared mutations, AUTH-only activation, complete + ART/REV custody references, and no service-row startup dependency. +- [ ] Active spec lists the proposed 22 core surface mappings using + `contribution.policy.*`; optional evidence is separate; protected handler + execution actions remain explicit human/AUTH gates until approved. +- [ ] Dispatcher authority is limited to outbox mechanics; delivery, + reconciliation, rebuild, and callback cannot inherit it. +- [ ] Exact D11 outcome and legacy-row decision are recorded before dependent implementation. -- [ ] Active spec reflects merged AUTH-08: 74 PermissionIds, 57 ActionIds, nine - active self/admin actions and 48 planned actions on reviewed main; every - WS-CON action remains absent until an AUTH-owned registration plus typed - evaluator/principal/transaction/availability gate merges. It defines D10's - prepared `T` protocol and the absent upstream `task.claim` ActionId gate - without authorizing CON to edit AUTH. It also records D11's human-approved - delivery/award/audit role outcomes and any required AUTH amendment without - treating broad permission candidacy or candidate narrowing as executable. -- [ ] D12 is human/AUTH-approved and the active spec lists one exact owner for - all 23 proposed actions plus the review claim/decision and eleven required - ART-02D custody amendments; it preserves exact ActionId/PermissionId mappings - and never conflates feature resource ownership with catalogue activation. In - the recommended transfer model the contract requires atomic removal of unused - `REV_08`/`ART_02D`; the global alternative keeps them only as feature owners - under a separate closed custody type. -- [ ] Required specification reviewers pass. -- [ ] `CONFORMANCE_MATRIX.md` maps every retained normative invariant to its - owning chunk, concrete behavioral case, and final evidence owner; no blanket - or unowned requirement remains. -- [ ] Every README-linked active document and generated companion containing - mutable PaymentRecord, accept-only/voidable contribution, automatic - reputation, or PaymentPolicy execution language is inventoried in the - conformance matrix. The scan also covers active templates and operations docs - even when not README-linked, and emits the exact REV-13 allowed-file inventory. - Historical review/reference evidence stays untouched. - -## Verification commands - -```bash -sha256sum -c docs/reference_specs/SHA256SUMS -python3 scripts/check_stale_authorization_docs.py -python3 scripts/check_stale_artifact_contracts.py -python3 scripts/test_agent_gates.py -python3 -m py_compile scripts/check_stale_authorization_docs.py scripts/test_agent_gates.py -python3 scripts/check_markdown_links.py -python3 scripts/check_stale_workstream_wording.py -rg -n '(^|[^[:alnum:]_/])/v1|WS-AUTH-001-A|review\.decision\.record|artifact\.recovery\.(request|execute)|artifact\.retrieve|ArtifactStorePort|production Flow Node' docs/spec_contribution_compensation.md -git diff --check -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, test-delta, and CI integrity. +- [ ] Public prefix is `/api/v1`; provider refs/credentials and settlement + ledgers are excluded. +- [ ] Conformance matrix maps every normative rule to a chunk/test/final gate. +- [ ] Archival inputs remain byte-for-byte untouched, including the user's + pre-existing deletion state. -## Human review focus +## Verification -ADR load-bearing decisions, archive provenance, the exact and fail-closed -historical-path classification, sole compensation authority, -ActionId/PermissionId mapping, and strict ownership exclusions. +Run all repository stale/link/agent gates, SHA verification for files actually +present, active-doc inventory checks, and git diff checks. Required reviewers: +senior, QA, security, product, architecture, docs, reuse, CI integrity, and test +delta when scanners/tests change. -## Stop conditions +## Stop -Stop if active adoption requires editing archival bytes, implementing AUTH/ART -behavior, or choosing a legacy-data migration not approved by the human. -Stop after merge/memory; do not start 02 automatically. +Stop after reviewed specification and merge memory. Do not start CON-02A +automatically. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md index 2eabdbec..7a6669ac 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md @@ -2,19 +2,22 @@ ## Goal and risk -Implement the one feature-neutral outbox dispatcher and operational recovery. -L1 worker/operations/infrastructure risk. +Implement feature-neutral claim/invoke/finalize, retry, dead-letter, replay, +retention, typed handler registry, claim validation, and drain observation. L1 +background-execution/operations/auth risk. ## Allowed files ```text -backend/app/modules/outbox/{models,schemas,repository,service,ports,dispatcher,handlers}.py -backend/app/workers/celery_app.py +backend/app/modules/outbox/** +backend/app/composition/outbox.py backend/app/workers/outbox.py -backend/app/core/config.py only bounded dispatcher settings +backend/app/workers/celery_app.py only dispatcher task registration +backend/app/core/config.py only bounded outbox/Celery/Redis settings backend/tests/test_outbox.py -backend/tests/test_config.py only dispatcher-setting coverage -docs/operations_outbox.md +backend/tests/test_config.py only exact new settings +backend/tests/test_authorization.py only exact boundary proof +docs/spec_shared_outbox.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-02B.json ``` @@ -22,68 +25,41 @@ docs/operations_outbox.md ## Not allowed ```text -backend/app/workers/async_runner.py or task_settings.py rewrites -feature callback/adapter, review or compensation behavior -second dispatcher/handler registry/async bridge/session factory/idempotency framework -dependency, workflow, test or coverage weakening +contribution, compensation, review, artifact, or provider semantics +protected feature-handler authority or provider I/O +AUTH implementation edits; dynamic registry/plugins; second outbox +test/coverage/CI weakening ``` ## Acceptance criteria -- [ ] AUTH has registered planned `outbox.dispatch` with its new service-only - PermissionId, typed context contract, fixed `workstream.outbox.dispatcher` - ActorProfile/link, exact action assignment, and D10 prepared-mutation - protocol. This chunk keeps dispatcher execution disabled and proves the real - kernel denies while planned; only a later AUTH-owned evaluator/activation - change may enable it, and no human grant can execute dispatch. -- [ ] The dispatcher prepares authority from a server-resolved preliminary - event target before locking/claiming OutboxEvent, then evaluates the opaque - handle exactly once against final typed event/claim/lease/generation facts - recomposed from locked rows. It retains the one AuthorizationDecision in the - dispatch causation/audit path, never asks AUTH to commit, and rejects missing, - reused, mismatched, cross-session or cross-action handles. -- [ ] While the action is planned, success-path domain tests use only an - explicit decision/fake below that prepared seam. Real-kernel and worker tests - remain fail-closed; transaction tests cover prepare denial, stale claim, - final-context mismatch and both AUTH-first/product-lock race orders. -- [ ] One explicit handler registry, stable Celery task IDs, fenced claim, - attempt, retry schedule, dead-letter, replay, retention and bounded recovery - preserve immutable event identity. -- [ ] The shared dispatcher alone mutates outbox claim, lease/generation, - retry/dead-letter and finalization state. Feature handlers receive an already - claimed immutable command and return a typed success/retry/terminal outcome; - they never claim or directly transition the OutboxEvent. -- [ ] Claim reservation commits and releases its session and every row/database - lock before handler invocation. The immutable handler command carries exact - event/claim generation, but no live ORM row or caller session. -- [ ] A read-only same-session `OutboxClaimValidationPort` lets a handler verify - that exact generation after acquiring its lifecycle fence and before locking - feature rows. It never locks or mutates OutboxEvent state and exposes no - repository; the dispatcher revalidates again when applying the typed outcome. -- [ ] Reuse `run_async_task`, current fresh-engine/session-disposal worker - pattern, existing Celery include list and `sync_task_settings`; no second async - bridge, session factory, handler registry, scheduler, or idempotency framework. -- [ ] Crash-before/after handler, stale completion, duplicate task, retry - exhaustion and reason-bound replay are real-PostgreSQL tested. -- [ ] A feature-neutral same-session `OutboxDrainObservationPort` reports - bounded counts by exact registered event type/handler and closed delivery - states, including pending, claimed, retryable and handler-in-flight work. It - is read-only, never commits or invokes a handler, and exposes neither the - repository nor mutable outbox rows. -- [ ] Observation races claim, stale-claim recovery, retry, dead-letter and - finalization in both orders without false zero. Feature modules may compose - the port with their own canonical state but may not extend its status model or - query outbox persistence directly. -- [ ] Handler invocation occurs after commit; no feature event semantics or - compensation adapter is implemented here. -- [ ] The post-CON AUTH activation gate owns end-to-end central evaluator and - service-assignment proof against this merged seam without editing dispatcher - code. CON-08A and any worker enablement remain blocked until that gate merges. +- [ ] AUTH registers planned `outbox.dispatch` plus its PermissionId and AUTH + custodian, closed `workstream.outbox.dispatcher` ServiceIdentity with exact + singleton static row, controlled ActorProfile/link provisioning, AUTH-09E + admission, typed context, and prepared protocol. Hidden dispatcher remains + disabled until later AUTH evaluator integration/activation. +- [ ] Dispatcher claims with lease/generation fencing, commits and releases all + locks before invoking a handler, and alone applies typed outcomes to retry/ + dead-letter/final state. +- [ ] Handler receives immutable event/payload/idempotency/claim generation and + validates it through OutboxClaimValidationPort. It cannot lock or mutate the + OutboxEvent. +- [ ] Dispatcher authority permits claim/invoke/finalize only. Tests deny every + contribution, compensation, ART, REV, callback, provider, reconciliation, or + projection action; a feature handler cannot borrow outbox.dispatch. +- [ ] Each protected handler must present its independently approved AUTH + service context/action. Registration rejects handlers lacking that manifest. +- [ ] Stable Celery task IDs, bounded leases, retry/dead-letter/replay, + deterministic backoff, cancellation, crash recovery, and retention are + covered with isolated PostgreSQL/Redis proof. +- [ ] Same-session drain observation counts pending/claimed/retryable/in-flight + work without repository leakage or false zero. +- [ ] Missing provisioned dispatcher rows deny dispatch/readiness but do not + fail app startup or administrative provisioning. +- [ ] Changed subsystem coverage is at least 90 percent; global floor 78. -## Verification and reviewers +## Review and stop -Execute the exact CON-02B expansion in `../RUNTIME_VERIFICATION.md`. Same-run -changed-subsystem coverage is at -least 90 percent. All baseline tracks plus architecture, security/auth, -product/ops, docs, reuse/dedup, test-delta and CI integrity. Stop before feature -handlers. +Required tracks include all baseline, architecture, security, product, docs, +reuse, CI integrity, and test-delta. Stop after hidden dispatcher; do not enable +feature execution. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md index 3807f328..ceba8ed2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md @@ -21,7 +21,7 @@ docs/architecture_data_model.md only exact shared-audit ownership note ```text AuditEvent schema/migration rewrite review, contribution, compensation, task, AUTH or outbox event semantics -commit ownership, route, worker, dependency or CI weakening +commit ownership, route, background executor, dependency or CI weakening ``` ## Acceptance criteria diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md index da475230..dc54e53f 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03A-adapter-binding-persistence.md @@ -1,16 +1,16 @@ -# Chunk Contract: WS-CON-001-03A - Compensation Adapter-Binding Persistence +# Chunk Contract: WS-CON-001-03A - Project Compensation Adapter-Binding Persistence ## Goal and risk -Persist immutable binding identity/lifecycle without adapter behavior. L1 -payment/auth/data risk. +Persist immutable `ProjectCompensationAdapterBinding` identity/lifecycle +without adapter behavior. L1 economic/auth/data risk. ## Allowed files ```text backend/app/modules/compensation/{__init__,models,schemas,repository}.py backend/app/db/models.py -backend/alembic/versions/_compensation_adapter_bindings.py +backend/alembic/versions/_project_compensation_adapter_bindings.py backend/tests/{test_compensation,test_alembic}.py .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-03A.json @@ -19,25 +19,24 @@ backend/tests/{test_compensation,test_alembic}.py ## Not allowed ```text -AUTH actor/grant/action-assignment edits -adapter, route, worker, policy, award, receipt or delivery behavior +AUTH actor/grant/ServiceIdentity/static-matrix edits +adapter, route, background executor, policy, award, receipt or delivery behavior credentials, secrets, raw provider refs, dependency or CI weakening ``` ## Acceptance criteria -- [ ] Binding stores project, instrument, typed capability, canonical - `adapter_actor_id`, non-secret route identity, state/version and immutable - lifecycle timestamps; credentials/provider refs are impossible. +- [ ] Binding stores project, instrument, typed capability, canonical service + actor ID, non-secret route identity, state/version, and immutable lifecycle + timestamps; credentials/provider refs are impossible. - [ ] Composite constraints preserve project/instrument ownership and valid active/suspended/retired transitions. -- [ ] Schema supports the callback guard but creates no ActorProfile, grant, - action assignment, adapter, route, or delivery behavior. +- [ ] Schema supports callback guards but creates no ActorProfile, identity + link, ServiceIdentity, static row, adapter, route, or delivery behavior. - [ ] Upgrade/downgrade and duplicate/state races use isolated PostgreSQL. ## Verification and reviewers -Execute the exact CON-03A expansion in `../RUNTIME_VERIFICATION.md`; changed -compensation code is at least 90 percent. Senior engineering, QA/test, -security/auth, product/ops, architecture, docs, reuse/dedup and test-delta are -required. Stop after schema. +Execute CON-03A in `../RUNTIME_VERIFICATION.md`; changed compensation code is +at least 90 percent. Required tracks: senior, QA, security, product, +architecture, docs, reuse, and test-delta. Stop after schema. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md deleted file mode 100644 index 619562de..00000000 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-compensation-policy-persistence.md +++ /dev/null @@ -1,42 +0,0 @@ -# Chunk Contract: WS-CON-001-03B - Compensation Policy Persistence - -## Goal and risk - -Persist draft/published/retired policy versions and Project active selector -without commands. L1 payment/data risk. - -## Allowed files - -```text -backend/app/modules/compensation/{models,schemas,repository}.py -backend/app/modules/projects/models.py only active compensation selector -backend/app/db/models.py -backend/alembic/versions/_compensation_policy_versions.py -backend/tests/{test_compensation,test_projects,test_alembic}.py -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** -.agent-loop/merge-intents/WS-CON-001-03B.json -``` - -## Not allowed - -```text -service, route, claim, award, adapter, AUTH or ART behavior -PaymentPolicy fallback or historical-row rewrite -public API, worker, dependency or CI weakening -``` - -## Acceptance criteria - -- [ ] Exact decimals/currency/points, explicit unpaid, contribution matching, - binding IDs, provenance and immutable publication lifecycle are constrained; - at most one money plus one points award exists per rule. -- [ ] Active selector references one same-project published version; published - content is immutable; missing policy has no fallback. -- [ ] Legacy classification follows D2/CON-05 and rewrites no history. -- [ ] Upgrade/downgrade and selector/version races use isolated PostgreSQL. - -## Verification and reviewers - -Execute CON-03B in `../RUNTIME_VERIFICATION.md`; changed subsystems are at least -90 percent. Senior engineering, QA/test, security/auth, product/ops, -architecture, docs, reuse/dedup and test-delta are required. Stop after schema. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-contribution-policy-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-contribution-policy-persistence.md new file mode 100644 index 00000000..60395b8e --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03B-contribution-policy-persistence.md @@ -0,0 +1,47 @@ +# Chunk Contract: WS-CON-001-03B - Contribution Policy Persistence + +## Goal and risk + +Persist `ContributionPolicy`, immutable versions, exact rules, award +definitions, and one-active-policy-per-project without commands. L1 economic/ +data risk. + +## Allowed files + +```text +backend/app/modules/contributions/{models,schemas,repository}.py +backend/app/modules/projects/models.py only contribution-policy relationship +backend/app/db/models.py +backend/alembic/versions/_contribution_policy.py +backend/tests/{test_contributions,test_projects,test_alembic}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-03B.json +``` + +## Not allowed + +```text +service, route, claim, award result, adapter execution, AUTH or ART behavior +legacy fallback, alias, automatic conversion, or historical-row rewrite +public API, background executor, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] One active ContributionPolicy per project points to one same-project + published immutable ContributionPolicyVersion. +- [ ] Every publishable version has exactly one accepted_submission and one + completed_review ContributionRule; each is unpaid or compensated. +- [ ] Unpaid rules have no definition. Compensated rules have at least one and + at most two ContributionAwardDefinitions: at most one money and at most one + project_points definition, each with exact positive decimal/unit/binding/ + provenance constraints. +- [ ] Published/retired content is immutable; missing policy has no fallback. +- [ ] Legacy classification follows D2/CON-05 and rewrites no history. +- [ ] Upgrade/downgrade and selector/version races use isolated PostgreSQL. + +## Verification and reviewers + +Execute CON-03B in `../RUNTIME_VERIFICATION.md`; changed subsystems are at least +90 percent. Required tracks: senior, QA, security, product, architecture, docs, +reuse, and test-delta. Stop after schema. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md index 7b575a79..d109d93d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md @@ -2,8 +2,8 @@ ## Goal and risk -Persist immutable contribution/award truth against merged REV-03/REV-04 exact -targets. L1 history/payment risk. +Persist immutable contribution/award truth against exact merged Review, +ReviewLease, TaskAssignment, and Submission targets. L1 history/economic risk. ## Allowed files @@ -21,18 +21,32 @@ backend/tests/{test_contributions,test_compensation,test_alembic}.py ```text review model/service/composition edits -service, route, worker, receipt, artifact, reputation or PaymentRecord behavior +service, route, background executor, receipt, artifact, reputation or legacy accepted-work settlement row behavior mutable/void/delete/adjust path, dependency or CI weakening ``` ## Acceptance criteria -- [ ] Existing Submission is the version identity; exact project/review/lease/ - assignment/contributor lineage and immutable digests are constrained. -- [ ] DB enforces immutability/at-most-one but does not require a contribution - child for staged Review writes. +- [ ] Existing Submission is the version identity. Project/task/submission/ + Review/lease/assignment/contributor and stabilized artifact_hash lineage are + same-chain and non-null as applicable. +- [ ] Reviewer rows are completed_review and bind source Review + ReviewLease + + reviewer + reviewer-frozen policy. Submitter rows are accepted_submission, + bind accepted source Review + TaskAssignment + submitter + submitter-frozen + policy, and are impossible for needs_revision/reject. +- [ ] Exact database uniqueness on `(source_review_id, contribution_type)` + prevents duplicate contribution type for one source Review while allowing + distinct reviewer contributions for distinct revision Reviews. Contributor + identity is a validated lineage field, never part of this uniqueness key. +- [ ] Each award references the exact ContributionRecord, its frozen + ContributionPolicyVersion, matching rule/definition, same project/contributor/ + contribution type, and same-project/instrument adapter binding. +- [ ] Unique `(contribution_record_id, instrument_type)` enforces at most one + money and one project_points award; quantity is exact and positive. +- [ ] Database enforces immutability/at-most-one but does not require a + contribution child during staged Review persistence before CON-07 flushes. - [ ] At-least-one per valid Review is deferred to CON-07 + REV-10 + preflight. -- [ ] No mutable/void/delete/adjust path or PaymentRecord/reputation schema. +- [ ] No mutable/void/delete/adjust path or legacy accepted-work settlement row/reputation schema. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md index 81870d12..19ab83a4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md @@ -19,7 +19,7 @@ backend/tests/{test_compensation,test_alembic}.py ## Not allowed ```text -worker, callback, adapter, router or reconciliation behavior +background executor, callback, adapter, router or reconciliation behavior provider request/attempt/balance, points ledger or settlement data AUTH/ART edit, dependency or CI weakening ``` @@ -28,6 +28,10 @@ AUTH/ART edit, dependency or CI weakening - [ ] Immutable award/event/payload/binding/idempotency identities are retained; acknowledgement is not fulfillment; receipts are append-only and terminal. +- [ ] Closed stored values are exact: receipt `reported_status` is `fulfilled` + or `failed`; delivery status is `pending_delivery` or + `acknowledged_by_adapter`; fulfillment status is `pending`, `failed`, or + `fulfilled`. No synonym or provider status is persisted. - [ ] Delivery state durably represents fenced pre-I/O `in_flight` ownership, the originating dispatcher claim generation, retryable recovery and callback suppression without storing a provider payment attempt. Crash recovery cannot diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md index 488b96af..1150d552 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md @@ -31,12 +31,13 @@ concrete adapter, provider secret/ref, dependency or CI weakening - [ ] AUTH's registration checkpoint is merged: exact planned binding actions, typed context contracts, applicable AdminRoleGrant definitions and prepared `T` protocol, plus the planned `compensation.fulfillment.report` ActionId/new - PermissionId and an active canonical callback service ActorProfile/link with - its exact action assignment. Both binding and callback actions remain planned - and fail-closed. This chunk changes no AUTH file and uses only an explicit + PermissionId plus the human/AUTH-approved callback ServiceIdentity and exact + static action row, with controlled ActorProfile/link provisioning and + AUTH-09E admission. Both binding and callback actions remain planned and + fail-closed. This chunk changes no AUTH file and uses only an explicit test decision/fake below the authorization boundary for domain-success tests. -- [ ] Create validates canonical active service ActorProfile, exact AUTH-owned - action assignment and non-secret route identity. +- [ ] Create validates canonical active service ActorProfile/link, immutable + approved ServiceIdentity, exact static row, and non-secret route identity. - [ ] Mutations follow PLAN locks and transaction-revalidate authority; own-state concurrent suspend/resume is deterministic. They use the AUTH-prepared handle and evaluate it once against facts recomposed from locked binding/project rows. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md deleted file mode 100644 index d09a1ba8..00000000 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-compensation-policy-service.md +++ /dev/null @@ -1,59 +0,0 @@ -# Chunk Contract: WS-CON-001-04B - Hidden Compensation-Policy Service - -## Goal and risk - -Implement authorization-ready draft/read/update/publish/retire domain behavior -and canonical resource composition while routes remain unregistered and AUTH -actions remain planned. L1 payment/auth risk. - -## Allowed files - -```text -backend/app/modules/compensation/{schemas,repository,service}.py -backend/app/modules/projects/repository.py only active-selector locking -backend/app/composition/compensation.py -backend/tests/{test_compensation,test_projects,test_authorization,test_api_contract_e2e}.py -docs/spec_contribution_compensation.md -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** -.agent-loop/merge-intents/WS-CON-001-04B.json -``` - -## Not allowed - -```text -production router registration, task/review claim integration or awards -AUTH catalogue/grant/kernel edits, adapter/provider calls -PaymentPolicy fallback, dependency or CI weakening -``` - -## Acceptance criteria - -- [ ] AUTH's registration checkpoint is merged: exact planned policy actions, - typed context contracts, Finance Authority grant definitions and prepared - `T` protocol. Read maps to `compensation.policy.manage`, never broad - `project.read`. This chunk changes no AUTH file, keeps the real kernel - fail-closed while planned, and uses only an explicit test decision/fake below - the authorization boundary for domain-success tests. -- [ ] Publish locks project/selector/version/bindings, revalidates authority, - validates closed rules/active bindings, and atomically changes selector with - audit/outbox. It evaluates one AUTH-prepared handle against facts recomposed - from those locked rows. -- [ ] The service accepts only an allowed decision whose complete resource- - context digest, matched AdminRoleGrant ID and covered project match the - locked policy facts; mismatched decision evidence is rejected. It flushes - and never commits. The later AUTH activation gate—not a CON role-aware - fake—proves Finance eligibility and every excluded/revoked/scope case. -- [ ] Explicit unpaid is valid; absent/incomplete/contradictory setup is stable - remediation failure; removed PaymentPolicy never executes or acts as fallback. -- [ ] Own-state concurrent draft/publish/retire/selector/binding changes are - deterministic. Claim races remain 05/06; delivery/callback races remain 08. -- [ ] Production OpenAPI remains unchanged. -- [ ] A later AUTH-owned gate integrates the central evaluators against this - merged composer and alone changes availability. CON-05A remains blocked until - that activation passes. - -## Verification and reviewers - -Execute CON-04B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 -percent. Senior engineering, QA/test, security/auth, product/ops, architecture, -docs, reuse/dedup and test-delta are required. Stop after hidden behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md new file mode 100644 index 00000000..72afe56e --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md @@ -0,0 +1,50 @@ +# Chunk Contract: WS-CON-001-04B - Hidden Contribution-Policy Service + +## Goal and risk + +Implement hidden read/draft/update/publish/retire ContributionPolicy behavior +and canonical resource composition while routes remain absent and AUTH actions +remain planned. L1 economic/auth risk. + +## Allowed files + +```text +backend/app/modules/contributions/{schemas,repository,service}.py +backend/app/modules/projects/repository.py only policy relationship locking +backend/app/composition/contributions.py +backend/tests/{test_contributions,test_projects,test_authorization,test_api_contract_e2e}.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-04B.json +``` + +## Not allowed + +```text +production router registration, task/review claim integration, award results +AUTH catalogue/grant/kernel/static-matrix edits, adapter/provider calls +legacy fallback, dependency or CI weakening +``` + +## Acceptance criteria + +- [ ] AUTH registration is merged for planned `contribution.policy.*` actions, + each mapped to stable `compensation.policy.manage`, with typed contexts, + Finance candidates, AUTH ActionOwner, and prepared T protocol. +- [ ] Publish locks project, active policy, version, rules, definitions, and + bindings; evaluates one prepared handle against recomposed final facts; and + atomically updates current_published_version_id with audit/outbox. +- [ ] Allowed decision evidence matches complete resource digest, grant ID, + project scope, request, and correlation. Service flushes and never commits. +- [ ] Explicit unpaid is valid. Missing/incomplete/contradictory setup is a + stable failure. No legacy authority executes. +- [ ] Concurrent draft/publish/retire/selector/binding changes are + deterministic. Production OpenAPI remains unchanged. +- [ ] AUTH later integrates exact evaluators and alone activates the actions; + CON-05A waits for activation. + +## Verification and reviewers + +Execute CON-04B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +percent. Required tracks: senior, QA, security, product, architecture, docs, +reuse, and test-delta. Stop after hidden behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md new file mode 100644 index 00000000..1e83b5b5 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md @@ -0,0 +1,70 @@ +# Chunk Contract: WS-CON-001-05A - Legacy Economic Terms Cutover And Task Freeze + +## Goal + +Remove the retired guide-bound economic contract from every semantic consumer, +classify existing rows, and freeze the active published +ContributionPolicyVersion on each successful new TaskAssignment. Physical dead- +schema removal belongs to 05B. + +## Risk + +L1 economic/task lifecycle/authorization; SLA P1. + +## Allowed files + +```text +backend/app/modules/contributions/{ports,service}.py +backend/app/modules/projects/{schemas,repository,service}.py only legacy consumer removal +backend/app/modules/tasks/{models,schemas,repository,service}.py only cutover/freeze +backend/app/modules/checkers/{schemas,repository,service,runner}.py only legacy consumer removal +backend/alembic/versions/_task_assignment_contribution_policy_freeze.py +backend/app/db/models.py +backend/tests/{test_contributions,test_projects,test_tasks,test_checkers,test_authorization,test_alembic,test_api_contract_e2e}.py +docs/spec_contribution_compensation.md +docs/architecture_data_model.md only exact implemented reconciliation +docs/operations_payment_reputation.md only implemented operations +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-05A.json +``` + +## Not allowed + +```text +task-claim permission/grant/kernel implementation +ReviewLease or Review behavior; contribution/award creation +public policy routes; dead physical schema removal +fallback, alias, automatic conversion, or guessed historical rewrite +provider/artifact calls; unrelated checker behavior +``` + +## Acceptance criteria + +- [ ] Every new TaskAssignment has immutable non-null + `submitter_contribution_policy_version_id`. +- [ ] Exact merged Submission.task_assignment_id lineage is preserved; no + parallel submission identity is added. +- [ ] No runtime/API/setup/task/checker/review consumer treats retired guide- + bound terms as current economic authority. A zero-consumer scanner proves + remaining physical schema is unreachable until 05B. +- [ ] `task.claim` is registered and active through AUTH with exact same-project + submitter ProjectRoleGrant, prepared T protocol, actor/link/grant + revalidation, and canonical task guards. No admin/adjudicator/reviewer grant + substitutes and CON contains no role logic. +- [ ] Claim locks active ContributionPolicy, published version, exact rule/ + definition/binding dependencies, evaluates the prepared handle once, and + copies one same-project published version. +- [ ] Missing/invalid policy fails with no assignment/task/audit/outbox partial + state. Later publication never updates an assignment. +- [ ] Publish versus claim and binding-state versus claim pass both lock orders + without deadlock or mixed versions. +- [ ] Existing rows follow the approved deterministic classification and cannot + enter new Review decisions without a valid freeze. Migration fails on + ambiguity and downgrade refuses post-cutover data loss. +- [ ] Changed subsystems remain at least 90 percent; global floor remains 78. + +## Review and stop + +Required tracks: senior, QA, security, product, architecture, docs, reuse, test- +delta, and CI integrity. Stop if exact task/Submission lineage, task.claim +authority, or migration classification is not merged. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md deleted file mode 100644 index 2a01fbb9..00000000 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-payment-policy-semantic-cutover-and-task-freeze.md +++ /dev/null @@ -1,129 +0,0 @@ -# Chunk Contract: WS-CON-001-05A - PaymentPolicy Semantic Consumer Cutover And Task Freeze - -## Parent initiative - -`WS-CON-001` - Contribution Record And Compensation Boundary - -## Goal - -Atomically remove PaymentPolicy from every runtime/API semantic consumer, -classify existing rows, and freeze the active published compensation version on -every successful new TaskAssignment. Physical schema removal belongs to 05B. - -## Why this chunk exists - -Submitter compensation must be known before work begins and must not drift when -the project changes policy later. - -## Approved plan reference - -- `../INTENT.md` -- `../PLAN.md` -- `../CHUNK_MAP.md` - -## Risk class - -L1 payment/task lifecycle/authorization; SLA P1. - -## Allowed files - -```text -backend/app/modules/compensation/ports.py -backend/app/modules/compensation/service.py -backend/app/modules/projects/{schemas,repository,service}.py only PaymentPolicy consumer removal -backend/app/modules/tasks/models.py -backend/app/modules/tasks/schemas.py only PaymentPolicy consumer removal/frozen-version API semantics -backend/app/modules/tasks/repository.py only exact cutover locking/classification -backend/app/modules/tasks/service.py only task-owned participant integration -backend/app/modules/checkers/{schemas,repository,service,runner}.py only PaymentPolicy consumer removal -backend/alembic/versions/_task_assignment_compensation_freeze.py -backend/app/db/models.py -backend/tests/test_compensation.py -backend/tests/test_projects.py -backend/tests/test_tasks.py -backend/tests/test_checkers.py -backend/tests/test_authorization.py only action/transaction proof -backend/tests/test_alembic.py -backend/tests/test_api_contract_e2e.py -docs/spec_contribution_compensation.md -docs/architecture_data_model.md only removed/canonical authority reconciliation -docs/operations_payment_reputation.md only setup/cutover operations -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** -.agent-loop/merge-intents/WS-CON-001-05A.json -``` - -## Not allowed - -```text -task claim permission/grant/kernel implementation -ReviewLease or Review behavior -contribution/award creation -public compensation routes -PaymentPolicy physical table/model/column removal, fallback, automatic conversion, or historical row rewrite -provider/artifact calls -review behavior or unrelated checker behavior -``` - -## Acceptance criteria - -- [ ] TaskAssignment has non-null immutable - `submitter_compensation_policy_version_id` for all new claims. -- [ ] Merged REV-02 has established exact non-null - `Submission.task_assignment_id` lineage and its accepted task-owned creation - contract; 05A preserves that lineage and introduces no parallel submission - ownership field. -- [ ] No runtime service, API schema/OpenAPI path, setup gate, task claim, - checker, review, or award consumer treats PaymentPolicy as current business - or economic authority; Finance publication is the only authority. CON-01 owns - the active specification inventory and REV-13 owns final joint release docs. -- [ ] A zero-consumer scanner proves the remaining PaymentPolicy model/table is - unreachable compatibility residue pending 05B, not an executable fallback. -- [ ] AUTH-13 or an approved AUTH successor has registered and activated the - currently absent ActionId `task.claim` mapped to existing PermissionId - `task.claim`, with its exact-project contributor evaluator and prepared `T` - protocol. WS-CON introduces no local role checks or AUTH edits. -- [ ] Claim follows the PLAN lock order, locks every referenced binding by UUID, - evaluates the AUTH-prepared task-claim handle once against final locked task/ - project/assignment facts, and copies one published same-project version whose - bindings are active. -- [ ] Missing/suspended/invalid policy fails with stable compensation error and - creates no assignment/task/audit/outbox partial state. -- [ ] Concurrent publish vs claim freezes one committed old or new version, - never a mixture and without deadlock in either permutation. -- [ ] Binding suspend/retire versus claim is proved in both permutations: new - work never freezes an inactive binding while already-frozen work is retained. -- [ ] Later policy change never updates the assignment. -- [ ] Legacy rows follow the approved migration classification and cannot enter - new Review decisions without a valid frozen ref. -- [ ] Deployment either drains all pre-cutover active assignments or executes - the explicitly approved deterministic rebuild; migration fails on ambiguity. - There is no intermediate deployment that changes economic meaning while - allowing unfrozen claims. -- [ ] Downgrade requires task claims and review intake disabled and refuses when - post-cutover assignments exist; rollback never silently drops a frozen ref. -- [ ] Changed subsystems remain >=90 percent; global floor remains >=78 percent. - -## Verification commands - -Execute the exact CON-05A expansion in `../RUNTIME_VERIFICATION.md`; same-run -changed compensation code is at least 90 percent and repository coverage at -least 78 percent. - -## Required reviewers - -Baseline plus architecture, security/auth, product/ops, docs, reuse/dedup, and -test-delta. - -## Human review focus - -Atomic semantic-consumer/claim cutover, exact freeze timing, auth/lock order, -policy/binding races, legacy drain/rebuild, rollback, and no PaymentPolicy -fallback. - -## Stop conditions - -Stop if merged REV-02 does not expose its exact reviewed -`Submission.task_assignment_id` lineage, AUTH task-claim cutover is incomplete, -TaskService cannot accept the participant within the listed files, or the lock -order conflicts with merged REV/ART/AUTH. Any future composition path requires -contract amendment and a new internal review before implementation. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md new file mode 100644 index 00000000..4382065f --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md @@ -0,0 +1,46 @@ +# Chunk Contract: WS-CON-001-05B - Legacy Economic Schema Removal + +## Goal and risk + +Delete the now-unreachable guide-bound economic model, tables, columns, +constraints, and compatibility code after 05A proves zero semantic consumers. +L1 migration/historical-data risk. + +## Allowed files + +```text +backend/app/modules/projects/{models,schemas,repository,service}.py only dead schema removal +backend/app/modules/tasks/{models,schemas,repository,service}.py only dead references +backend/app/modules/checkers/{models,schemas,repository,service,runner}.py only dead references +backend/app/db/models.py +backend/alembic/versions/_remove_legacy_project_economic_schema.py +backend/tests/{test_projects,test_tasks,test_checkers,test_alembic,test_api_contract_e2e}.py +docs/{architecture_data_model,operations_payment_reputation,spec_contribution_compensation}.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-05B.json +``` + +## Not allowed + +```text +new ContributionPolicy/award behavior or inferred backfill +ReviewLease/Review/contribution/award behavior +AUTH, ART, provider, frontend, dependency or CI changes +``` + +## Acceptance criteria + +- [ ] 05A zero-consumer proof still passes on current trusted main. +- [ ] Approved classification drains/rebuilds or explicitly maps every row; + ambiguous meaning fails migration and never guesses a policy version. +- [ ] Dead model/tables/columns/FKs/indexes and API/OpenAPI references are absent + after upgrade; ContributionPolicy and frozen references remain valid. +- [ ] Downgrade is data-loss aware, requires intake disabled, and never revives + the removed schema as executable authority. +- [ ] PostgreSQL upgrade/downgrade and fresh install pass; changed code remains + at least 90 percent and repository coverage at least 78 percent. + +## Review and stop + +Required tracks: senior, QA, security, product, architecture, docs, reuse, test- +delta, and CI integrity. Stop before CON-06. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md deleted file mode 100644 index a1a1dea5..00000000 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-payment-policy-physical-schema-removal.md +++ /dev/null @@ -1,48 +0,0 @@ -# Chunk Contract: WS-CON-001-05B - PaymentPolicy Physical Schema Removal - -## Goal and risk - -Delete the now-unreachable PaymentPolicy model, table, columns, constraints, -and compatibility code after 05A proves there are zero semantic consumers. L1 -migration and historical-data risk. - -## Allowed files - -```text -backend/app/modules/projects/{models,schemas,repository,service}.py only dead PaymentPolicy removal -backend/app/modules/tasks/{models,schemas,repository,service}.py only dead references -backend/app/modules/checkers/{models,schemas,repository,service,runner}.py only dead references -backend/app/db/models.py -backend/alembic/versions/_remove_payment_policy.py -backend/tests/{test_projects,test_tasks,test_checkers,test_alembic,test_api_contract_e2e}.py -docs/{architecture_data_model,operations_payment_reputation,spec_contribution_compensation}.md -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** -.agent-loop/merge-intents/WS-CON-001-05B.json -``` - -## Not allowed - -```text -new compensation behavior, policy conversion or inferred backfill -ReviewLease/Review/contribution/award behavior -AUTH, ART, provider, frontend, dependency or CI changes -``` - -## Acceptance criteria - -- [ ] Exact zero-consumer scan from 05A still passes on current trusted main. -- [ ] Approved legacy classification drains, resets, or deterministically - migrates every row; ambiguous economic meaning fails migration and never - guesses a CompensationPolicyVersion. -- [ ] PaymentPolicy model/table/columns/FKs/indexes and API/OpenAPI references - are absent after upgrade; active compensation/frozen references remain valid. -- [ ] Downgrade is explicitly data-loss aware, requires intake disabled, and - never recreates PaymentPolicy as executable authority. -- [ ] PostgreSQL upgrade/downgrade and fresh-install schema tests pass; changed - code remains at least 90 percent and repository coverage at least 78 percent. - -## Verification and reviewers - -Execute CON-05B in `../RUNTIME_VERIFICATION.md`. Senior engineering, QA/test, -security/auth, product/ops, architecture, docs, reuse/dedup, test-delta and CI -integrity are required. Stop before CON-06. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md deleted file mode 100644 index d8baa1d8..00000000 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-compensation-freeze.md +++ /dev/null @@ -1,90 +0,0 @@ -# Chunk Contract: WS-CON-001-06 - ReviewLease Compensation Freeze Participant - -## Parent initiative - -`WS-CON-001` - Contribution Record And Compensation Boundary - -## Goal - -Deliver and independently prove the narrow WS-CON compensation lookup/freeze -participant that REV-06 will invoke with canonical caller-supplied project and -binding facts inside the review-claim transaction. - -## Why this chunk exists - -Reviewer compensation must be fixed before review work begins and cannot depend -on the later decision outcome or current policy at decision time. - -## Approved plan reference - -- `../INTENT.md` -- `../PLAN.md` -- `../CHUNK_MAP.md` - -## Risk class - -L1 payment/review lifecycle/authorization; SLA P1. - -## Allowed files - -```text -backend/app/modules/compensation/ports.py -backend/app/modules/compensation/service.py -backend/tests/test_compensation.py -backend/tests/test_authorization.py only action/transaction proof -docs/spec_contribution_compensation.md -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** -.agent-loop/merge-intents/WS-CON-001-06.json -``` - -## Not allowed - -```text -review claim/queue/lease policy invention -review models, migrations, services, routes, or composition -AUTH catalogue/grants/kernel changes -review decision or contribution/award creation -task assignment freeze changes -provider/artifact/adapter calls -``` - -## Acceptance criteria - -- [ ] Port accepts caller AsyncSession plus canonical project/claim facts, - follows PLAN lock order, locks referenced bindings by UUID, returns one - published same-project version, flushes nothing outside its ownership, and - never commits. -- [ ] Missing/inactive/invalid policy or binding returns stable typed failure - with no WS-CON/audit/outbox partial state. -- [ ] Contract explicitly requires REV-03's immutable non-null ReviewLease FK - plus AUTH's planned `review.claim` typed/prepared contract and REV-06's hidden - resource composition, final-context integration, injection, lease write, - audit/outbox, release/expiry behavior, and planned-action fail-closed tests; - CON-06 implements none of them. After both merge, AUTH alone integrates the - evaluator and activates the action before production execution. -- [ ] Policy publish vs claim concurrency freezes one committed version and - passes both lock permutations without deadlock. -- [ ] Binding suspend/retire versus lookup is covered in both permutations. -- [ ] Reviewer award behavior is not implemented here. -- [ ] Changed modules remain >=90 percent; global floor stays >=78 percent. - -## Verification commands - -Execute the exact CON-06 expansion in `../RUNTIME_VERIFICATION.md`; the same run -proves changed compensation code at least 90 percent. - -## Required reviewers - -Baseline plus architecture, security/auth, product/ops, docs, reuse/dedup, and -test-delta. - -## Human review focus - -Exact lease freeze timing, REV ownership, review.claim authority, no -decision-dependent rate, lock ordering, and no contribution on incomplete lease. - -## Stop conditions - -Stop if REV-03's exact caller facts/FK contract is not merged or if any review -schema, claim wiring, or composition edit would move into WS-CON. REV-06, not -this chunk, owns integrated claim behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md new file mode 100644 index 00000000..3b680bde --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md @@ -0,0 +1,52 @@ +# Chunk Contract: WS-CON-001-06 - ReviewLease Contribution-Policy Freeze Participant + +## Goal + +Deliver the narrow CON policy lookup/freeze participant that REV invokes inside +the review-claim transaction. Reviewer award eligibility is frozen before +review work begins. + +## Risk + +L1 economic/review lifecycle/authorization; SLA P1. + +## Allowed files + +```text +backend/app/modules/contributions/{ports,service}.py +backend/tests/{test_contributions,test_authorization}.py +docs/spec_contribution_compensation.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-06.json +``` + +## Not allowed + +```text +review queue/lease policy, model, migration, service, route, or composition +AUTH catalogue/grant/kernel changes; review decision or award creation +task assignment changes; provider/artifact/adapter calls +``` + +## Acceptance criteria + +- [ ] Port accepts caller AsyncSession and canonical locked project/claim facts, + locks one active ContributionPolicy and published version plus referenced + definitions/bindings, returns the exact version ID, and never commits. +- [ ] Missing/inactive/invalid policy or binding returns stable failure with no + CON/audit/outbox partial state. +- [ ] REV-owned ReviewLease has immutable non-null + `reviewer_contribution_policy_version_id` and REV owns its write/wiring. +- [ ] review.claim uses exact active same-project reviewer ProjectRoleGrant; + submitter/adjudicator/admin grants do not substitute. No-self-review and REV + lifecycle guards remain REV-owned. +- [ ] CON hidden port and REV hidden composition merge while review.claim + remains planned; AUTH later integrates the evaluator and alone activates. +- [ ] Policy publish and binding state versus claim pass both lock orders; + changed modules stay at least 90 percent and global floor stays 78. + +## Review and stop + +Required tracks: senior, QA, security, product, architecture, docs, reuse, and +test-delta. Stop if REV lease schema/caller facts or review.claim authority are +not merged. CON owns no review composition. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md index a62af8d2..1f74aa0b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md @@ -1,43 +1,22 @@ # Chunk Contract: WS-CON-001-07 - Atomic Review Contribution And Award Participant -## Parent initiative - -`WS-CON-001` - Contribution Record And Compensation Boundary - ## Goal -Implement the mandatory database-local participant that creates reviewer and -accept-only submitter contributions, deterministic awards, pending evidence -projections, audit, and outbox events in the caller-owned Review transaction. - -## Why this chunk exists - -Contribution recognition must never lag behind or disagree with a committed -human Review, and no external system can participate in that atomic commit. +Implement the mandatory flush-only participant that creates reviewer and +accept-only submitter contributions, evaluates frozen ContributionRules, creates +applicable awards, and stages audit/outbox rows in the caller-owned Review +transaction. It performs no evidence projection or ART work. -## Approved plan reference +## Risk -- `../INTENT.md` -- `../PLAN.md` -- `../CHUNK_MAP.md` - -## Risk class - -L1 payment/canonical judgment/cross-domain transaction; SLA P1. +L1 economic/canonical-judgment/cross-domain transaction; SLA P1. ## Allowed files ```text -backend/app/modules/contributions/schemas.py -backend/app/modules/contributions/repository.py -backend/app/modules/contributions/service.py -backend/app/modules/compensation/repository.py -backend/app/modules/compensation/service.py -backend/app/modules/compensation/ports.py -backend/tests/test_contributions.py -backend/tests/test_compensation.py -backend/tests/test_authorization.py only decision-causation evidence proof -backend/tests/test_outbox.py +backend/app/modules/contributions/{schemas,repository,service,ports}.py +backend/app/modules/compensation/{repository,service}.py +backend/tests/{test_contributions,test_compensation,test_authorization,test_outbox}.py docs/spec_contribution_compensation.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-07.json @@ -46,69 +25,60 @@ docs/spec_contribution_compensation.md ## Not allowed ```text -Review decision/transition policy in contribution code -review service, model, route, or composition wiring -public route registration -ContributionRecordRequested compatibility event -AUTH catalogue/grants/kernel edits or new materialize permissions -external adapter, broker, or artifact provider calls -mutable/delete/void/adjust contribution/award path -reputation scoring +Review policy/model/service/route/composition wiring or commit +public route registration; optional/no-op participant +AUTH catalogue/grant/kernel edits or materialize actions +ART capability/repository/provider call or evidence projection row/event +mutable/delete/void/adjust contribution/award path; reputation scoring ``` -## Acceptance criteria +## Participant request -- [ ] Every committed Review creates exactly one reviewer - `completed_review`; `accept` additionally creates one submitter - `accepted_submission`; needs_revision/reject create none for submitter. -- [ ] Existing Submission/assignment/lease/Review/project/contributor chains and - immutable artifact digest are exact and DB-validated. -- [ ] Reviewer awards use lease-frozen version and are decision-neutral; - submitter awards use assignment-frozen version; explicit unpaid creates none. -- [ ] Participant uses caller AsyncSession, flushes, never commits, and retains - originating `review.decision` AuthorizationDecision as causation. -- [ ] Participant accepts only a typed allowed `review.decision` whose actor, - action, Review/lease/Submission/project resource, request, and correlation - facts match the locked caller transaction; denied, stale, unrelated, or - mismatched evidence is rejected. AUTH first supplies the planned - `review.decision` typed/prepared contract; REV-10 then owns hidden resource - composition, final-context integration and mandatory injection while the real - kernel remains fail-closed. After both merge, AUTH alone integrates the - evaluator and activates the action before production execution. -- [ ] Each contribution creates one pending evidence projection and one stable - projection request event in the same transaction. -- [ ] Versioned `ContributionRecorded`, `CompensationAwardCreated`, - `CompensationFulfillmentRequested`, and - `ContributionEvidenceProjectionRequested` use the shared outbox with - deterministic IDs/digests and no sensitive/provider data. These exact tokens - are feature-owned; the generic outbox never aliases them. -- [ ] Direct participant fault injection proves its contribution/award/audit/ - outbox writes roll back with the caller transaction. REV-10 owns cross-domain - Review/task/lease rollback and hidden-composition proof. -- [ ] Exact replay returns one logical set; changed/concurrent replay conflicts - cleanly; no optional/no-op production participant exists. -- [ ] Claims/releases/expiry/revocation/admin closure/artifact failure create no - contribution or award. -- [ ] No production composition or OpenAPI changes; new/changed modules >=90 - percent and global floor >=78 percent. +The typed request carries the caller AsyncSession and exact locked: -## Verification commands +- Review, ReviewLease, queue/lifecycle fence, and canonical decision; +- versioned Submission, TaskAssignment, task, and project; +- reviewer/submitter ActorProfile IDs; +- reviewer and submitter frozen ContributionPolicyVersion IDs; +- server-derived stabilized `Submission.artifact_hash`/reviewed-packet digest + from the merged REV/Submission lineage, never caller package data; +- originating review.decision AuthorizationDecision, request, and correlation. -Execute the exact CON-07 expansion in `../RUNTIME_VERIFICATION.md`; the same run -proves each changed subsystem at least 90 percent. - -## Required reviewers - -Baseline plus architecture, security/auth, product/ops, docs, reuse/dedup, and -test-delta. - -## Human review focus - -Creation matrix, exact frozen sources, no current-policy lookup, atomic rollback, -decision causation, replay/concurrency, and the explicit REV-10 integration -handoff. - -## Stop conditions +## Acceptance criteria -Stop if REV decision/revision schemas are not stable, shared audit/outbox cannot -join caller transaction, or any external call is required before commit. +- [ ] Every valid committed Review creates exactly one reviewer + `completed_review`; accept additionally creates one submitter + `accepted_submission`; needs_revision/reject create no submitter record. +- [ ] Repeated idempotent decision returns the same rows; a later revision + Review creates a distinct reviewer contribution; automated outcomes create + none. +- [ ] Reviewer uses lease-frozen policy; submitter uses assignment-frozen + policy. Matching explicit unpaid rule creates no award; compensated rule + creates at most one money and one project-points award copied from immutable + definitions. +- [ ] CON copies the supplied stabilized digest exactly into + ContributionRecord.artifact_hash. It does not load/rederive it or call ART. +- [ ] Participant validates exact Review/Submission/assignment/lease/project/ + actor/policy lineage and an allowed review.decision whose actor, action, + resource digest, matched reviewer grant/project, request, and correlation + match the locked transaction. +- [ ] Participant uses caller AsyncSession, stages contribution/award/audit and + stable shared-outbox events, flushes, and never commits. It creates no + evidence projection or evidence-request event. +- [ ] CON never reads REV/AUTH repositories or evaluates review.decision. REV + owns canonical composition and the single route commit. +- [ ] AUTH registration -> CON participant -> REV hidden composition -> AUTH + evaluator/activation order is proven. Real kernel denies while planned. +- [ ] Fault injection at every CON write/flush and every later REV step rolls + back Review/task/contribution/award/audit/outbox together. No post-commit + repair path exists. +- [ ] Static/runtime spies prove zero ART capability, repository, preparation, + provider, or evidence calls in every decision path. +- [ ] PostgreSQL uniqueness, replay, changed-fact conflict, and concurrency tests + pass; changed code is at least 90 percent and repository floor at least 78. + +## Review and stop + +Required tracks: senior, QA, security, product, architecture, docs, reuse, and +test-delta. Stop after the participant. REV, not CON-07, owns integration and +production execution. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md index 9d912e67..171413b6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md @@ -2,23 +2,33 @@ ## Goal and risk -Consume versioned `CompensationFulfillmentRequested` through one typed ADR-0014 -adapter and record acknowledgement. L1 payment/integration/worker risk. +Handle committed fulfillment-request events, persist durable pre-I/O delivery +state, call the typed external adapter after commit, and return a typed outbox +outcome. L1 economic/external-service/auth risk. + +## Prerequisites + +- CON-07 and shared outbox merged; +- exact outbound-delivery ServiceIdentity and ActionId/static row approved and + registered as planned by AUTH, or an explicitly approved closed + dual-principal design; +- provisioned service ActorProfile/link, AUTH-09E admission, typed context, and + prepared protocol; the action remains planned while this hidden behavior + merges; +- ADR 0014 typed adapter/factory composition and lifecycle fence port. ## Allowed files ```text +backend/app/modules/compensation/{schemas,repository,service,ports}.py backend/app/interfaces/compensation.py -backend/app/adapters/compensation/__init__.py -backend/app/adapters/compensation/deterministic.py -backend/app/modules/compensation/ports.py -backend/app/modules/compensation/{schemas,repository,service,delivery_handler}.py +backend/app/adapters/compensation/** backend/app/modules/outbox/handlers.py only explicit handler registration +backend/app/composition/compensation.py backend/app/workers/compensation.py -backend/app/workers/celery_app.py only include registration -backend/app/composition/compensation.py only explicit ExternalServiceAdapterFactory registration -backend/tests/{test_compensation,test_outbox,test_external_service_adapters}.py -docs/operations_payment_reputation.md only delivery operations +backend/app/workers/celery_app.py only delivery task registration +backend/tests/{test_compensation,test_outbox,test_authorization,test_external_service_adapters}.py +docs/spec_contribution_compensation.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-08A.json ``` @@ -26,69 +36,36 @@ docs/operations_payment_reputation.md only delivery operations ## Not allowed ```text -inbound router/callback, AUTH catalogue/grant/kernel edit -production provider-specific SDK, payment attempt/balance/ledger/settlement -dispatcher/async bridge/session/idempotency duplication, dependency/CI weakening -joint lifecycle-control persistence/phase policy or REV-owned implementation -optional/no-op/fallback dispatch fence or REV edits to CON product files +outbox claim/finalization transitions; callback behavior +generic dispatcher identity executing delivery +AUTH implementation; provider SDK/concrete adapter import in domain service +database/fence lock held during external I/O ``` ## Acceptance criteria -- [ ] The post-CON-02B AUTH checkpoint has integrated and activated the real - `outbox.dispatch` evaluator for the fixed dispatcher, including exact active - actor/link/action-assignment revalidation and end-to-end proof through the - merged prepared-dispatch seam. Real-kernel dispatch succeeds only for that - service identity; every human, stale assignment and mismatched event fails - closed. This chunk does not edit AUTH or activate a public route. -- [ ] Reuse shared dispatcher/hashing/idempotency/worker/session/task-settings; - preserve event/payload/binding/idempotency identity. -- [ ] Execute only as a handler of a currently claimed `outbox.dispatch` - command assigned to the fixed shared-outbox dispatcher. CON defines no - feature-local delivery-dispatch action, and human retry/reconciliation - authority cannot execute the side effect. -- [ ] Lock/revalidate frozen binding/award/delivery; active permits delivery, - suspended/retired blocks it, terminal callback status suppresses it. -- [ ] The shared dispatcher supplies an already-claimed immutable event and - exact claim generation only after its claim transaction releases every - database lock/session. In a new transaction, the handler acquires the injected - lifecycle fence, revalidates the generation through the outbox-owned - `OutboxClaimValidationPort` without locking/mutating OutboxEvent, then locks - CON rows and persists durable `in_flight` delivery state. -- [ ] The handler commits and releases its transaction and advisory fence before - adapter I/O. It finalizes CON delivery state in a new fenced transaction and - returns a typed success/retry/terminal outcome; only the dispatcher mutates - outbox claim/retry/finalization state. -- [ ] Timeout/crash/duplicate/out-of-order/ack retry never fabricates - fulfillment; binding-vs-dispatch races cover both orders. -- [ ] Instrumentation proves no provider I/O executes while a database - transaction, lifecycle advisory fence, or OutboxEvent row lock is held. Crash - recovery uses the durable claim/in-flight generation and never guesses - provider outcome. -- [ ] The delivery handler requires a narrow CON-owned - `FulfillmentDispatchFence` consumer port after the dispatcher's committed - claim handoff and before claim validation/CON row locks or any adapter call. - Construction or handler registration without an injected fence fails closed; - there is no optional/no-op/fallback production fence. -- [ ] CON owns the handler and port. REV-12A may inject its durable joint - lifecycle-control implementation only through explicit composition; it may - not edit `compensation/delivery_handler.py` or CON outbox handler policy. -- [ ] On a denied/lost release-control race, the handler performs no adapter I/O - or award/delivery identity mutation and returns the exact typed retry outcome; - the dispatcher alone returns its claimed event to retryable state. - Deterministic CON test doubles prove required-port construction failure plus - allow/deny behavior. REV-12A owns integrated independent-session proof of both - shared/exclusive advisory-lock orderings after consuming the merged CON-11 - hook manifest; REV-13 repeats the behavior in the joint live drill. -- [ ] Deterministic adapter conforms to the typed capability and registers only - through the shared `ExternalServiceAdapterFactory[CompensationDeliveryAdapter]` - in explicit FastAPI/Celery composition; no fallback constructor, service - locator, runtime discovery, compatibility alias, or second factory path. -- [ ] Reconciliation preserves exact original identities; no duplicate worker - bridge, registry, canonicalizer, or idempotency implementation. +- [ ] Handler validates committed claim generation but never locks/mutates the + OutboxEvent. Dispatcher later applies its typed outcome. +- [ ] Delivery authority is independent from `outbox.dispatch`. Dispatcher is + denied delivery; delivery identity is denied dispatch and every other + handler/action; humans are denied fixed-service execution. +- [ ] Prepared authorization locks service ActorProfile/link, validates exact + ServiceIdentity/static row/action, then CON locks award/binding/delivery rows + and evaluates final facts once. +- [ ] Durable in-flight generation and exact event/payload/binding/idempotency + identity commit before adapter I/O; every database transaction and lifecycle + fence is released before the call. +- [ ] Adapter result cannot change award identity/quantity. Retry, ambiguous + completion, acknowledgement, callback-before-ack, cancellation, and replay + preserve monotonic delivery/receipt truth. +- [ ] Provider I/O is only through typed capability/factory at composition root. +- [ ] Coverage/concurrency/failure proof meets repository floors. +- [ ] The real kernel continues to deny the planned action. AUTH activation is + a later checkpoint after this hidden handler and its evaluator composition + merge. -## Verification and reviewers +## Review and stop -Execute CON-08A in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 -percent. Senior engineering, QA/test, security/auth, product/ops, architecture, -docs, reuse/dedup, test-delta and CI integrity are required. Stop before callback. +All baseline plus architecture, security, product, docs, reuse, CI integrity, +and test-delta. Stop after hidden handler; do not activate the action or +register public routes. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md index 28e19d28..7d62a18b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -2,17 +2,17 @@ ## Goal and risk -Accept immutable reports from the exact service actor bound to the frozen -adapter binding, behind an unregistered route. L1 external-auth/payment risk. +Accept authenticated bound-service fulfillment results and create immutable +receipts/status updates. L1 auth/economic/replay risk. ## Allowed files ```text -backend/app/modules/compensation/{schemas,repository,service,ports,callback}.py +backend/app/modules/compensation/{schemas,repository,service,ports}.py backend/app/api/internal_compensation.py backend/app/composition/compensation.py -backend/tests/{test_compensation,test_authorization,test_api_contract_e2e}.py -docs/operations_payment_reputation.md only callback operations +backend/tests/{test_compensation,test_authorization,test_api_controls}.py +docs/spec_contribution_compensation.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-08B.json ``` @@ -20,57 +20,34 @@ docs/operations_payment_reputation.md only callback operations ## Not allowed ```text -production router registration or human authority -AUTH catalogue/grant/kernel/service-assignment edits -outbound adapter/dispatcher, provider secret/ref, dependency/CI weakening -REV-owned lifecycle-control persistence/phase policy or implementation -optional/no-op/fallback callback fence or REV edits to CON callback policy +AUTH catalogue/grant/ServiceIdentity/static-matrix implementation edits +human role fallback; dynamic service grant; provider credentials +outbox transition ownership; production route registration ``` ## Acceptance criteria -- [ ] The callback PermissionId/ActionId/audit parity, canonical service - ActorProfile/link and exact assignment prerequisite already merged before - CON-04A. AUTH has now also merged the typed context, service-capable dependency - and prepared `T` contracts needed by this handler. The real kernel remains - fail-closed while planned; human AdminRoleGrant/ProjectRoleGrant never - satisfies it. -- [ ] Locks revalidate actor/link/assignment/route/award/project/instrument/ - binding/state; durable rate control is per actor+binding. -- [ ] After signature verification and AUTH/idempotency locking, callback - handling requires a narrow CON-owned `FulfillmentCallbackFence`, captures the - allowed lifecycle phase before any compensation-domain row, and holds the - shared transaction fence through idempotent receipt commit. Missing injection - fails closed; there is no optional/no-op/fallback production fence. -- [ ] The callback route/transaction owner explicitly commits the exact - AuthorizationDecision, receipt and idempotency result together; the AUTH - dependency remains rollback-only and never rescues an omitted commit. - Authorization-evidence or commit failure returns the typed retryable error - with no partial receipt/status/idempotency state. REV-13 repeats this proof on - the registered service route. -- [ ] The callback fence allows authenticated callbacks through - `delivery_draining` and denies them after `disabled`. Deterministic CON test - doubles prove allow/deny semantics; REV-12A owns integrated callback-versus- - disable independent-session tests in both lock orderings, and REV-13 repeats - the behavior in the joint live drill. -- [ ] CON owns callback verification, receipt/idempotency policy, and the - callback-fence consumer port. REV-12A may inject its durable implementation - only through explicit composition and may not edit CON callback policy. -- [ ] Suspended accepts valid already-issued work; retired accepts only exact - previously accepted receipt replay; actor/link revocation always denies. -- [ ] Callback-before-ack suppresses delivery; replay is idempotent; changed - receipt conflicts; callback-vs-delivery/retire races cover both orders. -- [ ] Callback-before-ack derives `acknowledged_by_adapter`; a late dispatcher - acknowledgement is idempotent and cannot regress fulfillment or delivery. -- [ ] Behavior tests prove failed then fulfilled is allowed, fulfilled then - failed/changed-fulfilled is denied, and partial fulfillment is rejected. -- [ ] Production OpenAPI remains unchanged and secrets/refs are never stored. -- [ ] A later AUTH-owned gate integrates the callback evaluator against this - merged implementation and alone changes availability; CON-11 waits for it. - -## Verification and reviewers - -Execute CON-08B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 -percent. Senior engineering, QA/test, security/privacy, product/ops, -architecture, docs, reuse/dedup and test-delta are required. Stop before public -registration. +- [ ] Human/AUTH approves exact callback ServiceIdentity and static + `compensation.fulfillment.report` row (or an explicitly closed set of + identities), provisions ActorProfile/link, admits through AUTH-09E, and keeps + the action planned until hidden callback behavior merges. +- [ ] Prepared callback locks profile/link, validates immutable ServiceIdentity, + matrix membership and active action, then locks binding/award/delivery/ + receipt rows and evaluates final typed facts once. +- [ ] Exact route identity, project, instrument, award, frozen binding, external + event, quantity/status, and idempotency must match. Actor/link/binding state + loss denies. +- [ ] Duplicate exact receipt is idempotent; changed replay conflicts; fulfilled + receipt is immutable and at most one exists per award. +- [ ] Suspended binding accepts only valid already-issued obligations; retired + binding accepts only exact replay of a receipt accepted before retirement. +- [ ] Callback-before-local-ack creates terminal truth and suppresses later + delivery without regression. Both lock orders and rate limits per actor plus + binding are covered. +- [ ] Missing provisioned callback rows deny callback/readiness but do not fail + startup/provisioning. AUTH later activates after hidden behavior proof. + +## Review and stop + +All baseline plus architecture, security, product, docs, reuse, test-delta, and +CI integrity. Stop before public registration. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md index fa1002aa..24c63e57 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09A-contribution-evidence-write.md @@ -1,100 +1,40 @@ -# Chunk Contract: WS-CON-001-09A - Contribution Evidence Projection Write +# Chunk Contract: WS-CON-001-09A - Optional Contribution Evidence Projection Write -## Goal and risk +## Status -Build minimal deterministic evidence and bind it through an ART-owned typed -capability. L1 artifact/privacy/worker risk. +Deferred optional successor. This contract is a placeholder and does not +authorize implementation. -## Allowed files +## Goal if separately approved -```text -backend/app/modules/contributions/{schemas,repository,evidence}.py -backend/app/modules/outbox/handlers.py only evidence-handler registration -backend/app/workers/contribution_evidence.py -backend/app/workers/celery_app.py only include registration -backend/tests/{test_contributions,test_artifacts,test_outbox}.py -docs/spec_contribution_compensation.md -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** -.agent-loop/merge-intents/WS-CON-001-09A.json -``` +Create a deterministic post-commit evidence export through a named ART +capability with independent projection status and failure semantics. -## Not allowed +## Mandatory refresh gate -```text -raw ArtifactStore/provider ref, ART implementation edit -ArtifactScratchManager/PreparedArtifact/CommittedArtifactSource import or construction -scratch path/descriptor/ledger/cleanup ownership in CON -read route, semantic search, retain/pin or provider recovery invention -duplicate canonicalizer/worker/session/idempotency, dependency/CI weakening -``` +Before implementation, a new review must bind the then-current: -## Acceptance criteria +- ART store/admission/verification/recovery and typed write capability; +- document schema, media type, retention, disclosure, and replay rules; +- optional `artifact.contribution_evidence.binding.create` ActionId mapped to + stable `artifact.binding.create`; +- exact extension of `workstream.artifact.binding` static service row, + controlled provisioning, AUTH-09E admission, prepared protocol, and AUTH + activation after hidden behavior; +- scratch/preparation ownership, provider ambiguity, cancellation, cleanup, + commitment drift, binding/receipt validation, and cross-project negatives. -- [ ] AUTH has registered the planned - `artifact.contribution_evidence.binding.create` action with existing - `artifact.binding.create` PermissionId, typed context, D10 prepared-mutation - protocol and only the exact added assignment on the existing fixed - `workstream.artifact.binding` ActorProfile/link; ART has merged its capability. - A new or broader worker principal is forbidden. The real kernel remains - fail-closed while planned and CON adds no AUTH or ART bypass. -- [ ] Merged trusted main contains the required ART chain: 02A2 committed-source - preparation, 02A3 ArtifactStore v2, 02B1 MinIO/AWS provider, 02C1 durable - admission, 02C2 verification/publication and 02C3 recovery; fixed AUTH-09 - verifier/scanner/put-resolver registrations, identities and assignments; ART- - 02D hidden resource/behavior composition; D12 exact AUTH custody for all eight - ART-02D Operator and three internal actions without ActionId/PermissionId - drift; later AUTH-owned Operator/internal evaluator integration and separate - action activation; followed by the separately approved - `WS-ART-001-CON-EVIDENCE` write port. Presence of PR #129 symbols alone fails. -- [ ] From a read-only canonical snapshot the handler creates versioned JSON, - exact media type - `application/vnd.workstream.contribution-evidence+json;version=1`, expected - digest/size and stable identity. ART prepares the source before D10 and every database - mutation lock and retains the raw `PreparedArtifact` behind an opaque async- - context operation; no ART implementation type crosses into CON. -- [ ] Transaction A then asks AUTH to prepare D10 and lock authority, locks/ - reloads the CON projection/contribution rows, regenerates and compares the - final canonical facts/digest with the server commitment, and asks ART to lock - admission and stage the AuthorizationDecision plus durable attempt. ART - flushes but does not commit; no first-pass filesystem or provider I/O occurs - while AUTH/CON/ART rows are locked. -- [ ] After the caller explicitly commits, an opaque same-process ART - continuation uses a fresh transaction to prove/claim the committed attempt - before consuming the sealed stream once and calling the provider outside all - database transactions. Commit failure, rollback, drift, cancellation and - replay close/release or retain explicit ART cleanup custody until retry. - Process loss persists no handle/path; stale cleanup and deterministic outbox - replay regenerate identical bytes against the durable attempt. Observation - precedes any absent-object replay after ambiguous provider completion. -- [ ] While planned, success-path evidence tests use only an explicit fake below - that seam and real-kernel/worker tests fail closed. Transaction tests cover - prepare denial, CON/ART final-fact drift, handle misuse, ART Transaction-A - rollback, unsupported/wrong media or digest/size mismatch with zero admission/ - provider calls, no DB locks during first pass, locked-fact drift, post-commit - durable-attempt proof, prepared-source close/cancellation/quota custody, - process loss/replay without handle serialization, single-use second pass, and - AUTH -> CON -> ART lock races in both relevant orders. Provider I/O is - impossible before Transaction A commits. -- [ ] Versioned minimal schema/disclosure matrix excludes reviewer-private, - compensation/provider, credential, external-receipt and unnecessary actor data. -- [ ] Versioned `ContributionEvidenceProjectionRequested` reuses shared hashing, - outbox, worker, idempotency and session utilities; replay is byte-stable. -- [ ] ART owns admission/I/O/verification/binding/receipt/recovery; WS-CON stores - only projection state and verified binding reference. -- [ ] Before marking the projection `projected`, CON validates returned binding/ - receipt digest, byte count, exact media type, owner, project, logical role, - schema version and operation/idempotency identity against its immutable - projection. Any mismatch is an artifact integrity failure, never success. -- [ ] LocalStorage/MinIO capability conformance passes; new-schema rebuild - retains prior immutable bundles. -- [ ] A later AUTH-owned activation gate, after the ART capability and CON - composer are merged, integrates the evaluator against the merged seams - without editing CON feature code and alone changes availability; CON-11 - waits. +## Non-negotiable acceptance criteria -## Verification and reviewers +- [ ] CON-07 creates no projection row/event and never calls this capability. +- [ ] Failure cannot mutate Review, ContributionRecord, CompensationAward, + fulfillment receipt, or status projection truth. +- [ ] CON receives no ArtifactStore, ART repository, scratch/preparation type, + provider reference, path, or credential. +- [ ] Optional work is absent from CON-10A/B, CON-11, and joint release gates. +- [ ] PR #129 alone is insufficient proof. -Execute CON-09A in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 -percent. Senior engineering, QA/test, security/privacy, product/ops, -architecture, docs, reuse/dedup, test-delta and CI integrity are required. Stop -if ART capability/action is not merged. +## Stop + +Do not start without separate human approval and a refreshed internally reviewed +chunk contract. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md index 4157abf0..971a5770 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -1,59 +1,27 @@ -# Chunk Contract: WS-CON-001-09B - Authorized Contribution Evidence Read - -## Goal and risk - -Expose safe self/project evidence reads behind unregistered routes through ART's -typed read capability. L1 auth/privacy risk. - -## Allowed files - -```text -backend/app/modules/contributions/{schemas,repository,service}.py -backend/app/api/internal_contributions.py -backend/app/composition/contributions.py -backend/tests/{test_contributions,test_authorization,test_api_contract_e2e}.py -docs/spec_contribution_compensation.md -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** -.agent-loop/merge-intents/WS-CON-001-09B.json -``` - -## Not allowed - -```text -write projection, raw ArtifactStore/provider ref, AUTH/ART implementation edit -production router registration or broad artifact disclosure -dependency, test, coverage or CI weakening -``` - -## Acceptance criteria - -- [ ] Trusted main contains the separately approved - `WS-ART-001-CON-EVIDENCE` `ContributionEvidenceReadPort`; 09A's merged write - port does not imply read readiness unless the same ART chunk explicitly - delivers and proves both. -- [ ] AUTH has registered the exact planned contribution self/project read - actions, typed contexts and applicable actor-self/AdminRoleGrant definitions. - CON composes canonical facts; pre-filter pagination and cross-project - concealment are required. The real kernel remains fail-closed while planned; - a later AUTH gate owns evaluator integration and availability before CON-10A. -- [ ] Matrix proves self, Project Manager, Finance, Operator/Audit views and - Reviewer project-wide denial/self-only behavior without private/provider data. -- [ ] Grant-backed reads validate the allowed decision's complete resource- - context digest, matched AdminRoleGrant ID and matched project against the - canonical collection facts. CON tests disclosure with explicit allowed/ - denied decision seams only; the later AUTH activation gate proves exact role, - revoked-grant, mixed-grant and foreign-project candidate selection. -- [ ] ART result matches immutable projection binding, digest, byte count, - exact media type - `application/vnd.workstream.contribution-evidence+json;version=1`, owner/ - project/logical role and schema identity; evidence failure never changes - ContributionRecord truth. -- [ ] All product-fact/project mismatch cases map to CONFORMANCE_MATRIX; - AUTH-owned role cases map to the activation gate; OpenAPI is hidden. - -## Verification and reviewers - -Execute CON-09B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 -percent. Senior engineering, QA/test, security/privacy, product/ops, -architecture, docs, reuse/dedup and test-delta are required. Stop before public -registration. +# Chunk Contract: WS-CON-001-09B - Optional Authorized Contribution Evidence Read + +## Status + +Deferred optional successor after separately approved and merged CON-09A. It is +not a prerequisite for core contribution/award reads. + +## Goal if separately approved + +Expose a bounded evidence-export read through a separately proven ART read +capability and exact AUTH disclosure contract. + +## Mandatory refresh gate + +- Re-review the then-current projection schema/binding/retention state and ART + read port independently from the write port. +- Define exact self/project candidates, pre-filtering, concealment, media/schema + validation, and no reviewer-private/provider/credential disclosure. +- Prove evidence absence/failure leaves PostgreSQL contribution/award truth and + CON-10A reads unaffected. +- Keep routes hidden until its own AUTH evaluator/activation and optional release + gate pass. + +## Stop + +Do not start without separate human approval and a refreshed internally reviewed +chunk contract. CON-10A proceeds independently. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md index f9f8885e..2415122a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md @@ -2,16 +2,15 @@ ## Goal and risk -Implement authorized self/project contribution and award reads behind -unregistered routes. L1 auth/privacy/product risk. +Implement hidden authorized self/project reads directly from canonical +PostgreSQL ContributionRecord and CompensationAward truth. L1 auth/privacy risk. ## Allowed files ```text backend/app/modules/contributions/{schemas,repository,service}.py backend/app/modules/compensation/{schemas,repository,service}.py -backend/app/api/internal_contributions.py -backend/app/api/internal_compensation.py +backend/app/api/internal_{contributions,compensation}.py backend/app/composition/{contributions,compensation}.py backend/tests/{test_contributions,test_compensation,test_authorization,test_api_contract_e2e}.py docs/spec_contribution_compensation.md @@ -22,34 +21,29 @@ docs/spec_contribution_compensation.md ## Not allowed ```text -operations mutation/rebuild/reconciliation, AUTH edit -provider/evidence bytes/ref, balance/ledger, production registration -dependency, test, coverage or CI weakening +ART/evidence read or provider reference +operations mutation/rebuild/reconciliation; AUTH edit +balance/ledger; production route registration; CI weakening ``` ## Acceptance criteria -- [ ] The post-CON-09B AUTH contribution-read activation is merged. AUTH has - registered the exact planned award self/project actions, typed contexts and - applicable actor-self/AdminRoleGrant definitions. CON composes canonical - facts; stable pre-filter pagination and cross-project concealment are - enforced. A later AUTH gate activates award reads before CON-10B. -- [ ] D11's human-approved award-detail role set is frozen in the active - contract before this chunk. CON implements only its disclosure projection; - Project Manager behavior follows that decision rather than the unadopted - candidate or broad PermissionId by inference. Reviewer remains self-only - absent a later approved assigned-review action. -- [ ] Reads validate the allowed decision's complete resource-context digest, - matched AdminRoleGrant ID and covered project against canonical award facts. - CON uses role-agnostic allowed/denied seams; the later AUTH activation gate - proves the chosen role set, mixed grants, revocation and scope denials. -- [ ] Contribution, money, points, delivery acknowledgement and fulfillment - remain distinct; no provider/balance/ledger data appears. -- [ ] Query races never mutate truth; all matrix cases run; OpenAPI stays hidden. - -## Verification and reviewers - -Execute CON-10A in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 -percent. Senior engineering, QA/test, security/privacy, product/ops, -architecture, docs, reuse/dedup and test-delta are required. Stop before public -registration. +- [ ] AUTH registers planned contribution/award self/project actions and typed + contexts. CON composes canonical PostgreSQL facts while real kernel denies; + AUTH later integrates evaluators/activation. +- [ ] D11 exact award-detail candidate set is approved before implementation. + CON contains no role logic and never infers access from broad PermissionId. +- [ ] Self reads require exact contributor/beneficiary. Project reads use exact + eligible AdminRole, covered project, pre-filtered stable pagination, and + cross-project concealment. Reviewer has no project-wide access by review role. +- [ ] Allowed decisions bind complete resource digest, matched grant/project, + request, and correlation. Stale/mismatched evidence denies. +- [ ] Contribution, money, points, delivery acknowledgement, and fulfillment + are distinct. No provider/balance/ledger/evidence artifact data appears. +- [ ] CON-09A/09B absence or failure has no effect. OpenAPI remains hidden; + coverage stays at required floors. + +## Review and stop + +Required tracks: senior, QA, security, product, architecture, docs, reuse, and +test-delta. Stop before operations/public registration. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md index f855f2e9..464d9a2c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -1,20 +1,21 @@ -# Chunk Contract: WS-CON-001-10B - Operations, Reconciliation, And Rebuild +# Chunk Contract: WS-CON-001-10B - Operations Requests, Reads, And Drain Observation ## Goal and risk -Implement bounded status/audit reads, reconciliation and projection rebuild -without repairing immutable truth. L1 operations/auth/data risk. +Implement hidden bounded status/audit reads, binding retirement, durable +reconciliation/rebuild request creation, and fulfillment drain observation. +Execution belongs to 10C. L1 operations/auth/data risk. ## Allowed files ```text backend/app/modules/contributions/{schemas,repository,service}.py backend/app/modules/compensation/{schemas,repository,service,ports}.py -backend/app/modules/audit/{schemas,repository,service}.py only bounded WS-CON query/export capability +backend/app/modules/audit/{schemas,repository,service}.py only bounded WS-CON projection backend/app/api/internal_operations.py backend/app/composition/{contributions,compensation}.py backend/tests/{test_contributions,test_compensation,test_authorization,test_outbox,test_audit}.py -docs/operations_payment_reputation.md only WS-CON operations +docs/operations_payment_reputation.md only implemented WS-CON operations .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-10B.json ``` @@ -22,49 +23,32 @@ docs/operations_payment_reputation.md only WS-CON operations ## Not allowed ```text -production router registration, canonical award/receipt repair, AUTH edit -provider settlement/attempt/balance/ledger or second dispatcher -dependency, test, coverage or CI weakening +async reconciliation/rebuild execution or provider I/O +outbox dispatcher/transition implementation; immutable truth repair +AUTH implementation; production router registration; CI weakening ``` ## Acceptance criteria -- [ ] The post-CON-10A AUTH award-read activation is merged. AUTH has registered - planned binding-retire, delivery-reconcile, status, reconciliation, rebuild - and audit actions with D11's chosen AdminRole contracts, typed contexts and - prepared `T` handling where required. Any human-approved outcome differing - from merged AUTH-08 has a reviewed AUTH-owned amendment; CON makes no local - role exception. CON proves domain behavior below the authorization boundary - and changes no AUTH file; a later AUTH gate proves roles and activates these - evaluators before CON-11. -- [ ] Finance/Operator/audit behavior follows D11's exact approved sets. CON - proves reason/scope/product guards only from allowed/denied decision seams; - AUTH activation proves role intersection, mixed grants, revocation and scope. -- [ ] Every allowed grant-backed decision carries the exact complete resource- - context digest, matched AdminRoleGrant ID and covered project scope. Stale, - wrong-scope or digest-mismatched decision evidence produces no operation, - audit export, outbox request or idempotency completion. AUTH owns revoked/ - wrong-role decision production and tests. -- [ ] Reconcile preserves original identities; rebuild changes projection only; - bounded range/reason/audit/idempotency is durable. -- [ ] Audit read/export purpose/scope/redaction/max range is proved without - provider or sensitive failure leakage; OpenAPI remains hidden. -- [ ] Dependency-aware binding retirement is implemented as hidden behavior and - remains planned until the later AUTH gate activates it. It locks policy, - assignment, lease, award, delivery and receipt dependencies, denies any - active/unfinished/unfulfilled reference, races all dependency changes in both - orders, and afterward permits only exact accepted-receipt replay. -- [ ] A same-session read-only `FulfillmentLifecycleDrainObservationPort` - reports pending/claimed/retryable fulfillment outbox events, durable - in-flight dispatch, and nonterminal delivery/callback obligations using the - shared-outbox capability rather than importing its repository. It never - commits, repairs state, calls a provider, or widens Operator authority. -- [ ] Observation is transactionally stable, bounded and fail-closed; tests - cover concurrent claim/retry/callback/finalization and prove no false zero - while work can still perform remote I/O or accept a terminal receipt. - -## Verification and reviewers - -Execute CON-10B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 -percent. Senior engineering, QA/test, security/auth, product/ops, architecture, -docs, reuse/dedup and test-delta are required. Stop before public registration. +- [ ] D11 is final. AUTH registers binding-retire, delivery-reconcile, status, + reconcile-request, rebuild-request, and audit actions with exact candidates, + contexts, prepared protocol, and AUTH custodians. +- [ ] Human operations create bounded durable idempotent requests only; they do + not execute reconciliation/rebuild under human or dispatcher authority. +- [ ] Binding retirement locks policy/assignment/lease/award/delivery/receipt + dependencies and denies active/unfinished/unfulfilled references in both race + orders. Exact prior receipt replay remains the only post-retirement path. +- [ ] Audit read/export enforces purpose/scope/range/redaction with no provider + or sensitive failure leakage. +- [ ] `FulfillmentLifecycleDrainObservationPort` reports pending/claimed/ + retryable outbox work, durable in-flight delivery, and nonterminal callback + obligations through typed outbox capability, never repository import. +- [ ] Observation is same-session, bounded, read-only, and never returns false + zero while remote I/O or terminal receipt remains possible. +- [ ] AUTH later activates after hidden behavior; 10C waits for approved + executor identities/actions/static rows. + +## Review and stop + +Required tracks: senior, QA, security, product, architecture, docs, reuse, and +test-delta. Stop before executor work. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md new file mode 100644 index 00000000..e2939ab8 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md @@ -0,0 +1,65 @@ +# Chunk Contract: WS-CON-001-10C - Reconciliation And Projection Executors + +## Goal and risk + +Execute committed bounded compensation-reconciliation and contribution- +projection-rebuild requests under independent exact fixed-service authority. +L1 background-execution/auth/economic-data risk. + +## Prerequisites + +- 10B durable request and drain contracts merged; +- exact ServiceIdentity/ActionId/static-row design approved for compensation + reconciliation and contribution projection rebuild, or explicitly approved + closed dual-principal evaluators; +- controlled service ActorProfile/link provisioning, AUTH-09E admission, + typed context, and prepared protocol; both actions remain planned while this + hidden behavior merges; +- shared outbox claim validation and handler registry. + +## Allowed files + +```text +backend/app/modules/contributions/{repository,service}.py +backend/app/modules/compensation/{repository,service}.py +backend/app/modules/outbox/handlers.py only explicit registration +backend/app/workers/{contributions,compensation}.py +backend/app/composition/{contributions,compensation}.py +backend/tests/{test_contributions,test_compensation,test_outbox,test_authorization}.py +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +.agent-loop/merge-intents/WS-CON-001-10C.json +``` + +## Not allowed + +```text +generic dispatcher identity executing feature work +human request authority reused without approved dual-principal evaluator +canonical contribution/award/receipt mutation; provider settlement +outbox claim/finalization transitions; AUTH implementation +``` + +## Acceptance criteria + +- [ ] Dispatcher can invoke but is denied both executor actions. Each executor + is denied dispatch, the other executor's action, delivery/callback/ART/REV + actions, and every human action outside its exact row. +- [ ] Handler validates committed claim generation, prepares fixed-service + authority, locks bounded request/product rows, evaluates final facts once, + stages result/audit/projection state, and returns typed outcome. +- [ ] Compensation reconciliation compares immutable award/delivery/receipt + truth and creates durable findings/actions allowed by the approved contract; + it never changes award amount/eligibility or fabricates receipt truth. +- [ ] Contribution rebuild changes rebuildable projections only and never + mutates ContributionRecord or CompensationAward. +- [ ] Retry/replay/idempotency and crash fencing preserve request identity. + Missing service provisioning denies runtime/readiness without failing startup. +- [ ] Coverage, concurrency, and cross-service negative proof meet floors. +- [ ] The real kernel continues to deny both planned executor actions. AUTH + activation is a later checkpoint after hidden behavior and exact evaluator + composition merge. + +## Review and stop + +All baseline plus architecture, security, product, docs, reuse, CI integrity, +and test-delta. Stop before AUTH activation and CON-11. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index 6ce59d83..ce056266 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -2,22 +2,15 @@ ## Goal and risk -Prove the complete WS-CON subsystem is coherent while still hidden, emit an -exact dependency/action/schema/test/fence manifest, hand hidden joint -release-control composition to WS-REV-12A, and hand sole production activation -to WS-REV-13. L1 release/auth/payment risk. +Prove the core WS-CON subsystem coherent while hidden and publish an exact +merged-SHA/schema/action/service/handler/fence/drain/test manifest for the +reviewed REV release owner. L1 release/auth/economic risk. ## Allowed files ```text -backend/app/composition/contributions.py -backend/app/composition/compensation.py -backend/app/composition/outbox.py -backend/tests/test_api_contract_e2e.py -backend/tests/test_authorization.py -backend/tests/test_contributions.py -backend/tests/test_compensation.py -backend/tests/test_outbox.py +backend/app/composition/{contributions,compensation,outbox}.py +backend/tests/{test_api_contract_e2e,test_authorization,test_contributions,test_compensation,test_outbox}.py docs/spec_contribution_compensation.md docs/internal_reviews/WS-CON-001-hidden-release-readiness.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** @@ -27,93 +20,50 @@ docs/internal_reviews/WS-CON-001-hidden-release-readiness.md ## Not allowed ```text -production router registration or /v1 alias -review service/composition ownership -REV-owned lifecycle-control persistence, phase policy, or fence implementation -AUTH/ART catalogue, kernel, grant, provider, or storage edits -active public API/operations claims before REV-13 activation -archival reference edits +production route registration or noncanonical prefix alias +REV lifecycle-control persistence/policy; AUTH/ART implementation +optional evidence projection/read or ART readiness gate +archival input edits ``` ## Acceptance criteria -- [ ] Startup/preflight fails closed unless exact migrations, AUTH action - definitions/owners/PermissionId mappings/availability/typed - contexts/evaluators/matched authorities/prepared protocol/service - dependencies and assignments, ART capabilities, outbox dispatcher, REV-10 - integration and provider readiness are present. An active action without its - executable evaluator or feature behavior fails startup. -- [ ] ART readiness names exact merged 02A2, 02A3, 02B1, 02C1, 02C2, 02C3 and - hidden 02D behavior SHAs; fixed AUTH-09 verifier/scanner/put-resolver - registrations, identities and assignments; exact D12 AUTH custody and - unchanged ActionId/PermissionId mappings for all eight Operator/three internal - ART-02D actions; later AUTH-owned evaluator/activation evidence for Operator - recovery separately from all three internal actions; both - `WS-ART-001-CON-EVIDENCE` write/read port - symbols; `ArtifactOperatorRecoveryPort`; LocalStorage/MinIO conformance; AWS - proof; pre-lock preparation, locked-commitment revalidation, committed-attempt - continuation, one-shot stream and retained-cleanup-custody evidence. PR #129 - symbols alone fail readiness. -- [ ] AUTH manifest proves the reviewed post-AUTH-08 baseline, full D11 human - outcome plus any required AUTH matrix amendment, exact chosen per-action - AdminRole allowlists, complete - resource-context digests, matched grant/project evidence, explicit feature- - route commits, rollback of abandoned transactions and typed retryable - authorization-evidence failure. No service action uses a human grant. -- [ ] D12 manifest maps all 23 WS-CON actions and the coupled review claim/ - decision actions plus all eleven required ART-02D actions to exactly one - approved owner/activation custodian, matches the registered enum and AUTH - chunk map, preserves exact ActionId/PermissionId mappings, and fails startup - on dual, missing or feature-side availability custody. -- [ ] Under recommended D12, no `ActionOwner.REV_08` or - `ActionOwner.ART_02D` enum/definition/SQL/audit member remains after transfer, - `REV_06` remains for its other actions, and - `{definition.owner} == set(ActionOwner)`. Under the global alternative the - old feature owners remain and a separate closed custody catalogue has exact - one-per-action coverage; mixed models fail startup. -- [ ] Hidden integration proves `/api/v1` target paths are absent from production - OpenAPI before release and no partial direct construction path exists. -- [ ] `CONFORMANCE_MATRIX.md` has collected node IDs/evidence for every adopted - invariant; isolated full-suite metadata proves repository >=78 percent and - every changed subsystem >=90 percent from the same run. -- [ ] Dependency manifest names exact merged SHAs/schema symbols/action mappings, - migration heads, stable Celery task IDs, handler registry entries and live - preconditions consumed by REV-13. -- [ ] Manifest names the exact CON-owned `FulfillmentDispatchFence` and - `FulfillmentCallbackFence` port symbols, handler constructor/injection seams, - registry bindings, `OutboxClaimValidationPort`, committed claim handoff, - phase/command mappings, denied retry/callback transitions, and proof that - production construction fails closed without the REV-12A implementation. - REV-12A consumes both seams through composition and does not edit CON product - files. -- [ ] Manifest names the exact same-session - `FulfillmentLifecycleDrainObservationPort`, shared-outbox observation - capability, pending/claimed/retryable/in-flight/nonterminal count semantics, - and zero-obligation proof consumed by REV-12A. Lifecycle control receives no - CON or outbox repository. -- [ ] CON-01 inventory covers every active README-linked source/generated - companion with stale mutable PaymentRecord, accept-only/voidable contribution, - automatic reputation, PaymentPolicy execution or `/v1` wording. REV-13 owns - the atomic active-doc/API/live-drill update; archival/history remains untouched. -- [ ] Joint drill script/evidence contract covers every conformance family but - is not represented as executed until REV-13's sole activation PR. +- [ ] Startup parity covers closed ActionId/PermissionId/ActionOwner, typed + contexts/evaluators, ServiceIdentity/static rows, and active-feature behavior. + Active-without-evaluator/behavior or extra/missing matrix membership fails. +- [ ] Missing provisioned service ActorProfile/link rows do not fail app startup + or Access Administrator provisioning. Protected runtime calls deny and + release readiness stays false until exact rows exist. +- [ ] AUTH manifest binds trusted baseline, complete REV custody transfer, + proposed core CON mappings plus separately approved executor actions, D11 + role sets, exact grants/static rows, AUTH-09E admission, prepared protocol, + decision digests/matched authority, and activation evidence. +- [ ] No partial ART/REV transfer is restated. Complete mappings are referenced + from merged WS-XINT handoffs. ART and optional CON-09A/09B are absent from + core prerequisites. +- [ ] Hidden integration proves production OpenAPI routes remain absent and no + direct construction path bypasses AUTH, fixed-service admission, outbox + handler isolation, or mandatory REV/CON participant composition. +- [ ] Manifest names exact migrations, schemas, event/task IDs, registry rows, + service identities/actions/static rows, handler execution boundaries, and + retained test metadata. Dispatcher cannot execute protected handlers. +- [ ] Manifest names CON-owned FulfillmentDispatchFence, + FulfillmentCallbackFence, FulfillmentLifecycleDrainObservationPort, + OutboxClaimValidationPort, injection seams, phase mappings, denial states, + and fail-closed construction without REV release-control implementation. +- [ ] Core conformance matrix has executable evidence; same-run repository + coverage is at least 78 and changed subsystems at least 90. +- [ ] Joint drill contract covers all core families and explicitly asserts zero + ART calls in Review-to-contribution creation. It is not marked executed here. -## Verification commands +## Verification -Execute the exact CON-11 expansion in `../RUNTIME_VERIFICATION.md`, then: - -```bash -python3 scripts/check_markdown_links.py -python3 scripts/check_stale_workstream_wording.py -python3 scripts/check_stale_authorization_docs.py -python3 scripts/check_stale_artifact_contracts.py -git diff --check -``` +Run the initiative runtime commands plus Markdown links, stale wording, +authorization/artifact scanners, loop-memory check, internal evidence check, and +git diff check. ## Review and stop -All internal reviewer tracks, including CI integrity and test-delta, are -required. Stop after the reviewed hidden-readiness manifest. Do not register a -route, implement lifecycle-control policy, perform the production drill, edit -WS-REV, or start REV-12A/13. Only the human may direct the WS-REV owner to -consume this gate. +All internal tracks including CI integrity and test-delta. Stop after hidden +manifest. Do not register routes, implement REV release control, run production +activation, or start optional evidence work. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md index 0bdd71b4..96843a5e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN-contribution-compensation-planning.md @@ -1,215 +1,98 @@ # Chunk Contract: WS-CON-001-PLAN - Contribution And Compensation Planning -## Parent initiative - -`WS-CON-001` - Contribution Record And Compensation Boundary - ## Goal -Reconcile the supplied WS-CON pair with current code and parallel AUTH/REV -contracts, then produce a human-reviewable initiative plan without implementing -runtime behavior. - -## Why this chunk exists - -The candidate spans architecture, permissions, payment, artifacts, lifecycle, -workers, APIs, and migrations and contains conflicts with accepted repository -decisions. Implementation cannot safely begin from the candidate alone. +Reconcile WS-CON planning to merged PR #139 / WS-XINT-001 without implementing +runtime behavior, and repair only the exact active-contract scanner +classification/proof required by that reconciliation. -## Approved plan reference +## Risk -This chunk creates the parent `INTENT.md`, `DISCOVERY.md`, `PLAN.md`, and -`CHUNK_MAP.md`; no prior implementation plan exists. - -## Risk class - -L0 architecture/payment/authorization direction; P1 planning priority. +L0 architecture/economic/authorization planning plus CI-sensitive scanner +metadata; P1. ## Allowed files ```text .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +scripts/check_stale_workstream_wording.py only exact archival/current-runtime contract rules +scripts/check_stale_authorization_docs.py only exact archival classification +scripts/check_stale_artifact_contracts.py only exact archival classification parity +scripts/check_internal_review_evidence.py only deleted-contract provenance during chunk renames +scripts/test_agent_gates.py only fail-closed gate regressions for these rules +docs/current_system_data_flow.html only remove premature target-runtime type claim ``` ## Not allowed ```text -backend application, migrations, tests, workflows, dependencies -AUTH/ART/REV sibling worktree edits -reference-spec byte edits or archival replacement -active runtime documentation adoption +backend application, migrations, runtime tests, workflows, dependencies +AUTH/ART/REV initiative edits +reference-spec byte edits, restoration, rename, or archival replacement +active product documentation adoption +scanner threshold weakening, directory-wide archive exemption, or broad waiver ``` ## Acceptance criteria -- [x] Candidate Markdown/PDF and original PDF are inventoried by hash/status. -- [x] Current code, tests, docs, AUTH catalogue, REV plan, and ART contract are - cited concretely. -- [x] ActionIds and PermissionIds are separated and incorrect candidate IDs are - rejected. -- [x] `/api/v1`, Submission identity, provider, artifact capability, payment - model, outbox, and review integration conflicts are explicit. -- [x] Required initiative artifacts and bounded chunk contracts exist. -- [x] First implementation/spec chunk remains proposed until human approval. -- [x] Required plan reviewers complete and all valid findings are resolved or - recorded for human decision. -- [x] AUTH-07B refresh records the two-active/48-planned runtime, separates AUTH - registration from post-feature AUTH activation, adds the prepared `T` - protocol and absent upstream `task.claim` gate, and receives fresh required - review/evidence against current trusted main. -- [x] AUTH-08 refresh records the 74/57 and nine-active/48-planned runtime, - eight resource variants, two matched-authority kinds, resource/grant/scope - decision evidence and explicit feature commit ownership; reconciles D11's - cross-spec role choices and conditional AUTH changes; adds D12's exact - proposed ActionOwner/custody map; refreshes the clean/non-consumable REV - dependency; and receives fresh required review/evidence against `aa0fdcd`. -- [x] ART-02A2 PR #129 refresh records the inactive preparation-only boundary, - exact `ArtifactPreparationService`/sealed-source ownership, remaining ART - 02A3/02B1/02C1/02C2/02C3/02D/write-read-capability gates, concurrent - non-consumable REV discovery without a live-head pin, and D12's exact eight- - Operator/three-internal ART action custody without ActionId/PermissionId - drift; and receives fresh required review/evidence against `9a04434`. - -## Verification commands +- [ ] Trusted baseline is `5d353b6`; runtime AUTH remains 74 PermissionIds, 57 + ActionIds, nine active, and 48 planned. +- [ ] Canonical eligibility model is ContributionPolicy/version/rule/award + definition; CompensationAward remains the evaluated result. +- [ ] Core Review-to-contribution transaction creates no evidence projection, + makes zero ART calls, and copies stabilized Submission artifact_hash lineage. +- [ ] Project grants are independent submitter/reviewer/adjudicator; fixed + services use ServiceIdentity/static matrix/AUTH-09E, never persisted action + rows. +- [ ] ActionOwner is AUTH activation custody; complete ART/REV transfers are + referenced from WS-XINT rather than partially restated. +- [ ] Shared outbox dispatch cannot authorize protected feature handlers; + delivery/reconciliation/rebuild/callback identity/action decisions are open + exact gates. +- [ ] Proposed policy ActionIds use `contribution.policy.*` mapped to stable + `compensation.policy.manage`. The 22 core surface actions are tested + separately from optional evidence and unapproved executor candidates. +- [ ] CON-09A/09B are deferred optional and absent from core 10A/B/10C/11 and + joint release gates. +- [ ] Current chunk map includes independently authorized 10C executors. +- [ ] The pre-existing user deletion of the original PDF remains untouched and + unstaged. +- [ ] Exact WS-CON reference Markdown is classified historical consistently in + all three scanners; near misses and new docs remain scanned. +- [ ] Current-runtime scanner recognizes canonical unimplemented contribution/ + award types and fails on premature runtime walkthrough claims. +- [ ] Internal-review evidence discovery recovers a deleted contract heading + from the index, HEAD, or review base and retains its chunk ID alongside each + replacement; missing, empty, malformed, unreadable, dangling-symlink, and + non-file contracts fail closed. +- [ ] Required internal reviewers pass the exact final snapshot and no sessions + remain open. +- [ ] The repository loop-memory check is run and its only failure is the + unchanged AUTH status inherited from trusted `main`; this bounded CON chunk + does not edit another initiative to conceal the upstream failure. + +## Verification ```bash python3 scripts/check_markdown_links.py python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py python3 scripts/check_stale_artifact_contracts.py +# Expected inherited failure until AUTH/main repairs its own status: python3 scripts/check_loop_memory_state.py +git diff --exit-code origin/main -- \ + .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py -(cd backend && PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -p pytest_asyncio.plugin -q \ - tests/test_artifact_preparation.py::test_preparation_seals_exact_commitment_and_single_stream \ - tests/test_artifact_preparation.py::test_committed_sources_cannot_be_publicly_assembled \ - tests/test_artifact_preparation.py::test_client_commitment_mismatch_prevents_provider_call \ - tests/test_artifact_preparation.py::test_preparation_cancellation_releases_file_and_reservation \ - tests/test_artifact_preparation.py::test_closed_preparation_rejects_stream_and_is_idempotent \ - tests/test_artifact_preparation.py::test_cancelled_close_finishes_cleanup_and_closes_handle) git diff --check -test "$(git rev-parse origin/main)" = 9a04434e2f23c5dec8939dadb943bba4d85110c0 -git merge-base --is-ancestor 9a04434e2f23c5dec8939dadb943bba4d85110c0 HEAD -test "$(sha256sum docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md | cut -d' ' -f1)" = cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640 -test "$(sha256sum 'docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf' | cut -d' ' -f1)" = ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457 -test "$(git show origin/main:docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.pdf | sha256sum | cut -d' ' -f1)" = 34c4337f27e42a5b0ed5e153fe8ccd492ecede202c2764506a930d109aef66c1 -(cd backend && python3 - <<'PY' -from inspect import signature - -from app.modules.artifacts.preparation import ( - ArtifactPreparationService, - ArtifactScratchManager, -) -from app.modules.artifacts.sources import CommittedArtifactSource, PreparedArtifact - -parameters = signature(ArtifactPreparationService.prepare).parameters -assert list(parameters) == [ - "self", "stream", "media_type", "expected_sha256", "expected_size" -] -assert parameters["media_type"].kind.name == "KEYWORD_ONLY" -assert parameters["expected_sha256"].kind.name == "KEYWORD_ONLY" -assert parameters["expected_size"].kind.name == "KEYWORD_ONLY" -for value in (ArtifactScratchManager, PreparedArtifact, CommittedArtifactSource): - assert value.__module__.startswith("app.modules.artifacts.") -PY -) -(cd backend && python3 - <<'PY' -import re -from pathlib import Path - -from app.modules.authorization.catalogue import ( - ACTION_DEFINITIONS, ActionAvailability, ActionId, PermissionId, -) -from app.modules.authorization.policy import ADMIN_ROLE_PERMISSIONS -from app.modules.authorization.runtime import AuthorizationResourceContext, MatchedAuthorityKind -from app.modules.authorization.schemas import AdminRole - -actions = {item.value for item in ActionId} -permissions = {item.value for item in PermissionId} -active = { - row.action_id.value - for row in ACTION_DEFINITIONS - if row.availability is ActionAvailability.ACTIVE -} -ws_con_actions = { - "contribution.read_self", "contribution.read_project", - "compensation.policy.read", "compensation.policy.create_draft", - "compensation.policy.update_draft", "compensation.policy.publish", - "compensation.policy.retire", "compensation.adapter_binding.read", - "compensation.adapter_binding.create", "compensation.adapter_binding.suspend", - "compensation.adapter_binding.resume", "compensation.adapter_binding.retire", - "compensation.award.read_self", "compensation.award.read_project", - "compensation.delivery.reconcile", "compensation.status.read", - "compensation.reconcile.run", "contribution.projection.rebuild", - "audit.read", "audit.export", "compensation.fulfillment.report", - "outbox.dispatch", "artifact.contribution_evidence.binding.create", -} -operator = {item.value for item in ADMIN_ROLE_PERMISSIONS[AdminRole.OPERATOR]} -finance = {item.value for item in ADMIN_ROLE_PERMISSIONS[AdminRole.FINANCE_AUTHORITY]} -manager = {item.value for item in ADMIN_ROLE_PERMISSIONS[AdminRole.PROJECT_MANAGER]} -assert (len(permissions), len(actions), len(active)) == (74, 57, 9) -assert len(ACTION_DEFINITIONS) - len(active) == 48 -assert len(AuthorizationResourceContext.__args__) == 8 -assert {item.value for item in MatchedAuthorityKind} == {"actor_self", "admin_role_grant"} -assert not (ws_con_actions & actions) -assert "task.claim" in permissions and "task.claim" not in actions -assert not ({"outbox.dispatch", "compensation.fulfillment.report"} & permissions) -assert "compensation.delivery.reconcile" in finance -assert "compensation.delivery.reconcile" not in operator -assert "compensation.award.read" in manager -handoff = Path("../.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md").read_text() -owner_section = handoff.split("## Proposed AUTH-owned ActionOwner custody", 1)[1].split("## Proposed closed handoff", 1)[0] -owner_actions = [] -for line in owner_section.splitlines(): - if line.startswith("| `AUTH_CON_"): - owner_actions.extend(re.findall(r"`([^`]+)`", line.split("|")[3])) -assert len(owner_actions) == len(set(owner_actions)) == 23 -assert set(owner_actions) == ws_con_actions -definitions = { - row.action_id.value: (row.permission_id.value, row.owner.value) - for row in ACTION_DEFINITIONS -} -art_02d_mappings = { - "artifact.binding.read": "artifact.binding.read", - "artifact.replica.read": "artifact.replica.read", - "artifact.receipt.read": "artifact.receipt.read", - "artifact.verification_job.read": "artifact.verification_job.read", - "artifact.verification_job.retry": "artifact.verification_job.retry", - "artifact.recovery_attempt.read": "artifact.recovery_attempt.read", - "artifact.audit.read": "artifact.audit.read", - "operations.artifact_storage_admission.read": "operations.status.read", - "artifact.verification.execute": "artifact.verification.execute", - "artifact.pending_work.scan": "artifact.pending_work.scan", - "artifact.put_attempt.resolve": "artifact.put_attempt.resolve", -} -assert { - action: permission - for action, (permission, owner) in definitions.items() - if owner == "WS-ART-001-02D" -} == art_02d_mappings -assert "`AUTH_ART_02D_OPERATOR`" in owner_section -assert "`AUTH_ART_02D_INTERNAL`" in owner_section -for action, permission in art_02d_mappings.items(): - assert f"`{action}` -> `{permission}`" in owner_section -assert "removes the now-unused\n`ActionOwner.ART_02D`" in owner_section -assert "removes the now-unused\n`ActionOwner.REV_08`" in owner_section -assert "`REV_06` remains" in owner_section -PY -) +test "$(git rev-parse origin/main)" = 5d353b6d3f8a36b9b9ffdc1959487a150ac25fd1 ``` -## Required reviewers +## Reviewers Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -and reuse/dedup. CI integrity and test-delta are N/A because this chunk changes -only planning Markdown and no CI/tests. - -## Human review focus - -Review unresolved D1/D4/D7/D8/D10/D11/D12, confirm accepted D3/D5/D6/D9 and -approved D2, and assess D2's unresolved legacy-row handling rule, exact -authorization dependencies and role candidates, artifact boundary, cross- -initiative gates, and whether every runtime chunk is independently reviewable. +reuse/dedup, CI integrity, and test-delta. -## Stop conditions +## Stop -Stop after presenting the reviewed plan. Do not start `WS-CON-001-01` without -explicit human approval. +Stop after reviewed planning reconciliation. Do not start CON-01, runtime work, +optional evidence, push, or PR publication without explicit human direction. diff --git a/docs/current_system_data_flow.html b/docs/current_system_data_flow.html index c7553659..31aebca6 100644 --- a/docs/current_system_data_flow.html +++ b/docs/current_system_data_flow.html @@ -483,7 +483,7 @@

Project guide and policy are prepared

3

Guide activation locks contract

-

Activation validates a passing or acknowledged sufficiency report, immutable guide source snapshot, approved submission artifact policy, effective project submission artifact policy hash, project pre-submit checker compiled bundle hash, approved generated project post-submit checker policy with matching guide, source snapshot, effective project policy, and pre-submit checker provenance, review policy allowed decisions, and revision states. Task readiness later validates that the task locks the applicable guide snapshot, effective project submission artifact policy hash, pre-submit checker bundle hash, and approved provenance-matched project post-submit checker policy reference. Publication of a ContributionPolicyVersion is independent of guide activation.

+

Activation validates a passing or acknowledged sufficiency report, immutable guide source snapshot, approved submission artifact policy, effective project submission artifact policy hash, project pre-submit checker compiled bundle hash, approved generated project post-submit checker policy with matching guide, source snapshot, effective project policy, and pre-submit checker provenance, review policy allowed decisions, and revision states. Task readiness later validates that the task locks the applicable guide snapshot, effective project submission artifact policy hash, pre-submit checker bundle hash, and approved provenance-matched project post-submit checker policy reference. Contribution-policy publication is outside this current-backend walkthrough and remains independent of guide activation.

status=active one active guide diff --git a/scripts/check_internal_review_evidence.py b/scripts/check_internal_review_evidence.py index d5823c79..0a2b3705 100644 --- a/scripts/check_internal_review_evidence.py +++ b/scripts/check_internal_review_evidence.py @@ -230,7 +230,10 @@ def reviewer_rows(text: str) -> dict[str, tuple[str, str, str]]: in_reviewer_table = False continue notes = cells[3] if len(cells) > 3 else "" - rows[cells[0]] = (cells[1], cells[2], notes) + # Evidence addenda are newest-first, matching reviewed_sha() and + # provenance_value(). Preserve the first authoritative result for each + # track instead of letting an older table below overwrite it. + rows.setdefault(cells[0], (cells[1], cells[2], notes)) return rows @@ -423,8 +426,14 @@ def required_chunk_ids(paths: list[str]) -> list[str]: continue contract_path = ROOT / path try: - heading = contract_path.read_text(encoding="utf-8").splitlines()[0] - except (IndexError, OSError, UnicodeDecodeError) as exc: + if os.path.lexists(contract_path): + if contract_path.is_symlink() or not contract_path.is_file(): + raise RuntimeError("changed chunk contract is not a regular file") + text = contract_path.read_text(encoding="utf-8") + else: + text = historical_contract_text(path) + heading = text.splitlines()[0] + except (IndexError, OSError, UnicodeDecodeError, RuntimeError) as exc: raise RuntimeError(f"cannot read changed chunk contract {path}") from exc chunk_id = chunk_id_from_heading(heading) if chunk_id is None: @@ -436,6 +445,24 @@ def required_chunk_ids(paths: list[str]) -> list[str]: return chunk_ids +def historical_contract_text(path: str) -> str: + """Recover a deleted contract from index, HEAD, or the review base.""" + base_ref = resolve_base_ref() + object_names = (f":{path}", f"HEAD:{path}", f"{base_ref}:{path}") + for object_name in object_names: + result = subprocess.run( + ["git", "show", object_name], + cwd=ROOT, + check=False, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + if result.returncode == 0: + return result.stdout + raise RuntimeError(f"deleted contract has no recoverable provenance: {path}") + + def chunk_id_from_heading(heading: str) -> str | None: """Return the exact chunk ID from a canonical contract heading.""" for pattern in CHUNK_HEADING_PATTERNS: diff --git a/scripts/check_stale_artifact_contracts.py b/scripts/check_stale_artifact_contracts.py index 50e7c2f2..0127af73 100644 --- a/scripts/check_stale_artifact_contracts.py +++ b/scripts/check_stale_artifact_contracts.py @@ -42,6 +42,7 @@ "docs/internal_reviews/2026-06-13_week1_week2_deterministic_hardening.md", "docs/internal_reviews/2026-06-16_submission_artifact_policy_architecture.md", "docs/reference_specs/WS-AUTH-001-actor-profile-role-and-authorization-service-specification.md", + "docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md", "docs/reference_specs/WS-IMP-001-workstream-v0.1-coding-agent-implementation-specification.md", "docs/reference_specs/WS-REV-001-review-lifecycle-specification.md", "docs/roadmap_30_day_master_plan.md", diff --git a/scripts/check_stale_authorization_docs.py b/scripts/check_stale_authorization_docs.py index d0052d42..50f98ae5 100644 --- a/scripts/check_stale_authorization_docs.py +++ b/scripts/check_stale_authorization_docs.py @@ -26,6 +26,7 @@ "docs/internal_reviews/2026-06-13_week1_week2_deterministic_hardening.md": "closed internal review", "docs/internal_reviews/2026-06-16_submission_artifact_policy_architecture.md": "closed internal review", "docs/reference_specs/WS-AUTH-001-actor-profile-role-and-authorization-service-specification.md": "immutable archival input", + "docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md": "immutable archival input", "docs/reference_specs/WS-IMP-001-workstream-v0.1-coding-agent-implementation-specification.md": "immutable archival input", "docs/reference_specs/WS-REV-001-review-lifecycle-specification.md": "immutable archival input", "docs/roadmap_30_day_master_plan.md": "historical initial plan", @@ -377,7 +378,7 @@ def technical_worker_match(text: str, match: re.Match[str]) -> bool: token_end = worker_offset + len(token.group(0)) suffix = text[token_end : token_end + 20] exact_code_path = token.group(0).lower() == "workers" and ( - (prefix.endswith("backend/app/") and suffix.startswith("/")) + (prefix.endswith(("backend/app/", "app/")) and suffix.startswith("/")) or (prefix.endswith("app.") and suffix.startswith(".")) ) exact_celery_cli = bool( diff --git a/scripts/check_stale_workstream_wording.py b/scripts/check_stale_workstream_wording.py index 1f81f21f..6dd5b412 100644 --- a/scripts/check_stale_workstream_wording.py +++ b/scripts/check_stale_workstream_wording.py @@ -208,6 +208,7 @@ "docs/internal_reviews/2026-06-13_week1_week2_deterministic_hardening.md", "docs/internal_reviews/2026-06-16_submission_artifact_policy_architecture.md", "docs/reference_specs/WS-AUTH-001-actor-profile-role-and-authorization-service-specification.md", + "docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md", "docs/reference_specs/WS-IMP-001-workstream-v0.1-coding-agent-implementation-specification.md", "docs/reference_specs/WS-REV-001-review-lifecycle-specification.md", "docs/roadmap_30_day_master_plan.md", @@ -235,8 +236,13 @@ ), } UNIMPLEMENTED_CURRENT_RUNTIME_COMPENSATION_PATTERNS = ( - re.compile(r"\bCompensationPolicyVersion\b"), + re.compile(r"\bContributionPolicy\b"), + re.compile(r"\bContributionPolicyVersion\b"), + re.compile(r"\bContributionRule\b"), + re.compile(r"\bContributionAwardDefinition\b"), + re.compile(r"\bProjectCompensationAdapterBinding\b"), re.compile(r"\bReviewLease\b"), + re.compile(r"\bContributionRecord\b"), re.compile(r"\bCompensationAward\b"), re.compile(r"\bCompensationFulfillmentReceipt\b"), re.compile(r"\bCompensationStatusProjection\b"), diff --git a/scripts/test_agent_gates.py b/scripts/test_agent_gates.py index c94eeb05..20e935aa 100644 --- a/scripts/test_agent_gates.py +++ b/scripts/test_agent_gates.py @@ -372,15 +372,13 @@ def test_evidence_must_reference_changed_chunk() -> None: chunks = gate.ROOT / ".agent-loop/initiatives/example/chunks" chunks.mkdir(parents=True) invalid_contracts = { - "missing.md": None, "empty.md": b"", "malformed.md": b"# Contract without a lifecycle id\n", "invalid-utf8.md": b"\xff", } for filename, content in invalid_contracts.items(): relative_path = ".agent-loop/initiatives/example/chunks/" + filename - if content is not None: - (chunks / filename).write_bytes(content) + (chunks / filename).write_bytes(content) try: gate.required_chunk_ids([relative_path]) except RuntimeError: @@ -400,6 +398,74 @@ def test_evidence_must_reference_changed_chunk() -> None: pass else: raise AssertionError("unreadable changed contract did not fail closed") + + missing_relative = ( + ".agent-loop/initiatives/example/chunks/missing.md" + ) + try: + gate.required_chunk_ids([missing_relative]) + except RuntimeError: + pass + else: + raise AssertionError("missing changed contract did not fail closed") + + dangling_path = chunks / "dangling.md" + dangling_path.symlink_to(chunks / "absent-target.md") + try: + gate.required_chunk_ids( + [".agent-loop/initiatives/example/chunks/dangling.md"] + ) + except RuntimeError: + pass + else: + raise AssertionError( + "dangling changed contract did not fail closed" + ) + + linked_target = chunks / "linked-target.md" + linked_target.write_text( + "# Chunk Contract: WS-EXAMPLE-001-LINKED - External\n", + encoding="utf-8", + ) + linked_path = chunks / "linked.md" + linked_path.symlink_to(linked_target) + try: + gate.required_chunk_ids( + [".agent-loop/initiatives/example/chunks/linked.md"] + ) + except RuntimeError: + pass + else: + raise AssertionError( + "resolvable symlink contract did not fail closed" + ) + + replacement = chunks / "WS-EXAMPLE-001-NEW-replacement.md" + replacement.write_text( + "# Chunk Contract: WS-EXAMPLE-001-NEW - Replacement\n", + encoding="utf-8", + ) + original_historical_contract_text = gate.historical_contract_text + gate.historical_contract_text = lambda _path: ( + "# Chunk Contract: WS-EXAMPLE-001-OLD - Deleted\n" + ) + try: + assert gate.required_chunk_ids( + [ + ".agent-loop/initiatives/example/chunks/" + "WS-EXAMPLE-001-OLD-deleted.md" + ] + ) == ["ws-example-001-old"] + assert gate.required_chunk_ids( + [ + ".agent-loop/initiatives/example/chunks/" + "WS-EXAMPLE-001-OLD-deleted.md", + ".agent-loop/initiatives/example/chunks/" + "WS-EXAMPLE-001-NEW-replacement.md", + ] + ) == ["ws-example-001-old", "ws-example-001-new"] + finally: + gate.historical_contract_text = original_historical_contract_text finally: gate.ROOT = original_root original_changed_files = gate.changed_files @@ -526,6 +592,17 @@ def test_evidence_accepts_exact_pass_and_approved_na_results() -> None: ) assert gate.validate_reviewer_rows(text.lower(), required) == [] + newest_first_text = ( + "| Reviewer | Result | Blocking findings | Notes |\n" + "|---|---:|---|---|\n" + "| senior engineering | PASS AFTER FIXES | None | current addendum |\n" + "\nHistorical addendum\n\n" + "| Reviewer | Result | Blocking findings | Notes |\n" + "|---|---:|---|---|\n" + "| senior engineering | Pending | Old finding | superseded |\n" + ) + assert gate.validate_reviewer_rows(newest_first_text.lower(), required) == [] + bad_text = ( "| Reviewer | Result | Blocking findings | Notes |\n" "|---|---:|---|---|\n" @@ -1339,8 +1416,13 @@ def test_current_runtime_walkthrough_rejects_unimplemented_compensation_records( ) sample = " ".join( ( - "CompensationPolicyVersion", + "ContributionPolicy", + "ContributionPolicyVersion", + "ContributionRule", + "ContributionAwardDefinition", + "ProjectCompensationAdapterBinding", "ReviewLease", + "ContributionRecord", "CompensationAward", "CompensationFulfillmentReceipt", "CompensationStatusProjection", @@ -1351,8 +1433,13 @@ def test_current_runtime_walkthrough_rejects_unimplemented_compensation_records( pattern.pattern for pattern in stale.UNIMPLEMENTED_CURRENT_RUNTIME_COMPENSATION_PATTERNS } == { - r"\bCompensationPolicyVersion\b", + r"\bContributionPolicy\b", + r"\bContributionPolicyVersion\b", + r"\bContributionRule\b", + r"\bContributionAwardDefinition\b", + r"\bProjectCompensationAdapterBinding\b", r"\bReviewLease\b", + r"\bContributionRecord\b", r"\bCompensationAward\b", r"\bCompensationFulfillmentReceipt\b", r"\bCompensationStatusProjection\b", @@ -1361,6 +1448,13 @@ def test_current_runtime_walkthrough_rejects_unimplemented_compensation_records( pattern.search(sample) for pattern in stale.UNIMPLEMENTED_CURRENT_RUNTIME_COMPENSATION_PATTERNS ) + current_walkthrough = Path("docs/current_system_data_flow.html").read_text( + encoding="utf-8" + ) + assert not any( + pattern.search(current_walkthrough) + for pattern in stale.UNIMPLEMENTED_CURRENT_RUNTIME_COMPENSATION_PATTERNS + ) def test_stale_wording_skips_only_docs_internal_reviews_prefix() -> None: @@ -3788,6 +3882,7 @@ def test_stale_authorization_rule_examples_are_rejected() -> None: "Celery worker_id identifies the background process.", "The checker worker_id is included in internal telemetry.", "See backend/app/workers/tasks.py.", + "See app/workers/tasks.py.", ) for sample in technical_worker_statements: assert gate.scan_text("docs/new_active_doc.md", sample) == [], sample From c41687511cb2701075e80b3c2b568d5eec5a7d23 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 06:20:47 +0100 Subject: [PATCH 10/22] Bind WS-CON XINT reconciliation evidence --- .../STATUS.md | 8 +- ...S-CON-001-PLAN-internal-review-evidence.md | 89 +++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 22ed14c4..34447557 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,8 +2,10 @@ ## Current status -`WS-CON-001-PLAN` is being reconciled to trusted `main` `5d353b6`, which merged -WS-XINT-001 boundary reconciliation through PR #139. Runtime code is unchanged. +`WS-CON-001-PLAN` is reconciled and internally reviewed against trusted `main` +`5d353b6`, which merged WS-XINT-001 boundary reconciliation through PR #139. +The reviewed content commit is `c4242e0`; runtime code is unchanged and the +result remains local/unpublished. The prior plan is superseded where it used the older policy aggregate, made ART evidence mandatory, described service action rows as persisted assignments, allowed partial activation-custody transfer, or let outbox dispatch imply @@ -29,7 +31,7 @@ feature-handler authority. | Chunk | Status | Notes | |---|---|---| -| `WS-CON-001-PLAN` | Reconciliation and internal review in progress | Based on PR #139 / `5d353b6` | +| `WS-CON-001-PLAN` | Reconciled and internally reviewed; unpublished | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | | `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index f020addf..7772bb58 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -1,5 +1,94 @@ # Internal Review Evidence: WS-CON-001-PLAN +## 2026-07-17 WS-XINT-001 Boundary Reconciliation + +This addendum is the current authoritative review state and supersedes the +older policy-model, mandatory-evidence, service-assignment, partial-custody, +trusted-main, and chunk-order statements below. Trusted `main` +`5d353b6d3f8a36b9b9ffdc1959487a150ac25fd1` merges WS-XINT-001 PR #139. + +Reviewed code SHA: `c4242e0b7c3441c23ce8b3a3facc45ae00de848a` + +Reviewed non-review planning-tree SHA-256: +`586658fb55eadcc36f8095051ed7ff3281a714672456221de7d7041c6f040465` + +The digest excludes `reviews/**` and is reproduced from the repository root: + +```bash +find .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary \ + -type f -name '*.md' ! -path '*/reviews/*' -print0 \ + | sort -z | xargs -0 sha256sum | sha256sum +``` + +Reviewed at: 2026-07-17T05:16:47Z + +Reviewer run IDs: senior/architecture/reuse=`/root/auth08_arch_review`; +QA/test/product/ops/docs/test-delta=`/root/auth08_qa_product_review`; +security/auth/CI-integrity=`/root/auth08_security_review` + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS AFTER FIXES | None | Operation-specific lifecycle-before-policy locking, chunk gates, and hidden-before-activation sequencing are executable. | +| QA/test | PASS AFTER FIXES | None | Contribution/award cardinality, exact uniqueness/enums, chunk file scopes, and deleted-contract evidence regressions are explicit. | +| security/auth | PASS AFTER FIXES | None | Human grants, fixed-service static authority, AUTH-only activation custody, callback isolation, and optional evidence separation are fail closed. | +| product/ops | PASS AFTER FIXES | None | Every valid human Review recognizes reviewer work; accept alone recognizes submitter work; policy, award, fulfillment, and legacy cutover boundaries are coherent. | +| architecture | PASS AFTER FIXES | None | ContributionPolicy is the eligibility aggregate, ART is absent from the core transaction, and dispatcher authority cannot leak to feature handlers. | +| CI integrity | PASS AFTER FIXES | None | Scanner changes are exact; deleted contract provenance is recovered index to HEAD to base; regular-file enforcement prevents path/symlink bypass. | +| docs | PASS AFTER FIXES | None | PR #139 precedence, optional evidence, complete ART/REV custody references, open AUTH decisions, and inherited loop-memory failure are truthful. | +| reuse/dedup | PASS AFTER FIXES | None | Existing AUTH kernel, static matrix, outbox, lifecycle, audit, adapter-factory, and PostgreSQL truth boundaries are reused. | +| test delta | PASS AFTER FIXES | None | Added regressions preserve failure for missing, malformed, unreadable, non-file, dangling/resolvable-symlink, pure-deletion, and replacement contracts. | + +Open sub-agent sessions: none + +Valid findings addressed: yes + +- Replaced the obsolete policy model with `ContributionPolicy`, immutable + `ContributionPolicyVersion`, exact `ContributionRule`, and + `ContributionAwardDefinition`; `CompensationAward` is only the evaluated + downstream result. PaymentPolicy has no compatibility path. +- Removed ART and evidence projection from the atomic Review-to-contribution + transaction. CON copies the stabilized versioned `Submission.artifact_hash`; + it does not introduce SubmissionVersion or make an ART/provider call. +- Fixed product cardinality: every valid committed human Review creates one + reviewer `completed_review`; only `accept` additionally creates submitter + `accepted_submission`; automated outcomes create neither. +- Replaced combined role semantics with independent exact `submitter`, + `reviewer`, and `adjudicator` grants. +- Reconciled 22 core proposed ActionIds to existing stable PermissionIds where + present. Policy actions use `contribution.policy.*` while retaining + `compensation.policy.manage`; optional evidence and unapproved executor + candidates are outside the core count. +- Fixed service authorization now requires provisioned ActorProfile/link, + immutable closed ServiceIdentity, exact static matrix row, AUTH-09E, typed + context, prepared mutation protocol, and later AUTH activation. There is no + persisted service grant/action-assignment row. +- Kept complete 25-action ART and 19-action REV activation-custody transfer in + WS-XINT/AUTH ownership. WS-CON references those complete handoffs and does not + restate partial subsets. +- Split human operations requests/reads/drain observation in CON-10B from + independently authorized async executors in new CON-10C. Outbox dispatch owns + mechanics only and never grants delivery, callback, reconciliation, or + rebuild authority. +- Deferred CON-09A/09B as optional successors. Neither ART nor evidence + projection gates core reads, readiness, or joint REV/CON release. +- Repaired the internal-review evidence gate for renamed/deleted contracts: + deleted headings are recovered from index, HEAD, then review base and retain + their chunk ID; missing provenance, invalid content, non-regular files, and + symlinks fail closed. + +Deterministic evidence passed: Markdown links for 44 changed Markdown files; +stale Workstream wording; stale authorization documentation; stale artifact +contracts; `git diff --check`; Python compilation for all five changed gate +files; 80/80 agent-gate tests; trusted-main ancestry; no backend diff; exact +74 PermissionId / 57 ActionId / nine active / 48 planned runtime catalogue; +and the 22-action proposal audit. The repository-wide loop-memory check has one +inherited failure: merged `origin/main` leaves the unchanged WS-AUTH status at +the human merge checkpoint. WS-CON does not edit that externally owned file to +conceal the failure. + +Application/runtime code changed: no. The original PDF deletion remains the +pre-existing unstaged user-worktree change and is excluded from both commits. + ## 2026-07-16 ART-02A2 PR #129 And Exact Custody Reconciliation This addendum is the current authoritative review state and supersedes older From c02afaf81b4490eb3393573e65ab32d4ac6d13d4 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 09:40:32 +0100 Subject: [PATCH 11/22] Reconcile CON with FinalAcceptance boundary --- .../AUTHORIZATION_HANDOFF.md | 12 +- .../CHUNK_MAP.md | 35 +++--- .../CONFORMANCE_MATRIX.md | 6 +- .../DECISIONS.md | 57 ++++++++-- .../DISCOVERY.md | 40 +++++-- .../INTENT.md | 22 ++-- .../JOINT_RELEASE_HANDOFF.md | 84 ++++++++++++-- .../PLAN.md | 107 ++++++++++++++---- .../RISKS.md | 4 +- .../SOURCE_MANIFEST.md | 23 ++++ .../STATUS.md | 22 ++-- ...-CON-001-01-canonical-contract-adoption.md | 4 + ...-001-03C-contribution-award-persistence.md | 32 ++++-- ...-economic-terms-cutover-and-task-freeze.md | 2 +- ...review-lease-contribution-policy-freeze.md | 5 +- ...c-review-contribution-award-participant.md | 36 ++++-- .../WS-CON-001-11-hidden-release-readiness.md | 12 +- ...1-PLAN2-final-acceptance-reconciliation.md | 107 ++++++++++++++++++ ...-CON-001-PLAN2-internal-review-evidence.md | 85 ++++++++++++++ README.md | 9 +- .../workstream_architecture_brief.md | 2 +- docs/architecture_data_model.md | 73 ++++++++++-- docs/architecture_lifecycle_state_machine.md | 20 +++- docs/architecture_lockdown.md | 18 ++- docs/architecture_system_architecture.md | 2 +- docs/glossary.md | 20 +++- docs/operations_operator_workflow.md | 31 +++-- docs/operations_payment_reputation.md | 29 +++-- docs/operations_queue_policy.md | 15 ++- docs/operations_reviewer_workflow.md | 44 +++++-- docs/product_first_user_flows.md | 12 +- docs/risk_register.md | 13 ++- docs/template_project_guide.md | 14 +-- docs/template_review_packet.md | 7 +- 34 files changed, 809 insertions(+), 195 deletions(-) create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN2-final-acceptance-reconciliation.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md index 85d8a59e..be721fea 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -44,9 +44,15 @@ turn a fake/test decision into a production allow path. - administrative policy, binding, project reads, and operations: one exact eligible AdminRoleGrant selected by the action evaluator. -`submitter`, `reviewer`, and `adjudicator` are independent immutable grants. -There is no combined grant. Adjudicator does not substitute for submitter or -reviewer. One role's revocation leaves every other project/admin grant intact. +The shipping path consumes exact `submitter` and `reviewer` grants. There is no +combined grant and no unrelated project/admin grant substitutes. WS-CON adds no +adjudication grant or action and has no adjudication readiness dependency; any +separate global project-role catalogue state remains AUTH-owned and outside +this transaction. + +FinalAcceptance creation has no ActionId. It is an internal REV-owned +consequence of an already-authorized `review.decision` with `accept`; CON only +validates and consumes the locked fact when creating `accepted_submission`. ### Fixed service diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md index 7a9736ac..3b2350e8 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -11,21 +11,22 @@ availability writer. Optional evidence chunks are not part of the core order. | Chunk | Title | Risk | Gate | Status | |---|---|---:|---|---| -| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Reconciled to PR #139; internal review pending | +| `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Complete; unpublished | +| `WS-CON-001-PLAN2` | Final Acceptance Reconciliation | L0 | Human FinalAcceptance/no-adjudication direction | Complete; unpublished | | `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Reconciled plan and human decisions approved | Proposed | | `WS-CON-001-02A` | Shared Transactional Outbox Persistence | L1 | 01; event ownership approved | Proposed | | `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; AUTH registers `outbox.dispatch`, approved `workstream.outbox.dispatcher` ServiceIdentity/static row, AUTH-09E admission, prepared protocol; dispatcher remains disabled until AUTH activation | Proposed | | `WS-CON-001-02C` | Shared Lifecycle Audit Participant | L1 | 02B; current AuditEvent contract refreshed | Proposed | | `WS-CON-001-03A` | Project Compensation Adapter-Binding Persistence | L1 | 02C; migration head refreshed | Proposed | | `WS-CON-001-03B` | Contribution Policy Persistence | L1 | 03A; legacy-data rule | Proposed | -| `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; exact merged REV FK targets | Proposed | +| `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; exact merged REV FinalAcceptance/Review/ReviewLease FK targets | Proposed | | `WS-CON-001-03D` | Delivery, Receipt, And Status Persistence | L1 | 03C | Proposed | | `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; planned AUTH binding actions/contexts/prepared protocol; callback ServiceIdentity/action/static row approved but inactive | Proposed | | `WS-CON-001-04B` | Hidden Contribution-Policy Service | L1 | 03B, 04A; binding activation merged; planned `contribution.policy.*` actions/contexts/prepared protocol | Proposed | | `WS-CON-001-05A` | Legacy Economic Terms Cutover And Task Freeze | L1 | 04B; exact Submission/TaskAssignment lineage; AUTH task.claim with exact submitter grant and prepared protocol active; legacy rule | Proposed | | `WS-CON-001-05B` | Legacy Economic Schema Removal | L1 | 05A; zero-consumer scan; removal migration approval | Proposed | | `WS-CON-001-06` | Review-Lease Contribution-Policy Freeze Capability | L1 | REV lease schema; 05B; planned review.claim typed/prepared contract; exact reviewer grant facts stable | Proposed | -| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D, 05A, 06; merged TaskAssignment freeze field and REV ReviewLease schema/hidden claim composition carrying non-null reviewer policy version; shared audit/outbox; planned review.decision typed/prepared contract | Proposed | +| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D, 05A, 06; merged TaskAssignment freeze field and REV ReviewLease plus accept-only FinalAcceptance persistence and locked decision-lineage contract; shared audit/outbox; planned review.decision typed/prepared contract | Proposed | | `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07, 02B; exact delivery ServiceIdentity/ActionId/static row registered but planned; AUTH-09E typed context/prepared protocol; ADR 0014 adapter foundation; lifecycle-fence port | Proposed | | `WS-CON-001-08R` | Bound-Service Callback Rate Control | L1 | 08A; shared API-control contract | Proposed | | `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; exact callback ServiceIdentity/ActionId/static row, AUTH-09E context, prepared protocol, and callback-fence port | Proposed | @@ -39,7 +40,7 @@ availability writer. Optional evidence chunks are not part of the core order. ## Core dependency order ```text -PLAN -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D +PLAN -> PLAN2 -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D -> 04A -> 04B -> 05A -> 05B -> 06 -> 07 -> 08A -> 08R -> 08B -> 10A -> 10B -> 10C -> 11 ``` @@ -68,13 +69,17 @@ AUTH registration -> CON hidden behavior -> AUTH activation -> later consumer/re activates review.claim after both merge. - Review decision requires the reviewer grant and no-self-review/lifecycle guards. CON-07 starts only after the TaskAssignment submitter freeze and REV - ReviewLease reviewer freeze/hidden claim composition are merged with non-null - policy-version lineage. CON-07 supplies the flush-only participant with no - ART/evidence work; REV supplies hidden decision composition; AUTH activates - review.decision afterward. -- CON-07 creates contributions, applicable awards, audit, and shared-outbox rows - in the Review transaction. It copies stabilized artifact-hash lineage and - performs no ART call. + ReviewLease reviewer freeze plus accept-only FinalAcceptance persistence and + locked decision-lineage contract are merged with non-null policy-version + lineage. CON-07 then supplies the flush-only participant with no ART/evidence + work; REV consumes that participant in hidden decision composition, stages + shared audit/outbox, and owns the single commit. AUTH activates + `review.decision` only after that hidden REV composition merges. +- CON-07 creates contributions and applicable awards in the Review transaction. + Reviewer work is sourced from Review; submitter work is sourced only from + REV-owned FinalAcceptance. REV stages shared audit/outbox rows, owns the + single commit, and supplies stabilized artifact-hash lineage; no ART call is + made. - CON-08A/B and 10C cannot reuse outbox dispatcher authority for delivery, callback, reconciliation, or rebuild execution. - CON-10A owns core PostgreSQL contribution/award reads directly; it does not @@ -93,15 +98,17 @@ AUTH registration -> CON hidden behavior -> AUTH activation -> later consumer/re owns the shared caller-transaction audit participant. - 03A uses `ProjectCompensationAdapterBinding`; 03B owns ContributionPolicy, versions, rules, and award definitions; 03C/D own contribution/award and - downstream fulfillment records respectively. + downstream fulfillment records respectively. 03C references but never owns + REV's FinalAcceptance. - 04A/04B add hidden binding and policy services while AUTH actions remain planned. - 05A removes semantic consumers and freezes task assignments; 05B removes dead physical schema. - 06 exposes only a CON policy-freeze capability; REV owns ReviewLease schema and wiring. -- 07 exposes only the flush-only decision participant; REV owns Review and the - single commit. No evidence projection is staged. +- 07 exposes only the flush-only decision participant; REV owns Review, + FinalAcceptance, shared audit/outbox staging, and the single commit. No + evidence projection is staged. - 08A is a feature handler with its own protected execution boundary; 08R owns rate-control scope; 08B owns callback authentication/composition. - 09A/09B are deferred optional projection chunks and must be re-reviewed if diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md index aab14bbd..eeb526fb 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -5,10 +5,11 @@ | Canonical policy model | 01,03B,04B | ContributionPolicy/version/rules/definitions; explicit unpaid; immutable publish; one active policy; stable binding references | CON-11 | | Legacy clean cut | 05A,05B | zero semantic consumers before schema removal; deterministic row treatment; no alias/fallback; migration upgrade/downgrade | CON-11 | | Authorization | AUTH + each feature | 74/57 baseline refreshed; proposed mappings exact; full ART/REV custody referenced; one AUTH custodian; planned denial; exact grant/static row; AUTH-09E; prepared handle misuse; no local role logic | AUTH activation + CON-11 | -| Contribution cardinality | 03C,07 + REV | one completed_review per valid Review; accept adds accepted_submission; revision Reviews distinct; automated outcomes create none | joint live drill | +| Final acceptance | REV + 03C,07 | accept creates one immutable FinalAcceptance per task/Review/Submission; needs_revision/reject create none; no create API/action, reopen, replacement, or adjudication path | joint live drill | +| Contribution cardinality | 03C,07 + REV | one completed_review per valid Review with direct Review/lease lineage; one accepted_submission per FinalAcceptance with assignment lineage; mutually exclusive sources; revision Reviews distinct; automated outcomes create none | joint live drill | | Policy freeze | 05A,06 + task/REV | exact submitter/reviewer fields; published version; no drift; publish/suspend races both orders | joint live drill | | Award evaluation | 03C,07 | matching frozen ContributionRule; unpaid creates none; at most one money/points; exact decimal; replay stable | joint live drill | -| Atomic REV/CON | 07 + REV | exact locked request and stabilized digest; CON copies artifact_hash; zero ART calls; every injected failure rolls back Review/task/contribution/award/audit/outbox | joint live drill | +| Atomic REV/CON | 07 + REV | exact locked request and stabilized digest; REV creates accept-only FinalAcceptance and stages audit/outbox; CON copies artifact_hash and flushes contributions/awards; zero ART calls; every injected failure rolls back Review/FinalAcceptance/task/contribution/award/audit/outbox | joint live drill | | Outbox isolation | 02A,02B | stable event/task IDs; claim fencing; retry/dead-letter/replay; dispatcher cannot inherit feature authority; handler returns typed outcome | CON-11 | | Delivery and callback | 08A,08R,08B | exact feature service authority; no I/O under locks; callback/binding/award match; replay and callback-before-ack; immutable receipts | joint live drill | | Product reads | 10A | PostgreSQL contribution/award truth; D11 exact role sets; stable pagination/concealment; no ART/provider data | AUTH activation + joint drill | @@ -16,6 +17,7 @@ | Operations executors | 10C | exact independent fixed-service authority; dispatcher/cross-executor denial; retry/replay/finding proof; projection-only rebuild mutation; immutable contribution/award/receipt truth | AUTH activation + joint drill | | Public release | 11 + REV | hidden before release; exact `/api/v1` manifest; provisioning-aware readiness; no optional evidence/ART gate | joint live drill | | Optional evidence | 09A,09B only if approved | separately reviewed ART/AUTH capability; independent status/failure; no effect on canonical truth or core release | separate optional release | +| No adjudication | all core | only accept/needs_revision/reject; no adjudication grant/action/state/queue/lease/decision/contribution/branch/readiness or initiative dependency | CON-11 + joint drill | Executable node IDs and retained evidence are added by each implementation chunk. Planning rows are contracts, not claims that tests already ran. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md index 39ca84db..53adb42a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -51,10 +51,12 @@ canonical product model. The authorized `review.decision` transaction invokes one mandatory CON participant in the caller's AsyncSession. It creates a reviewer -`completed_review` for every committed Review and a submitter -`accepted_submission` only for `accept`, evaluates each applicable frozen -ContributionRule, and stages applicable awards/audit/outbox rows. It flushes -and never commits. There is no `contribution.materialize` or +`completed_review` for every committed Review. For accept only, REV first +creates FinalAcceptance and CON creates `accepted_submission` from that locked +fact, never directly from Review.decision. CON evaluates each applicable frozen +ContributionRule, stages applicable contribution/award rows, returns typed +audit/outbox inputs to REV, flushes, and never commits. REV stages the shared +audit/outbox records and owns the single commit. There is no `contribution.materialize` or `compensation.award.materialize` action and no no-op production participant. ## D6 - ART Is Not A Core Contribution Dependency @@ -121,11 +123,11 @@ snapshots, double decisions, and feature-side catalogue changes are rejected. **Status:** project-role model resolved by ADR 0015; AdminRole surface choices remain human gates before CON-10A/10B. -ProjectRoleGrant values are exactly `submitter`, `reviewer`, and `adjudicator`. -Task claim requires submitter; review claim/decision require reviewer plus -no-self-review. Adjudicator does not substitute. Revoking one role leaves the -others and AdminRoleGrants unchanged; the owning task/review lifecycle consumes -the exact invalidation. +The current shipping path requires exact `submitter` for task claim and exact +`reviewer` plus no-self-review for review claim/decision. Any unrelated project +or administrative grant does not substitute. The existing global AUTH project- +role catalogue remains AUTH-owned, but WS-CON adds no adjudication grant, +action, invalidation consumer, or readiness dependency. Merged AUTH currently gives Finance Authority `compensation.delivery.reconcile` but not Operator, while the earlier WS-CON @@ -172,3 +174,40 @@ CON-09A/09B are outside the core dependency order. If the human later approves them, their chunk contracts must be refreshed against then-current ART/AUTH contracts and internally reviewed again. The optional evidence action is not counted as a core release action and cannot gate product reads or release. + +## D15 - FinalAcceptance Is The Sole Submitter-Acceptance Source + +**Status:** accepted by explicit human direction on 2026-07-17; REV merge is an +upstream implementation gate. + +REV owns immutable FinalAcceptance and creates it only inside an authorized +`Review(accept)` transaction. There is no manual/public create API and no +separate authorization action: creation is a lifecycle consequence of the +already-authorized review operation. `needs_revision` and `reject` create none. + +The non-accept effects follow REV's canonical lifecycle: `needs_revision` sets +the Task to `needs_revision` and keeps its TaskAssignment `active`; `reject` +sets the Task to `rejected` with a bounded human reason and blocks only the +same-task TaskAssignment with its source Review. Reject changes no grant or +unrelated task. The archival `closed/review_rejected` wording is not adopted. + +The repository's existing immutable `Submission` row is already the submission +version identity. Therefore FinalAcceptance stores canonical `submission_id`, +not `submission_version_id`, and enforces unique task, source Review, and +Submission lineage. The handoff's `policy_context_ref` maps to canonical +immutable `ReviewPolicy.id`, stored as `review_policy_id`; REV proves the locked +same-chain lineage. CON does not interpret it as contribution policy or use it +to decide awards. + +`completed_review` keeps direct Review/ReviewLease lineage and is unique per +Review. `accepted_submission` requires `source_final_acceptance_id` plus the +exact TaskAssignment and is unique per FinalAcceptance; its direct +`source_review_id` is null because the FinalAcceptance already owns that link. +Database checks enforce the mutually exclusive source shapes. + +REV creates Review and optional FinalAcceptance, applies task/assignment +effects, invokes the mandatory CON flush-only participant, stages shared audit/ +outbox records, and commits once. CON failure rolls the entire unit back. ART +and provider calls remain absent; fulfillment begins asynchronously after +commit. V0.1 has no adjudication policy, queue, lease, state, decision, +contribution type, branch, action, readiness check, or initiative dependency. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md index c4164ae6..45e5d66e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -10,6 +10,8 @@ authorization spec, artifact spec, roles/operations docs, and ADRs 0012-0015; - current backend project/task/submission/checker, AUTH, audit, artifact, and migration code/tests; +- human-approved 2026-07-17 FinalAcceptance/no-adjudication direction and the + current sibling REV planning head `69fb231` as discovery-only context; - stale wording, authorization, artifact, link, loop-memory, and agent-gate scanners/tests. @@ -20,7 +22,12 @@ canonical ContributionPolicy aggregate, ContributionRecord, CompensationAward, fulfillment receipt, or status projection runtime. - Existing Submission rows carry `version` and supersession lineage. A separate - SubmissionVersion model would duplicate current identity. + SubmissionVersion model would duplicate current identity. The handoff field + named `submission_version_id` therefore maps to canonical `Submission.id` and + is stored as `submission_id`. +- No FinalAcceptance runtime or reviewed merged REV contract exists yet. The + current sibling REV plan creates Review/task effects directly and must be + reconciled and merged before CON consumes the new fact. - The merged AUTH catalogue has 74 PermissionIds and 57 ActionIds. Nine self/admin actions are active and 48 are planned. No WS-CON ActionId is registered. @@ -40,13 +47,16 @@ 1. `ContributionPolicy`, `ContributionPolicyVersion`, `ContributionRule`, and `ContributionAwardDefinition` decide award eligibility. CompensationAward is the evaluated downstream result. -2. Every valid Review creates reviewer `completed_review`; `accept` additionally - creates submitter `accepted_submission`. +2. Every valid Review creates reviewer `completed_review`. REV creates exactly + one FinalAcceptance for `accept`; submitter `accepted_submission` consumes + FinalAcceptance rather than inferring acceptance from Review.decision. 3. Core contribution creation is a flush-only CON participant in the REV-owned transaction. It performs no ART call or evidence projection. 4. CON copies the stabilized versioned Submission/packet digest supplied by REV into `ContributionRecord.artifact_hash`; it does not verify or rederive it. -5. Project grants are exactly independent submitter, reviewer, and adjudicator. +5. The current shipping path consumes exact submitter and reviewer grants only. + The separate global AUTH role catalogue is not expanded here; no adjudication + behavior or readiness dependency enters WS-CON. 6. ActionOwner is AUTH activation custody. ART and REV transfers must be complete across their full current catalogues; WS-CON cannot prescribe partial subsets. @@ -55,6 +65,9 @@ 8. The shared outbox dispatcher cannot inherit protected feature-handler authority. Delivery, reconciliation, rebuild, and callback boundaries need exact approved service contracts. +9. REV owns FinalAcceptance persistence, Review/task effects, shared audit/ + outbox staging, and the single commit. CON validates the locked acceptance + fact, flushes contributions/awards, returns a typed result, and never commits. ## Relevant files and symbols @@ -69,6 +82,7 @@ | `WS-XINT-001/AUTH_ART_HANDOFF.md` | Full 25-action ART transfer; not a core CON gate | | `backend/app/modules/projects/{models,schemas,repository,service}.py` | Current guide-bound economic fields and consumers to cut over/remove | | `backend/app/modules/tasks/**` | TaskAssignment creation and future submitter policy freeze seam | +| `backend/app/modules/tasks/models.py::Submission` | Existing immutable version identity: `id`, integer `version`, and `supersedes_submission_id`; no SubmissionVersion table | | `backend/app/modules/authorization/{catalogue,policy,kernel,schemas}.py` | Current 74/57/9/48 runtime and stable PermissionIds | | `backend/app/modules/audit/**` | Shared append-only audit extension point | | `backend/app/modules/artifacts/{preparation,sources}.py` | Inactive ART-only preparation; no core CON import | @@ -86,15 +100,18 @@ - No tests yet cover ContributionRecord cardinality, frozen rule evaluation, money/points award uniqueness, fulfillment callback, delivery replay, shared-outbox handler isolation, or REV/CON atomic rollback. +- No tests yet cover FinalAcceptance one-per-task/Review/Submission constraints, + accept-only creation, source-lineage exclusivity, or rollback when CON fails. ## Dependencies - AUTH: reviewed registration and later activation chunks, independent project grants, prepared mutation protocol, fixed service admission, exact CON service identities/static rows, and action-specific evaluators. -- REV: ReviewLease reviewer policy FK, canonical claim/decision composition, - stabilized artifact-hash facts, mandatory CON participant injection, single - route commit, and no no-op fallback. +- REV: ReviewLease reviewer policy FK; canonical claim/decision composition; + REV-owned FinalAcceptance with exact policy-context typing; stabilized + artifact-hash facts; mandatory CON participant injection; REV-staged shared + audit/outbox; single route commit; and no no-op fallback. - Task/Submission: submitter policy freeze and stable assignment/version lineage. - Shared outbox/audit: caller-transaction append and feature-neutral dispatch. - ADR 0014 adapters: typed capability port, factory, and composition-root @@ -107,6 +124,7 @@ |---|---| | Two award-eligibility models | Clean semantic then physical cutover; no fallback | | Contribution missing after Review | Mandatory flush-only participant and one caller commit | +| Submitter contribution inferred from Review decision | REV-owned immutable FinalAcceptance is the only submitter source; exact one-to-one constraints and lineage checks | | ART outage suppresses contribution | No core ART/evidence operation | | Wrong policy version | Assignment/lease freeze before work; immutable published versions | | Cross-domain deadlock | AUTH-first lock order and two-order PostgreSQL tests | @@ -116,6 +134,14 @@ | Partial activation transfer | Consume complete WS-XINT AUTH handoffs, never local subsets | | Legacy row ambiguity | Human-approved deterministic rebuild/classification before migration | | Premature public surface | Hidden behavior until AUTH activation and joint release proof | +| Adjudication leaks into v0.1 | No adjudication type/action/state/queue/readiness dependency; reject and accept remain terminal | + +## Resolved FinalAcceptance policy lineage + +The handoff's UUID `policy_context_ref` maps to canonical immutable +`ReviewPolicy.id`, stored as `review_policy_id`. REV must enforce that exact +locked policy and its same project/task/Submission/Review lineage. CON does not +interpret it as contribution policy or use it for award eligibility. ## Open questions diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md index 4bc74b99..85bf7172 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md @@ -16,14 +16,16 @@ the merged WS-XINT-001 boundary from PR #139. - Every valid recorded human Review creates one immutable reviewer `completed_review` contribution. -- `accept` additionally creates one immutable submitter - `accepted_submission`; `needs_revision` and `reject` do not. +- REV creates one immutable `FinalAcceptance` only for `Review(accept)`. + `accepted_submission` consumes that FinalAcceptance; it is never inferred + directly from `Review.decision`. `needs_revision` and `reject` create neither. - TaskAssignment and ReviewLease freeze independent published ContributionPolicyVersions before work is performed. - Explicit unpaid rules create no award; compensated rules create at most one money and one project-points CompensationAward. -- Review/task effects, contributions, awards, audit, and shared-outbox rows - commit or roll back in one caller-owned transaction. +- REV owns the request and single commit: Review/task effects, optional + FinalAcceptance, CON-flushed contributions/awards, and REV-staged shared + audit/outbox rows commit or roll back together. - Core contribution creation copies stabilized artifact-hash lineage supplied by REV and has no ART or provider dependency. - Downstream adapters fulfill awards but never determine eligibility. @@ -41,8 +43,10 @@ the merged WS-XINT-001 boundary from PR #139. and separately approved. - Provider-specific settlement SDKs, attempts, payout batches, accounts, balances, points ledgers, credits, or blockchain work. -- Reputation scores, aggregates, adjudication, reversals, or mutable - contribution/award truth. +- Reputation scores, aggregates, adjudication, appeals, reversals, or mutable + contribution/award truth. V0.1 has no adjudication policy, action, queue, + lease, state, decision, contribution, branch, readiness gate, or initiative + dependency. - A second artifact store, raw provider references, or ArtifactStore injection. - Frontend work before backend contracts and guards stabilize. @@ -50,8 +54,10 @@ the merged WS-XINT-001 boundary from PR #139. Workstream certifies useful human work independently from external fulfillment. Reviewer work is a contribution for every valid Review. ContributionPolicy -decides what that work earns; immutable awards record the result; adapters carry -out fulfillment later. +decides what that work earns. FinalAcceptance is the stable REV-owned fact that +allows CON to recognize accepted submitter work without treating the mutable +shape of a Review decision as its source. Immutable awards record the result; +adapters carry out fulfillment later. ## Human judgment required diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md index 9affa7e1..60edc0ec 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -2,10 +2,11 @@ ## Boundary -REV owns Review decisions, queue/lease/task effects, release-control state, and +REV owns Review decisions, FinalAcceptance, queue/lease/task effects, shared +audit/outbox staging for the decision transaction, release-control state, and the single route commit. CON owns ContributionPolicy, ContributionRecord, -CompensationAward, fulfillment, shared outbox participation, and CON -audit/projections. AUTH owns all authorization and activation. +CompensationAward, fulfillment behavior, and CON projections. AUTH owns all +authorization and activation. The canonical cross-boundary source is merged `WS-XINT-001/REV_CON_HANDOFF.md`. Sibling worktree state is discovery only until @@ -17,11 +18,18 @@ reviewed and merged to trusted `main`. AUTH prepares review.decision with exact reviewer grant -> REV locks and recomposes canonical facts -> AUTH evaluates once --> REV stages Review/lease/queue/task effects +-> REV stages Review/findings/resolutions, consumes ReviewLease, closes queue +-> on accept, REV creates immutable FinalAcceptance linked to Review, + canonical Submission, Task, submitter, reviewer and locked ReviewPolicy + then accepts Task and completes TaskAssignment +-> on needs_revision, REV sets Task to needs_revision and keeps TaskAssignment active +-> on reject, REV sets Task to rejected with a bounded human reason and blocks + only the same-task TaskAssignment with its source Review -> CON flush-only participant creates reviewer contribution --> on accept only, CON creates submitter contribution +-> on accept only, CON creates submitter contribution from FinalAcceptance, + never directly from Review.decision -> CON evaluates frozen ContributionRules and creates applicable awards --> CON stages audit/outbox rows +-> REV stages shared audit/outbox rows from the typed participant result -> REV route commits once ``` @@ -29,12 +37,58 @@ No no-op participant, post-commit repair, ART call, evidence projection, or provider I/O exists in this transaction. CON copies stabilized artifact-hash lineage from REV facts. +## FinalAcceptance contract + +The external shorthand `submission_version_id` means canonical +`Submission.id`; the repository stores `submission_id` because each immutable +Submission row is already one version. The external `policy_context_ref` means +the exact locked `ReviewPolicy.id`; the repository stores `review_policy_id`. +REV owns this record and the composite same-chain constraints. + +```text +FinalAcceptance + id + project_id + task_id UNIQUE + submission_id UNIQUE + source_review_id UNIQUE + accepted_submitter_id + accepted_at + recorded_by_reviewer_id + review_policy_id +``` + +It is created only inside `Review(accept)`. There is no public/manual creation +API and no separate authorization action. `needs_revision` and `reject` create +none. Accept/reject are terminal in v0.1; there is no adjudication, appeal, +replacement acceptance, or reopen path. + +For `needs_revision`, REV keeps the same TaskAssignment `active`. For `reject`, +REV blocks only that same-task TaskAssignment, binds the block to the reject +Review, and sets the Task to canonical `rejected` with its bounded human reason; +it changes no grant or unrelated task. The archival `closed/review_rejected` +wording is not a lifecycle token. + +Optional reviewer-quality sampling is non-mutating audit only. It does not +delay or replace FinalAcceptance and cannot change Review/task/contribution +truth. + +`completed_review` binds directly to Review and ReviewLease and is unique per +Review. `accepted_submission` binds to FinalAcceptance and TaskAssignment and +is unique per FinalAcceptance. Database checks make those source shapes +mutually exclusive; CON never infers a submitter record by reading +Review.decision. + ## Release prerequisites - ContributionPolicy publish/freeze and adapter-binding behavior are merged. - TaskAssignment and ReviewLease carry exact frozen policy-version IDs. +- REV FinalAcceptance persistence and its locked decision-lineage contract are + merged, including exact task/Review/Submission uniqueness and ReviewPolicy + lineage. - Shared outbox/audit participants and CON-07 are mandatory and merged. -- REV hidden claim/decision composition consumes CON-06/07 and has no fallback. +- REV hidden claim/decision composition then consumes CON-06/07 and has no + fallback. - AUTH complete REV custody transfer, exact evaluators, reviewer grant path, prepared protocol, and activation are merged. - Every public/service CON action has exact AUTH registration, evaluator, @@ -58,11 +112,17 @@ readiness remains false until exact rows exist. ## Joint live proof -The release drill covers accept, needs_revision, reject, explicit unpaid, -money+points, frozen-version changes, repeated/revision Reviews, no-self-review, -grant revocation, atomic rollback, adapter outage/replay, callback-before-ack, -failure then fulfillment, reconciliation, drain fencing, and hidden-to-active -route transition. It asserts zero ART calls in core contribution creation. +The release drill covers accept with exactly one FinalAcceptance, accepted Task, +completed Assignment, and submitter contribution; needs_revision with an active +Assignment and neither acceptance fact nor submitter contribution; reject with +canonical rejected Task, same-task blocked Assignment/source Review, and neither +acceptance fact nor submitter contribution; one reviewer contribution per +Review, explicit unpaid, money+points, frozen-version changes, +repeated/revision Reviews, no-self-review, grant revocation, source-shape and +uniqueness conflicts, atomic rollback, adapter outage/replay, +callback-before-ack, failure then fulfillment, reconciliation, drain fencing, +and hidden-to-active route transition. It asserts zero ART calls and no +adjudication action/state/queue/readiness dependency. ## Ownership and stop diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md index 693e83e7..1f12f251 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -10,9 +10,14 @@ local and has no ART dependency: AUTH prepares review.decision and locks reviewer authority -> REV locks and recomposes canonical Review/Submission facts -> AUTH evaluates once and stages decision evidence --> REV stages Review, lease/queue consumption, and task effects --> CON flush-only participant creates contributions and applicable awards --> CON stages audit and shared-outbox rows +-> REV stages Review/findings/resolutions, consumes ReviewLease, and closes queue +-> on accept, REV creates immutable FinalAcceptance, accepts Task, and completes Assignment +-> on needs_revision, REV sets Task to needs_revision and keeps Assignment active +-> on reject, REV sets Task to rejected with a bounded human reason and blocks + only the same-task Assignment with its source Review +-> CON flush-only participant creates reviewer contribution and, only from + FinalAcceptance, submitter contribution plus applicable awards +-> REV stages shared audit and outbox rows -> REV route commits once ``` @@ -23,8 +28,11 @@ activation sequence and the joint REV/CON release gate pass. ## Canonical product model - `ContributionRecord` is immutable. Every valid recorded human Review creates - one reviewer `completed_review`; only `accept` additionally creates one - submitter `accepted_submission`. + one reviewer `completed_review`. REV creates `FinalAcceptance` only for + `accept`; one submitter `accepted_submission` consumes that stable fact. +- `FinalAcceptance` is an immutable REV-owned internal derived fact, not a + public resource command. It has no independent authorization action or manual + creation API. - Existing `Submission` plus its `version` and `supersedes_submission_id` is the versioned submission identity. WS-CON does not add `SubmissionVersion`. - `ContributionPolicy` is the stable project aggregate. It has one active @@ -53,6 +61,7 @@ activation sequence and the joint REV/CON release gate pass. `AsyncSession` and a typed request containing: - exact Review, ReviewLease, queue/lifecycle fence, and decision; +- exact FinalAcceptance for accept, otherwise null; - versioned Submission, TaskAssignment, task, and project identities; - reviewer and submitter canonical ActorProfile IDs; - lease-frozen reviewer and assignment-frozen submitter @@ -64,15 +73,61 @@ activation sequence and the joint REV/CON release gate pass. CON validates the supplied locked facts, copies the stabilized digest into `ContributionRecord.artifact_hash`, evaluates the matching frozen -`ContributionRule`, stages applicable awards/audit/outbox rows, flushes, and -never commits. It never reads REV or AUTH repositories, evaluates +`ContributionRule`, stages applicable contribution/award rows, returns typed +audit/outbox inputs to REV, flushes, and never commits. It never reads REV or AUTH repositories, evaluates `review.decision`, calls ART, rehashes artifact bytes, performs provider I/O, or offers a no-op production participant. Any CON failure rolls back the complete Review decision. `needs_revision` and `reject` still create the reviewer contribution and any -award earned by its frozen reviewer rule. They create no submitter contribution. -Automated checker outcomes create neither contribution type. +award earned by its frozen reviewer rule. They create no FinalAcceptance or +submitter contribution. Automated checker outcomes create neither contribution +type. + +The REV-owned lifecycle effects are exact and remain inputs to CON rather than +CON behavior: `needs_revision` sets `Task.status = needs_revision` and keeps the +same TaskAssignment `active`; `reject` sets `Task.status = rejected` with the +bounded human reason and sets only the same-task TaskAssignment to `blocked` +with its reject Review reference. Reject changes no actor grant and no other +task or assignment. The archival `closed/review_rejected` wording is not a +canonical status. + +### FinalAcceptance lineage + +REV persists the minimal same-chain fact: + +```text +FinalAcceptance + id + project_id + task_id + submission_id + source_review_id + accepted_submitter_id + accepted_at + recorded_by_reviewer_id + review_policy_id +``` + +The external handoff's `submission_version_id` maps to `submission_id` because +the existing immutable Submission row is already the version identity. The +external `policy_context_ref` maps to the exact locked `ReviewPolicy.id`; REV +must prove the Review, policy, project, task, Submission, submitter and reviewer +chain. PostgreSQL enforces `UNIQUE(task_id)`, `UNIQUE(source_review_id)`, and +`UNIQUE(submission_id)`. There is no reopen, replacement, adjudication, or +second acceptance path in v0.1. + +Any reviewer-quality sampling is a non-mutating audit after the transaction. It +does not delay FinalAcceptance, create a second Review decision, or alter +acceptance/contribution truth. + +Reviewer contributions require direct `source_review_id` and +`source_review_lease_id`, with `source_final_acceptance_id` null. Submitter +contributions require `source_final_acceptance_id` and +`source_task_assignment_id`, with direct `source_review_id` and +`source_review_lease_id` null. Partial unique constraints enforce one +`completed_review` per Review and one `accepted_submission` per +FinalAcceptance; checks reject mixed or missing source shapes. ## Contribution-policy freezing @@ -122,12 +177,13 @@ unregistered until their own reviewed registration contract. ### Human project grants -Project contributor grants are exactly independent `submitter`, `reviewer`, -and `adjudicator` rows. Task claim requires one active exact-project submitter -grant. Review claim/decision require one active exact-project reviewer grant -plus no-self-review and lifecycle guards. Adjudicator authority does not -substitute for either. Revoking one grant does not revoke the other two or any -AdminRoleGrant; the owning task/review lifecycle consumes its exact invalidation. +The shipping path consumes exactly two project authorities: task claim requires +one active exact-project `submitter` grant, while review claim/decision require +one active exact-project `reviewer` grant plus no-self-review and lifecycle +guards. Any unrelated project or administrative grant does not substitute. +WS-CON introduces no adjudicator grant/action, adjudication invalidation +consumer, or readiness dependency; the separate global AUTH role catalogue is +outside this lifecycle contract. ### Prepared mutation protocol @@ -185,10 +241,12 @@ actor/link authority, then its idempotency row and applicable lifecycle fence. After that common prefix, the owning operation uses one explicit order: - `review.decision`: REV task, assignment, Submission, queue/lease, Review and - finding rows in REV's canonical order; the assignment- and lease-frozen + finding/resolution rows in REV's canonical order; accept-only + FinalAcceptance plus exact task/assignment effects; the assignment- and lease-frozen ContributionPolicyVersion, matching rule/definition, and referenced binding; stabilized reviewed-packet and Submission artifact-hash lineage; then - ContributionRecord, CompensationAward, audit, and shared-outbox rows; + ContributionRecord and CompensationAward; then REV-owned shared audit and + outbox append participants; - task/review claim freeze: the owning task/assignment/Submission or REV queue/lease rows first, then the selected published policy version, rule/definition and referenced binding, then the frozen lineage write; @@ -251,6 +309,7 @@ subsystem owns no contribution, award, adapter, review, or provider semantics. and activation gates pass. 3. CON-03A-D add inactive policy, binding, contribution, award, delivery, receipt, and status persistence using the canonical names and boundaries. + CON-03C lands only after REV's FinalAcceptance persistence target is merged. 4. CON-04A/B add hidden binding and ContributionPolicy behavior behind planned AUTH actions. 5. CON-05A removes retired semantic consumers and freezes the published @@ -258,8 +317,9 @@ subsystem owns no contribution, award, adapter, review, or provider semantics. physical schema after a zero-consumer proof. 6. CON-06 supplies reviewer policy freeze; the REV owner wires it into hidden review claim behavior before AUTH activates `review.claim`. -7. CON-07 supplies the flush-only decision participant; the REV owner wires it - into the complete hidden decision path before AUTH activates +7. CON-07 supplies the flush-only decision participant that consumes REV-owned + FinalAcceptance for submitter work; the REV owner wires it into the complete + hidden decision path and owns audit/outbox staging before AUTH activates `review.decision`. 8. CON-08A/R/B add fulfillment delivery and callback behavior only after exact service execution/callback identities, actions, static rows, AUTH-09E, and @@ -282,11 +342,12 @@ automatically. - Same-run repository coverage at or above 78 percent and each new/materially changed subsystem at or above 90 percent. - Exact contribution cardinality for all three decisions and repeated/revision - Reviews; automated checks create none. + Reviews; accept-only FinalAcceptance one-to-one constraints; mutually + exclusive reviewer/submitter source shapes; automated checks create none. - Policy publication/freeze races, explicit unpaid rules, immutable published versions, and at most one award per contribution/instrument. -- Participant fault injection proving Review/task/contribution/award/audit/ - outbox atomic rollback and no ART call. +- Participant fault injection proving Review/FinalAcceptance/task/contribution/ + award/audit/outbox atomic rollback and no ART call. - AUTH tests for planned denial, exact grant/static-matrix candidates, prepared handle misuse, role-specific revocation, cross-service denial, and one activation custodian per action. @@ -308,6 +369,8 @@ automatically. approved and registered by AUTH. - Legacy pre-production row classification before CON-05A/05B migration. - Optional evidence projection remains deferred unless separately approved. +- No adjudication decision remains: v0.1 accept/reject are terminal and no + adjudication initiative or readiness gate may enter the core order. ## Review and stop diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md index 4b197f6e..96217824 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -4,6 +4,7 @@ |---|---|---|---| | Competing award-eligibility models | Critical | ContributionPolicy is sole authority; semantic then physical clean cut with no fallback | CON-05A/B | | Review commits without contribution | Critical | Mandatory flush-only participant and one REV-owned commit; fault-injection rollback | CON-07 + REV | +| Submitter contribution inferred from mutable decision shape | Critical | REV-owned immutable FinalAcceptance is the sole accepted_submission source; unique task/Review/Submission and source-shape constraints | REV + CON-03C/07 | | Mandatory ART projection blocks product truth | Critical | No ART/evidence work in core transaction or release; optional successor only | CON-07/09/11 | | Wrong frozen policy | Critical | Assignment/lease freeze before work; immutable versions; concurrency proof | CON-05A/06 | | Dispatcher inherits handler authority | Critical | Dispatcher-only action; exact independent service authority for protected handlers | CON-02B/08A/10C + AUTH | @@ -11,10 +12,11 @@ | Broad or dynamic service access | Critical | Closed ServiceIdentity/static rows, controlled provisioning, AUTH-09E, cross-service denial | AUTH + CON | | Partial ART/REV custody transfer | High | Reference complete WS-XINT handoffs; no local subset or dual writer | AUTH | | Cross-domain deadlock/partial commit | Critical | AUTH-first common prefix; operation-specific REV/task lifecycle-before-policy order; one session/commit; both-order PostgreSQL tests | AUTH + REV + CON | -| Role coupling or substitution | High | Independent submitter/reviewer/adjudicator grants and exact invalidation | AUTH + lifecycle owners | +| Wrong grant substitutes for shipping authority | High | Exact submitter and reviewer grants only; unrelated project/admin grants deny; no adjudication dependency | AUTH + task/REV | | Provider I/O under locks | Critical | Durable pre-I/O state; release transaction/fence before adapter call | CON-08A/outbox | | Callback spoofing/replay | Critical | Exact service identity/static row, binding match, prepared protocol, idempotent receipt | CON-08B + AUTH | | Legacy row ambiguity | High | Human-approved deterministic rebuild/classification; migration fails closed | Human + CON-05 | | Premature public release | High | Hidden OpenAPI, exact manifest, AUTH activation, joint REV/CON gate | CON-11 + REV | +| Adjudication scope leaks into v0.1 | High | Accept/reject are terminal; no adjudication model/action/queue/state/contribution/readiness or initiative gate | REV + CON | No runtime work starts while a blocking decision or prerequisite remains open. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md index af43cc7f..7d3ff17a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -18,6 +18,27 @@ - PR #139 changed planning/canonical docs/scanners, not runtime CON behavior or action availability. +## Human boundary amendment + +- On 2026-07-17 the human fixed the v0.1 shipping path as + `Review(accept) -> FinalAcceptance -> accepted_submission` and explicitly + excluded adjudication lifecycle/actions/readiness. +- The current sibling REV worktree now plans FinalAcceptance and the exact + `accepted`/`needs_revision`/`rejected` effects. That concurrent work remains + discovery-only; WS-CON implementation consumes only reviewed REV contracts + merged to trusted main. +- The amendment's `submission_version_id` is normalized to canonical + `Submission.id` / `submission_id`; current runtime already stores each + immutable version as a Submission row. +- The amendment's `policy_context_ref` is normalized to exact locked + `ReviewPolicy.id` / `review_policy_id`; REV owns and proves that lineage. +- `docs/review_closure.md`, `docs/review_final_adversarial_review.md`, and + `docs/review_adversarial_quality_review.md` are historical internal-review + recommendations, not live lifecycle specifications. Their older “second + review” or “overturned” proposals cannot delay FinalAcceptance, add a second + decision, or gate CON readiness. PLAN2 updates active operations/templates + only and preserves those review records as historical evidence. + ## Normative repository sources - `AGENTS.md` @@ -56,6 +77,8 @@ and 05B own semantic then physical removal after a human migration decision. - No ContributionPolicy, ContributionRecord, CompensationAward, fulfillment, or WS-CON action runtime exists yet. +- No FinalAcceptance runtime exists yet; it will be REV-owned and is a hard + merged-schema/composition prerequisite for CON-03C/07. - Existing `Submission` is the versioned identity; no new SubmissionVersion is required. - ART preparation from PR #129 is inactive foundation only and does not approve diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 34447557..fd6c0a81 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,10 +2,11 @@ ## Current status -`WS-CON-001-PLAN` is reconciled and internally reviewed against trusted `main` -`5d353b6`, which merged WS-XINT-001 boundary reconciliation through PR #139. -The reviewed content commit is `c4242e0`; runtime code is unchanged and the -result remains local/unpublished. +`WS-CON-001-PLAN2` has reconciled the human-approved v0.1 +`Review(accept) -> FinalAcceptance -> accepted_submission` boundary against the +previously reviewed WS-XINT plan. Runtime code is unchanged. The addendum passed +architecture, QA/product/test-delta, and security/auth review on 2026-07-17 and +remains unpublished pending human direction. The prior plan is superseded where it used the older policy aggregate, made ART evidence mandatory, described service action rows as persisted assignments, allowed partial activation-custody transfer, or let outbox dispatch imply @@ -16,7 +17,10 @@ feature-handler authority. - ContributionPolicyVersion and ContributionRule decide award eligibility. - Core Review -> ContributionRecord/Award is one PostgreSQL transaction with no ART call or evidence projection. -- Project grants are independently submitter/reviewer/adjudicator. +- REV creates FinalAcceptance only for accept. Reviewer contributions source + Review directly; submitter contributions source FinalAcceptance only. +- Shipping authority uses exact submitter and reviewer grants only; unrelated + grants do not substitute and WS-CON has no adjudication dependency. - Fixed services require closed ServiceIdentity, exact static matrix membership, provisioned ActorProfile/link, AUTH-09E admission, and active action. - ActionOwner is AUTH activation custody. Complete ART/REV transfers are @@ -27,18 +31,20 @@ feature-handler authority. ## Active chunk -`WS-CON-001-PLAN` only. No implementation chunk is active. +No implementation chunk is active. | Chunk | Status | Notes | |---|---|---| -| `WS-CON-001-PLAN` | Reconciled and internally reviewed; unpublished | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | -| `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required | +| `WS-CON-001-PLAN` | Complete; unpublished | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | +| `WS-CON-001-PLAN2` | Complete; unpublished | FinalAcceptance is REV-owned; CON trigger changes only; all required internal tracks pass | +| `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN2 and upstream merge refresh | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | ## Open gates | Gate | Owner | Required action | |---|---|---| +| FinalAcceptance and decision integration | REV + CON | Merge REV-owned persistence and locked lineage first; then CON-03C/07; then REV consumes CON-07 in hidden single-commit composition before AUTH activation | | Active specification/archive handling | Human | Approve CON-01 repository-owned specification | | Pre-production legacy rows | Human | Choose deterministic rebuild or explicit classified migration before 05A/05B | | D11 AdminRole candidates | Human + AUTH | Fix award-detail, delivery-recovery, and audit candidates before registration | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index 6b80c84e..882c512e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -42,6 +42,10 @@ roadmap changes without synchronized local XLSX/CSV exports unpaid. - [ ] Existing versioned Submission is retained. CON copies stabilized artifact_hash lineage and performs no core ART/evidence operation. +- [ ] Active spec defines REV-owned accept-only FinalAcceptance with canonical + `submission_id` and `review_policy_id`; FinalAcceptance-sourced submitter + contribution; direct Review-sourced reviewer contribution; and one REV-owned + commit. It adds no SubmissionVersion alias or adjudication dependency. - [ ] Optional evidence is clearly deferred with separate ART/AUTH approval and is absent from the core release path. - [ ] AUTH boundary matches PR #139: independent project grants, fixed-service diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md index d109d93d..48c4a499 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md @@ -2,8 +2,9 @@ ## Goal and risk -Persist immutable contribution/award truth against exact merged Review, -ReviewLease, TaskAssignment, and Submission targets. L1 history/economic risk. +Persist immutable contribution/award truth against exact merged +FinalAcceptance, Review, ReviewLease, TaskAssignment, and Submission targets. +L1 history/economic risk. ## Allowed files @@ -28,16 +29,21 @@ mutable/void/delete/adjust path, dependency or CI weakening ## Acceptance criteria - [ ] Existing Submission is the version identity. Project/task/submission/ - Review/lease/assignment/contributor and stabilized artifact_hash lineage are - same-chain and non-null as applicable. + FinalAcceptance/Review/lease/assignment/contributor and stabilized + artifact_hash lineage are same-chain and non-null as applicable. No + SubmissionVersion entity or `submission_version_id` alias is added. - [ ] Reviewer rows are completed_review and bind source Review + ReviewLease + - reviewer + reviewer-frozen policy. Submitter rows are accepted_submission, - bind accepted source Review + TaskAssignment + submitter + submitter-frozen - policy, and are impossible for needs_revision/reject. -- [ ] Exact database uniqueness on `(source_review_id, contribution_type)` - prevents duplicate contribution type for one source Review while allowing - distinct reviewer contributions for distinct revision Reviews. Contributor - identity is a validated lineage field, never part of this uniqueness key. + reviewer + reviewer-frozen policy, with FinalAcceptance/assignment sources + null. Submitter rows are accepted_submission and bind source FinalAcceptance + + TaskAssignment + submitter + submitter-frozen policy, with direct Review/ + lease sources null; they are impossible for needs_revision/reject. +- [ ] Partial uniqueness enforces one completed_review per source Review and one + accepted_submission per source FinalAcceptance. Contributor identity is a + validated lineage field, never part of either uniqueness key. Checks reject + mixed, incomplete, or wrong-type source shapes. +- [ ] `source_final_acceptance_id` references REV's immutable record; the exact + FinalAcceptance task/project/submission/submitter/source-Review chain matches + the contribution, but CON does not infer acceptance from that Review. - [ ] Each award references the exact ContributionRecord, its frozen ContributionPolicyVersion, matching rule/definition, same project/contributor/ contribution type, and same-project/instrument adapter binding. @@ -46,6 +52,8 @@ mutable/void/delete/adjust path, dependency or CI weakening - [ ] Database enforces immutability/at-most-one but does not require a contribution child during staged Review persistence before CON-07 flushes. - [ ] At-least-one per valid Review is deferred to CON-07 + REV-10 + preflight. +- [ ] At-least-one accepted_submission per FinalAcceptance is deferred to + CON-07 + REV hidden composition + preflight. - [ ] No mutable/void/delete/adjust path or legacy accepted-work settlement row/reputation schema. ## Verification and reviewers @@ -53,4 +61,4 @@ mutable/void/delete/adjust path, dependency or CI weakening Execute CON-03C in `../RUNTIME_VERIFICATION.md`; changed subsystems are at least 90 percent. Senior engineering, QA/test, security/auth, product/ops, architecture, docs, reuse/dedup and test-delta are required. Stop if exact -REV-03/REV-04 targets are not merged. +REV FinalAcceptance/Review/ReviewLease targets are not merged. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md index 1e83b5b5..01f20cff 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md @@ -49,7 +49,7 @@ provider/artifact calls; unrelated checker behavior remaining physical schema is unreachable until 05B. - [ ] `task.claim` is registered and active through AUTH with exact same-project submitter ProjectRoleGrant, prepared T protocol, actor/link/grant - revalidation, and canonical task guards. No admin/adjudicator/reviewer grant + revalidation, and canonical task guards. No unrelated project/admin grant substitutes and CON contains no role logic. - [ ] Claim locks active ContributionPolicy, published version, exact rule/ definition/binding dependencies, evaluates the prepared handle once, and diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md index 3b680bde..ad7f91eb 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md @@ -38,8 +38,9 @@ task assignment changes; provider/artifact/adapter calls - [ ] REV-owned ReviewLease has immutable non-null `reviewer_contribution_policy_version_id` and REV owns its write/wiring. - [ ] review.claim uses exact active same-project reviewer ProjectRoleGrant; - submitter/adjudicator/admin grants do not substitute. No-self-review and REV - lifecycle guards remain REV-owned. + unrelated project/admin grants do not substitute. No-self-review and REV + lifecycle guards remain REV-owned; no adjudication behavior or dependency is + introduced. - [ ] CON hidden port and REV hidden composition merge while review.claim remains planned; AUTH later integrates the evaluator and alone activates. - [ ] Policy publish and binding state versus claim pass both lock orders; diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md index 1f74aa0b..60ee5d8c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md @@ -3,9 +3,10 @@ ## Goal Implement the mandatory flush-only participant that creates reviewer and -accept-only submitter contributions, evaluates frozen ContributionRules, creates -applicable awards, and stages audit/outbox rows in the caller-owned Review -transaction. It performs no evidence projection or ART work. +FinalAcceptance-sourced submitter contributions, evaluates frozen +ContributionRules, creates applicable awards, and returns typed audit/outbox +inputs in the caller-owned Review transaction. It performs no evidence +projection or ART work. ## Risk @@ -37,6 +38,7 @@ mutable/delete/void/adjust contribution/award path; reputation scoring The typed request carries the caller AsyncSession and exact locked: - Review, ReviewLease, queue/lifecycle fence, and canonical decision; +- accept-only REV-owned FinalAcceptance, otherwise null; - versioned Submission, TaskAssignment, task, and project; - reviewer/submitter ActorProfile IDs; - reviewer and submitter frozen ContributionPolicyVersion IDs; @@ -47,8 +49,14 @@ The typed request carries the caller AsyncSession and exact locked: ## Acceptance criteria - [ ] Every valid committed Review creates exactly one reviewer - `completed_review`; accept additionally creates one submitter - `accepted_submission`; needs_revision/reject create no submitter record. + `completed_review`. Accept requires exactly one same-chain FinalAcceptance and + creates one submitter `accepted_submission` from it; needs_revision/reject + require no FinalAcceptance and create no submitter record. +- [ ] Locked participant inputs prove REV already applied the exact outcome: + accept has Task `accepted` and Assignment `completed`; needs_revision has Task + `needs_revision` and Assignment still `active`; reject has Task `rejected` + with the bounded human reason and only the same-task Assignment `blocked` with + its source Review. CON does not own or mutate those lifecycle effects. - [ ] Repeated idempotent decision returns the same rows; a later revision Review creates a distinct reviewer contribution; automated outcomes create none. @@ -58,20 +66,24 @@ The typed request carries the caller AsyncSession and exact locked: definitions. - [ ] CON copies the supplied stabilized digest exactly into ContributionRecord.artifact_hash. It does not load/rederive it or call ART. -- [ ] Participant validates exact Review/Submission/assignment/lease/project/ - actor/policy lineage and an allowed review.decision whose actor, action, +- [ ] Participant validates exact FinalAcceptance/Review/Submission/assignment/ + lease/project/actor/policy lineage and an allowed review.decision whose actor, action, resource digest, matched reviewer grant/project, request, and correlation match the locked transaction. -- [ ] Participant uses caller AsyncSession, stages contribution/award/audit and - stable shared-outbox events, flushes, and never commits. It creates no - evidence projection or evidence-request event. +- [ ] Participant uses caller AsyncSession, stages contribution/award rows, + returns canonical typed audit/outbox inputs, flushes, and never commits. REV + stages shared audit/outbox rows after the participant and before its single + commit. CON creates no evidence projection or evidence-request event. - [ ] CON never reads REV/AUTH repositories or evaluates review.decision. REV owns canonical composition and the single route commit. - [ ] AUTH registration -> CON participant -> REV hidden composition -> AUTH evaluator/activation order is proven. Real kernel denies while planned. - [ ] Fault injection at every CON write/flush and every later REV step rolls - back Review/task/contribution/award/audit/outbox together. No post-commit - repair path exists. + back Review/FinalAcceptance/task/assignment/contribution/award/audit/outbox + together. No post-commit repair path exists. +- [ ] No FinalAcceptance create action/API exists. Static/runtime proof finds no + adjudication policy, grant/action, queue/lease, state, decision, contribution, + conditional branch, readiness check, or initiative dependency. - [ ] Static/runtime spies prove zero ART capability, repository, preparation, provider, or evidence calls in every decision path. - [ ] PostgreSQL uniqueness, replay, changed-fact conflict, and concurrency tests diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index ce056266..82554c02 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -53,8 +53,16 @@ archival input edits and fail-closed construction without REV release-control implementation. - [ ] Core conformance matrix has executable evidence; same-run repository coverage is at least 78 and changed subsystems at least 90. -- [ ] Joint drill contract covers all core families and explicitly asserts zero - ART calls in Review-to-contribution creation. It is not marked executed here. +- [ ] Joint drill contract covers all core families. Accept proves Task + `accepted`, Assignment `completed`, one FinalAcceptance and one submitter + contribution. Needs_revision proves Task `needs_revision`, Assignment still + `active`, and neither acceptance fact nor submitter contribution. Reject + proves Task `rejected` with bounded human reason, only the same-task + Assignment blocked with its source Review, and neither acceptance fact nor + submitter contribution. Every Review proves one reviewer contribution. It + explicitly + asserts zero ART calls and no adjudication model/action/state/queue/readiness + dependency. It is not marked executed here. ## Verification diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN2-final-acceptance-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN2-final-acceptance-reconciliation.md new file mode 100644 index 00000000..2a80c6a2 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN2-final-acceptance-reconciliation.md @@ -0,0 +1,107 @@ +# Chunk Contract: WS-CON-001-PLAN2 - Final Acceptance Reconciliation + +## Goal + +Adopt the human-approved v0.1 `Review(accept) -> FinalAcceptance -> +accepted_submission` boundary in WS-CON planning and shared product wording, +without implementing runtime behavior or introducing adjudication. + +## Risk + +L0 architecture/economic/lifecycle specification; P1. + +## Allowed files + +```text +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** +README.md only exact review/final-acceptance/contribution wording +docs/architecture_brief/workstream_architecture_brief.md only contribution principle wording +docs/architecture_data_model.md only FinalAcceptance/contribution lineage and non-mutating reviewer-quality event tokens +docs/architecture_lifecycle_state_machine.md only accepted transition facts and no-adjudication invariant +docs/architecture_lockdown.md only v0.1 acceptance/contribution invariants +docs/architecture_system_architecture.md only replace second-review flags with non-mutating post-decision quality-audit observations +docs/glossary.md only FinalAcceptance/ContributionRecord definitions and exact no-adjudication clarification +docs/operations_reviewer_workflow.md only exact decision effects and non-mutating quality audit +docs/operations_operator_workflow.md only acceptance sequence +docs/operations_payment_reputation.md only contribution/award trigger wording and non-mutating reviewer-quality event tokens +docs/operations_queue_policy.md only accepted-lane required facts +docs/product_first_user_flows.md only reviewer decision effects +docs/risk_register.md only reviewer-quality mitigation wording that could imply a second lifecycle decision +docs/template_project_guide.md only replace mandatory second-review gating with non-mutating quality-audit sampling +docs/template_review_packet.md only replace second-review gating fields with non-mutating quality-audit fields +``` + +## Not allowed + +```text +backend application, migrations, runtime tests, workflows, dependencies +REV/AUTH/ART initiative or runtime edits +reference-spec/PDF byte edits, restoration, rename, or replacement +SubmissionVersion entity or submission_version_id compatibility alias +adjudicator grant/action implementation; adjudication policy, queue, lease, +state, decision, contribution type, branch, readiness gate, or initiative dependency +new authorization action for FinalAcceptance creation +manual/public FinalAcceptance creation API +rewriting historical docs/review_* internal-review evidence +``` + +## Acceptance criteria + +- [x] REV owns immutable `FinalAcceptance`, creates it only as an internal + consequence of an authorized `Review(accept)`, and exposes no independent + create action or API. +- [x] Existing immutable `Submission` remains the version identity. The + external `submission_version_id` shorthand maps to canonical `submission_id`; + no duplicate entity or alias is introduced. +- [x] FinalAcceptance has exact task/project/submission/Review/submitter/ + reviewer/time/policy-context lineage and unique task, Review, and Submission + constraints. REV must type the policy-context reference against its canonical + immutable review-policy fact before its persistence chunk starts. +- [x] `completed_review` remains directly sourced from every valid human Review + and ReviewLease. `accepted_submission` is sourced only from FinalAcceptance + plus TaskAssignment and never inferred directly from Review.decision. +- [x] One completed_review exists per Review and one accepted_submission per + FinalAcceptance; needs_revision/reject create no FinalAcceptance or submitter + contribution. +- [x] Outcome effects match REV's canonical lifecycle exactly: accept sets Task + `accepted` and Assignment `completed`; needs_revision sets Task + `needs_revision` and keeps Assignment `active`; reject sets Task `rejected` + with a bounded human reason and blocks only the same-task Assignment with its + source Review. No `closed/review_rejected` token, grant mutation, or unrelated + task effect is introduced. +- [x] The REV request owns one transaction. REV creates Review and optional + FinalAcceptance, invokes CON flush-only contribution/award behavior, stages + shared audit/outbox records, and commits once. +- [x] Any CON failure rolls back Review, FinalAcceptance, task/assignment + effects, contributions, awards, audit, and outbox together. External + fulfillment starts only after commit. +- [x] Core contribution creation copies stabilized Submission artifact-hash + lineage and makes zero ART/provider calls. +- [x] WS-CON has no adjudication lifecycle, action, state, queue, contribution, + authorization, or release dependency. Existing unrelated AUTH role catalogue + state is neither expanded nor implemented here. +- [x] Required internal reviewers pass the exact final snapshot; no sub-agent + session remains open. + +## Verification + +```bash +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py +git diff --check +test -z "$(git diff --name-only -- backend)" +``` + +## Reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +reuse/dedup, and test-delta. CI integrity is N/A only if no script, workflow, +dependency, test, threshold, or runner changes. + +## Stop + +Stop after reviewed specification reconciliation. Do not implement +FinalAcceptance, start CON-01/03C/07, push, or open a PR automatically. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md new file mode 100644 index 00000000..6abf53a4 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md @@ -0,0 +1,85 @@ +# WS-CON-001-PLAN2 Internal Review Evidence + +Date: 2026-07-17 + +## Reviewed boundary + +The reviewed specification snapshot establishes: + +- `Review(accept) -> FinalAcceptance -> accepted_submission`; +- one reviewer `completed_review` for every valid human Review; +- REV-owned Review/FinalAcceptance/task/assignment/audit/outbox orchestration + and one commit; +- CON-owned flush-only contribution/award participation with no ART or provider + call; +- canonical `Submission.id` version identity and exact immutable + `ReviewPolicy.id` lineage; +- exact `accepted`, `needs_revision`, and `rejected` effects; and +- no v0.1 adjudication action, policy, queue, lease, state, decision, + contribution, branch, readiness dependency, manual FinalAcceptance API, or + independent FinalAcceptance authorization action. + +The pre-existing deletion of the archival WS-CON PDF was excluded from this +chunk and remains user-owned. + +## Internal reviews + +### Architecture + +Final result: PASS. + +Resolved findings: + +- removed the REV/CON cycle by ordering REV persistence and locked lineage, + then CON-03C/07, then REV hidden composition, then AUTH activation; +- resolved `policy_context_ref` to canonical immutable `ReviewPolicy.id`; +- reverted an out-of-scope global AUTH role-catalogue wording change; +- bounded active reviewer-quality wording changes explicitly in PLAN2; and +- consolidated duplicate second-review/template language into non-mutating + post-decision quality-audit sampling. + +### QA, product/ops, docs, and test delta + +Final result: PASS. + +Resolved findings: + +- made non-accept effects exact: needs revision keeps the Assignment active; + reject uses canonical Task `rejected`, blocks only the same-task Assignment + with its source Review, and changes no grant or unrelated task; +- rejected the archival `closed/review_rejected` token using current REV plan, + discovery, and conformance evidence; +- classified historical `docs/review_*` recommendations as non-normative; and +- removed active mutating “overturned”/second-review wording in favor of + non-mutating reviewer-quality audit observations. + +### Security and authorization + +Final result: PASS. + +The reviewer confirmed no FinalAcceptance ActionId/API, adjudication path, +catalogue/runtime/backend change, grant mutation, cross-task reject effect, or +authorization bypass. CON remains flush-only and REV remains the sole commit +owner. + +## Deterministic evidence + +Passed on the final reviewed snapshot: + +```text +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py +git diff --check +test -z "$(git diff --name-only -- backend)" +``` + +Result: 80 agent-gate tests passed; markdown links and all stale-contract scans +passed; no backend delta exists. + +## Stop + +PLAN2 is complete but unpublished. No runtime chunk, push, or PR begins without +explicit human direction. diff --git a/README.md b/README.md index ce633c0b..5b7d1004 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Project Guide -> Platform Checkers -> Human Review -> Needs Revision / Accepted / Rejected +-> Final Acceptance on Accepted -> Contribution Record -> Compensation Award / Fulfillment when payable -> Reputation Update @@ -51,7 +52,8 @@ Different projects speak different domain languages, but serious task evaluation - every review creates a decision - every revision must close prior feedback - every valid human review creates a reviewer contribution -- every accepted task additionally creates a submitter contribution +- every accepted Review creates one immutable FinalAcceptance +- every submitter accepted_submission contribution consumes FinalAcceptance - every payable contribution updates compensation fulfillment; all contributions can update reputation @@ -252,7 +254,7 @@ Run checks Review packet Record review decision: accept, needs_revision, or reject Create reviewer contribution for every valid human review -Create submitter contribution only for accepted work +On accept, create FinalAcceptance then create the submitter contribution only from it Record compensation status only for payable contribution awards Update reputation from review outcome Review lessons learned @@ -287,7 +289,8 @@ Artifacts, evidence, and auditing: Contribution and compensation: - every valid human review creates a reviewer contribution from locked evidence -- accepted work additionally creates a submitter contribution +- accepted work creates an immutable FinalAcceptance, which is the sole source + for the submitter contribution - only payable contributions create immutable awards and fulfillment tracking; explicit unpaid rules create none - compensation fulfillment is recorded separately from task acceptance diff --git a/docs/architecture_brief/workstream_architecture_brief.md b/docs/architecture_brief/workstream_architecture_brief.md index adfb4f73..187a548f 100644 --- a/docs/architecture_brief/workstream_architecture_brief.md +++ b/docs/architecture_brief/workstream_architecture_brief.md @@ -44,7 +44,7 @@ Current v0.1 is backend-first and internal-loop-first. External source adapters, | Postgres record database | Local, CI, and production-like development use Postgres as the record database. | | Object-storage abstraction | Local filesystem storage is allowed only behind the provider-neutral `ArtifactStore`; AWS S3 is the v0.1 hosted provider and MinIO is the local/CI protocol proof. | | Async-first execution | Long-running checker work does not block request/response paths. | -| Contribution before compensation | Every valid human review creates a reviewer contribution; accepted work additionally creates a submitter contribution. Compensation and reputation attach afterward. | +| Contribution before compensation | Every valid human Review creates a reviewer contribution; accepted work creates REV-owned FinalAcceptance, which alone sources the submitter contribution. Compensation and reputation attach afterward. |
diff --git a/docs/architecture_data_model.md b/docs/architecture_data_model.md index e4bcfe4d..2eb4b47a 100644 --- a/docs/architecture_data_model.md +++ b/docs/architecture_data_model.md @@ -44,6 +44,7 @@ Task ReadinessCertificate (later optional) Review ReviewFinding + FinalAcceptance (accept only) RevisionReplay RevisionContextPreparation ContributionRecord @@ -1452,6 +1453,36 @@ new ReviewLease independently freezes the then-current The contributor and reviewer packets must show the prior version, next version, rebase reason, and change summary when `context_rebased = true`. +## FinalAcceptance + +Fields: + +- `id` +- `project_id` +- `task_id` +- `submission_id` +- `source_review_id` +- `accepted_submitter_id` +- `accepted_at` +- `recorded_by_reviewer_id` +- `review_policy_id` + +Purpose: + +This immutable REV-owned internal fact is created only inside the authorized +`Review(accept)` transaction. Existing `Submission` is already the version +identity, so the stored FK is `submission_id`; no SubmissionVersion entity or +`submission_version_id` alias is introduced. `review_policy_id` is the exact +locked ReviewPolicy context for the accepted Review. + +PostgreSQL enforces `UNIQUE(task_id)`, `UNIQUE(source_review_id)`, and +`UNIQUE(submission_id)` plus same-project/task/Submission/Review/submitter/ +reviewer/policy lineage. There is no public/manual create API and no separate +authorization action. `needs_revision` and `reject` create none. Accept/reject +are terminal in v0.1; no adjudication or replacement-acceptance path exists. +Reviewer-quality sampling is a non-mutating audit and never delays or changes +this record. + ## ContributionRecord Fields: @@ -1464,6 +1495,7 @@ Fields: - `contributor_id` - `source_review_id` - `source_review_lease_id` +- `source_final_acceptance_id` - `source_task_assignment_id` - `artifact_hash` - `contribution_policy_version_id` @@ -1472,11 +1504,20 @@ Fields: Purpose: The record is immutable. Every valid recorded human Review creates one reviewer -`completed_review` contribution. `accept` additionally creates one submitter -`accepted_submission`; `needs_revision` and `reject` do not. The record carries -the exact Review, submission, assignment or lease, frozen contribution policy, -and stabilized artifact-hash lineage. Compensation awards and reputation events -may reference it, but do not replace it. +`completed_review` contribution with direct Review and ReviewLease lineage. +`Review(accept)` creates FinalAcceptance; exactly one submitter +`accepted_submission` consumes that fact plus the exact TaskAssignment. +`needs_revision` and `reject` create no FinalAcceptance or submitter record. + +Reviewer rows require `source_review_id` and `source_review_lease_id` and have +null FinalAcceptance/assignment sources. Submitter rows require +`source_final_acceptance_id` and `source_task_assignment_id` and have null +direct Review/lease sources. Partial unique constraints enforce one +`completed_review` per Review and one `accepted_submission` per +FinalAcceptance; database checks reject mixed or incomplete source shapes. The +record carries the exact Submission, actor, frozen contribution policy, and +stabilized artifact-hash lineage. Compensation awards and reputation events may +reference it, but do not replace it. ## CompensationAward @@ -1563,8 +1604,12 @@ Event types: - revision_closed - contribution_recorded - compensation_fulfilled -- review_overturned -- review_confirmed +- review_quality_audit_completed +- review_quality_issue_flagged + +Reviewer-quality events are non-mutating observations. They cannot reopen or +replace Review, FinalAcceptance, task, contribution, or award truth and are not +adjudication decisions. ## AuditEvent @@ -1618,12 +1663,18 @@ open an independent session. registered scoped permission and cannot bypass missing task policy context - a submission must belong to a task - a review must belong to a submission -- an accepted task must have at least one accepted submission +- an accepted task must have exactly one immutable FinalAcceptance bound to its + accepted Submission and source Review - every valid recorded human review must create one reviewer `completed_review` contribution -- an accepted task must additionally create one submitter - `accepted_submission` contribution -- `needs_revision` and `reject` must not create a submitter contribution +- every FinalAcceptance must create one submitter `accepted_submission` + contribution in the same transaction +- `needs_revision` and `reject` must not create FinalAcceptance or a submitter + contribution +- FinalAcceptance is unique per task, source Review, and Submission and has no + independent creation API/action +- v0.1 has no adjudication state/action/queue/lease/decision/contribution or + readiness dependency - no compensation award exists without its contribution record - a fulfilled award must have an immutable fulfillment receipt with the exact authorized quantity and external reference diff --git a/docs/architecture_lifecycle_state_machine.md b/docs/architecture_lifecycle_state_machine.md index 07748011..9d25491f 100644 --- a/docs/architecture_lifecycle_state_machine.md +++ b/docs/architecture_lifecycle_state_machine.md @@ -156,6 +156,8 @@ Required before entering: - from `REVIEW_PENDING`: review decision id, at least one structured review finding, reviewer `completed_review` contribution, and any applicable reviewer award +- from `REVIEW_PENDING`: the same TaskAssignment remains `active`, with no + FinalAcceptance or submitter contribution Before the contributor resumes, Workstream prepares the next revision context. That preparation checks whether the active project guide or policy context changed since the prior submission was locked. Revision policy decides whether the next attempt keeps the prior context, rebases to the current active context, or is blocked for project-manager repair. @@ -168,6 +170,9 @@ The submission is accepted. Required before entering: - accepted review decision +- one immutable FinalAcceptance bound to the accepted Review, existing + versioned Submission, task, submitter, recording reviewer, and locked + ReviewPolicy - no unresolved blocking checker failure under the locked post-submit checker policy - evidence present - reviewer cited evidence supporting acceptance @@ -178,8 +183,9 @@ Required before entering: Required side effects: - reviewer `completed_review` contribution created with the Review -- submitter `accepted_submission` contribution created from the accepted - submission, accepting Review, frozen policy lineage, and artifact hash +- submitter `accepted_submission` contribution created from FinalAcceptance, + the exact TaskAssignment, frozen policy lineage, and artifact hash; it is not + inferred directly from Review.decision - applicable awards created independently from the reviewer and submitter contribution records - reputation events reference the applicable contribution record @@ -191,9 +197,15 @@ The task or submission is rejected. Required before entering: - rejection review decision -- rejection reason +- bounded human rejection reason - reviewer `completed_review` contribution and any applicable reviewer award +Required side effects: + +- same-task TaskAssignment is `blocked` and bound to the source reject Review +- no other task, assignment, or actor grant changes +- no FinalAcceptance or submitter `accepted_submission` exists + ### CANCELLED The task is cancelled before acceptance. @@ -228,6 +240,7 @@ No administrative or recovery grant authorizes these transitions: - `SUBMITTED -> REVIEW_PENDING` without checker run - `REVIEW_PENDING -> ACCEPTED` without review decision +- `REVIEW_PENDING -> ACCEPTED` without exactly one FinalAcceptance - `REVIEW_PENDING -> ACCEPTED` without contribution record creation - `NEEDS_REVISION -> ACCEPTED` without new submission or explicit finding closure - `SUBMITTED -> ACCEPTED` directly @@ -236,6 +249,7 @@ No administrative or recovery grant authorizes these transitions: - compensation projection `pending -> fulfilled` without an immutable payable award and fulfillment receipt - compensation exposure without a contribution record and frozen policy +- adjudication, appeal, acceptance replacement, or reopen transition in v0.1 - fulfillment without an external reference ## Submission Versioning diff --git a/docs/architecture_lockdown.md b/docs/architecture_lockdown.md index ebe0a384..d1e7bfd2 100644 --- a/docs/architecture_lockdown.md +++ b/docs/architecture_lockdown.md @@ -59,6 +59,10 @@ local ActorProfile/ActorIdentityLink records, administrative grants, exact-project submitter/reviewer/adjudicator grants, registered permissions, resource and lifecycle guards, revocation, and append-only authority evidence. +The global role catalogue does not define the v0.1 review lifecycle. Shipping +uses submitter and reviewer authority only; no adjudication policy, action, +queue, lease, state, decision, contribution, or readiness dependency exists. + Token roles and typed workflow profiles are not product authority. All public routes remain under `/api/v1`. ADR 0012 and the canonical authorization service specification control authorization wording in this lockdown. @@ -181,15 +185,23 @@ separate deferred adapter initiatives and are not v0.1 runtime dependencies. Every valid recorded human Review creates an immutable reviewer `completed_review` contribution record, regardless of whether the decision is -`accept`, `needs_revision`, or `reject`. An `accept` decision additionally -creates one submitter `accepted_submission` contribution record. Automated -checker outcomes create neither type. +`accept`, `needs_revision`, or `reject`. REV creates one immutable +FinalAcceptance only for `accept`; that fact, not direct inspection of +`Review.decision`, sources one submitter `accepted_submission` contribution +record. `needs_revision`, `reject`, and automated checker outcomes create no +FinalAcceptance or submitter contribution. Contribution records are separate from compensation status. Each record freezes its exact review, submission, actor, policy, and artifact-hash lineage. Compensation awards and reputation events may attach to a contribution record, but do not replace it. +FinalAcceptance is internal and REV-owned. It has no independent API/action, +uses canonical `Submission.id` because each Submission row is already a +version, and is unique per task, source Review, and Submission. V0.1 contains +no adjudication policy, action, queue, lease, state, decision, contribution +type, branch, readiness check, or adjudication-initiative dependency. + ## Deferred These ideas remain architecture-compatible, but they are not part of the first build: diff --git a/docs/architecture_system_architecture.md b/docs/architecture_system_architecture.md index 9000c393..8c5140f2 100644 --- a/docs/architecture_system_architecture.md +++ b/docs/architecture_system_architecture.md @@ -184,7 +184,7 @@ Owns: - review queue - findings - review decisions -- second-review flags +- non-mutating post-decision reviewer-quality audit selections and observations - reviewer audit history ### Revision Service diff --git a/docs/glossary.md b/docs/glossary.md index bba3c7db..28d0625e 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -144,9 +144,9 @@ through separate active grants. The umbrella human product term for a person participating in Workstream. A contributor may have exact-project `submitter`, `reviewer`, and `adjudicator` grants as independent records. The adjudicator grant creates no adjudication -capability until WS-REV defines the lifecycle and AUTH activates exact -adjudication actions. Celery, checker, setup, and background workers are -internal services, not human product roles. +capability in v0.1 and creates no review-lifecycle or release dependency. +Celery, checker, setup, and background workers are internal services, not +human product roles. ## Source @@ -312,10 +312,22 @@ The outcome-based record of contributor and reviewer performance. The immutable, evidence-backed record of one completed contribution under locked project context. `completed_review` is created for every valid recorded human -Review; `accepted_submission` is created for the submitter only on `accept`. +Review and binds directly to that Review and ReviewLease. +`accepted_submission` is created only from FinalAcceptance and the exact +TaskAssignment; it is never inferred directly from `Review.decision`. Compensation and reputation records may attach to either contribution type, but do not replace the contribution record. +## Final Acceptance + +The immutable REV-owned internal fact created only as a lifecycle consequence +of `Review(accept)`. It binds one project, task, existing versioned Submission, +source Review, accepted submitter, recording reviewer, acceptance time, and +locked ReviewPolicy. There is no public/manual create API or separate +authorization action. `needs_revision` and `reject` create none. In v0.1 it is +unique per task, source Review, and Submission and is the sole source of an +`accepted_submission` ContributionRecord. + ## Human Owner The person accountable for a submitted packet, even when agents or external tools helped produce the work. diff --git a/docs/operations_operator_workflow.md b/docs/operations_operator_workflow.md index 854efb57..2ab5f263 100644 --- a/docs/operations_operator_workflow.md +++ b/docs/operations_operator_workflow.md @@ -93,23 +93,36 @@ Reads authorized immutable and operational evidence without mutation. ## Acceptance Workflow 1. Reviewer accepts submission. -2. Task moves to ACCEPTED. -3. Workstream records reviewer `completed_review` and submitter - `accepted_submission` contributions. -4. Frozen contribution policies create awards only for payable contributions; +2. REV records the immutable Review and one internal FinalAcceptance for the + exact task, Submission, submitter, reviewer, and locked ReviewPolicy. +3. Task moves to ACCEPTED and the TaskAssignment completes. +4. Workstream records reviewer `completed_review` directly from Review and + submitter `accepted_submission` only from FinalAcceptance. +5. Frozen contribution policies create awards only for payable contributions; explicit unpaid rules create none. -5. Reputation events are recorded from contribution facts. -6. Finance Authority follows delivery and fulfillment only for created awards. +6. Reputation events are recorded from contribution facts. +7. Finance Authority follows delivery and fulfillment only for created awards. + +The Review request owns one commit for Review, FinalAcceptance, task effects, +contributions, awards, audit, and outbox. There is no manual FinalAcceptance +command and no adjudication/reopen step in v0.1. ## Rejection Workflow 1. Reviewer rejects submission or task. -2. Review must include rejection reason. -3. Reputation event is recorded. -4. The frozen reviewer contribution award rule determines whether the resulting +2. Review must include a bounded human rejection reason. +3. REV sets the Task to canonical `rejected`, blocks only the same-task + TaskAssignment, and binds that block to the reject Review. It changes no + actor grant or unrelated task. +4. Reputation event is recorded. +5. The frozen reviewer contribution award rule determines whether the resulting `completed_review` contribution creates a `CompensationAward`; rejection creates no submitter `accepted_submission` contribution. +For `needs_revision`, REV instead sets the Task to `needs_revision`, keeps the +same TaskAssignment `active`, and creates no FinalAcceptance or submitter +contribution. `closed/review_rejected` is not a canonical task state. + ## Lessons Learned Every project maintains lessons learned: diff --git a/docs/operations_payment_reputation.md b/docs/operations_payment_reputation.md index c47c45fe..6e24d1e3 100644 --- a/docs/operations_payment_reputation.md +++ b/docs/operations_payment_reputation.md @@ -7,7 +7,8 @@ the authorized award and immutable fulfillment result with the same discipline as automated settlement. Every valid recorded human Review creates a reviewer `completed_review` -contribution. `accept` additionally creates a submitter `accepted_submission` +contribution. `Review(accept)` first creates REV-owned FinalAcceptance; that +immutable fact is the sole source of a submitter `accepted_submission` contribution. Compensation is evaluated independently for each record from its frozen policy version; an explicit unpaid rule creates no award. Awards, fulfillment receipts, projections, and reputation events attach to contributions @@ -53,17 +54,19 @@ Default: - a valid human `needs_revision`, `accept`, or `reject` decision creates one reviewer `completed_review`; the ReviewLease-frozen `ContributionPolicyVersion` decides whether it creates an award -- `accept` additionally creates one submitter `accepted_submission`; the - TaskAssignment-frozen `ContributionPolicyVersion` decides whether it creates - an award -- `needs_revision` and `reject` create no submitter contribution or award +- `accept` creates one FinalAcceptance and exactly one submitter + `accepted_submission` from it; the TaskAssignment-frozen + `ContributionPolicyVersion` decides whether it creates an award +- `needs_revision` and `reject` create no FinalAcceptance, submitter + contribution, or submitter award - fulfillment is recorded only by an authenticated adapter callback bound to the award's frozen adapter binding - a fulfilled award requires an immutable receipt, exact quantity, and external reference -Review decisions, task acceptance, award creation, and fulfillment remain -separate facts. +Review decisions, FinalAcceptance, contribution recognition, award creation, +and fulfillment remain separate facts. FinalAcceptance has no manual API/action +and v0.1 has no adjudication or reopen path. `ACCEPTED` means the work met the guide. `fulfilled` means the bound adapter reported completion with an immutable receipt and external reference. @@ -120,10 +123,10 @@ Track: - completed reviews - decision distribution -- overturned decisions +- non-mutating quality-audit findings - unclear feedback reports - average turnaround -- second-review agreement +- quality-audit agreement Suggested v0.1 reviewer events: @@ -131,10 +134,14 @@ Suggested v0.1 reviewer events: | --- | ---: | --- | | clear_review | +2 | Structured findings or clear acceptance evidence. | | unclear_feedback | -2 | Finding lacks issue, evidence, or required fix. | -| overturned_accept | -3 | Accepted work later found non-compliant. | -| overturned_reject | -3 | Rejected work that belonged in accepted or needs-revision state. | +| review_quality_audit_completed | 0 | Records that the decision evidence was independently sampled. | +| review_quality_issue_flagged | -3 | Non-mutating audit found unsupported decision reasoning. | | missed_prior_finding | -2 | Resubmission accepted with unresolved prior issue. | +Quality-audit events may affect reputation only. They do not reopen Review, +replace FinalAcceptance, mutate task status or contributions, or create an +adjudication decision. + ## Skill Tags Reputation is tagged by skill so a contributor can be strong in one domain and weak in another. diff --git a/docs/operations_queue_policy.md b/docs/operations_queue_policy.md index e1738f0c..bfc0dd95 100644 --- a/docs/operations_queue_policy.md +++ b/docs/operations_queue_policy.md @@ -177,8 +177,9 @@ Owner: Policy: -- the accepting Review creates reviewer `completed_review` and submitter - `accepted_submission` contribution records atomically +- the accepting Review creates reviewer `completed_review`, REV-owned + FinalAcceptance, and FinalAcceptance-sourced submitter `accepted_submission` + contribution records atomically - each frozen contribution policy is evaluated independently; only payable contributions create awards and fulfillment follow-up - accepted task is not confused with fulfilled compensation @@ -195,6 +196,10 @@ Owner: Policy: - rejection requires evidence and guide-grounded reason +- the Task enters canonical `rejected`; only its same-task TaskAssignment is + blocked and bound to the reject Review +- no FinalAcceptance or submitter contribution is created; no actor grant or + unrelated task changes ### Compensation Fulfillment Follow-Up @@ -234,9 +239,9 @@ Every operating day starts with: | `SUBMITTED -> EVALUATION_PENDING` | immutable submission version, locked post-submit checker policy id/version/hash/body copied from the task context | | `EVALUATION_PENDING -> REVIEW_PENDING` | checker run for exact submission version, readiness certificate, no blocking failures | | `EVALUATION_PENDING -> NEEDS_REVISION` | checker run id, outcome source `auto_checker`, contributor-visible checker failures with severity, message, suggested fix | -| `REVIEW_PENDING -> NEEDS_REVISION` | review decision, at least one structured finding, reviewer `completed_review` contribution and applicable reviewer award, revision policy still permits revision | -| `REVIEW_PENDING -> ACCEPTED` | accepted review, acceptance evidence refs, reviewer `completed_review` and submitter `accepted_submission` contributions, applicable awards | -| `REVIEW_PENDING -> REJECTED` | rejected review, rejection reason/finding, reviewer `completed_review` contribution and applicable reviewer award; no submitter contribution | +| `REVIEW_PENDING -> NEEDS_REVISION` | review decision, at least one structured finding, TaskAssignment remains `active`, reviewer `completed_review` contribution and applicable reviewer award, no FinalAcceptance or submitter contribution, revision policy still permits revision | +| `REVIEW_PENDING -> ACCEPTED` | accepted Review, one FinalAcceptance for the exact task/Review/Submission, acceptance evidence refs, reviewer `completed_review` and FinalAcceptance-sourced submitter `accepted_submission` contributions, applicable awards | +| `REVIEW_PENDING -> REJECTED` | rejected Review, bounded human reason/finding, only the same-task TaskAssignment blocked with its source Review, reviewer `completed_review` contribution and applicable reviewer award; no FinalAcceptance, submitter contribution, grant change, or unrelated task effect | | pre-submit feedback in `NEEDS_REVISION` | prior findings visible to contributor, revision deadline active, no new submission created | | `NEEDS_REVISION -> SUBMITTED` | replacement submission packet, revision replay covering every high and medium prior finding, revision count under policy limit | | compensation `pending -> fulfilled` | immutable fulfillment receipt, external reference, and audit event | diff --git a/docs/operations_reviewer_workflow.md b/docs/operations_reviewer_workflow.md index 9b66fc40..9617d522 100644 --- a/docs/operations_reviewer_workflow.md +++ b/docs/operations_reviewer_workflow.md @@ -31,9 +31,11 @@ Allowed decisions: Decision rules: -- `accept` means the submission satisfies the project guide and creates the - submitter `accepted_submission` contribution. Its frozen contribution award rule - independently decides whether that contribution creates an award. +- `accept` means the submission satisfies the project guide. The same + transaction creates internal FinalAcceptance, then creates the submitter + `accepted_submission` contribution only from that fact. Its frozen + contribution award rule independently decides whether that contribution + creates an award. - `needs_revision` means the work is fixable and the reviewer can name concrete required changes. - `reject` means the work is not reasonably salvageable or violates policy. @@ -79,9 +81,13 @@ Use accept only when: Accept must create: - review decision record +- one immutable internal FinalAcceptance linked to the exact Review, existing + versioned Submission, task, submitter, recording reviewer, and locked + ReviewPolicy - acceptance audit event - reviewer `completed_review` contribution record -- submitter `accepted_submission` contribution record +- submitter `accepted_submission` contribution record sourced from + FinalAcceptance, not directly from Review.decision - any awards required by the separately frozen reviewer and submitter contribution policies - reputation event @@ -107,6 +113,10 @@ Each high or medium finding must have: - required fix - evidence reference or file/section reference +Recording `needs_revision` sets the Task to `needs_revision`, keeps the same +TaskAssignment `active`, and creates no FinalAcceptance or submitter +contribution. The reviewer `completed_review` still commits atomically. + ## Reject Use reject when: @@ -118,6 +128,11 @@ Use reject when: Use reject carefully. If the work can be reasonably corrected through one revision cycle, use `needs_revision`. +Recording `reject` sets the Task to canonical `rejected` with the bounded human +reason and blocks only the same-task TaskAssignment with its source Review. It +changes no actor grant or unrelated task and creates no FinalAcceptance or +submitter contribution. `closed/review_rejected` is not a canonical state. + Every valid recorded `needs_revision` or `reject` decision still creates the reviewer's `completed_review` contribution and evaluates the ReviewLease-frozen reviewer contribution policy. Neither decision creates a submitter contribution @@ -129,21 +144,22 @@ Track: - review count - decision distribution -- overturned decisions +- non-mutating quality-audit findings - unclear feedback reports - average turnaround -- agreement with second reviewer +- quality-audit agreement Reviewer reputation matters because low-quality review damages the whole system. Reviewer quality events are generated when: -- review is overturned - feedback is marked unclear -- reviewer accepts work later found non-compliant -- reviewer rejects work that belonged in revision +- a non-mutating quality audit finds unsupported acceptance/rejection reasoning - reviewer misses unresolved prior findings +These quality signals never reopen or replace Review, FinalAcceptance, task, or +ContributionRecord truth. V0.1 has no adjudication decision or queue. + ## Reviewer Checklist Before accepting: @@ -153,6 +169,8 @@ Before accepting: - evidence supports the claim - checker results are acceptable - no prior findings are open +- FinalAcceptance can be created exactly once for this task, source Review, and + existing versioned Submission - reviewer and submitter contribution lineage can be created atomically - both frozen contribution policies can be evaluated; explicit unpaid results are valid and create no award @@ -170,13 +188,15 @@ Before rejection: - evidence is cited - task is not merely fixable -## Second Review Sampling +## Non-Mutating Quality Sampling -During the first 30 days, sample at least: +During the first 30 days, audit at least: - 25 percent of accepted submissions - 25 percent of rejected submissions - any submission matching the configured high-value criterion in `ReviewPolicy` -Second review checks whether the first reviewer followed the guide, cited evidence, and made the correct decision type. +Sampling checks whether the reviewer followed the guide and cited evidence. It +does not create a Review, adjudication result, reopen path, replacement +FinalAcceptance, or lifecycle mutation. diff --git a/docs/product_first_user_flows.md b/docs/product_first_user_flows.md index e3ce7f4e..71e459b6 100644 --- a/docs/product_first_user_flows.md +++ b/docs/product_first_user_flows.md @@ -121,8 +121,8 @@ Acceptance: 4. Reviewer enters structured findings. 5. Reviewer selects accept, needs_revision, or reject. 6. Workstream atomically creates the reviewer `completed_review` contribution; - `accept` additionally creates the submitter `accepted_submission` - contribution. + `accept` also creates internal FinalAcceptance and then the submitter + `accepted_submission` contribution from that fact. Acceptance: @@ -130,6 +130,14 @@ Acceptance: - needs_revision and reject require at least one finding. - accept requires no unresolved critical- or high-severity checker failure. - Every valid human decision has exactly one reviewer contribution. +- Accept sets Task `accepted`, Assignment `completed`, and has exactly one + FinalAcceptance and one submitter contribution. +- Needs revision sets Task `needs_revision`, keeps Assignment `active`, and has + neither FinalAcceptance nor submitter contribution. +- Reject sets Task `rejected` with a bounded human reason, blocks only the + same-task Assignment with its source Review, changes no grant or unrelated + task, and has neither FinalAcceptance nor submitter contribution. +- FinalAcceptance has no manual API/action and no adjudication/reopen path. - Only accept has a submitter contribution. ## Flow 6: Revision Replay diff --git a/docs/risk_register.md b/docs/risk_register.md index bdf83a1b..8cb5679b 100644 --- a/docs/risk_register.md +++ b/docs/risk_register.md @@ -62,7 +62,7 @@ Mitigation: - structured findings required - reviewer quality metrics -- second-review audits +- post-decision non-mutating reviewer-quality audits ### R4: Revision Loops Without Closure @@ -105,8 +105,8 @@ Bad review decisions can demoralize contributors and corrupt quality metrics. Mitigation: - reviewer reputation -- second-review sampling -- overturned decision tracking +- non-mutating reviewer-quality sampling +- reviewer-quality signal tracking - escalation process ### R7: Fake Evidence @@ -172,11 +172,12 @@ Reviewers can repeatedly approve weak work for favored contributors or skip evid Mitigation: -- sample accepted work for second review +- sample accepted work for a non-mutating post-decision quality audit - flag repeated contributor-reviewer pairs - require evidence citation on accept -- track overturned accept decisions -- require independent review for high-value or disputed tasks +- track unsupported-decision quality signals +- require independent non-mutating quality audits for high-value or disputed + tasks; they cannot delay or replace the recorded decision ### R12: Bad Project Guides diff --git a/docs/template_project_guide.md b/docs/template_project_guide.md index e331eb34..dc52d254 100644 --- a/docs/template_project_guide.md +++ b/docs/template_project_guide.md @@ -152,17 +152,17 @@ Needs revision requires: - required fix per finding - severity per finding -Second-review sampling: - -- accepted: -- rejected: -- high-value tasks: - -Mandatory second review: +Post-decision non-mutating reviewer-quality audit sampling: +- accepted sample rate: +- rejected sample rate: - suspected copied or confidential material: - high-value criterion defined by `ReviewPolicy`: - reviewer conflict of interest: + +These criteria select quality audits only. They do not delay Review, +FinalAcceptance, contribution creation, or task closure and do not create a +second decision or adjudication path. - registered recovery operation used (permission, actor, reason, evidence): ## Revision Policy diff --git a/docs/template_review_packet.md b/docs/template_review_packet.md index a38ae16a..f0278ddf 100644 --- a/docs/template_review_packet.md +++ b/docs/template_review_packet.md @@ -17,8 +17,11 @@ - assigned reason: - conflict-of-interest attestation: - contributor-reviewer pair risk: -- second review required: -- second review trigger: +- non-mutating quality audit selected: +- quality audit selection reason: + +Quality-audit selection cannot delay or replace the Review decision, +FinalAcceptance, task effects, or contribution transaction. ## Decision From 545f250db8d5d1df05cf33cc5b22d1c933217ae8 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 10:08:02 +0100 Subject: [PATCH 12/22] Reconcile CON plan with AUTH PR 140 --- .../AUTHORIZATION_HANDOFF.md | 124 +++++++++++------- .../CHUNK_MAP.md | 21 +-- .../CONFORMANCE_MATRIX.md | 2 +- .../DECISIONS.md | 44 +++++-- .../DISCOVERY.md | 42 ++++-- .../INTENT.md | 2 +- .../JOINT_RELEASE_HANDOFF.md | 8 +- .../PLAN.md | 58 ++++---- .../RISKS.md | 2 + .../SOURCE_MANIFEST.md | 18 ++- .../STATUS.md | 26 ++-- ...-CON-001-01-canonical-contract-adoption.md | 6 +- ...WS-CON-001-02B-shared-outbox-dispatcher.md | 5 + ...-001-04A-hidden-adapter-binding-service.md | 5 +- ...-04B-hidden-contribution-policy-service.md | 7 +- ...-economic-terms-cutover-and-task-freeze.md | 27 ++-- ...review-lease-contribution-policy-freeze.md | 4 + ...-001-08A-outbound-compensation-delivery.md | 7 +- ...ON-001-08B-inbound-fulfillment-callback.md | 8 +- ...1-10B-operations-reconciliation-rebuild.md | 3 + .../WS-CON-001-10C-operations-executors.md | 7 +- .../WS-CON-001-11-hidden-release-readiness.md | 5 + ...CON-001-PLAN3-auth-pr140-reconciliation.md | 115 ++++++++++++++++ .../merge-intents/WS-CON-001-PLAN3.json | 9 ++ 24 files changed, 412 insertions(+), 143 deletions(-) create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md create mode 100644 .agent-loop/merge-intents/WS-CON-001-PLAN3.json diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md index be721fea..f2c0c66f 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -2,10 +2,12 @@ ## Current baseline -Trusted `main` is `5d353b6` from merged PR #139. The runtime catalogue still -contains 74 PermissionIds and 57 ActionIds: nine active and 48 planned. No -WS-CON-specific ActionId below is registered. WS-XINT changed planning and -canonical contracts, not runtime authorization. +Trusted `main` is `d541521` from merged AUTH PR #140, which reconciles AUTH to +the earlier WS-XINT PR #139 boundary. The runtime catalogue still contains 74 +PermissionIds and 57 ActionIds: nine active and 48 planned. No WS-CON-specific +ActionId below is registered. PR #140 adds reviewed AUTH planning contracts; it +does not implement AUTH-PREP, transfer ART/REV custody, register a CON action, +or activate a feature action. AUTH owns identifiers, stable mappings, activation custody, typed resource and principal contexts, grants, fixed ServiceIdentity/static matrix, AUTH-09E @@ -77,14 +79,20 @@ release readiness, but do not fail application startup or provisioning. ## Prepared mutation protocol -For `T` actions AUTH resolves a server-owned preliminary target, locks human -actor/link/grant or fixed-service actor/link authority first, and returns one -opaque non-serializable handle. The handle is bound to request, session, actor, -action, target, and authority snapshot. CON then locks product rows in the -canonical order, recomposes final typed facts, and AUTH evaluates once. AUTH -stages decision evidence and never commits; the route/executor/callback boundary -commits explicitly. Missing, reused, cross-session, cross-action, target- -drifted, or authority-drifted handles deny with zero product mutation. +For `T` actions AUTH locks canonical current human actor/link/exact-grant or +fixed-service actor/link authority first and returns one opaque, +non-serializable `PreparedAuthorizationHandle`. The handle is bound exactly to +the caller session, ActionId, actor-reference kind, actor reference, +idempotency key, and canonical request digest. ServiceIdentity, static matrix +membership, and availability are code-owned validations after profile/link +locks, never database lock targets. CON or the owning feature then locks +product rows in the canonical order and recomposes final typed facts; AUTH +consumes the handle, evaluates once, and stages decision evidence. AUTH and all +feature participants flush only; the route/executor/callback command commits +once. Reused, serialized, caller-constructed, cross-session/action/actor/ +request, binding-mismatched, or authority-lost handles deny before product +mutation. A failed substitution attempt does not consume an otherwise valid +handle. `Q` reads use request-scoped require plus canonical CON loaders, pre-filtered pagination, and concealment. No authorization result or grant cache survives a @@ -93,39 +101,41 @@ request. ## Proposed core action mappings These 22 feature-surface mappings preserve existing stable PermissionIds except -for the two explicitly proposed service-only PermissionIds. They are a product -proposal, not registered runtime. Policy ActionIds use the canonical -`contribution.policy.*` namespace while retaining stable +for the two explicitly proposed service-only PermissionIds. They are product +proposals, not registered runtime, and they are not a final action count until +the protected execution boundaries are approved. Policy ActionIds use the +canonical `contribution.policy.*` namespace while retaining stable `compensation.policy.manage` PermissionId compatibility. -| Proposed AUTH custodian | ActionId | PermissionId | Principal / target | Revalidation | Feature owner | -|---|---|---|---|---:|---| -| `AUTH_CON_OUTBOX` | `outbox.dispatch` | proposed `outbox.dispatch` | fixed outbox dispatcher / claimed event | T | shared outbox 02B | -| `AUTH_CON_BINDING` | `compensation.adapter_binding.read` | `compensation.adapter_binding.manage` | Finance / ProjectCompensationAdapterBinding | Q | CON-04A | -| `AUTH_CON_BINDING` | `compensation.adapter_binding.create` | `compensation.adapter_binding.manage` | Finance / project binding collection | T | CON-04A | -| `AUTH_CON_BINDING` | `compensation.adapter_binding.suspend` | `compensation.adapter_binding.manage` | Finance / active binding | T | CON-04A | -| `AUTH_CON_BINDING` | `compensation.adapter_binding.resume` | `compensation.adapter_binding.manage` | Finance / suspended binding | T | CON-04A | -| `AUTH_CON_OPERATIONS` | `compensation.adapter_binding.retire` | `compensation.adapter_binding.manage` | Finance / dependency-free binding | T | CON-10B | -| `AUTH_CON_POLICY` | `contribution.policy.read` | `compensation.policy.manage` | Finance / ContributionPolicyVersion | Q | CON-04B | -| `AUTH_CON_POLICY` | `contribution.policy.create_draft` | `compensation.policy.manage` | Finance / project policy collection | T | CON-04B | -| `AUTH_CON_POLICY` | `contribution.policy.update_draft` | `compensation.policy.manage` | Finance / draft version | T | CON-04B | -| `AUTH_CON_POLICY` | `contribution.policy.publish` | `compensation.policy.manage` | Finance / complete draft version | T | CON-04B | -| `AUTH_CON_POLICY` | `contribution.policy.retire` | `compensation.policy.manage` | Finance / published version | T | CON-04B | -| `AUTH_CON_CALLBACK` | `compensation.fulfillment.report` | proposed `compensation.fulfillment.report` | exact bound service / award and binding | T | CON-08B | -| `AUTH_CON_CONTRIBUTION_READS` | `contribution.read_self` | `contribution.read_self` | contributor / own record | Q | CON-10A | -| `AUTH_CON_CONTRIBUTION_READS` | `contribution.read_project` | `contribution.read_project` | exact eligible AdminRole / project collection | Q | CON-10A | -| `AUTH_CON_AWARD_READS` | `compensation.award.read_self` | `contribution.read_self` | beneficiary / own award | Q | CON-10A | -| `AUTH_CON_AWARD_READS` | `compensation.award.read_project` | `compensation.award.read` | D11 role set / project award collection | Q | CON-10A | -| `AUTH_CON_OPERATIONS` | `compensation.delivery.reconcile` | `compensation.delivery.reconcile` | D11 role set / delivery request | T | CON-10B | -| `AUTH_CON_OPERATIONS` | `compensation.status.read` | `operations.status.read` | Operator / bounded status | Q | CON-10B | -| `AUTH_CON_OPERATIONS` | `compensation.reconcile.run` | `operations.reconcile.run` | reason-bound Operator / durable request | T | CON-10B | -| `AUTH_CON_OPERATIONS` | `contribution.projection.rebuild` | `operations.projection.rebuild` | reason-bound Operator / durable request | T | CON-10B | -| `AUTH_CON_OPERATIONS` | `audit.read` | `audit.read` | D11 role set / bounded WS-CON audit | Q | CON-10B | -| `AUTH_CON_OPERATIONS` | `audit.export` | `audit.export` | D11 role set / bounded export | T | CON-10B | - -The proposed AUTH custodian names are exact candidates for AUTH-owned chunk -contracts. AUTH may adjust chunk grouping before registration, but every action -must have exactly one AUTH ActionOwner and unchanged PermissionId mapping. +| Proposed ActionId | PermissionId | Principal / target | Protocol | Feature owner | +|---|---|---|---:|---| +| `outbox.dispatch` | proposed `outbox.dispatch` | fixed outbox dispatcher / claimed event | T | shared outbox 02B | +| `compensation.adapter_binding.read` | `compensation.adapter_binding.manage` | Finance / ProjectCompensationAdapterBinding | Q | CON-04A | +| `compensation.adapter_binding.create` | `compensation.adapter_binding.manage` | Finance / project binding collection | T | CON-04A | +| `compensation.adapter_binding.suspend` | `compensation.adapter_binding.manage` | Finance / active binding | T | CON-04A | +| `compensation.adapter_binding.resume` | `compensation.adapter_binding.manage` | Finance / suspended binding | T | CON-04A | +| `compensation.adapter_binding.retire` | `compensation.adapter_binding.manage` | Finance / dependency-free binding | T | CON-10B | +| `contribution.policy.read` | `compensation.policy.manage` | Finance / ContributionPolicyVersion | Q | CON-04B | +| `contribution.policy.create_draft` | `compensation.policy.manage` | Finance / project policy collection | T | CON-04B | +| `contribution.policy.update_draft` | `compensation.policy.manage` | Finance / draft version | T | CON-04B | +| `contribution.policy.publish` | `compensation.policy.manage` | Finance / complete draft version | T | CON-04B | +| `contribution.policy.retire` | `compensation.policy.manage` | Finance / published version | T | CON-04B | +| `compensation.fulfillment.report` | proposed `compensation.fulfillment.report` | exact bound service / award and binding | T | CON-08B | +| `contribution.read_self` | `contribution.read_self` | contributor / own record | Q | CON-10A | +| `contribution.read_project` | `contribution.read_project` | exact eligible AdminRole / project collection | Q | CON-10A | +| `compensation.award.read_self` | `contribution.read_self` | beneficiary / own award | Q | CON-10A | +| `compensation.award.read_project` | `compensation.award.read` | D11 role set / project award collection | Q | CON-10A | +| `compensation.delivery.reconcile` | `compensation.delivery.reconcile` | D11 role set / delivery request | T | CON-10B | +| `compensation.status.read` | `operations.status.read` | Operator / bounded status | Q | CON-10B | +| `compensation.reconcile.run` | `operations.reconcile.run` | reason-bound Operator / durable request | T | CON-10B | +| `contribution.projection.rebuild` | `operations.projection.rebuild` | reason-bound Operator / durable request | T | CON-10B | +| `audit.read` | `audit.read` | D11 role set / bounded WS-CON audit | Q | CON-10B | +| `audit.export` | `audit.export` | D11 role set / bounded export | T | CON-10B | + +PR #140 approves no `AUTH_CON_*` owner identifiers. After a complete +feature-owned manifest exists, AUTH must assign each registered action to one +exact future `WS-AUTH-001-*` activation chunk and prove unchanged mapping plus +planned availability. CON must not predict or add ActionOwner enum values. ## Core resource guards @@ -177,12 +187,36 @@ activation only after hidden behavior merges. ## Upstream review and task actions -`task.claim` is an upstream AUTH action mapped to existing `task.claim`; it -requires the exact submitter grant and task guards before CON-05A participates. +Only the stable `task.claim` PermissionId exists on trusted main; there is no +registered task-claim ActionId among the 57 actions. AUTH-PREP, the exact +submitter grant, and the task-owned claim seam precede CON-05A's hidden freeze +participant. CON-05A and task-owned composition must merge first. AUTH-13 then +enumerates/registers the exact task-claim ActionId, integrates its evaluator, +and activates only after the immutable ContributionPolicyVersion freeze and +rollback proof exist. `review.claim` and `review.decision` are current planned actions; CON-06/07 provide hidden participants, REV supplies canonical composition, and AUTH activates only after the complete behavior merges. +### Required AUTH follow-up from PR #140 + +- The current `WS-AUTH-001-13` contract owns future task-claim ActionId + enumeration/registration, activation, and exact submitter-grant evaluation, + but it does not yet name the CON-05A TaskAssignment + ContributionPolicyVersion freeze as a prerequisite. Its executable refresh + must consume the merged CON-05A manifest and prove task-owned participant + composition before it registers/activates that action. +- Future CON registration contracts must choose exact `WS-AUTH-001-*` + activation custodians from complete feature manifests. The removed + `AUTH_CON_*` planning labels are not approved ActionOwner values. +- `review.claim` activation must consume CON-06 through REV's hidden claim + composition. PR #140 already states that `review.decision` activation + requires the merged mandatory CON participant and one rollback-safe REV+CON + transaction; no additional FinalAcceptance action is needed. + +These are upstream AUTH contract gates. CON does not edit AUTH files, register +identifiers, integrate evaluators, or change availability. + AUTH must reconcile all 19 current review actions as one complete activation- custody transfer under `WS-XINT-001/AUTH_REV_HANDOFF.md`. WS-CON declares only its two dependencies and must not remove or retain individual REV ActionOwner diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md index 3b2350e8..d2ae95b1 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -13,6 +13,7 @@ availability writer. Optional evidence chunks are not part of the core order. |---|---|---:|---|---| | `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Complete; unpublished | | `WS-CON-001-PLAN2` | Final Acceptance Reconciliation | L0 | Human FinalAcceptance/no-adjudication direction | Complete; unpublished | +| `WS-CON-001-PLAN3` | AUTH PR 140 Reconciliation | L0/L1 | Merged AUTH PR #140 at `d541521` | Complete; unpublished | | `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Reconciled plan and human decisions approved | Proposed | | `WS-CON-001-02A` | Shared Transactional Outbox Persistence | L1 | 01; event ownership approved | Proposed | | `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; AUTH registers `outbox.dispatch`, approved `workstream.outbox.dispatcher` ServiceIdentity/static row, AUTH-09E admission, prepared protocol; dispatcher remains disabled until AUTH activation | Proposed | @@ -23,10 +24,10 @@ availability writer. Optional evidence chunks are not part of the core order. | `WS-CON-001-03D` | Delivery, Receipt, And Status Persistence | L1 | 03C | Proposed | | `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; planned AUTH binding actions/contexts/prepared protocol; callback ServiceIdentity/action/static row approved but inactive | Proposed | | `WS-CON-001-04B` | Hidden Contribution-Policy Service | L1 | 03B, 04A; binding activation merged; planned `contribution.policy.*` actions/contexts/prepared protocol | Proposed | -| `WS-CON-001-05A` | Legacy Economic Terms Cutover And Task Freeze | L1 | 04B; exact Submission/TaskAssignment lineage; AUTH task.claim with exact submitter grant and prepared protocol active; legacy rule | Proposed | +| `WS-CON-001-05A` | Legacy Economic Terms Cutover And Task Freeze | L1 | 04B; exact Submission/TaskAssignment lineage; AUTH-10 exact submitter grants and AUTH-PREP merged; task.claim PermissionId exists but ActionId remains absent; stable task-owned claim seam; legacy rule | Proposed | | `WS-CON-001-05B` | Legacy Economic Schema Removal | L1 | 05A; zero-consumer scan; removal migration approval | Proposed | -| `WS-CON-001-06` | Review-Lease Contribution-Policy Freeze Capability | L1 | REV lease schema; 05B; planned review.claim typed/prepared contract; exact reviewer grant facts stable | Proposed | -| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D, 05A, 06; merged TaskAssignment freeze field and REV ReviewLease plus accept-only FinalAcceptance persistence and locked decision-lineage contract; shared audit/outbox; planned review.decision typed/prepared contract | Proposed | +| `WS-CON-001-06` | Review-Lease Contribution-Policy Freeze Capability | L1 | REV lease schema; 05B; AUTH-PREP; planned review.claim typed contract; exact reviewer grant facts stable | Proposed | +| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D, 05A, 06; AUTH-PREP and complete REV custody transfer; merged TaskAssignment freeze field and REV ReviewLease plus accept-only FinalAcceptance persistence and locked decision-lineage contract; shared audit/outbox; planned review.decision typed contract | Proposed | | `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07, 02B; exact delivery ServiceIdentity/ActionId/static row registered but planned; AUTH-09E typed context/prepared protocol; ADR 0014 adapter foundation; lifecycle-fence port | Proposed | | `WS-CON-001-08R` | Bound-Service Callback Rate Control | L1 | 08A; shared API-control contract | Proposed | | `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; exact callback ServiceIdentity/ActionId/static row, AUTH-09E context, prepared protocol, and callback-fence port | Proposed | @@ -40,7 +41,7 @@ availability writer. Optional evidence chunks are not part of the core order. ## Core dependency order ```text -PLAN -> PLAN2 -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D +PLAN -> PLAN2 -> PLAN3 -> 01 -> 02A -> 02B -> 02C -> 03A -> 03B -> 03C -> 03D -> 04A -> 04B -> 05A -> 05B -> 06 -> 07 -> 08A -> 08R -> 08B -> 10A -> 10B -> 10C -> 11 ``` @@ -62,8 +63,11 @@ AUTH registration -> CON hidden behavior -> AUTH activation -> later consumer/re provisioning never activates a feature action. - The outbox dispatcher owns only claim/invoke/finalize under `outbox.dispatch`. Each protected handler has independent approved authority. -- Task claim requires one exact active same-project submitter grant and freezes - the published ContributionPolicyVersion through CON-05A. +- Task claim requires AUTH-PREP and one exact active same-project submitter + grant. CON-05A first lands the hidden freeze participant; task-owned claim + composition consumes it after task/assignment locks; `WS-AUTH-001-13` then + enumerates/registers the exact ActionId, integrates its evaluator, and + activates. Registration/activation before that freeze proof is prohibited. - Review claim requires one exact active same-project reviewer grant. CON-06 supplies only the freeze port; REV supplies hidden claim composition; AUTH activates review.claim after both merge. @@ -87,8 +91,9 @@ AUTH registration -> CON hidden behavior -> AUTH activation -> later consumer/re - CON-11 has no ART or evidence-projection prerequisite. It hands typed fulfillment fence/drain seams to the reviewed REV release-control work and registers no production route. -- AUTH's complete ART and REV activation-custody transfers are consumed by - reference to WS-XINT handoffs. WS-CON does not define partial subsets. +- AUTH PR #140's complete ART and REV activation-custody transfer contracts are + consumed by reference to AUTH/WS-XINT handoffs. The runtime transfers remain + upstream gates; WS-CON does not define partial subsets. ## Chunk boundaries diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md index eeb526fb..bac4b7f4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -4,7 +4,7 @@ |---|---|---|---| | Canonical policy model | 01,03B,04B | ContributionPolicy/version/rules/definitions; explicit unpaid; immutable publish; one active policy; stable binding references | CON-11 | | Legacy clean cut | 05A,05B | zero semantic consumers before schema removal; deterministic row treatment; no alias/fallback; migration upgrade/downgrade | CON-11 | -| Authorization | AUTH + each feature | 74/57 baseline refreshed; proposed mappings exact; full ART/REV custody referenced; one AUTH custodian; planned denial; exact grant/static row; AUTH-09E; prepared handle misuse; no local role logic | AUTH activation + CON-11 | +| Authorization | AUTH + each feature | PR #140 / 74-57-9-48 baseline refreshed; proposed mappings remain unregistered; full ART/REV custody referenced; one future AUTH custodian; planned denial; exact grant/static row; AUTH-09E; prepared handle bound to session/action/actor-ref/idempotency/request digest with substitution non-consumption; no local role logic | AUTH activation + CON-11 | | Final acceptance | REV + 03C,07 | accept creates one immutable FinalAcceptance per task/Review/Submission; needs_revision/reject create none; no create API/action, reopen, replacement, or adjudication path | joint live drill | | Contribution cardinality | 03C,07 + REV | one completed_review per valid Review with direct Review/lease lineage; one accepted_submission per FinalAcceptance with assignment lineage; mutually exclusive sources; revision Reviews distinct; automated outcomes create none | joint live drill | | Policy freeze | 05A,06 + task/REV | exact submitter/reviewer fields; published version; no drift; publish/suspend races both orders | joint live drill | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md index 53adb42a..cc3efb8c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -6,8 +6,8 @@ The supplied reference files are archival inputs. The active implementation contract is the repository specification produced by CON-01 and reconciled with -trusted `main`, including WS-XINT-001 from PR #139. Archival files are not edited -or treated as runtime authority. +trusted `main`, including AUTH PR #140 and WS-XINT-001 PR #139. Archival files +are not edited or treated as runtime authority. ## D2 - ContributionPolicy Is The Only Award-Eligibility Policy @@ -109,14 +109,19 @@ eligibility. AUTH locks and revalidates human actor/link/grant rows or fixed-service actor/link rows first. Fixed services additionally require immutable ServiceIdentity, exact static service-action matrix membership, AUTH-09E typed -admission, and active action. AUTH returns one opaque, request/session/action/ -target-bound, single-use handle. The feature locks product rows, recomposes -final typed facts, and AUTH evaluates exactly once. AUTH stages one decision and -never commits. - -Missing, reused, serialized, cross-session, cross-action, target-drifted, or -authority-drifted handles fail closed. Product-first locks, unlocked resource -snapshots, double decisions, and feature-side catalogue changes are rejected. +admission, and active action as code-owned validations rather than lock targets. +AUTH returns one opaque, single-use `PreparedAuthorizationHandle` bound exactly +to session, ActionId, actor-reference kind/reference, idempotency key, and +canonical request digest. The feature then locks product rows and recomposes +final typed facts; AUTH consumes the handle, evaluates exactly once, and stages +decision evidence. AUTH and feature participants flush only; the route or +service command commits once. + +Missing, reused, serialized, caller-constructed, cross-session/action/actor/ +request, binding-mismatched, or authority-lost handles fail closed before +feature mutation. A failed substitution does not consume an otherwise valid +handle. Product-first locks, unlocked resource snapshots, double decisions, +and feature-side catalogue changes are rejected. ## D11 - Project Roles Are Independent; Admin Candidate Differences Remain Exact @@ -211,3 +216,22 @@ outbox records, and commits once. CON failure rolls the entire unit back. ART and provider calls remain absent; fulfillment begins asynchronously after commit. V0.1 has no adjudication policy, queue, lease, state, decision, contribution type, branch, action, readiness check, or initiative dependency. + +## D16 - AUTH PR 140 Is Planning Authority, Not Runtime Activation + +**Status:** accepted by merged AUTH PR #140 on 2026-07-17. + +Trusted main remains at 74 PermissionIds, 57 ActionIds, nine active actions, and +48 planned actions, with no registered CON ActionId. PR #140 supplies the exact +prepared protocol, complete ART/REV custody maps, and feature-manifest +activation rule; their runtime implementation remains upstream work. + +CON removes speculative `AUTH_CON_*` owner labels. Its proposed action mappings +remain unregistered and non-final until each complete feature manifest exists +and AUTH assigns an exact `WS-AUTH-001-*` custodian. Only the `task.claim` +PermissionId exists today; AUTH-13 must not register or activate a task-claim +ActionId before task-owned composition consumes CON-05A's immutable +TaskAssignment policy freeze. `review.claim` similarly consumes CON-06 through +REV, and `review.decision` consumes CON-07 through the rollback-safe REV-owned +transaction. AUTH alone registers/evaluates/activates; CON alone supplies its +hidden facts and participants. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md index 45e5d66e..834d2e4b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -2,7 +2,8 @@ ## Baseline inspected -- trusted `origin/main` at `5d353b6`, merged PR #139; +- trusted `origin/main` at `d541521`, merged AUTH PR #140, including the earlier + WS-XINT PR #139 boundary; - complete WS-XINT intent, decisions, plan, REV/CON, AUTH/role-service, AUTH/REV, AUTH/ART, and ART/REV handoffs; - current WS-CON initiative package and archival reference inputs; @@ -11,7 +12,7 @@ - current backend project/task/submission/checker, AUTH, audit, artifact, and migration code/tests; - human-approved 2026-07-17 FinalAcceptance/no-adjudication direction and the - current sibling REV planning head `69fb231` as discovery-only context; + current sibling REV planning worktree as discovery-only context; - stale wording, authorization, artifact, link, loop-memory, and agent-gate scanners/tests. @@ -26,14 +27,15 @@ named `submission_version_id` therefore maps to canonical `Submission.id` and is stored as `submission_id`. - No FinalAcceptance runtime or reviewed merged REV contract exists yet. The - current sibling REV plan creates Review/task effects directly and must be - reconciled and merged before CON consumes the new fact. + current sibling REV plan now includes FinalAcceptance and exact outcome + effects, but must be reviewed and merged before CON consumes that fact. - The merged AUTH catalogue has 74 PermissionIds and 57 ActionIds. Nine self/admin actions are active and 48 are planned. No WS-CON ActionId is registered. - Current AUTH supports actor-self and AdminRoleGrant evaluation. Independent ProjectRoleGrant runtime, fixed-service runtime admission, CON evaluators, - and the cross-domain prepared mutation protocol remain future AUTH work. + ART/REV custody transfer, and the cross-domain prepared mutation protocol + remain future AUTH work. PR #140 adds their reviewed plans, not runtime. - AUTH's static service-action matrix is typed code; it is not a database grant table. AUTH-09E is the required runtime admission path. - PR #129 added inactive ART preparation/source values only. It added no @@ -68,6 +70,17 @@ 9. REV owns FinalAcceptance persistence, Review/task effects, shared audit/ outbox staging, and the single commit. CON validates the locked acceptance fact, flushes contributions/awards, returns a typed result, and never commits. +10. PR #140 fixes the prepared handle to exact session, ActionId, + actor-reference kind/reference, idempotency key, and canonical request + digest bindings. Final resource facts are recomposed after feature locks; + AUTH consumes the handle, evaluates once, and stages evidence. +11. PR #140 publishes complete 25-ART/19-REV custody-transfer maps, but those + availability-neutral runtime transfers remain proposed. CON depends on the + complete REV transfer and never restates a two-action subset. +12. Trusted main has stable PermissionId `task.claim` but no task-claim + ActionId. CON-05A's hidden TaskAssignment policy freeze must merge into + task-owned claim composition before AUTH-13 enumerates/registers and + activates that action. ## Relevant files and symbols @@ -76,6 +89,10 @@ | `docs/architecture_data_model.md` | Canonical policy/rule/definition, binding, contribution, award, receipt, and projection names/fields | | `docs/decision_0015_project_contributor_roles_are_independent.md` | Exact project role values and independent revocation | | `docs/spec_authorization_service.md` | Stable permissions, current actions, ActionOwner semantics, static service matrix, AUTH-09E order | +| `WS-AUTH-001/ACTIVATION_CUSTODY.md` | Exact complete custody transfers, feature-manifest activation gates, and mandatory CON participant prerequisite for review.decision | +| `WS-AUTH-001-PREP` chunk | Exact prepared-handle bindings, authority-first locks, single use, caller-owned commit, and concurrency/rollback proof | +| `WS-AUTH-001-13` chunk | Future task-claim ActionId enumeration, registration, evaluator integration, and activation owner; exact submitter grant, task-owned resource composition, and AUTH-PREP dependency | +| `WS-AUTH-001-16` chunk | Aggregate proof that active review.decision uses one rollback-safe REV+CON transaction with no ART/fallback | | `WS-XINT-001/REV_CON_HANDOFF.md` | Exact core participant sequence and optional-evidence boundary | | `WS-XINT-001/AUTH_ROLE_SERVICE_HANDOFF.md` | Fixed service and project grant contract | | `WS-XINT-001/AUTH_REV_HANDOFF.md` | Full review activation-custody/hidden behavior sequence | @@ -92,9 +109,10 @@ - Project/task tests cover current setup/claim/submission behavior but not ContributionPolicy freezes or retirement of the legacy economic schema. - AUTH tests cover catalogue parity, planned denial, actor-self/admin grants, - decision digest, scope evidence, and route commit/rollback. They do not cover - CON contexts, independent project grants at CON call sites, AUTH-09E CON - identities, or prepared cross-domain mutations. + decision digest, scope evidence, and route commit/rollback. PR #140 changes + planning/tests for documentation gates but does not implement CON contexts, + independent project grants at CON call sites, AUTH-09E CON identities, + custody transfer, or prepared cross-domain mutations. - ART tests prove preparation only. No optional evidence projection capability exists or is needed for core contribution tests. - No tests yet cover ContributionRecord cardinality, frozen rule evaluation, @@ -105,9 +123,11 @@ ## Dependencies -- AUTH: reviewed registration and later activation chunks, independent project - grants, prepared mutation protocol, fixed service admission, exact CON - service identities/static rows, and action-specific evaluators. +- AUTH: AUTH-10 independent project grants, AUTH-09A-E fixed-service sequence, + complete ART/REV custody transfers, AUTH-PREP, reviewed CON registration and + later activation chunks, exact CON service identities/static rows, and + action-specific evaluators. Task claim activation must consume the merged + CON-05A freeze participant; review.decision activation must consume CON-07. - REV: ReviewLease reviewer policy FK; canonical claim/decision composition; REV-owned FinalAcceptance with exact policy-context typing; stabilized artifact-hash facts; mandatory CON participant injection; REV-staged shared diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md index 85bf7172..8bb15f50 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md @@ -10,7 +10,7 @@ points ledger, or reputation scoring. The supplied WS-CON reference pair is input to reconcile, not authority to accept blindly. The active contract follows trusted repository decisions and -the merged WS-XINT-001 boundary from PR #139. +merged AUTH PR #140 and its underlying WS-XINT-001 boundary from PR #139. ## Success state diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md index 60edc0ec..fa8ba326 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -15,9 +15,10 @@ reviewed and merged to trusted `main`. ## Required decision composition ```text -AUTH prepares review.decision with exact reviewer grant +AUTH locks exact reviewer authority and prepares review.decision handle bound to +session/action/actor reference/idempotency key/canonical request digest -> REV locks and recomposes canonical facts --> AUTH evaluates once +-> AUTH consumes the handle, evaluates once, and stages decision evidence -> REV stages Review/findings/resolutions, consumes ReviewLease, closes queue -> on accept, REV creates immutable FinalAcceptance linked to Review, canonical Submission, Task, submitter, reviewer and locked ReviewPolicy @@ -90,7 +91,8 @@ Review.decision. - REV hidden claim/decision composition then consumes CON-06/07 and has no fallback. - AUTH complete REV custody transfer, exact evaluators, reviewer grant path, - prepared protocol, and activation are merged. + prepared protocol, and activation are merged. The transfer is the complete + PR #140 19-action map, not a local review.claim/review.decision subset. - Every public/service CON action has exact AUTH registration, evaluator, principal path, and activation after hidden behavior. - Protected outbox handlers have their own exact service authority; dispatcher diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md index 1f12f251..a2b8037f 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -2,9 +2,9 @@ ## Proposed approach -Adopt the merged WS-XINT-001 boundary from PR #139 before runtime work, then -deliver WS-CON through hidden, reviewable chunks. The core path is PostgreSQL- -local and has no ART dependency: +Adopt merged AUTH PR #140 and its underlying WS-XINT PR #139 boundary before +runtime work, then deliver WS-CON through hidden, reviewable chunks. The core +path is PostgreSQL-local and has no ART dependency: ```text AUTH prepares review.decision and locks reviewer authority @@ -149,9 +149,11 @@ models, routes, lifecycle decisions, or commits. ## Authorization boundary -Trusted `main` is `5d353b6`, merging WS-XINT-001 through PR #139. Runtime -catalogue counts remain 74 PermissionIds, 57 ActionIds, nine active actions, and -48 planned actions. No WS-CON ActionId is registered yet. +Trusted `main` is `d541521`, merging AUTH PR #140 after WS-XINT PR #139. +Runtime catalogue counts remain 74 PermissionIds, 57 ActionIds, nine active +actions, and 48 planned actions. No WS-CON ActionId is registered. PR #140 +adds reviewed AUTH custody/PREP/activation contracts only; the custody +transfers and prepared protocol remain proposed runtime work. WS-XINT D1/D2 is final for this plan: `ActionOwner` is the exact AUTH activation custodian. Each protected surface follows: @@ -168,12 +170,14 @@ CON never reads grants, imports AUTH repositories, constructs PermissionIds or roles, changes availability, or supplies a production allow fallback. AUTH never imports CON repositories or mutates contribution/award state. -The current complete ART and REV custody transfers are AUTH-owned coordination -work. WS-CON references the canonical WS-XINT `AUTH_ART_HANDOFF.md` and -`AUTH_REV_HANDOFF.md`; it does not prescribe a partial transfer. CON depends on -`review.claim` and `review.decision`, but AUTH must reconcile every current REV -action as one complete boundary. The four proposed additive REV actions remain -unregistered until their own reviewed registration contract. +PR #140's complete ART and REV custody-transfer contracts are AUTH-owned +coordination work; their runtime transfers have not yet merged. WS-CON +references the canonical AUTH `ACTIVATION_CUSTODY.md` plus WS-XINT +`AUTH_ART_HANDOFF.md` and `AUTH_REV_HANDOFF.md`; it does not prescribe a partial +transfer. CON depends on `review.claim` and `review.decision`, but AUTH must +transfer every current REV action as one complete boundary. The four proposed +additive REV actions remain unregistered until their own reviewed registration +contract. ### Human project grants @@ -187,14 +191,18 @@ outside this lifecycle contract. ### Prepared mutation protocol -For mutations, AUTH first locks and revalidates either human actor/link/grant -rows or fixed-service actor/link rows. A fixed service additionally requires an -unchanged closed `ServiceIdentity`, exact static service-action matrix -membership, AUTH-09E typed service admission, and active action. AUTH returns a -single-use, non-serializable handle bound to request, session, actor, action, -target, and authority snapshot. The feature locks canonical rows, recomposes -final typed facts, and AUTH evaluates once. AUTH stages one decision and never -commits. Reads use request-scoped `require()` and canonical feature loaders. +For mutations, AUTH first locks and revalidates either human actor/link/exact- +grant rows or fixed-service actor/link rows. It returns an opaque, single-use, +non-serializable `PreparedAuthorizationHandle` bound exactly to session, +ActionId, actor-reference kind/reference, idempotency key, and canonical +request digest. A fixed service additionally requires closed ServiceIdentity, +exact static service-action matrix membership, AUTH-09E admission, and active +action as code-owned validations after profile/link locks, not database lock +targets. The feature then locks canonical rows and recomposes final typed +facts; AUTH consumes the handle, evaluates once, and stages decision evidence. +AUTH and feature participants flush only; the route or service command commits +once. Substitution/reuse denial does not consume an otherwise valid handle. +Reads use request-scoped `require()` and canonical feature loaders. Missing provisioned service ActorProfile/ActorIdentityLink rows deny that runtime request and block release readiness, but do not fail application startup @@ -312,9 +320,13 @@ subsystem owns no contribution, award, adapter, review, or provider semantics. CON-03C lands only after REV's FinalAcceptance persistence target is merged. 4. CON-04A/B add hidden binding and ContributionPolicy behavior behind planned AUTH actions. -5. CON-05A removes retired semantic consumers and freezes the published - ContributionPolicyVersion on new TaskAssignments; 05B drops unreachable - physical schema after a zero-consumer proof. +5. After AUTH-PREP, exact-project submitter grants, and the planned task-claim + contract exist, CON-05A removes retired semantic consumers and lands the + hidden participant that freezes the published ContributionPolicyVersion on + new TaskAssignments. Task-owned claim composition consumes it before + `WS-AUTH-001-13` enumerates/registers the task-claim ActionId, integrates its + evaluator, and activates; 05B then drops unreachable physical schema after + zero-consumer proof. 6. CON-06 supplies reviewer policy freeze; the REV owner wires it into hidden review claim behavior before AUTH activates `review.claim`. 7. CON-07 supplies the flush-only decision participant that consumes REV-owned diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md index 96217824..c65433a7 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -7,11 +7,13 @@ | Submitter contribution inferred from mutable decision shape | Critical | REV-owned immutable FinalAcceptance is the sole accepted_submission source; unique task/Review/Submission and source-shape constraints | REV + CON-03C/07 | | Mandatory ART projection blocks product truth | Critical | No ART/evidence work in core transaction or release; optional successor only | CON-07/09/11 | | Wrong frozen policy | Critical | Assignment/lease freeze before work; immutable versions; concurrency proof | CON-05A/06 | +| task.claim activates before submitter policy freeze | Critical | AUTH-PREP + task seam -> CON-05A hidden participant -> task-owned composition -> AUTH-13 activation; pre-activation real-kernel denial | AUTH + task + CON-05A | | Dispatcher inherits handler authority | Critical | Dispatcher-only action; exact independent service authority for protected handlers | CON-02B/08A/10C + AUTH | | Operations request authority leaks into execution | Critical | 10B persists bounded human requests only; 10C uses exact fixed-service actions, cross-executor denial, replay/finding proof, and projection-only mutation | CON-10B/10C + AUTH | | Broad or dynamic service access | Critical | Closed ServiceIdentity/static rows, controlled provisioning, AUTH-09E, cross-service denial | AUTH + CON | | Partial ART/REV custody transfer | High | Reference complete WS-XINT handoffs; no local subset or dual writer | AUTH | | Cross-domain deadlock/partial commit | Critical | AUTH-first common prefix; operation-specific REV/task lifecycle-before-policy order; one session/commit; both-order PostgreSQL tests | AUTH + REV + CON | +| Prepared handle substitution or stale authority | Critical | Exact session/action/actor-ref/idempotency/request-digest binding; AUTH consumption after final-fact recomposition; single use and non-consumption on rejected substitution | AUTH + each mutation owner | | Wrong grant substitutes for shipping authority | High | Exact submitter and reviewer grants only; unrelated project/admin grants deny; no adjudication dependency | AUTH + task/REV | | Provider I/O under locks | Critical | Durable pre-I/O state; release transaction/fence before adapter call | CON-08A/outbox | | Callback spoofing/replay | Critical | Exact service identity/static row, binding match, prepared protocol, idempotent receipt | CON-08B + AUTH | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md index 7d3ff17a..6c048d78 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -10,13 +10,15 @@ ## Trusted baseline -- `origin/main` / merged PR #139 at - `5d353b6d3f8a36b9b9ffdc1959487a150ac25fd1`. -- PR #139 title: `ws-xint-001-boundary-reconciliation` / AUTH, ART, REV, and - CON lifecycle boundary reconciliation. +- `origin/main` / merged AUTH PR #140 at + `d541521790a0441cfd2193f466e00ef81248ec31`. +- PR #140 title/branch: AUTH WS-XINT reconciliation / + `codex/ws-auth-001-xint-reconciliation`; it adopts the earlier PR #139 AUTH, + ART, REV, and CON lifecycle boundary. - Runtime AUTH remains 74 PermissionIds, 57 ActionIds, nine active, 48 planned. -- PR #139 changed planning/canonical docs/scanners, not runtime CON behavior or - action availability. +- PR #140 adds AUTH activation-custody, prepared-protocol, revised chunk, + operations, and verification contracts. It changes no runtime CON behavior, + registers no CON action, and activates no feature action. ## Human boundary amendment @@ -57,6 +59,10 @@ - `docs/decision_0015_project_contributor_roles_are_independent.md` - `docs/spec_authorization_service.md` - `docs/spec_artifact_storage_service.md` +- `.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/ACTIVATION_CUSTODY.md` +- `.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PREP-prepared-mutation-protocol.md` +- `.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-13-task-assignment-cutover.md` +- `.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md` - `.agent-loop/policies/*` ## Normative WS-XINT handoffs diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index fd6c0a81..7800c3b2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,7 +2,9 @@ ## Current status -`WS-CON-001-PLAN2` has reconciled the human-approved v0.1 +`WS-CON-001-PLAN3` is reconciling merged AUTH PR #140 at trusted main +`d541521` with the previously reviewed CON plan. PLAN2 already reconciled the +human-approved v0.1 `Review(accept) -> FinalAcceptance -> accepted_submission` boundary against the previously reviewed WS-XINT plan. Runtime code is unchanged. The addendum passed architecture, QA/product/test-delta, and security/auth review on 2026-07-17 and @@ -28,16 +30,21 @@ feature-handler authority. - Outbox dispatch owns outbox mechanics only. Protected handlers need exact independent authority. - CON-09A/09B are deferred optional successors and do not gate the core release. +- AUTH PR #140 registers no CON ActionId and activates no feature action. Its + exact custody and prepared-protocol contracts are now upstream gates. +- `task.claim` activation must follow, not precede, the CON-05A hidden + TaskAssignment contribution-policy freeze. ## Active chunk -No implementation chunk is active. +`WS-CON-001-PLAN3` only. No implementation chunk is active. | Chunk | Status | Notes | |---|---|---| -| `WS-CON-001-PLAN` | Complete; unpublished | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | +| `WS-CON-001-PLAN` | Complete; superseded baseline | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | | `WS-CON-001-PLAN2` | Complete; unpublished | FinalAcceptance is REV-owned; CON trigger changes only; all required internal tracks pass | -| `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN2 and upstream merge refresh | +| `WS-CON-001-PLAN3` | Reconciliation and internal review in progress | AUTH PR #140 exact PREP/custody/activation sequencing only | +| `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN3 and upstream merge refresh | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | ## Open gates @@ -51,13 +58,14 @@ No implementation chunk is active. | Core WS-CON action registration/activation | AUTH | Add reviewed registration and later activation chunks; CON remains hidden | | Fixed service runtime | AUTH | Complete AUTH-09A through 09E before protected service calls | | Feature handler authority | Human + AUTH + CON | Approve exact identities/actions/static rows; no dispatcher inheritance | -| Repository loop-memory state | AUTH / merged-main owner | `check_loop_memory_state.py` currently fails on the unchanged AUTH status inherited from `origin/main`; WS-CON must not repair that external initiative file | -| task.claim | AUTH/task owner | Register/evaluate/activate with exact submitter grant before CON-05A | -| review.claim/review.decision | AUTH + REV + CON | Complete hidden participants/composition, full REV custody transfer, then AUTH activation | +| AUTH prepared protocol | AUTH | Merge AUTH-PREP after AUTH-09E; all CON-sensitive mutations consume its exact opaque handle contract | +| task.claim | AUTH + task + CON | Only PermissionId exists; after AUTH-10/PREP and stable task seam, merge CON-05A freeze and task-owned composition; AUTH-13 enumerates/registers/evaluates/activates afterward | +| review.claim/review.decision | AUTH + REV + CON | Complete REV custody transfer and AUTH-PREP; merge hidden CON participants and REV composition; AUTH-REV-06/08 activate afterward | | Shared outbox | CON-02A/B | Land generic persistence/dispatcher after approval | | Joint release | REV + CON + AUTH | Consume exact hidden manifest; optional evidence and ART are not prerequisites | ## Stop condition -Do not edit runtime code, start CON-01, publish, push, or open a PR without -explicit human direction. +Do not edit runtime code, start CON-01, push, open, or merge a PR without +explicit human direction. PLAN3 may prepare its trust bundle and merge intent +for review readiness only. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index 882c512e..ece260b6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -48,11 +48,11 @@ roadmap changes without synchronized local XLSX/CSV exports commit. It adds no SubmissionVersion alias or adjudication dependency. - [ ] Optional evidence is clearly deferred with separate ART/AUTH approval and is absent from the core release path. -- [ ] AUTH boundary matches PR #139: independent project grants, fixed-service +- [ ] AUTH boundary matches PR #140 (adopting PR #139): independent project grants, fixed-service static matrix/AUTH-09E, prepared mutations, AUTH-only activation, complete ART/REV custody references, and no service-row startup dependency. -- [ ] Active spec lists the proposed 22 core surface mappings using - `contribution.policy.*`; optional evidence is separate; protected handler +- [ ] Active spec lists the proposed 22 core surface mappings as unregistered, + non-final identifiers using `contribution.policy.*`; optional evidence is separate; protected handler execution actions remain explicit human/AUTH gates until approved. - [ ] Dispatcher authority is limited to outbox mechanics; delivery, reconciliation, rebuild, and callback cannot inherit it. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md index 7a6669ac..69b8019b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md @@ -38,6 +38,11 @@ test/coverage/CI weakening singleton static row, controlled ActorProfile/link provisioning, AUTH-09E admission, typed context, and prepared protocol. Hidden dispatcher remains disabled until later AUTH evaluator integration/activation. +- [ ] Prepared dispatch follows PR #140 exactly: AUTH locks service profile/link + and prepares the session/action/actor-ref/idempotency/request-digest-bound + handle; the dispatcher locks and recomposes canonical claim facts; AUTH + consumes/evaluates once before claim mutation. Matrix/availability are + code-owned validations, not database lock targets. - [ ] Dispatcher claims with lease/generation fencing, commits and releases all locks before invoking a handler, and alone applies typed outcomes to retry/ dead-letter/final state. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md index 1150d552..6cb7039a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md @@ -39,8 +39,9 @@ concrete adapter, provider secret/ref, dependency or CI weakening - [ ] Create validates canonical active service ActorProfile/link, immutable approved ServiceIdentity, exact static row, and non-secret route identity. - [ ] Mutations follow PLAN locks and transaction-revalidate authority; own-state - concurrent suspend/resume is deterministic. They use the AUTH-prepared handle - and evaluate it once against facts recomposed from locked binding/project rows. + concurrent suspend/resume is deterministic. AUTH prepares its exact bound + handle first; CON locks binding/project rows and recomposes final facts; AUTH + consumes the handle and evaluates once before CON mutates or flushes. - [ ] The service accepts only an allowed decision whose complete resource- context digest, matched AdminRoleGrant ID and covered project match the locked binding facts; mismatched decision evidence is rejected. It flushes diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md index 72afe56e..00d2fa80 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md @@ -31,9 +31,10 @@ legacy fallback, dependency or CI weakening - [ ] AUTH registration is merged for planned `contribution.policy.*` actions, each mapped to stable `compensation.policy.manage`, with typed contexts, Finance candidates, AUTH ActionOwner, and prepared T protocol. -- [ ] Publish locks project, active policy, version, rules, definitions, and - bindings; evaluates one prepared handle against recomposed final facts; and - atomically updates current_published_version_id with audit/outbox. +- [ ] AUTH prepares its exact bound handle first. Publish then locks project, + active policy, version, rules, definitions, and bindings; recomposes final + facts; AUTH consumes the handle and evaluates once; only then may the caller + atomically update current_published_version_id with audit/outbox. - [ ] Allowed decision evidence matches complete resource digest, grant ID, project scope, request, and correlation. Service flushes and never commits. - [ ] Explicit unpaid is valid. Missing/incomplete/contradictory setup is a diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md index 01f20cff..e6f82fb6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md @@ -47,13 +47,21 @@ provider/artifact calls; unrelated checker behavior - [ ] No runtime/API/setup/task/checker/review consumer treats retired guide- bound terms as current economic authority. A zero-consumer scanner proves remaining physical schema is unreachable until 05B. -- [ ] `task.claim` is registered and active through AUTH with exact same-project - submitter ProjectRoleGrant, prepared T protocol, actor/link/grant - revalidation, and canonical task guards. No unrelated project/admin grant - substitutes and CON contains no role logic. -- [ ] Claim locks active ContributionPolicy, published version, exact rule/ - definition/binding dependencies, evaluates the prepared handle once, and - copies one same-project published version. +- [ ] Stable PermissionId `task.claim` exists but no task-claim ActionId is + registered. AUTH-10 exact same-project submitter ProjectRoleGrant and + AUTH-PREP contracts are merged; no unrelated project/admin grant substitutes + and CON contains no role logic. +- [ ] AUTH prepares exact submitter authority first. Task-owned composition + locks canonical task/assignment facts, invokes the CON participant to lock + active ContributionPolicy, published version, exact rule/definition/binding + dependencies and return one same-project version, then recomposes final + facts. AUTH consumes the handle and evaluates once before TaskAssignment is + created with that immutable version. CON flushes only and never commits. +- [ ] CON-05A and task-owned claim composition merge while the task-claim + ActionId remains absent. `WS-AUTH-001-13` enumerates/registers the exact + action, integrates its evaluator, and activates only after the merged feature + manifest proves the freeze, canonical guards, rollback, and real-kernel + unavailable behavior before activation. - [ ] Missing/invalid policy fails with no assignment/task/audit/outbox partial state. Later publication never updates an assignment. - [ ] Publish versus claim and binding-state versus claim pass both lock orders @@ -66,5 +74,6 @@ provider/artifact calls; unrelated checker behavior ## Review and stop Required tracks: senior, QA, security, product, architecture, docs, reuse, test- -delta, and CI integrity. Stop if exact task/Submission lineage, task.claim -authority, or migration classification is not merged. +delta, and CI integrity. Stop if exact task/Submission lineage, AUTH-PREP, +task-owned composition seam, or migration classification is not merged. Do not +wait for or perform `task.claim` activation inside this chunk. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md index ad7f91eb..a3da9cbf 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md @@ -41,6 +41,10 @@ task assignment changes; provider/artifact/adapter calls unrelated project/admin grants do not substitute. No-self-review and REV lifecycle guards remain REV-owned; no adjudication behavior or dependency is introduced. +- [ ] AUTH-PREP locks reviewer authority and prepares its exact bound handle; + REV locks queue/lease/Submission facts; CON locks policy dependencies and + returns the version; REV recomposes final facts; AUTH consumes/evaluates once + before REV writes the lease freeze. CON flushes only and never commits. - [ ] CON hidden port and REV hidden composition merge while review.claim remains planned; AUTH later integrates the evaluator and alone activates. - [ ] Policy publish and binding state versus claim pass both lock orders; diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md index 171413b6..75e99bc7 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md @@ -49,9 +49,10 @@ database/fence lock held during external I/O - [ ] Delivery authority is independent from `outbox.dispatch`. Dispatcher is denied delivery; delivery identity is denied dispatch and every other handler/action; humans are denied fixed-service execution. -- [ ] Prepared authorization locks service ActorProfile/link, validates exact - ServiceIdentity/static row/action, then CON locks award/binding/delivery rows - and evaluates final facts once. +- [ ] Prepared authorization locks service ActorProfile/link and validates exact + ServiceIdentity/static row/action as code-owned facts. AUTH prepares its exact + bound handle; CON locks award/binding/delivery rows and recomposes final + facts; AUTH consumes/evaluates once before durable delivery mutation. - [ ] Durable in-flight generation and exact event/payload/binding/idempotency identity commit before adapter I/O; every database transaction and lifecycle fence is released before the call. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md index 7d62a18b..fa771b8d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -31,9 +31,11 @@ outbox transition ownership; production route registration `compensation.fulfillment.report` row (or an explicitly closed set of identities), provisions ActorProfile/link, admits through AUTH-09E, and keeps the action planned until hidden callback behavior merges. -- [ ] Prepared callback locks profile/link, validates immutable ServiceIdentity, - matrix membership and active action, then locks binding/award/delivery/ - receipt rows and evaluates final typed facts once. +- [ ] Prepared callback locks profile/link and validates immutable + ServiceIdentity, matrix membership and active action as code-owned facts. + AUTH prepares its exact bound handle; CON locks binding/award/delivery/ + receipt rows and recomposes final facts; AUTH consumes/evaluates once before + callback mutation. - [ ] Exact route identity, project, instrument, award, frozen binding, external event, quantity/status, and idempotency must match. Actor/link/binding state loss denies. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md index 464d9a2c..8734458d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -33,6 +33,9 @@ AUTH implementation; production router registration; CI weakening - [ ] D11 is final. AUTH registers binding-retire, delivery-reconcile, status, reconcile-request, rebuild-request, and audit actions with exact candidates, contexts, prepared protocol, and AUTH custodians. +- [ ] Every mutation uses the exact PR #140 prepared protocol: AUTH prepares + authority first; CON locks and recomposes final facts; AUTH consumes/evaluates + once before request/retirement mutation; the route commits once. - [ ] Human operations create bounded durable idempotent requests only; they do not execute reconciliation/rebuild under human or dispatcher authority. - [ ] Binding retirement locks policy/assignment/lease/award/delivery/receipt diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md index e2939ab8..d0911983 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md @@ -44,9 +44,10 @@ outbox claim/finalization transitions; AUTH implementation - [ ] Dispatcher can invoke but is denied both executor actions. Each executor is denied dispatch, the other executor's action, delivery/callback/ART/REV actions, and every human action outside its exact row. -- [ ] Handler validates committed claim generation, prepares fixed-service - authority, locks bounded request/product rows, evaluates final facts once, - stages result/audit/projection state, and returns typed outcome. +- [ ] Handler validates committed claim generation; AUTH locks fixed-service + authority and prepares its exact bound handle; CON locks bounded request/ + product rows and recomposes final facts; AUTH consumes/evaluates once; CON + then stages result/audit/projection state and returns a typed outcome. - [ ] Compensation reconciliation compares immutable award/delivery/receipt truth and creates durable findings/actions allowed by the approved contract; it never changes award amount/eligibility or fabricates receipt truth. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index 82554c02..404e6858 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -38,6 +38,11 @@ archival input edits proposed core CON mappings plus separately approved executor actions, D11 role sets, exact grants/static rows, AUTH-09E admission, prepared protocol, decision digests/matched authority, and activation evidence. +- [ ] Prepared-protocol proof binds handles exactly to session, ActionId, + actor-reference kind/reference, idempotency key, and request digest; proves + same-session/action cross-actor/request substitution does not mutate state or + consume a valid handle; and proves ServiceIdentity/matrix/availability are not + database lock targets. - [ ] No partial ART/REV transfer is restated. Complete mappings are referenced from merged WS-XINT handoffs. ART and optional CON-09A/09B are absent from core prerequisites. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md new file mode 100644 index 00000000..ee9cb049 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md @@ -0,0 +1,115 @@ +# Chunk Contract: WS-CON-001-PLAN3 - AUTH PR 140 Reconciliation + +## Goal + +Reconcile WS-CON planning with trusted `main` at merged AUTH PR #140 without +implementing runtime behavior, changing AUTH-owned files, or weakening the +review/FinalAcceptance/contribution transaction. + +## Risk + +L0/L1 authorization, transaction, and release specification; P1. + +## Allowed files + +```text +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +.agent-loop/merge-intents/WS-CON-001-PLAN3.json +``` + +## Not allowed + +```text +backend application, migrations, tests, workflows, dependencies, or runtime catalogue edits +AUTH/REV/ART/XINT initiative or implementation edits +active product-document changes without a newly discovered canonical mismatch +new PermissionId, ActionId, ServiceIdentity, grant, or action activation +feature-owned authorization evaluator, grant query, or availability writer +FinalAcceptance API/action or adjudication lifecycle/dependency +reference specification/PDF edits, restoration, rename, or replacement +``` + +## Acceptance criteria + +- [x] Trusted baseline is merged PR #140 at `d541521`; the runtime catalogue + remains 74 PermissionIds, 57 ActionIds, nine active and 48 planned, with no + registered CON-specific ActionId. +- [x] CON consumes AUTH's exact prepared mutation protocol: AUTH locks current + authority first and creates an opaque single-use handle bound to session, + ActionId, actor-reference kind/reference, idempotency key, and canonical + request digest; feature rows lock afterward; final facts are recomposed; AUTH + evaluates once and stages evidence; the route/command commits once. +- [x] CON never describes ServiceIdentity, static matrix membership, or action + availability as database lock targets and never imports AUTH persistence or + evaluates grants locally. +- [x] Only the stable `task.claim` PermissionId exists today; no task-claim + ActionId is registered. After AUTH-10/PREP, CON-05A and task-owned freeze + composition merge first; AUTH-13 then enumerates/registers the exact action, + integrates its evaluator, and activates only after merged proof. Existing + `review.claim` and `review.decision` ActionIds remain planned and require the + exact reviewer grant plus REV guards before activation. +- [x] `review.decision` activation requires the merged mandatory CON flush-only + participant and rollback-safe REV+CON single transaction. FinalAcceptance + remains an internal REV consequence with no action/API. +- [x] All 19 REV actions are referenced through the complete AUTH custody + transfer. CON names only its `review.claim` and `review.decision` + dependencies and never owns or partially transfers ActionOwner metadata. +- [x] The existing 22 CON surface mappings and service-execution identifiers + remain explicitly non-final proposals. Each requires a later exact + feature-owned manifest, reviewed AUTH registration, hidden behavior, and + AUTH-only activation; dispatcher authority is never inherited by handlers. +- [x] No adjudication dependency, retired compensation-policy compatibility + path, ART call in + core contribution creation, or independent CON commit is introduced. +- [x] Required internal reviewers pass the exact final snapshot, deterministic + gates pass, the PR trust bundle is complete, and exactly one PLAN3 merge + intent is present in the branch delta. + +## Verification + +```bash +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py +git diff --check +test -z "$(git diff origin/main --name-only -- backend)" +``` + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +reuse/dedup, and test-delta. CI integrity is required if any script, workflow, +test, dependency, threshold, or runner changes. + +## Stop + +Stop after reviewed planning reconciliation, PR trust bundle, and merge-intent +preparation. Do not implement CON-01 or any runtime chunk, push, open, or merge +a PR without the user's explicit next instruction and merge approval. diff --git a/.agent-loop/merge-intents/WS-CON-001-PLAN3.json b/.agent-loop/merge-intents/WS-CON-001-PLAN3.json new file mode 100644 index 00000000..2253e569 --- /dev/null +++ b/.agent-loop/merge-intents/WS-CON-001-PLAN3.json @@ -0,0 +1,9 @@ +{ + "chunk_id": "WS-CON-001-PLAN3", + "chunk_title": "AUTH PR 140 Reconciliation", + "initiative_id": "WS-CON-001", + "next_chunk_id": "WS-CON-001-01", + "next_chunk_title": "Canonical Contract Adoption And Architecture Decision", + "next_requires_explicit_start": true, + "schema_version": 2 +} From 6ef261ddbd4388e8f831e04fa88bc63484636602 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 10:18:10 +0100 Subject: [PATCH 13/22] Bind WS-CON AUTH PR 140 review evidence --- .../STATUS.md | 17 +- ...-CON-001-PLAN3-internal-review-evidence.md | 117 +++++++++++++ .../WS-CON-001-PLAN3-pr-trust-bundle.md | 163 ++++++++++++++++++ 3 files changed, 290 insertions(+), 7 deletions(-) create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 7800c3b2..8bbef4b9 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,13 +2,15 @@ ## Current status -`WS-CON-001-PLAN3` is reconciling merged AUTH PR #140 at trusted main -`d541521` with the previously reviewed CON plan. PLAN2 already reconciled the +`WS-CON-001-PLAN3` completed reconciliation of merged AUTH PR #140 at trusted +main `d541521` with the previously reviewed CON plan. The planning snapshot at +`545f250db8d5d1df05cf33cc5b22d1c933217ae8` passed all required exact-SHA +internal reviewer tracks and deterministic gates. Its review evidence, trust +bundle, and schema-v2 merge intent are prepared; it remains unpublished pending +the user's explicit PR direction. PLAN2 already reconciled the human-approved v0.1 `Review(accept) -> FinalAcceptance -> accepted_submission` boundary against the -previously reviewed WS-XINT plan. Runtime code is unchanged. The addendum passed -architecture, QA/product/test-delta, and security/auth review on 2026-07-17 and -remains unpublished pending human direction. +previously reviewed WS-XINT plan. Runtime code is unchanged. The prior plan is superseded where it used the older policy aggregate, made ART evidence mandatory, described service action rows as persisted assignments, allowed partial activation-custody transfer, or let outbox dispatch imply @@ -37,13 +39,14 @@ feature-handler authority. ## Active chunk -`WS-CON-001-PLAN3` only. No implementation chunk is active. +No chunk is active. PLAN3 is complete and unpublished; no implementation chunk +starts automatically. | Chunk | Status | Notes | |---|---|---| | `WS-CON-001-PLAN` | Complete; superseded baseline | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | | `WS-CON-001-PLAN2` | Complete; unpublished | FinalAcceptance is REV-owned; CON trigger changes only; all required internal tracks pass | -| `WS-CON-001-PLAN3` | Reconciliation and internal review in progress | AUTH PR #140 exact PREP/custody/activation sequencing only | +| `WS-CON-001-PLAN3` | Complete; unpublished | Exact-SHA reviewers and deterministic gates pass; AUTH PR #140 PREP/custody/activation sequencing only | | `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN3 and upstream merge refresh | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md new file mode 100644 index 00000000..590e9075 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md @@ -0,0 +1,117 @@ +# WS-CON-001-PLAN3 Internal Review Evidence + +Reviewed code SHA: 545f250db8d5d1df05cf33cc5b22d1c933217ae8 +Reviewed at: 2026-07-17T09:16:36Z +Reviewer run IDs: auth08_arch_review/McClintock, auth08_qa_product_review/Popper, auth08_security_review/Newton + +## Reviewed boundary + +The exact reviewed commit reconciles CON planning with merged AUTH PR #140. It +changes 24 planning/merge-intent files with 412 insertions and 143 deletions and +changes no backend, migration, runtime catalogue, test, script, workflow, or +dependency file. + +The reviewed boundary establishes: + +- 74 runtime PermissionIds and 57 ActionIds, with nine active and 48 planned; +- no registered CON-specific ActionId and no task-claim ActionId; +- stable PermissionId `task.claim` followed by the safe order AUTH-10/PREP and + task seam, CON-05A hidden freeze and task composition, then AUTH-13 action + enumeration/registration/evaluator integration/activation; +- planned `review.claim` and `review.decision` actions gated on the merged + hidden CON participants, REV-owned composition, and later AUTH activation; +- exact AUTH-PREP authority-first lock, opaque-handle binding, feature-lock, + recomposition, single AUTH evaluation, flush-only participant, and + caller-owned commit semantics; +- 22 explicitly unregistered, non-final CON surface mappings and no speculative + `AUTH_CON_*` ActionOwner candidates; +- `Review(accept) -> FinalAcceptance -> accepted_submission`, with REV as the + transaction owner, CON as a mandatory flush-only participant, no separate + FinalAcceptance action/API, and no adjudication dependency; and +- one schema-v2 merge intent naming `WS-CON-001-01` as an explicit-start + same-initiative successor. + +## Reviewer results + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | The 24-file reconciliation is coherent, bounded to planning, and preserves single ownership for AUTH, REV, and CON responsibilities. | +| qa/test | PASS AFTER FIXES | None | The false task-claim ActionId statement was corrected; lifecycle outcomes, 22-mapping count, and deterministic gates pass. | +| security/auth | PASS AFTER FIXES | None | Exact prepared-handle semantics and AUTH-only identifier/evaluator/activation ownership pass after the task-claim correction. | +| product/ops | PASS AFTER FIXES | None | Accept, needs-revision, reject, FinalAcceptance, contribution, compensation, and no-adjudication boundaries remain correct. | +| architecture | PASS | None | Safe task/review sequencing, complete custody references, flush-only CON participation, and same-initiative successor all pass. | +| ci integrity | PASS | None | PLAN3 changes no CI, workflow, threshold, runner, script, dependency, test, or runtime file and adds no bypass. | +| docs | PASS AFTER FIXES | None | Runtime versus planned identifiers, PR #140 provenance, and non-final proposals are explicit; required evidence and trust bundle were then added through allowed post-review paths. | +| reuse/dedup | PASS | None | No duplicate runtime abstraction or alternative authorization path is introduced; common AUTH/REV contracts are referenced. | +| test delta | PASS | None | No tests changed or were required for the planning-only reconciliation; 80 existing agent-gate tests pass. | + +## Findings and repairs + +### Resolved substantive finding + +Initial QA and security reviews found that the draft treated `task.claim` as an +existing ActionId. Runtime inspection proved it exists only as a PermissionId. +The plan, discovery, handoff, decisions, status, chunk map, PLAN3 contract, and +CON-05A contract now state that the ActionId remains absent until the hidden +freeze and task composition merge. AUTH-13 alone owns the later enumeration, +registration, evaluator integration, and activation. + +### Resolved process finding + +The exact-SHA QA re-review found that the PLAN3 contract's evidence criterion +could not be complete until this evidence file and the PR trust bundle existed. +Both were added after review through paths explicitly allowed by the repository +evidence gate; no reviewed planning or implementation file changed afterward. + +### Confirmed non-findings + +- A failed same-session/action substitution does not consume an otherwise valid + prepared handle. +- ServiceIdentity, static-matrix membership, and action availability are + code-owned validations rather than database lock targets. +- CON imports no AUTH persistence, grant query, evaluator, registration, + ActionOwner, or availability writer. +- FinalAcceptance has no public API or independent authorization action. +- No adjudication lifecycle or dependency was introduced. +- The archival PDF deletion is user-owned, unstaged, and excluded from every + reviewed commit. + +## Deterministic evidence + +```text +python3 scripts/check_markdown_links.py + PASS - 57 changed Markdown files before evidence addenda +python3 scripts/check_stale_workstream_wording.py + PASS +python3 scripts/check_stale_authorization_docs.py + PASS +python3 scripts/check_stale_artifact_contracts.py + PASS - foundation phase +python3 scripts/check_loop_memory_state.py + PASS +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py + PASS - 80 tests +git diff --check 545f250^..545f250 + PASS +git diff --check + PASS +PLAN3 backend/.github/scripts delta + none +python3 scripts/update_post_merge_memory.py validate-merge-intent --base-ref origin/main + PASS - WS-CON-001-PLAN3 +``` + +The circuit-breaker passed with a documentation-only size exception. The full +branch is large because it contains the original reference transcription and +durable planning/review history, but PLAN3 is one bounded 24-file planning +correction, has no runtime boundary, and required no split. + +Valid findings addressed: yes + +Open sub-agent sessions: none + +## Stop + +PLAN3 is reviewed and PR-ready but unpublished. No push, PR, merge, or CON-01 +start is authorized by this evidence. The user retains the human checkpoint and +must explicitly approve the specific PR before merge. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md new file mode 100644 index 00000000..68f1a002 --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md @@ -0,0 +1,163 @@ +# WS-CON-001-PLAN3 PR Trust Bundle + +## Chunk + +`WS-CON-001-PLAN3` - AUTH PR 140 Reconciliation. + +## Goal + +Reconcile the contribution and compensation plan with trusted `main` at merged +AUTH PR #140 (`d541521`) before any CON runtime implementation begins. + +## Human-approved intent + +- The current compensation-policy model completely supersedes the retired + policy model; no compatibility path returns. +- The v0.1 accept path is `Review(accept) -> FinalAcceptance -> + accepted_submission` with no adjudication lifecycle. +- REV owns Review and FinalAcceptance orchestration and the single transaction; + CON is a mandatory flush-only contribution/award participant. +- AUTH owns identifiers, grants, evaluator integration, ActionOwner custody, + evidence, and activation. CON must validate upstream planning rather than + copy speculative identifiers. +- Pull and reconcile merged AUTH work before publishing this plan; do not start + CON runtime work automatically. + +## What changed + +- Rebased CON authorization assumptions on AUTH PR #140 while preserving PR + #139 as the underlying cross-initiative boundary. +- Replaced the older prepared-authorization description with the exact opaque, + single-use handle binding and authority-first lock protocol. +- Corrected `task.claim`: only its stable PermissionId exists; no task-claim + ActionId is registered. +- Ordered task work as AUTH-10/PREP and the task seam, then CON-05A hidden + policy freeze plus task composition, then AUTH-13 enumeration, registration, + evaluator integration, and activation. +- Preserved planned `review.claim` and `review.decision` actions and their + dependency on hidden CON participants, REV composition, and later AUTH + activation. +- Removed speculative `AUTH_CON_*` ActionOwner candidates. The 22 CON surface + mappings remain unregistered, non-final proposals. +- Added the reviewed PLAN3 contract and one schema-v2 merge intent naming + `WS-CON-001-01` as the same-initiative successor with an explicit start gate. + +## Why + +Treating a PermissionId as an existing ActionId would invert the safe rollout: +AUTH could activate task claim before the assignment captured its immutable +contribution-policy version. The corrected order keeps the feature unavailable +until hidden behavior and rollback proof are merged. + +## Design and boundaries + +AUTH locks current actor/link/exact-grant authority first and prepares one +opaque handle bound to session, ActionId, actor-reference kind/reference, +idempotency key, and canonical request digest. The feature then locks product +rows and recomposes final facts. AUTH consumes the handle, evaluates once, and +stages evidence. Participants flush only and the owning request/command commits +once. A failed substitution attempt does not consume an otherwise valid handle. + +ServiceIdentity, static-matrix membership, and action availability are +code-owned validations, not database lock targets. No AUTH persistence, grant +query, evaluator, identifier registration, or availability writer moves into +CON. + +FinalAcceptance remains an internal REV-derived fact with no public API or +separate authorization action. No adjudication policy, state, action, queue, +lease, contribution, or release dependency is added. + +## Alternatives rejected + +- Activating task claim before CON-05A: rejected because assignment policy + lineage would not be guaranteed. +- Treating `task.claim` as an existing ActionId: rejected by runtime catalogue + evidence. +- Retaining `AUTH_CON_*` planning labels: rejected because PR #140 approves no + such ActionOwner values. +- Giving CON an authorization evaluator or commit: rejected because those + responsibilities remain AUTH- and request-owned. +- Adding a FinalAcceptance action or adjudication branch: rejected by the + approved v0.1 lifecycle. + +## Scope + +PLAN3 itself changes 24 planning/merge-intent files with 412 insertions and 143 +deletions. It changes no backend, migration, test, workflow, script, dependency, +runtime catalogue, or active product document. The full planning branch is 65 +files with 7,633 insertions and 91 deletions against `origin/main`; most of that +delta is the original reference transcription and durable planning/review +record. + +The circuit-breaker passed with a documentation-only size exception: the branch +is one coherent specification initiative, its runtime boundary is empty, and +the earlier planning snapshots retain their own review evidence. The user-owned +deletion of the archival CON PDF is unstaged and excluded. + +## Acceptance-criteria proof + +- Runtime catalogue verified at 74 PermissionIds and 57 ActionIds: nine active, + 48 planned, no CON-specific ActionId, and no task-claim ActionId. +- Prepared-handle wording matches merged AUTH PR #140. +- The task and review activation sequences explicitly require hidden feature + behavior before AUTH-only activation. +- Reviewer and submitter contribution lineage remains Review and + FinalAcceptance respectively, inside the REV-owned transaction. +- The 22 CON mappings are explicitly unregistered/non-final; only the two + proposed service PermissionIds remain identified as proposals. +- Merge-intent validation passes for successor `WS-CON-001-01`. + +## Tests and checks + +```text +Markdown link check: PASS (57 changed Markdown files) +Stale Workstream wording: PASS +Stale authorization documentation: PASS +Stale artifact contracts: PASS at foundation phase +Loop-memory state: PASS +Agent gates: PASS (80 tests) +PLAN3 commit diff check: PASS +Working-tree diff check: PASS +PLAN3 backend/.github/scripts delta: none +Merge-intent schema-v2 validation: PASS +Local roadmap workbook: not present, so no sheet-export check applies +``` + +## Test delta and CI integrity + +PLAN3 changes no test or CI file, removes no assertion, skips no test, changes +no threshold, and adds no bypass. Existing agent-gate coverage remains intact. + +## Internal reviewer results + +The exact reviewed code SHA and complete reviewer table are recorded in +`WS-CON-001-PLAN3-internal-review-evidence.md`. The initial QA/security finding +that `task.claim` was incorrectly described as an existing ActionId was fixed +before the exact-SHA review. No blocking finding remains. + +## External review + +Pending PR publication. CodeRabbit, GitHub checks, and human PR review supplement +but do not replace the completed internal review. + +## Risks and follow-up + +- AUTH-13 must be refreshed to consume the merged CON-05A/task-composition + manifest before task-claim registration or activation. +- Future CON actions need complete feature manifests and exact AUTH-owned + registration/activation contracts; the proposed table is not a registry. +- `review.claim` and `review.decision` remain unavailable until their complete + REV/CON composition and AUTH gates merge. +- CON-01 remains a separate explicit human start after this planning PR. + +## Human review focus + +Confirm the corrected task-claim ordering, the exact prepared-handle contract, +the removal of speculative ActionOwner labels, and the unchanged +Review/FinalAcceptance/contribution transaction. Also confirm that the 65-file +planning PR is acceptable as one coherent specification record. + +## Human merge ownership + +This bundle does not authorize publication or merge. The user must explicitly +approve this specific PR for merge. No successor chunk starts automatically. From 09128ee1aed941682c7cb59ca04698de496de682 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 10:20:02 +0100 Subject: [PATCH 14/22] Allow cumulative CON evidence rebind --- .../chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md index ee9cb049..61975661 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md @@ -37,6 +37,8 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md .agent-loop/merge-intents/WS-CON-001-PLAN3.json @@ -88,7 +90,9 @@ reference specification/PDF edits, restoration, rename, or replacement core contribution creation, or independent CON commit is introduced. - [x] Required internal reviewers pass the exact final snapshot, deterministic gates pass, the PR trust bundle is complete, and exactly one PLAN3 merge - intent is present in the branch delta. + intent is present in the branch delta. Older PLAN/PLAN2 evidence receives a + provenance-only rebind when the PR-level gate requires every evidence file + added by the cumulative branch to match the final reviewed revision. ## Verification From 25b5b165ffd4e0cc207709c80eeeaeb7e1e9d5a7 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 10:23:27 +0100 Subject: [PATCH 15/22] Rebind cumulative WS-CON review evidence --- .../STATUS.md | 2 +- ...S-CON-001-PLAN-internal-review-evidence.md | 29 +++++++++++++++++++ ...-CON-001-PLAN2-internal-review-evidence.md | 29 +++++++++++++++++++ ...-CON-001-PLAN3-internal-review-evidence.md | 19 +++++++----- .../WS-CON-001-PLAN3-pr-trust-bundle.md | 4 ++- 5 files changed, 74 insertions(+), 9 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 8bbef4b9..e8283f14 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -4,7 +4,7 @@ `WS-CON-001-PLAN3` completed reconciliation of merged AUTH PR #140 at trusted main `d541521` with the previously reviewed CON plan. The planning snapshot at -`545f250db8d5d1df05cf33cc5b22d1c933217ae8` passed all required exact-SHA +`09128ee1aed941682c7cb59ca04698de496de682` passed all required exact-SHA internal reviewer tracks and deterministic gates. Its review evidence, trust bundle, and schema-v2 merge intent are prepared; it remains unpublished pending the user's explicit PR direction. PLAN2 already reconciled the diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index 7772bb58..96204278 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -1,5 +1,34 @@ # Internal Review Evidence: WS-CON-001-PLAN +## 2026-07-17 Final PR Provenance Rebind + +Reviewed code SHA: 09128ee1aed941682c7cb59ca04698de496de682 +Reviewed at: 2026-07-17T09:22:25Z +Reviewer run IDs: auth08_arch_review/rebind-09128ee, auth08_qa_product_review/rebind-09128ee, auth08_security_review/rebind-09128ee + +This provenance-only addendum binds the earlier substantive PLAN review chain to +the final reviewed cumulative planning snapshot. PLAN3 authorizes this evidence +rebind because the PR-level gate validates every evidence file added by the +branch. It changes no historical finding or product conclusion. The exact-SHA +re-review confirmed that the merged AUTH boundary, later FinalAcceptance +reconciliation, and evidence-schema update introduce no remaining blocker. + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | The cumulative specification remains coherent and PLAN3 is a bounded process/specification correction. | +| qa/test | PASS AFTER FIXES | None | The task-claim ActionId error and missing-evidence process gap are resolved. | +| security/auth | PASS AFTER FIXES | None | Exact AUTH-PREP semantics and AUTH-only identifier/evaluator/activation ownership pass. | +| product/ops | PASS AFTER FIXES | None | Review outcomes, FinalAcceptance lineage, contribution atomicity, and no-adjudication boundary pass. | +| architecture | PASS | None | Ownership, transaction, rollout, and same-initiative successor boundaries remain coherent. | +| ci integrity | PASS | None | The rebind changes evidence only; no CI, runtime, test, script, workflow, dependency, or threshold changes. | +| docs | PASS AFTER FIXES | None | Runtime-versus-planned identifiers and cumulative evidence provenance are explicit. | +| reuse/dedup | PASS | None | No duplicate service, evaluator, registry, or transaction abstraction is introduced. | +| test delta | PASS | None | No test delta; all 80 agent-gate tests pass. | + +Valid findings addressed: yes + +Open sub-agent sessions: none + ## 2026-07-17 WS-XINT-001 Boundary Reconciliation This addendum is the current authoritative review state and supersedes the diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md index 6abf53a4..bd52fe5a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md @@ -1,5 +1,34 @@ # WS-CON-001-PLAN2 Internal Review Evidence +## Final PR provenance rebind + +Reviewed code SHA: 09128ee1aed941682c7cb59ca04698de496de682 +Reviewed at: 2026-07-17T09:22:25Z +Reviewer run IDs: auth08_arch_review/rebind-09128ee, auth08_qa_product_review/rebind-09128ee, auth08_security_review/rebind-09128ee + +This provenance-only addendum binds the reviewed FinalAcceptance reconciliation +to the final cumulative planning snapshot. It changes no PLAN2 lifecycle fact. +The exact-SHA re-review confirms that PLAN3 preserves REV-owned +FinalAcceptance, CON flush-only participation, all three review outcomes, and +the no-adjudication boundary while correcting only AUTH sequencing and evidence +provenance. + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS | None | FinalAcceptance and contribution responsibilities retain single owners and one commit. | +| qa/test | PASS AFTER FIXES | None | Accept, needs-revision, reject, lineage, rollback, and evidence completeness pass. | +| security/auth | PASS AFTER FIXES | None | No FinalAcceptance action/API, adjudication path, authorization bypass, or CON evaluator is introduced. | +| product/ops | PASS AFTER FIXES | None | Reviewer and submitter contribution triggers remain Review and FinalAcceptance respectively. | +| architecture | PASS | None | REV persistence, CON participant, REV composition, and later AUTH activation remain correctly ordered. | +| ci integrity | PASS | None | The rebind changes evidence only and weakens no gate. | +| docs | PASS AFTER FIXES | None | Historical PLAN2 conclusions and final provenance are explicit. | +| reuse/dedup | PASS | None | Existing REV/AUTH contracts are referenced without a parallel path. | +| test delta | PASS | None | No test delta; all 80 agent-gate tests pass. | + +Valid findings addressed: yes + +Open sub-agent sessions: none + Date: 2026-07-17 ## Reviewed boundary diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md index 590e9075..a0fabcfc 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md @@ -1,15 +1,17 @@ # WS-CON-001-PLAN3 Internal Review Evidence -Reviewed code SHA: 545f250db8d5d1df05cf33cc5b22d1c933217ae8 -Reviewed at: 2026-07-17T09:16:36Z -Reviewer run IDs: auth08_arch_review/McClintock, auth08_qa_product_review/Popper, auth08_security_review/Newton +Reviewed code SHA: 09128ee1aed941682c7cb59ca04698de496de682 +Reviewed at: 2026-07-17T09:22:25Z +Reviewer run IDs: auth08_arch_review/rebind-09128ee, auth08_qa_product_review/rebind-09128ee, auth08_security_review/rebind-09128ee ## Reviewed boundary -The exact reviewed commit reconciles CON planning with merged AUTH PR #140. It -changes 24 planning/merge-intent files with 412 insertions and 143 deletions and -changes no backend, migration, runtime catalogue, test, script, workflow, or -dependency file. +The exact reviewed snapshot reconciles CON planning with merged AUTH PR #140 +and authorizes the provenance-only rebind of the older PLAN/PLAN2 evidence that +the cumulative PR gate requires. Its substantive PLAN3 commit changes 24 +planning/merge-intent files with 412 insertions and 143 deletions and changes no +backend, migration, runtime catalogue, test, script, workflow, or dependency +file. The reviewed boundary establishes: @@ -62,6 +64,9 @@ The exact-SHA QA re-review found that the PLAN3 contract's evidence criterion could not be complete until this evidence file and the PR trust bundle existed. Both were added after review through paths explicitly allowed by the repository evidence gate; no reviewed planning or implementation file changed afterward. +The final exact-SHA rebind then added the two older evidence paths to PLAN3's +allowed scope so every evidence file added by the cumulative branch can carry +current, parser-complete provenance without rewriting historical conclusions. ### Confirmed non-findings diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md index 68f1a002..761c7261 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md @@ -133,7 +133,9 @@ no threshold, and adds no bypass. Existing agent-gate coverage remains intact. The exact reviewed code SHA and complete reviewer table are recorded in `WS-CON-001-PLAN3-internal-review-evidence.md`. The initial QA/security finding that `task.claim` was incorrectly described as an existing ActionId was fixed -before the exact-SHA review. No blocking finding remains. +before the exact-SHA review. A final process-only rebind authorized +parser-complete provenance addenda for the older PLAN/PLAN2 evidence files +validated by the cumulative PR gate. No blocking finding remains. ## External review From 5e1311c4e8b176b92c62959daaafb8ae5a922913 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 16:08:57 +0100 Subject: [PATCH 16/22] Reconcile CON plan with merged REV boundary --- .../AUTHORIZATION_HANDOFF.md | 15 +- .../CHUNK_MAP.md | 22 +-- .../CONFORMANCE_MATRIX.md | 7 +- .../DECISIONS.md | 54 ++++++- .../DISCOVERY.md | 49 ++++-- .../INTENT.md | 9 +- .../JOINT_RELEASE_HANDOFF.md | 55 ++++--- .../PLAN.md | 144 ++++++++++++------ .../RISKS.md | 2 + .../SOURCE_MANIFEST.md | 43 +++--- .../STATUS.md | 32 ++-- ...-CON-001-01-canonical-contract-adoption.md | 10 +- ...-001-03C-contribution-award-persistence.md | 3 +- ...03D-delivery-receipt-status-persistence.md | 6 + ...c-review-contribution-award-participant.md | 62 +++++--- ...-001-08A-outbound-compensation-delivery.md | 16 +- ...ON-001-08B-inbound-fulfillment-callback.md | 10 ++ ...1-10B-operations-reconciliation-rebuild.md | 10 +- .../WS-CON-001-10C-operations-executors.md | 5 + .../WS-CON-001-11-hidden-release-readiness.md | 25 ++- ...CON-001-PLAN3-auth-pr140-reconciliation.md | 25 ++- .../merge-intents/WS-CON-001-PLAN3.json | 2 +- 22 files changed, 429 insertions(+), 177 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md index f2c0c66f..f1bd4e01 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/AUTHORIZATION_HANDOFF.md @@ -2,12 +2,13 @@ ## Current baseline -Trusted `main` is `d541521` from merged AUTH PR #140, which reconciles AUTH to -the earlier WS-XINT PR #139 boundary. The runtime catalogue still contains 74 -PermissionIds and 57 ActionIds: nine active and 48 planned. No WS-CON-specific -ActionId below is registered. PR #140 adds reviewed AUTH planning contracts; it -does not implement AUTH-PREP, transfer ART/REV custody, register a CON action, -or activate a feature action. +Trusted `main` is `0302bcf` from merged REV PR #128. It contains AUTH-09A after +AUTH PR #140 and the earlier WS-XINT PR #139 boundary. The runtime catalogue now +contains 74 PermissionIds and 65 ActionIds: nine active and 56 planned. The +eight added planned actions belong to AUTH-09 service-identity administration; +no WS-CON-specific or task-claim ActionId below is registered. PR #140 still +defines the prepared/custody plan; it does not implement AUTH-PREP, transfer +ART/REV custody, register a CON action, or activate a feature action. AUTH owns identifiers, stable mappings, activation custody, typed resource and principal contexts, grants, fixed ServiceIdentity/static matrix, AUTH-09E @@ -188,7 +189,7 @@ activation only after hidden behavior merges. ## Upstream review and task actions Only the stable `task.claim` PermissionId exists on trusted main; there is no -registered task-claim ActionId among the 57 actions. AUTH-PREP, the exact +registered task-claim ActionId among the 65 actions. AUTH-PREP, the exact submitter grant, and the task-owned claim seam precede CON-05A's hidden freeze participant. CON-05A and task-owned composition must merge first. AUTH-13 then enumerates/registers the exact task-claim ActionId, integrates its evaluator, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md index d2ae95b1..3e96ed0b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CHUNK_MAP.md @@ -13,21 +13,21 @@ availability writer. Optional evidence chunks are not part of the core order. |---|---|---:|---|---| | `WS-CON-001-PLAN` | Contribution And Compensation Planning | L0 | None | Complete; unpublished | | `WS-CON-001-PLAN2` | Final Acceptance Reconciliation | L0 | Human FinalAcceptance/no-adjudication direction | Complete; unpublished | -| `WS-CON-001-PLAN3` | AUTH PR 140 Reconciliation | L0/L1 | Merged AUTH PR #140 at `d541521` | Complete; unpublished | +| `WS-CON-001-PLAN3` | AUTH/REV Current-Main Reconciliation | L0/L1 | Merged AUTH PR #140 plus AUTH-09A and REV PR #128 at `0302bcf` | Complete; unpublished | | `WS-CON-001-01` | Canonical Contract Adoption And Architecture Decision | L0/L1 | Reconciled plan and human decisions approved | Proposed | | `WS-CON-001-02A` | Shared Transactional Outbox Persistence | L1 | 01; event ownership approved | Proposed | | `WS-CON-001-02B` | Shared Outbox Dispatcher And Recovery | L1 | 02A; AUTH registers `outbox.dispatch`, approved `workstream.outbox.dispatcher` ServiceIdentity/static row, AUTH-09E admission, prepared protocol; dispatcher remains disabled until AUTH activation | Proposed | | `WS-CON-001-02C` | Shared Lifecycle Audit Participant | L1 | 02B; current AuditEvent contract refreshed | Proposed | | `WS-CON-001-03A` | Project Compensation Adapter-Binding Persistence | L1 | 02C; migration head refreshed | Proposed | -| `WS-CON-001-03B` | Contribution Policy Persistence | L1 | 03A; legacy-data rule | Proposed | -| `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; exact merged REV FinalAcceptance/Review/ReviewLease FK targets | Proposed | -| `WS-CON-001-03D` | Delivery, Receipt, And Status Persistence | L1 | 03C | Proposed | +| `WS-CON-001-03B` | Contribution Policy Persistence | L1 | 03A; legacy-data rule; must precede REV-03 ReviewLease FK | Proposed | +| `WS-CON-001-03C` | Contribution And Award Persistence | L1 | 03B; merged REV-04 runtime FinalAcceptance/Review/ReviewLease FK targets | Proposed | +| `WS-CON-001-03D` | Delivery, Receipt, And Status Persistence | L1 | 03C; immutable fulfillment root ordinal/generation contract | Proposed | | `WS-CON-001-04A` | Hidden Adapter-Binding Service | L1 | 03A; planned AUTH binding actions/contexts/prepared protocol; callback ServiceIdentity/action/static row approved but inactive | Proposed | | `WS-CON-001-04B` | Hidden Contribution-Policy Service | L1 | 03B, 04A; binding activation merged; planned `contribution.policy.*` actions/contexts/prepared protocol | Proposed | | `WS-CON-001-05A` | Legacy Economic Terms Cutover And Task Freeze | L1 | 04B; exact Submission/TaskAssignment lineage; AUTH-10 exact submitter grants and AUTH-PREP merged; task.claim PermissionId exists but ActionId remains absent; stable task-owned claim seam; legacy rule | Proposed | | `WS-CON-001-05B` | Legacy Economic Schema Removal | L1 | 05A; zero-consumer scan; removal migration approval | Proposed | | `WS-CON-001-06` | Review-Lease Contribution-Policy Freeze Capability | L1 | REV lease schema; 05B; AUTH-PREP; planned review.claim typed contract; exact reviewer grant facts stable | Proposed | -| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D, 05A, 06; AUTH-PREP and complete REV custody transfer; merged TaskAssignment freeze field and REV ReviewLease plus accept-only FinalAcceptance persistence and locked decision-lineage contract; shared audit/outbox; planned review.decision typed contract | Proposed | +| `WS-CON-001-07` | Atomic Contribution/Award Decision Participant | L1 | 03C-D, 05A, 06; AUTH-PREP and complete REV custody transfer; REV-04 FinalAcceptance plus REV-09B locked lineage; shared audit/outbox; planned review.decision typed contract; two ordered operation-specific inputs | Proposed | | `WS-CON-001-08A` | Outbound Compensation Delivery Handler | L1 | 07, 02B; exact delivery ServiceIdentity/ActionId/static row registered but planned; AUTH-09E typed context/prepared protocol; ADR 0014 adapter foundation; lifecycle-fence port | Proposed | | `WS-CON-001-08R` | Bound-Service Callback Rate Control | L1 | 08A; shared API-control contract | Proposed | | `WS-CON-001-08B` | Inbound Fulfillment Callback | L1 | 08R; exact callback ServiceIdentity/ActionId/static row, AUTH-09E context, prepared protocol, and callback-fence port | Proposed | @@ -36,7 +36,7 @@ availability writer. Optional evidence chunks are not part of the core order. | `WS-CON-001-10A` | Contribution And Award Product Reads | L1 | 08B; D11 award-role outcome; planned contribution/award read actions and typed contexts | Proposed | | `WS-CON-001-10B` | Operations Requests, Reads, And Fulfillment Drain Observation | L1 | 10A; D11 complete; operations request/read actions/contexts/prepared protocol; outbox observation port | Proposed | | `WS-CON-001-10C` | Reconciliation And Projection Executors | L1 | 10B; exact executor identities/actions/static rows; AUTH-09E; hidden behavior then AUTH activation | Proposed | -| `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10C; merged REV decision integration; exact AUTH evaluator/action/service manifest; outbox readiness; CON fence/drain ports | Proposed | +| `WS-CON-001-11` | Hidden Release Readiness And Dependency Manifest | L1 | 10C; merged REV-10 decision integration; exact AUTH evaluator/action/service manifest; every obligation-writer/dispatch/callback hook; monotonic root ordinal; same-session cutoff/drain port | Proposed | ## Core dependency order @@ -84,13 +84,17 @@ AUTH registration -> CON hidden behavior -> AUTH activation -> later consumer/re REV-owned FinalAcceptance. REV stages shared audit/outbox rows, owns the single commit, and supplies stabilized artifact-hash lineage; no ART call is made. +- Merged REV PR #128 is planning authority, not runtime readiness. CON-03B must + precede REV-03; CON-02A/02C precede REV-04; REV-04 precedes CON-03C; CON-06 + precedes REV-06; REV-09B plus CON-03C/07 precede REV-10; and CON-11's exact + obligation hooks/ordinal/drain manifest precedes REV-12A. - CON-08A/B and 10C cannot reuse outbox dispatcher authority for delivery, callback, reconciliation, or rebuild execution. - CON-10A owns core PostgreSQL contribution/award reads directly; it does not wait for optional evidence reads. -- CON-11 has no ART or evidence-projection prerequisite. It hands typed - fulfillment fence/drain seams to the reviewed REV release-control work and - registers no production route. +- CON-11 has no ART or evidence-projection prerequisite. It hands mandatory + obligation-writer, dispatch, callback, maximum-ordinal, and drain-observation + seams to REV-12A's single shared lifecycle controller and registers no route. - AUTH PR #140's complete ART and REV activation-custody transfer contracts are consumed by reference to AUTH/WS-XINT handoffs. The runtime transfers remain upstream gates; WS-CON does not define partial subsets. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md index bac4b7f4..d33d3481 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/CONFORMANCE_MATRIX.md @@ -4,18 +4,19 @@ |---|---|---|---| | Canonical policy model | 01,03B,04B | ContributionPolicy/version/rules/definitions; explicit unpaid; immutable publish; one active policy; stable binding references | CON-11 | | Legacy clean cut | 05A,05B | zero semantic consumers before schema removal; deterministic row treatment; no alias/fallback; migration upgrade/downgrade | CON-11 | -| Authorization | AUTH + each feature | PR #140 / 74-57-9-48 baseline refreshed; proposed mappings remain unregistered; full ART/REV custody referenced; one future AUTH custodian; planned denial; exact grant/static row; AUTH-09E; prepared handle bound to session/action/actor-ref/idempotency/request digest with substitution non-consumption; no local role logic | AUTH activation + CON-11 | +| Authorization | AUTH + each feature | current 74-65-9-56 baseline after AUTH-09A; proposed mappings remain unregistered; full ART/REV custody referenced; one future AUTH custodian; planned denial; exact grant/static row; AUTH-09E; prepared handle bound to session/action/actor-ref/idempotency/request digest with substitution non-consumption; no local role logic | AUTH activation + CON-11 | | Final acceptance | REV + 03C,07 | accept creates one immutable FinalAcceptance per task/Review/Submission; needs_revision/reject create none; no create API/action, reopen, replacement, or adjudication path | joint live drill | | Contribution cardinality | 03C,07 + REV | one completed_review per valid Review with direct Review/lease lineage; one accepted_submission per FinalAcceptance with assignment lineage; mutually exclusive sources; revision Reviews distinct; automated outcomes create none | joint live drill | | Policy freeze | 05A,06 + task/REV | exact submitter/reviewer fields; published version; no drift; publish/suspend races both orders | joint live drill | | Award evaluation | 03C,07 | matching frozen ContributionRule; unpaid creates none; at most one money/points; exact decimal; replay stable | joint live drill | -| Atomic REV/CON | 07 + REV | exact locked request and stabilized digest; REV creates accept-only FinalAcceptance and stages audit/outbox; CON copies artifact_hash and flushes contributions/awards; zero ART calls; every injected failure rolls back Review/FinalAcceptance/task/contribution/award/audit/outbox | joint live drill | +| Atomic REV/CON | 07 + REV | reviewer operation before branch; accept-only submitter operation after FinalAcceptance/accepted effects; stabilized digest; REV stages audit/outbox; CON flushes contributions/awards; zero ART calls; complete rollback | REV-10 + joint live drill | | Outbox isolation | 02A,02B | stable event/task IDs; claim fencing; retry/dead-letter/replay; dispatcher cannot inherit feature authority; handler returns typed outcome | CON-11 | | Delivery and callback | 08A,08R,08B | exact feature service authority; no I/O under locks; callback/binding/award match; replay and callback-before-ack; immutable receipts | joint live drill | | Product reads | 10A | PostgreSQL contribution/award truth; D11 exact role sets; stable pagination/concealment; no ART/provider data | AUTH activation + joint drill | -| Operations requests and observation | 10B | bounded durable requests; AdminRole and prepared-protocol proof; audit redaction; stable drain observation; no executor authority | AUTH activation + joint drill | +| Operations requests and observation | 10B | bounded durable requests; AdminRole and prepared-protocol proof; audit redaction; same-session outbox/fulfillment counts plus maximum immutable root ordinal; no executor authority | REV-12A + joint drill | | Operations executors | 10C | exact independent fixed-service authority; dispatcher/cross-executor denial; retry/replay/finding proof; projection-only rebuild mutation; immutable contribution/award/receipt truth | AUTH activation + joint drill | | Public release | 11 + REV | hidden before release; exact `/api/v1` manifest; provisioning-aware readiness; no optional evidence/ART gate | joint live drill | +| Fulfillment cutoff | 03D,08A/B,10B/C,11 + REV-12A | one immutable monotonic ordinal per obligation root; shared fence before every writer; persisted generation cutoff; same-generation at-or-below-cutoff completion only; no provider I/O under fence | independent-session writer/dispatch/callback races | | Optional evidence | 09A,09B only if approved | separately reviewed ART/AUTH capability; independent status/failure; no effect on canonical truth or core release | separate optional release | | No adjudication | all core | only accept/needs_revision/reject; no adjudication grant/action/state/queue/lease/decision/contribution/branch/readiness or initiative dependency | CON-11 + joint drill | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md index cc3efb8c..7f8a204a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DECISIONS.md @@ -199,10 +199,11 @@ unrelated task. The archival `closed/review_rejected` wording is not adopted. The repository's existing immutable `Submission` row is already the submission version identity. Therefore FinalAcceptance stores canonical `submission_id`, not `submission_version_id`, and enforces unique task, source Review, and -Submission lineage. The handoff's `policy_context_ref` maps to canonical -immutable `ReviewPolicy.id`, stored as `review_policy_id`; REV proves the locked -same-chain lineage. CON does not interpret it as contribution policy or use it -to decide awards. +Submission lineage. Merged REV-04 retains `policy_context_ref` as the foreign +key to canonical immutable `ReviewPolicy.id` and retains `recorded_by` as the +reviewer ActorProfile field; REV proves the locked same-chain lineage. CON adds +no aliases and does not interpret review policy as contribution policy or use +it to decide awards. `completed_review` keeps direct Review/ReviewLease lineage and is unique per Review. `accepted_submission` requires `source_final_acceptance_id` plus the @@ -221,10 +222,12 @@ contribution type, branch, action, readiness check, or initiative dependency. **Status:** accepted by merged AUTH PR #140 on 2026-07-17. -Trusted main remains at 74 PermissionIds, 57 ActionIds, nine active actions, and -48 planned actions, with no registered CON ActionId. PR #140 supplies the exact -prepared protocol, complete ART/REV custody maps, and feature-manifest -activation rule; their runtime implementation remains upstream work. +Trusted main after AUTH-09A and merged REV PR #128 has 74 PermissionIds, 65 +ActionIds, nine active actions, and 56 planned actions, with no registered CON +or task-claim ActionId. The eight additional planned actions are AUTH-09 +identity-administration surfaces. PR #140 supplies the exact prepared protocol, +complete ART/REV custody maps, and feature-manifest activation rule; their +runtime implementation remains upstream work. CON removes speculative `AUTH_CON_*` owner labels. Its proposed action mappings remain unregistered and non-final until each complete feature manifest exists @@ -235,3 +238,38 @@ TaskAssignment policy freeze. `review.claim` similarly consumes CON-06 through REV, and `review.decision` consumes CON-07 through the rollback-safe REV-owned transaction. AUTH alone registers/evaluates/activates; CON alone supplies its hidden facts and participants. + +## D17 - Review Contribution Integration Uses Two Ordered Operations + +**Status:** accepted from merged REV PR #128 on 2026-07-17. + +One mandatory CON participant exposes two operation-specific flush-only methods +in REV's caller session. The reviewer method runs after immutable Review/ +finding/resolution creation plus lease/queue closure and before the decision +branch. It accepts no FinalAcceptance, submitter source, or submitter policy. +The submitter method exists only after `accept` creates FinalAcceptance and +applies accepted Task/TaskAssignment effects. It accepts no direct Review/ +ReviewLease contribution-source shape. An omnibus input with nullable +FinalAcceptance or both actors' policy contexts is prohibited. + +Each method evaluates only its frozen ContributionRule, creates its own +contribution and eligible awards, returns typed shared-audit/outbox inputs, and +never commits. REV collects the invoked results, stages the shared rows, and +the request route or service command commits once. + +## D18 - REV Owns One Joint Controller; CON Supplies Fenced Fulfillment Hooks + +**Status:** accepted from merged REV PR #128 on 2026-07-17. + +REV-12A owns the sole PostgreSQL `JointLifecycleReleaseControl` and shared +`JointLifecycleMutationFence`. CON creates no parallel phase/controller. Every +fulfillment-obligation root creation, requeue, successor, and repair writer +must acquire that fence before it allocates one immutable, monotonically +increasing root ordinal or locks obligation rows. + +CON's same-session drain observation returns outbox/fulfillment counts and the +current maximum ordinal. REV atomically persists that value as the generation +cutoff after admitted writers drain. During `delivery_draining`, dispatch and +callback may finalize only a same-generation root at or below the cutoff and +cannot create follow-on obligations. Provider I/O occurs after the fenced +pre-I/O transaction commits and releases every database/advisory lock. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md index 834d2e4b..af357dc0 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/DISCOVERY.md @@ -2,8 +2,8 @@ ## Baseline inspected -- trusted `origin/main` at `d541521`, merged AUTH PR #140, including the earlier - WS-XINT PR #139 boundary; +- trusted `origin/main` at `0302bcf`, merged REV PR #128, including AUTH-09A, + AUTH PR #140, and the earlier WS-XINT PR #139 boundary; - complete WS-XINT intent, decisions, plan, REV/CON, AUTH/role-service, AUTH/REV, AUTH/ART, and ART/REV handoffs; - current WS-CON initiative package and archival reference inputs; @@ -12,7 +12,7 @@ - current backend project/task/submission/checker, AUTH, audit, artifact, and migration code/tests; - human-approved 2026-07-17 FinalAcceptance/no-adjudication direction and the - current sibling REV planning worktree as discovery-only context; + complete merged WS-REV-001 planning package; - stale wording, authorization, artifact, link, loop-memory, and agent-gate scanners/tests. @@ -26,12 +26,12 @@ SubmissionVersion model would duplicate current identity. The handoff field named `submission_version_id` therefore maps to canonical `Submission.id` and is stored as `submission_id`. -- No FinalAcceptance runtime or reviewed merged REV contract exists yet. The - current sibling REV plan now includes FinalAcceptance and exact outcome - effects, but must be reviewed and merged before CON consumes that fact. -- The merged AUTH catalogue has 74 PermissionIds and 57 ActionIds. Nine - self/admin actions are active and 48 are planned. No WS-CON ActionId is - registered. +- No FinalAcceptance runtime exists yet. Merged REV PR #128 is reviewed planning + authority and defines the exact schema/transaction, but CON-03C still waits + for the REV-04 runtime target. +- The merged AUTH catalogue has 74 PermissionIds and 65 ActionIds. Nine actions + are active and 56 are planned. AUTH-09A added eight planned identity- + administration actions; no WS-CON or task-claim ActionId is registered. - Current AUTH supports actor-self and AdminRoleGrant evaluation. Independent ProjectRoleGrant runtime, fixed-service runtime admission, CON evaluators, ART/REV custody transfer, and the cross-domain prepared mutation protocol @@ -81,6 +81,15 @@ ActionId. CON-05A's hidden TaskAssignment policy freeze must merge into task-owned claim composition before AUTH-13 enumerates/registers and activates that action. +13. Merged REV rejects the prior omnibus CON decision input. One mandatory + participant exposes a reviewer operation before the decision branch and an + accept-only submitter operation after FinalAcceptance and accepted task + effects. Neither input carries nullable cross-actor source/policy facts. +14. REV-12A requires one shared `JointLifecycleMutationFence`. Every CON + fulfillment-obligation creation/requeue/successor/repair writer must fence + before allocating an immutable monotonic root ordinal. CON must expose the + current maximum ordinal with drain counts; delivery-draining dispatch and + callback may complete only same-generation roots at or below REV's cutoff. ## Relevant files and symbols @@ -94,13 +103,16 @@ | `WS-AUTH-001-13` chunk | Future task-claim ActionId enumeration, registration, evaluator integration, and activation owner; exact submitter grant, task-owned resource composition, and AUTH-PREP dependency | | `WS-AUTH-001-16` chunk | Aggregate proof that active review.decision uses one rollback-safe REV+CON transaction with no ART/fallback | | `WS-XINT-001/REV_CON_HANDOFF.md` | Exact core participant sequence and optional-evidence boundary | +| `WS-REV-001/CON_INTEGRATION_REVIEW.md` | Merged two-operation participant, exact lineage, interleaving, and release-control dependencies | +| `WS-REV-001-08/10` chunks | Decision input freeze followed by first hidden canonical Review commit only after exact CON participant merge | +| `WS-REV-001-12A` chunk | Single shared lifecycle fence, obligation-writer ordinal order, cutoff capture, and drain-phase behavior required from CON | | `WS-XINT-001/AUTH_ROLE_SERVICE_HANDOFF.md` | Fixed service and project grant contract | | `WS-XINT-001/AUTH_REV_HANDOFF.md` | Full review activation-custody/hidden behavior sequence | | `WS-XINT-001/AUTH_ART_HANDOFF.md` | Full 25-action ART transfer; not a core CON gate | | `backend/app/modules/projects/{models,schemas,repository,service}.py` | Current guide-bound economic fields and consumers to cut over/remove | | `backend/app/modules/tasks/**` | TaskAssignment creation and future submitter policy freeze seam | | `backend/app/modules/tasks/models.py::Submission` | Existing immutable version identity: `id`, integer `version`, and `supersedes_submission_id`; no SubmissionVersion table | -| `backend/app/modules/authorization/{catalogue,policy,kernel,schemas}.py` | Current 74/57/9/48 runtime and stable PermissionIds | +| `backend/app/modules/authorization/{catalogue,policy,kernel,schemas}.py` | Current 74/65/9/56 runtime and stable PermissionIds; no CON/task-claim ActionId | | `backend/app/modules/audit/**` | Shared append-only audit extension point | | `backend/app/modules/artifacts/{preparation,sources}.py` | Inactive ART-only preparation; no core CON import | @@ -120,6 +132,9 @@ shared-outbox handler isolation, or REV/CON atomic rollback. - No tests yet cover FinalAcceptance one-per-task/Review/Submission constraints, accept-only creation, source-lineage exclusivity, or rollback when CON fails. +- No tests yet cover the two ordered CON operation inputs, reviewer-before- + branch fault boundaries, immutable fulfillment root ordinals, every writer + versus cutoff capture, or same-generation pre-cutoff drain completion. ## Dependencies @@ -132,6 +147,9 @@ REV-owned FinalAcceptance with exact policy-context typing; stabilized artifact-hash facts; mandatory CON participant injection; REV-staged shared audit/outbox; single route commit; and no no-op fallback. +- REV release control: CON writer/dispatch/callback hooks, immutable root + ordinal allocation under the shared fence, and same-session maximum-ordinal/ + drain observation must merge before REV-12A. - Task/Submission: submitter policy freeze and stable assignment/version lineage. - Shared outbox/audit: caller-transaction append and feature-neutral dispatch. - ADR 0014 adapters: typed capability port, factory, and composition-root @@ -144,6 +162,7 @@ |---|---| | Two award-eligibility models | Clean semantic then physical cutover; no fallback | | Contribution missing after Review | Mandatory flush-only participant and one caller commit | +| Reviewer contribution ordered after branch | Two operation-specific inputs; reviewer operation always precedes branch and cannot depend on branch effects | | Submitter contribution inferred from Review decision | REV-owned immutable FinalAcceptance is the only submitter source; exact one-to-one constraints and lineage checks | | ART outage suppresses contribution | No core ART/evidence operation | | Wrong policy version | Assignment/lease freeze before work; immutable published versions | @@ -154,14 +173,16 @@ | Partial activation transfer | Consume complete WS-XINT AUTH handoffs, never local subsets | | Legacy row ambiguity | Human-approved deterministic rebuild/classification before migration | | Premature public surface | Hidden behavior until AUTH activation and joint release proof | +| Shutdown loses or admits fulfillment work | Shared fence before every writer ordinal; immutable cutoff; same-generation pre-cutoff completion only; exact drain counts | | Adjudication leaks into v0.1 | No adjudication type/action/state/queue/readiness dependency; reject and accept remain terminal | ## Resolved FinalAcceptance policy lineage -The handoff's UUID `policy_context_ref` maps to canonical immutable -`ReviewPolicy.id`, stored as `review_policy_id`. REV must enforce that exact -locked policy and its same project/task/Submission/Review lineage. CON does not -interpret it as contribution policy or use it for award eligibility. +Merged REV-04 retains the handoff's `policy_context_ref` field as a foreign key +to canonical immutable `ReviewPolicy.id` and retains `recorded_by` for the +reviewer ActorProfile. REV must enforce that exact locked policy and its same +project/task/Submission/Review lineage. CON adds no renamed aliases and does not +interpret review policy as contribution policy or award authority. ## Open questions diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md index 8bb15f50..19377aa5 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md @@ -10,7 +10,8 @@ points ledger, or reputation scoring. The supplied WS-CON reference pair is input to reconcile, not authority to accept blindly. The active contract follows trusted repository decisions and -merged AUTH PR #140 and its underlying WS-XINT-001 boundary from PR #139. +merged REV PR #128 at `0302bcf`, AUTH PR #140, and the underlying WS-XINT-001 +boundary from PR #139. ## Success state @@ -26,9 +27,15 @@ merged AUTH PR #140 and its underlying WS-XINT-001 boundary from PR #139. - REV owns the request and single commit: Review/task effects, optional FinalAcceptance, CON-flushed contributions/awards, and REV-staged shared audit/outbox rows commit or roll back together. +- One mandatory CON participant exposes a reviewer operation before the + decision branch and an accept-only submitter operation after FinalAcceptance + and accepted task effects; no nullable cross-actor omnibus input exists. - Core contribution creation copies stabilized artifact-hash lineage supplied by REV and has no ART or provider dependency. - Downstream adapters fulfill awards but never determine eligibility. +- Every fulfillment-obligation writer uses REV-12A's one shared lifecycle fence + before monotonic root-ordinal allocation; drain dispatch/callback completes + only same-generation roots at or below the persisted cutoff. - Every protected human/service surface uses AUTH's exact grant or ServiceIdentity/static-matrix path, prepared mutation protocol when needed, and AUTH-owned activation. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md index fa8ba326..13d43fd2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md @@ -9,8 +9,8 @@ CompensationAward, fulfillment behavior, and CON projections. AUTH owns all authorization and activation. The canonical cross-boundary source is merged -`WS-XINT-001/REV_CON_HANDOFF.md`. Sibling worktree state is discovery only until -reviewed and merged to trusted `main`. +`WS-XINT-001/REV_CON_HANDOFF.md`. Merged REV PR #128 at trusted main `0302bcf` +is the reviewed owner contract; runtime REV behavior remains unimplemented. ## Required decision composition @@ -20,20 +20,26 @@ session/action/actor reference/idempotency key/canonical request digest -> REV locks and recomposes canonical facts -> AUTH consumes the handle, evaluates once, and stages decision evidence -> REV stages Review/findings/resolutions, consumes ReviewLease, closes queue +-> CON reviewer operation creates completed_review from Review/ReviewLease, + evaluates only the lease-frozen reviewer rule, and returns typed staging inputs -> on accept, REV creates immutable FinalAcceptance linked to Review, canonical Submission, Task, submitter, reviewer and locked ReviewPolicy then accepts Task and completes TaskAssignment + -> CON submitter operation creates accepted_submission from FinalAcceptance + and TaskAssignment, evaluates only the assignment-frozen submitter rule, + and returns typed staging inputs -> on needs_revision, REV sets Task to needs_revision and keeps TaskAssignment active -> on reject, REV sets Task to rejected with a bounded human reason and blocks only the same-task TaskAssignment with its source Review --> CON flush-only participant creates reviewer contribution --> on accept only, CON creates submitter contribution from FinalAcceptance, - never directly from Review.decision --> CON evaluates frozen ContributionRules and creates applicable awards -> REV stages shared audit/outbox rows from the typed participant result --> REV route commits once +-> request route or service command commits once ``` +The participant is one mandatory interface with two ordered operation-specific +inputs. The reviewer input never carries nullable FinalAcceptance or submitter +policy/source facts. The submitter input does not exist outside `accept` and +never uses direct Review/ReviewLease contribution-source fields. + No no-op participant, post-commit repair, ART call, evidence projection, or provider I/O exists in this transaction. CON copies stabilized artifact-hash lineage from REV facts. @@ -42,9 +48,11 @@ lineage from REV facts. The external shorthand `submission_version_id` means canonical `Submission.id`; the repository stores `submission_id` because each immutable -Submission row is already one version. The external `policy_context_ref` means -the exact locked `ReviewPolicy.id`; the repository stores `review_policy_id`. -REV owns this record and the composite same-chain constraints. +Submission row is already one version. Merged REV-04 retains +`policy_context_ref` as the foreign key to the exact locked `ReviewPolicy.id` +and retains `recorded_by` for the canonical reviewer ActorProfile. CON consumes +those owner-defined names without aliases. REV owns this record and the +composite same-chain constraints. ```text FinalAcceptance @@ -55,8 +63,8 @@ FinalAcceptance source_review_id UNIQUE accepted_submitter_id accepted_at - recorded_by_reviewer_id - review_policy_id + recorded_by + policy_context_ref ``` It is created only inside `Review(accept)`. There is no public/manual creation @@ -97,9 +105,18 @@ Review.decision. principal path, and activation after hidden behavior. - Protected outbox handlers have their own exact service authority; dispatcher authority is not inherited. -- CON-owned fulfillment dispatch/callback fence ports and same-session drain - observation are injected through composition without REV importing CON/outbox - repositories. +- Every CON fulfillment-obligation creation, requeue, successor, and repair + writer exposes a mandatory hook that acquires REV-12A's shared + `JointLifecycleMutationFence` before allocating an immutable monotonically + increasing root ordinal or locking obligation rows. +- CON dispatch and callback hooks consume that shared fence. In + `delivery_draining`, they may complete only the same generation and a root + ordinal at or below REV's persisted cutoff; they cannot create successor, + retry-root, repair, or other follow-on obligations. +- `FulfillmentLifecycleDrainObservationPort` is same-session/read-only and + returns pending/claimed/retryable/in-flight counts, nonterminal delivery and + callback obligations, and the current maximum root ordinal through typed + shared-outbox capability. REV imports no CON/outbox repository. - Exact migrations, handler registry, task IDs, route inventory, and retained tests are bound to merged SHAs. @@ -122,9 +139,11 @@ acceptance fact nor submitter contribution; one reviewer contribution per Review, explicit unpaid, money+points, frozen-version changes, repeated/revision Reviews, no-self-review, grant revocation, source-shape and uniqueness conflicts, atomic rollback, adapter outage/replay, -callback-before-ack, failure then fulfillment, reconciliation, drain fencing, -and hidden-to-active route transition. It asserts zero ART calls and no -adjudication action/state/queue/readiness dependency. +callback-before-ack, failure then fulfillment, reconciliation, every obligation +writer versus cutoff capture in both orders, same-generation pre-cutoff +dispatch/callback completion, post-cutoff denial before provider I/O, drain +fencing, and hidden-to-active route transition. It asserts zero ART calls and +no adjudication action/state/queue/readiness dependency. ## Ownership and stop diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md index a2b8037f..3dc49002 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md @@ -2,23 +2,24 @@ ## Proposed approach -Adopt merged AUTH PR #140 and its underlying WS-XINT PR #139 boundary before -runtime work, then deliver WS-CON through hidden, reviewable chunks. The core -path is PostgreSQL-local and has no ART dependency: +Adopt merged REV PR #128 at trusted main `0302bcf`, including AUTH-09A, AUTH PR +#140, and the underlying WS-XINT PR #139 boundary before runtime work, then +deliver WS-CON through hidden, reviewable chunks. The core path is +PostgreSQL-local and has no ART dependency: ```text AUTH prepares review.decision and locks reviewer authority -> REV locks and recomposes canonical Review/Submission facts -> AUTH evaluates once and stages decision evidence -> REV stages Review/findings/resolutions, consumes ReviewLease, and closes queue +-> CON reviewer operation creates completed_review and applicable reviewer awards -> on accept, REV creates immutable FinalAcceptance, accepts Task, and completes Assignment + -> CON submitter operation creates accepted_submission and applicable submitter awards -> on needs_revision, REV sets Task to needs_revision and keeps Assignment active -> on reject, REV sets Task to rejected with a bounded human reason and blocks only the same-task Assignment with its source Review --> CON flush-only participant creates reviewer contribution and, only from - FinalAcceptance, submitter contribution plus applicable awards -> REV stages shared audit and outbox rows --> REV route commits once +-> request route or service command commits once ``` Public contribution, policy, award, fulfillment, and operations surfaces stay @@ -57,27 +58,36 @@ activation sequence and the joint REV/CON release gate pass. ## Review and contribution boundary -`ContributionCompensationDecisionParticipant` receives the caller-owned -`AsyncSession` and a typed request containing: - -- exact Review, ReviewLease, queue/lifecycle fence, and decision; -- exact FinalAcceptance for accept, otherwise null; -- versioned Submission, TaskAssignment, task, and project identities; -- reviewer and submitter canonical ActorProfile IDs; -- lease-frozen reviewer and assignment-frozen submitter - `ContributionPolicyVersion` IDs; -- the stabilized reviewed-packet/submission artifact digest already established - by REV and Submission; -- the originating allowed `review.decision` AuthorizationDecision reference, - request ID, and correlation ID. - -CON validates the supplied locked facts, copies the stabilized digest into -`ContributionRecord.artifact_hash`, evaluates the matching frozen +One mandatory `ContributionCompensationDecisionParticipant` exposes two ordered +operation-specific methods in the caller-owned `AsyncSession`; it does not +accept one omnibus request with nullable FinalAcceptance or both actors' policy +contexts. + +The reviewer operation is required for every valid decision after REV appends +Review/findings/resolutions, consumes ReviewLease, and closes the queue but +before REV applies the decision branch. Its typed input contains only exact +locked Review, ReviewLease, versioned Submission, project/task, reviewer, +lease-frozen reviewer `ContributionPolicyVersion`, originating allowed +`review.decision` AuthorizationDecision, request/correlation references, and +the stabilized server-derived `Submission.artifact_hash`. It contains no +FinalAcceptance, TaskAssignment source field, submitter, or submitter policy. + +The submitter operation exists only after the `accept` branch creates +FinalAcceptance and applies Task `accepted` plus TaskAssignment `completed`. Its +typed input contains exact locked FinalAcceptance, TaskAssignment, versioned +Submission, project/task, submitter, assignment-frozen submitter +`ContributionPolicyVersion`, the same authorization/request/correlation +references, and stabilized artifact hash. It contains no direct Review or +ReviewLease contribution-source fields and is unavailable for `needs_revision` +or `reject`. + +Each operation validates only its supplied locked lineage, copies the stabilized +digest into `ContributionRecord.artifact_hash`, evaluates its matching frozen `ContributionRule`, stages applicable contribution/award rows, returns typed -audit/outbox inputs to REV, flushes, and never commits. It never reads REV or AUTH repositories, evaluates -`review.decision`, calls ART, rehashes artifact bytes, performs provider I/O, or -offers a no-op production participant. Any CON failure rolls back the complete -Review decision. +audit/outbox inputs to REV, flushes, and never commits. CON never reads REV or +AUTH repositories, evaluates `review.decision`, calls ART, rehashes artifact +bytes, performs provider I/O, or offers a no-op production participant. Any CON +failure rolls back the complete Review decision. `needs_revision` and `reject` still create the reviewer contribution and any award earned by its frozen reviewer rule. They create no FinalAcceptance or @@ -105,15 +115,17 @@ FinalAcceptance source_review_id accepted_submitter_id accepted_at - recorded_by_reviewer_id - review_policy_id + recorded_by + policy_context_ref ``` The external handoff's `submission_version_id` maps to `submission_id` because -the existing immutable Submission row is already the version identity. The -external `policy_context_ref` maps to the exact locked `ReviewPolicy.id`; REV -must prove the Review, policy, project, task, Submission, submitter and reviewer -chain. PostgreSQL enforces `UNIQUE(task_id)`, `UNIQUE(source_review_id)`, and +the existing immutable Submission row is already the version identity. Merged +REV-04 retains `policy_context_ref` as the foreign key to the exact locked +`ReviewPolicy.id` and `recorded_by` as the reviewer ActorProfile field; CON adds +no alias. REV must prove the Review, policy, project, task, Submission, +submitter and reviewer chain. PostgreSQL enforces `UNIQUE(task_id)`, +`UNIQUE(source_review_id)`, and `UNIQUE(submission_id)`. There is no reopen, replacement, adjudication, or second acceptance path in v0.1. @@ -149,9 +161,10 @@ models, routes, lifecycle decisions, or commits. ## Authorization boundary -Trusted `main` is `d541521`, merging AUTH PR #140 after WS-XINT PR #139. -Runtime catalogue counts remain 74 PermissionIds, 57 ActionIds, nine active -actions, and 48 planned actions. No WS-CON ActionId is registered. PR #140 +Trusted `main` is `0302bcf`, merging REV PR #128 and AUTH-09A after AUTH PR +#140 and WS-XINT PR #139. Runtime catalogue counts are 74 PermissionIds, 65 +ActionIds, nine active actions, and 56 planned actions. No WS-CON or task-claim +ActionId is registered. PR #140 adds reviewed AUTH custody/PREP/activation contracts only; the custody transfers and prepared protocol remain proposed runtime work. @@ -248,13 +261,14 @@ rows. Every mutation first locks AUTH human actor/link/grant or fixed-service actor/link authority, then its idempotency row and applicable lifecycle fence. After that common prefix, the owning operation uses one explicit order: -- `review.decision`: REV task, assignment, Submission, queue/lease, Review and - finding/resolution rows in REV's canonical order; accept-only - FinalAcceptance plus exact task/assignment effects; the assignment- and lease-frozen - ContributionPolicyVersion, matching rule/definition, and referenced binding; - stabilized reviewed-packet and Submission artifact-hash lineage; then - ContributionRecord and CompensationAward; then REV-owned shared audit and - outbox append participants; +- `review.decision`: REV follows its canonical idempotency/fence, queue, lease, + task, assignment, Submission, predecessor Review, finding/resolution order; + the reviewer operation then locks only the lease-frozen policy/rule/definition/ + binding and reviewer contribution/award rows. REV applies the branch. For + accept, REV creates FinalAcceptance and applies accepted task/assignment + effects before the submitter operation locks only the assignment-frozen + policy/rule/definition/binding and submitter contribution/award rows. REV then + stages shared audit and outbox rows; - task/review claim freeze: the owning task/assignment/Submission or REV queue/lease rows first, then the selected published policy version, rule/definition and referenced binding, then the frozen lineage write; @@ -335,18 +349,56 @@ subsystem owns no contribution, award, adapter, review, or provider semantics. `review.decision`. 8. CON-08A/R/B add fulfillment delivery and callback behavior only after exact service execution/callback identities, actions, static rows, AUTH-09E, and - lifecycle fencing are approved. + lifecycle fencing are approved. Every fulfillment-obligation root writer, + requeue, successor, and repair path acquires the shared lifecycle fence + before allocating its immutable monotonic ordinal. Dispatch and callback + composition exposes same-generation/pre-cutoff completion behavior without + provider I/O under the fence. 9. CON-10A/B add PostgreSQL product reads and bounded operation requests; 10C adds independently authorized reconciliation/rebuild executors. Optional 09A/09B remain outside the core dependency sequence. -10. CON-11 proves hidden readiness. REV release-control composition consumes - only typed fence/drain ports; the reviewed REV release chunk owns the final - public route activation and joint live drill. +10. CON-11 proves hidden readiness. It enumerates every obligation writer and + supplies mandatory dispatch/callback hooks plus a same-session observation + port returning outbox/fulfillment counts and the maximum root ordinal. REV- + 12A injects the one shared `JointLifecycleMutationFence`, persists the + generation cutoff, and owns release-control state; CON creates no second + controller. REV-13 owns final public release and the joint live drill. Every chunk refreshes trusted-main SHA, migration custody, exact port/action symbols, and merged dependency evidence. No cross-initiative successor starts automatically. +### Merged REV interleaving + +Merged REV PR #128 fixes cross-initiative gates without starting either +initiative automatically: + +```text +REV-02 immutable Submission/TaskAssignment attribution + -> CON-05A/B task freeze and retired-field cutover + +CON-03B ContributionPolicyVersion persistence + -> REV-03 ReviewLease foreign key + +CON-02A shared outbox + CON-02C lifecycle audit participant + -> REV-04 Review/FinalAcceptance persistence + -> CON-03C exact contribution source schema + +CON-06 reviewer policy freeze + -> REV-06 claim composition + +REV-09B stable lineage + CON-03C schema + CON-07 two-operation participant + -> REV-10 first canonical Review-committing transaction + +CON-11 writer/dispatch/callback/ordinal/drain manifest + REV-12 observations + -> REV-12A shared lifecycle controller/fence + -> AUTH action-specific activation + -> REV-13 joint release +``` + +The merged REV plan proves ownership and ordering only. Each arrow still waits +for the exact runtime predecessor on then-current trusted main. + ## Verification strategy - Isolated PostgreSQL migration, constraint, rollback, idempotency, and both- diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md index c65433a7..4be86f60 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md @@ -4,11 +4,13 @@ |---|---|---|---| | Competing award-eligibility models | Critical | ContributionPolicy is sole authority; semantic then physical clean cut with no fallback | CON-05A/B | | Review commits without contribution | Critical | Mandatory flush-only participant and one REV-owned commit; fault-injection rollback | CON-07 + REV | +| Reviewer contribution depends on branch state | Critical | Required reviewer operation precedes every branch and has no FinalAcceptance/submitter input; separate accept-only submitter operation | CON-07 + REV-08/10 | | Submitter contribution inferred from mutable decision shape | Critical | REV-owned immutable FinalAcceptance is the sole accepted_submission source; unique task/Review/Submission and source-shape constraints | REV + CON-03C/07 | | Mandatory ART projection blocks product truth | Critical | No ART/evidence work in core transaction or release; optional successor only | CON-07/09/11 | | Wrong frozen policy | Critical | Assignment/lease freeze before work; immutable versions; concurrency proof | CON-05A/06 | | task.claim activates before submitter policy freeze | Critical | AUTH-PREP + task seam -> CON-05A hidden participant -> task-owned composition -> AUTH-13 activation; pre-activation real-kernel denial | AUTH + task + CON-05A | | Dispatcher inherits handler authority | Critical | Dispatcher-only action; exact independent service authority for protected handlers | CON-02B/08A/10C + AUTH | +| Release cutoff misses admitted fulfillment work | Critical | Shared fence before every writer ordinal; maximum-ordinal same-session observation; both-order cutoff races; completion-only drain | CON-03D/08/10B/C/11 + REV-12A | | Operations request authority leaks into execution | Critical | 10B persists bounded human requests only; 10C uses exact fixed-service actions, cross-executor denial, replay/finding proof, and projection-only mutation | CON-10B/10C + AUTH | | Broad or dynamic service access | Critical | Closed ServiceIdentity/static rows, controlled provisioning, AUTH-09E, cross-service denial | AUTH + CON | | Partial ART/REV custody transfer | High | Reference complete WS-XINT handoffs; no local subset or dual writer | AUTH | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md index 6c048d78..30e297ca 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md @@ -10,13 +10,15 @@ ## Trusted baseline -- `origin/main` / merged AUTH PR #140 at - `d541521790a0441cfd2193f466e00ef81248ec31`. -- PR #140 title/branch: AUTH WS-XINT reconciliation / - `codex/ws-auth-001-xint-reconciliation`; it adopts the earlier PR #139 AUTH, - ART, REV, and CON lifecycle boundary. -- Runtime AUTH remains 74 PermissionIds, 57 ActionIds, nine active, 48 planned. -- PR #140 adds AUTH activation-custody, prepared-protocol, revised chunk, +- `origin/main` / merged REV PR #128 at + `0302bcf854a565d429e232ad6b076a1931ea74e4`. +- PR #128 merges the reviewed WS-REV-001 plan after AUTH-09A, AUTH PR #140, and + WS-XINT PR #139. It is planning authority, not Review runtime implementation. +- Runtime AUTH is 74 PermissionIds, 65 ActionIds, nine active, 56 planned. + AUTH-09A contributes eight planned identity-administration actions; no CON or + task-claim ActionId exists. +- PR #140 remains the source for AUTH activation-custody, prepared-protocol, + revised chunk, operations, and verification contracts. It changes no runtime CON behavior, registers no CON action, and activates no feature action. @@ -25,15 +27,16 @@ - On 2026-07-17 the human fixed the v0.1 shipping path as `Review(accept) -> FinalAcceptance -> accepted_submission` and explicitly excluded adjudication lifecycle/actions/readiness. -- The current sibling REV worktree now plans FinalAcceptance and the exact - `accepted`/`needs_revision`/`rejected` effects. That concurrent work remains - discovery-only; WS-CON implementation consumes only reviewed REV contracts - merged to trusted main. +- Merged REV PR #128 now plans FinalAcceptance, exact + `accepted`/`needs_revision`/`rejected` effects, two ordered CON participant + operations, and REV-12A lifecycle-control hooks. WS-CON implementation still + waits for each exact runtime chunk and consumes no sibling-worktree behavior. - The amendment's `submission_version_id` is normalized to canonical `Submission.id` / `submission_id`; current runtime already stores each immutable version as a Submission row. -- The amendment's `policy_context_ref` is normalized to exact locked - `ReviewPolicy.id` / `review_policy_id`; REV owns and proves that lineage. +- Merged REV-04 retains `policy_context_ref` as the foreign key to exact locked + `ReviewPolicy.id` and `recorded_by` as the reviewer ActorProfile field; CON + consumes those names and REV owns/proves the lineage. - `docs/review_closure.md`, `docs/review_final_adversarial_review.md`, and `docs/review_adversarial_quality_review.md` are historical internal-review recommendations, not live lifecycle specifications. Their older “second @@ -63,6 +66,12 @@ - `.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PREP-prepared-mutation-protocol.md` - `.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-13-task-assignment-cutover.md` - `.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md` +- `.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CON_INTEGRATION_REVIEW.md` +- `.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DECISIONS.md` +- `.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/PLAN.md` +- `.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-08-immutable-decision-kernel.md` +- `.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-10-contribution-integration-hidden-composition.md` +- `.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12A-joint-lifecycle-release-control.md` - `.agent-loop/policies/*` ## Normative WS-XINT handoffs @@ -83,14 +92,14 @@ and 05B own semantic then physical removal after a human migration decision. - No ContributionPolicy, ContributionRecord, CompensationAward, fulfillment, or WS-CON action runtime exists yet. -- No FinalAcceptance runtime exists yet; it will be REV-owned and is a hard - merged-schema/composition prerequisite for CON-03C/07. +- No FinalAcceptance runtime exists yet; merged planning assigns it to REV-04 + and makes that exact schema a prerequisite for CON-03C/07. - Existing `Submission` is the versioned identity; no new SubmissionVersion is required. - ART preparation from PR #129 is inactive foundation only and does not approve optional contribution-evidence projection. -- Sibling worktrees are discovery evidence only. Implementation consumes only - reviewed contracts merged to trusted `main`. +- Sibling worktrees remain discovery evidence only. Merged REV planning is + authoritative for sequencing but does not satisfy its own runtime gates. ## Adoption note diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index e8283f14..7471a641 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,12 +2,14 @@ ## Current status -`WS-CON-001-PLAN3` completed reconciliation of merged AUTH PR #140 at trusted -main `d541521` with the previously reviewed CON plan. The planning snapshot at -`09128ee1aed941682c7cb59ca04698de496de682` passed all required exact-SHA -internal reviewer tracks and deterministic gates. Its review evidence, trust -bundle, and schema-v2 merge intent are prepared; it remains unpublished pending -the user's explicit PR direction. PLAN2 already reconciled the +`WS-CON-001-PLAN3` is reopened only for current-main reconciliation after merged +REV PR #128 at `0302bcf`, which also contains AUTH-09A after AUTH PR #140. The +prior planning snapshot `09128ee1aed941682c7cb59ca04698de496de682` remains +historically reviewed but no longer controls publication. The refresh corrects +the AUTH catalogue baseline, replaces the obsolete omnibus nullable CON +decision input with two ordered operations, and adopts REV-12A's exact +obligation-writer/ordinal/cutoff hooks. Runtime code remains unchanged. PLAN2 +already reconciled the human-approved v0.1 `Review(accept) -> FinalAcceptance -> accepted_submission` boundary against the previously reviewed WS-XINT plan. Runtime code is unchanged. @@ -34,19 +36,28 @@ feature-handler authority. - CON-09A/09B are deferred optional successors and do not gate the core release. - AUTH PR #140 registers no CON ActionId and activates no feature action. Its exact custody and prepared-protocol contracts are now upstream gates. +- Current main has 74 PermissionIds and 65 ActionIds: nine active and 56 + planned. AUTH-09A added eight planned identity-administration actions; no CON + or task-claim ActionId exists. - `task.claim` activation must follow, not precede, the CON-05A hidden TaskAssignment contribution-policy freeze. +- Merged REV planning requires the CON reviewer operation before the decision + branch and the accept-only submitter operation afterward; it rejects one + nullable omnibus participant input. +- REV-12A requires every CON fulfillment-obligation writer to fence before + monotonic ordinal allocation and requires same-session maximum-ordinal/drain + observation for the immutable delivery cutoff. ## Active chunk -No chunk is active. PLAN3 is complete and unpublished; no implementation chunk -starts automatically. +`WS-CON-001-PLAN3` current-main refresh only. No implementation chunk is active +or starts automatically. | Chunk | Status | Notes | |---|---|---| | `WS-CON-001-PLAN` | Complete; superseded baseline | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | | `WS-CON-001-PLAN2` | Complete; unpublished | FinalAcceptance is REV-owned; CON trigger changes only; all required internal tracks pass | -| `WS-CON-001-PLAN3` | Complete; unpublished | Exact-SHA reviewers and deterministic gates pass; AUTH PR #140 PREP/custody/activation sequencing only | +| `WS-CON-001-PLAN3` | Current-main refresh in review | AUTH PR #140 PREP/custody plus merged REV PR #128 participant/release-control reconciliation | | `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN3 and upstream merge refresh | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | @@ -54,7 +65,7 @@ starts automatically. | Gate | Owner | Required action | |---|---|---| -| FinalAcceptance and decision integration | REV + CON | Merge REV-owned persistence and locked lineage first; then CON-03C/07; then REV consumes CON-07 in hidden single-commit composition before AUTH activation | +| FinalAcceptance and decision integration | REV + CON | REV-04 runtime persistence -> CON-03C; REV-09B lineage + CON-07 two-operation participant -> REV-10 hidden single-commit composition -> AUTH activation | | Active specification/archive handling | Human | Approve CON-01 repository-owned specification | | Pre-production legacy rows | Human | Choose deterministic rebuild or explicit classified migration before 05A/05B | | D11 AdminRole candidates | Human + AUTH | Fix award-detail, delivery-recovery, and audit candidates before registration | @@ -66,6 +77,7 @@ starts automatically. | review.claim/review.decision | AUTH + REV + CON | Complete REV custody transfer and AUTH-PREP; merge hidden CON participants and REV composition; AUTH-REV-06/08 activate afterward | | Shared outbox | CON-02A/B | Land generic persistence/dispatcher after approval | | Joint release | REV + CON + AUTH | Consume exact hidden manifest; optional evidence and ART are not prerequisites | +| Fulfillment cutoff/drain | CON + REV-12A | CON-03D ordinal; all writer/dispatch/callback hooks; CON-10B observation; CON-11 manifest -> REV-12A shared fence/controller | ## Stop condition diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index ece260b6..8cb61e18 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -43,9 +43,13 @@ roadmap changes without synchronized local XLSX/CSV exports - [ ] Existing versioned Submission is retained. CON copies stabilized artifact_hash lineage and performs no core ART/evidence operation. - [ ] Active spec defines REV-owned accept-only FinalAcceptance with canonical - `submission_id` and `review_policy_id`; FinalAcceptance-sourced submitter + `submission_id`, `policy_context_ref`, and `recorded_by`; + FinalAcceptance-sourced submitter contribution; direct Review-sourced reviewer contribution; and one REV-owned commit. It adds no SubmissionVersion alias or adjudication dependency. +- [ ] Active spec adopts merged REV PR #128's two ordered operation-specific CON + inputs: reviewer before branch, accept-only submitter after FinalAcceptance + and accepted task effects; no nullable omnibus input. - [ ] Optional evidence is clearly deferred with separate ART/AUTH approval and is absent from the core release path. - [ ] AUTH boundary matches PR #140 (adopting PR #139): independent project grants, fixed-service @@ -56,6 +60,10 @@ roadmap changes without synchronized local XLSX/CSV exports execution actions remain explicit human/AUTH gates until approved. - [ ] Dispatcher authority is limited to outbox mechanics; delivery, reconciliation, rebuild, and callback cannot inherit it. +- [ ] Active spec adopts REV-12A's single shared lifecycle controller/fence, + immutable monotonic fulfillment-root ordinal, every-writer fence order, + maximum-ordinal drain observation, and same-generation pre-cutoff completion + rules without moving controller ownership into CON. - [ ] Exact D11 outcome and legacy-row decision are recorded before dependent implementation. - [ ] Public prefix is `/api/v1`; provider refs/credentials and settlement diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md index 48c4a499..367e2b53 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md @@ -61,4 +61,5 @@ mutable/void/delete/adjust path, dependency or CI weakening Execute CON-03C in `../RUNTIME_VERIFICATION.md`; changed subsystems are at least 90 percent. Senior engineering, QA/test, security/auth, product/ops, architecture, docs, reuse/dedup and test-delta are required. Stop if exact -REV FinalAcceptance/Review/ReviewLease targets are not merged. +REV-04 runtime FinalAcceptance/Review/ReviewLease targets are not merged. Merged +REV PR #128 is planning authority only and does not satisfy that runtime gate. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md index 19ab83a4..0ed7cb0c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md @@ -36,6 +36,12 @@ AUTH/ART edit, dependency or CI weakening the originating dispatcher claim generation, retryable recovery and callback suppression without storing a provider payment attempt. Crash recovery cannot erase or guess whether remote I/O may have started. +- [ ] Every fulfillment-obligation root has one immutable, database-allocated, + monotonically increasing `fulfillment_obligation_ordinal` and exact lifecycle + generation lineage. Requeue, successor, and repair rows retain their canonical + root identity; they do not allocate a second root ordinal. Uniqueness and + immutability constraints support REV-12A cutoff capture without making the + ordinal a caller-supplied or provider field. - [ ] Status is rebuildable and cannot overwrite award/receipt truth. - [ ] Callback-before-ack, duplicate exact receipt and changed receipt are representable without provider-attempt/balance/ledger data. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md index 60ee5d8c..0b38127a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md @@ -33,18 +33,24 @@ ART capability/repository/provider call or evidence projection row/event mutable/delete/void/adjust contribution/award path; reputation scoring ``` -## Participant request +## Participant operations -The typed request carries the caller AsyncSession and exact locked: +One mandatory typed participant uses the caller AsyncSession and exposes two +ordered operations rather than an omnibus nullable request. -- Review, ReviewLease, queue/lifecycle fence, and canonical decision; -- accept-only REV-owned FinalAcceptance, otherwise null; -- versioned Submission, TaskAssignment, task, and project; -- reviewer/submitter ActorProfile IDs; -- reviewer and submitter frozen ContributionPolicyVersion IDs; -- server-derived stabilized `Submission.artifact_hash`/reviewed-packet digest - from the merged REV/Submission lineage, never caller package data; -- originating review.decision AuthorizationDecision, request, and correlation. +The reviewer operation receives exact locked Review, ReviewLease, versioned +Submission, project/task, reviewer ActorProfile, lease-frozen reviewer +ContributionPolicyVersion, originating `review.decision` +AuthorizationDecision, request/correlation references, and server-derived +stabilized `Submission.artifact_hash`. It never receives FinalAcceptance, +TaskAssignment contribution-source lineage, submitter, or submitter policy. + +The submitter operation exists only after REV creates FinalAcceptance and +applies accepted task/assignment effects. It receives exact locked +FinalAcceptance, TaskAssignment, versioned Submission, project/task, submitter +ActorProfile, assignment-frozen submitter ContributionPolicyVersion, the same +authorization/request/correlation lineage, and stabilized artifact hash. It +never uses direct Review/ReviewLease contribution-source fields. ## Acceptance criteria @@ -52,11 +58,14 @@ The typed request carries the caller AsyncSession and exact locked: `completed_review`. Accept requires exactly one same-chain FinalAcceptance and creates one submitter `accepted_submission` from it; needs_revision/reject require no FinalAcceptance and create no submitter record. -- [ ] Locked participant inputs prove REV already applied the exact outcome: - accept has Task `accepted` and Assignment `completed`; needs_revision has Task - `needs_revision` and Assignment still `active`; reject has Task `rejected` - with the bounded human reason and only the same-task Assignment `blocked` with - its source Review. CON does not own or mutate those lifecycle effects. +- [ ] REV calls the reviewer operation after appending Review/findings/ + resolutions, consuming the lease, and closing the queue but before any + decision branch. It therefore validates Review/ReviewLease lineage without + requiring branch effects. REV then applies the exact outcome. Accept creates + FinalAcceptance, sets Task `accepted`, and completes the Assignment before the + submitter operation. Needs revision keeps the Assignment active and reject + blocks only the same-task Assignment; neither invokes the submitter operation. + CON owns none of those lifecycle effects. - [ ] Repeated idempotent decision returns the same rows; a later revision Review creates a distinct reviewer contribution; automated outcomes create none. @@ -66,21 +75,24 @@ The typed request carries the caller AsyncSession and exact locked: definitions. - [ ] CON copies the supplied stabilized digest exactly into ContributionRecord.artifact_hash. It does not load/rederive it or call ART. -- [ ] Participant validates exact FinalAcceptance/Review/Submission/assignment/ - lease/project/actor/policy lineage and an allowed review.decision whose actor, action, +- [ ] Each operation validates only its exact source shape and frozen policy. + Both receive the allowed review.decision reference whose actor, action, resource digest, matched reviewer grant/project, request, and correlation - match the locked transaction. -- [ ] Participant uses caller AsyncSession, stages contribution/award rows, - returns canonical typed audit/outbox inputs, flushes, and never commits. REV - stages shared audit/outbox rows after the participant and before its single - commit. CON creates no evidence projection or evidence-request event. + match the locked transaction; CON does not re-evaluate it. +- [ ] Both operations use caller AsyncSession, stage contribution/award rows, + return canonical typed audit/outbox inputs, flush, and never commit. REV + collects results from the reviewer operation and, on accept, the later + submitter operation, then stages shared audit/outbox rows before the single + caller commit. CON creates no evidence projection or evidence-request event. - [ ] CON never reads REV/AUTH repositories or evaluates review.decision. REV owns canonical composition and the single route commit. - [ ] AUTH registration -> CON participant -> REV hidden composition -> AUTH evaluator/activation order is proven. Real kernel denies while planned. -- [ ] Fault injection at every CON write/flush and every later REV step rolls - back Review/FinalAcceptance/task/assignment/contribution/award/audit/outbox - together. No post-commit repair path exists. +- [ ] Fault injection after the reviewer operation, after every branch effect, + after FinalAcceptance, after the submitter operation, and at every later REV + audit/outbox step rolls back Review/FinalAcceptance/task/assignment/ + contribution/award/audit/outbox together. The reviewer operation never + commits independently and no post-commit repair path exists. - [ ] No FinalAcceptance create action/API exists. Static/runtime proof finds no adjudication policy, grant/action, queue/lease, state, decision, contribution, conditional branch, readiness check, or initiative dependency. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md index 75e99bc7..349d604a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md @@ -54,13 +54,25 @@ database/fence lock held during external I/O bound handle; CON locks award/binding/delivery rows and recomposes final facts; AUTH consumes/evaluates once before durable delivery mutation. - [ ] Durable in-flight generation and exact event/payload/binding/idempotency - identity commit before adapter I/O; every database transaction and lifecycle - fence is released before the call. + identity commit before adapter I/O. The already-claimed command resolves its + immutable obligation root, ordinal, and lifecycle generation under the shared + `JointLifecycleMutationFence`. In `delivery_draining`, only a same-generation + root at or below the persisted cutoff may enter durable `in_flight`; no new + root, requeue, successor, or repair work is allowed. +- [ ] The pre-I/O transaction commits and releases every database transaction + and lifecycle fence before the adapter call. Finalization occurs in a new + fenced transaction for the same root. A lost pre-I/O race returns the same + event to retryable pending without changing award or delivery truth; only the + shared dispatcher mutates outbox claim/retry/dead-letter state. - [ ] Adapter result cannot change award identity/quantity. Retry, ambiguous completion, acknowledgement, callback-before-ack, cancellation, and replay preserve monotonic delivery/receipt truth. - [ ] Provider I/O is only through typed capability/factory at composition root. - [ ] Coverage/concurrency/failure proof meets repository floors. +- [ ] Independent-session tests cover dispatch versus cutoff/disable in both + orders, same-generation pre-cutoff completion, post-cutoff/cross-generation + denial before provider I/O, and instrumentation proving no advisory fence or + database transaction is held during adapter I/O. - [ ] The real kernel continues to deny the planned action. AUTH activation is a later checkpoint after this hidden handler and its evaluator composition merge. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md index fa771b8d..b5ccb008 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -39,6 +39,16 @@ outbox transition ownership; production route registration - [ ] Exact route identity, project, instrument, award, frozen binding, external event, quantity/status, and idempotency must match. Actor/link/binding state loss denies. +- [ ] After CON-owned signature verification plus AUTH/idempotency locking, the + callback acquires the shared `JointLifecycleMutationFence`, resolves the + canonical obligation root, immutable ordinal, and generation, and holds the + fence through receipt commit. In `delivery_draining`, only same-generation + roots at or below the persisted cutoff may finalize; `disabled`, post-cutoff, + crossed-generation, or missing lineage denies before provider/follow-on I/O. +- [ ] Callback finalization cannot create a successor event, retry root, + delivery obligation, repair, award, or other follow-on work while draining. + Callback-versus-disable tests prove the exclusive transition cannot cross an + in-flight receipt transaction. - [ ] Duplicate exact receipt is idempotent; changed replay conflicts; fulfilled receipt is immutable and at most one exists per award. - [ ] Suspended binding accepts only valid already-issued obligations; retired diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md index 8734458d..946be77d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -45,9 +45,13 @@ AUTH implementation; production router registration; CI weakening or sensitive failure leakage. - [ ] `FulfillmentLifecycleDrainObservationPort` reports pending/claimed/ retryable outbox work, durable in-flight delivery, and nonterminal callback - obligations through typed outbox capability, never repository import. -- [ ] Observation is same-session, bounded, read-only, and never returns false - zero while remote I/O or terminal receipt remains possible. + obligations through typed outbox capability, plus the current maximum + immutable `fulfillment_obligation_ordinal`; zero is valid only when no root + exists. It never imports an outbox or lifecycle-control repository. +- [ ] Observation uses the caller AsyncSession, is bounded/read-only, never + commits or calls a provider, and never returns false zero while remote I/O or + terminal receipt remains possible. Caller-supplied timestamps, ordinals, + generation, or event IDs cannot substitute. - [ ] AUTH later activates after hidden behavior; 10C waits for approved executor identities/actions/static rows. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md index d0911983..d4d7c033 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md @@ -51,6 +51,11 @@ outbox claim/finalization transitions; AUTH implementation - [ ] Compensation reconciliation compares immutable award/delivery/receipt truth and creates durable findings/actions allowed by the approved contract; it never changes award amount/eligibility or fabricates receipt truth. +- [ ] Any reconciliation path that creates, requeues, succeeds, or repairs a + fulfillment obligation is classified as an obligation writer, acquires the + shared lifecycle fence before allocating/locking its immutable root ordinal, + and is denied from `commands_draining` onward. Completion-only observation or + same-root finalization cannot be used to smuggle new work into the drain. - [ ] Contribution rebuild changes rebuildable projections only and never mutates ContributionRecord or CompensationAward. - [ ] Retry/replay/idempotency and crash fencing preserve request identity. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index 404e6858..7a757eca 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -52,10 +52,27 @@ archival input edits - [ ] Manifest names exact migrations, schemas, event/task IDs, registry rows, service identities/actions/static rows, handler execution boundaries, and retained test metadata. Dispatcher cannot execute protected handlers. -- [ ] Manifest names CON-owned FulfillmentDispatchFence, - FulfillmentCallbackFence, FulfillmentLifecycleDrainObservationPort, - OutboxClaimValidationPort, injection seams, phase mappings, denial states, - and fail-closed construction without REV release-control implementation. +- [ ] Manifest names mandatory CON obligation-writer, dispatch, callback, and + same-session `FulfillmentLifecycleDrainObservationPort` hooks plus + `OutboxClaimValidationPort`, injection seams, phase mappings, denial states, + and fail-closed construction. REV-12A injects the one shared + `JointLifecycleMutationFence`; CON defines no second controller or optional/ + no-op fence. +- [ ] The manifest enumerates every fulfillment-obligation root creation, + requeue, successor, and repair writer and proves each acquires the shared + fence before allocating its immutable monotonic ordinal or locking obligation + rows. Missing, extra, ambiguous, differently ordered, or completion-only- + misclassified writers fail composition and preflight. +- [ ] Drain observation returns pending/claimed/retryable outbox events, durable + in-flight dispatch, nonterminal delivery/callback obligations, and the current + maximum root ordinal in the caller session. Independent-session proof races + every writer against cutoff capture and proves it either commits under an + included ordinal or observes `commands_draining` without allocation/mutation. +- [ ] Dispatch and callback readiness proves `delivery_draining` permits only + same-generation, at-or-below-cutoff completion and denies new roots, requeue, + successor, repair, post-cutoff, and crossed-generation work before provider + I/O. Disable waits for zero dispatchable/retryable/claimed/in-flight work and + zero nonterminal delivery/callback obligations. - [ ] Core conformance matrix has executable evidence; same-run repository coverage is at least 78 and changed subsystems at least 90. - [ ] Joint drill contract covers all core families. Accept proves Task diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md index 61975661..f0c7b790 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md @@ -2,8 +2,9 @@ ## Goal -Reconcile WS-CON planning with trusted `main` at merged AUTH PR #140 without -implementing runtime behavior, changing AUTH-owned files, or weakening the +Reconcile WS-CON planning with trusted `main` after merged AUTH PR #140 and the +later merged AUTH-09A/REV PR #128 boundary without implementing runtime +behavior, changing AUTH/REV-owned files, or weakening the review/FinalAcceptance/contribution transaction. ## Risk @@ -26,11 +27,14 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md @@ -58,9 +62,9 @@ reference specification/PDF edits, restoration, rename, or replacement ## Acceptance criteria -- [x] Trusted baseline is merged PR #140 at `d541521`; the runtime catalogue - remains 74 PermissionIds, 57 ActionIds, nine active and 48 planned, with no - registered CON-specific ActionId. +- [x] Trusted baseline is merged REV PR #128 at `0302bcf`, containing AUTH-09A + after PR #140. The runtime catalogue has 74 PermissionIds, 65 ActionIds, nine + active and 56 planned, with no registered CON-specific or task-claim ActionId. - [x] CON consumes AUTH's exact prepared mutation protocol: AUTH locks current authority first and creates an opaque single-use handle bound to session, ActionId, actor-reference kind/reference, idempotency key, and canonical @@ -76,8 +80,10 @@ reference specification/PDF edits, restoration, rename, or replacement `review.claim` and `review.decision` ActionIds remain planned and require the exact reviewer grant plus REV guards before activation. - [x] `review.decision` activation requires the merged mandatory CON flush-only - participant and rollback-safe REV+CON single transaction. FinalAcceptance - remains an internal REV consequence with no action/API. + participant with two ordered operation-specific inputs and rollback-safe + REV+CON single transaction. The reviewer operation precedes the branch; the + accept-only submitter operation follows FinalAcceptance and accepted task + effects. FinalAcceptance remains an internal REV consequence with no action/API. - [x] All 19 REV actions are referenced through the complete AUTH custody transfer. CON names only its `review.claim` and `review.decision` dependencies and never owns or partially transfers ActionOwner metadata. @@ -93,6 +99,11 @@ reference specification/PDF edits, restoration, rename, or replacement intent is present in the branch delta. Older PLAN/PLAN2 evidence receives a provenance-only rebind when the PR-level gate requires every evidence file added by the cumulative branch to match the final reviewed revision. +- [x] Merged REV PR #128 release-control dependencies are reflected exactly: + every fulfillment-obligation writer uses the shared lifecycle fence before + allocating a monotonic root ordinal; the same-session drain port returns the + maximum ordinal; and delivery-draining dispatch/callback paths are limited to + same-generation roots at or below the persisted cutoff. ## Verification diff --git a/.agent-loop/merge-intents/WS-CON-001-PLAN3.json b/.agent-loop/merge-intents/WS-CON-001-PLAN3.json index 2253e569..926058d8 100644 --- a/.agent-loop/merge-intents/WS-CON-001-PLAN3.json +++ b/.agent-loop/merge-intents/WS-CON-001-PLAN3.json @@ -1,6 +1,6 @@ { "chunk_id": "WS-CON-001-PLAN3", - "chunk_title": "AUTH PR 140 Reconciliation", + "chunk_title": "AUTH And REV Current-Main Reconciliation", "initiative_id": "WS-CON-001", "next_chunk_id": "WS-CON-001-01", "next_chunk_title": "Canonical Contract Adoption And Architecture Decision", From e968430b0c3b5f1432899c9aa31ef209b774eae0 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 16:16:34 +0100 Subject: [PATCH 17/22] Align PLAN3 reconciliation scope --- .../chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md index f0c7b790..05a9c85a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md @@ -1,4 +1,4 @@ -# Chunk Contract: WS-CON-001-PLAN3 - AUTH PR 140 Reconciliation +# Chunk Contract: WS-CON-001-PLAN3 - AUTH And REV Current-Main Reconciliation ## Goal @@ -34,7 +34,6 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md From adf5cc12b35e46d7e45cc29221d39bc05a169d57 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 16:29:34 +0100 Subject: [PATCH 18/22] Bind CON reconciliation review evidence --- .../STATUS.md | 31 ++++--- ...S-CON-001-PLAN-internal-review-evidence.md | 25 +++--- ...-CON-001-PLAN2-internal-review-evidence.md | 24 ++--- ...-CON-001-PLAN3-internal-review-evidence.md | 72 +++++++++------ .../WS-CON-001-PLAN3-pr-trust-bundle.md | 88 ++++++++++++------- 5 files changed, 143 insertions(+), 97 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 7471a641..d799a912 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,17 +2,16 @@ ## Current status -`WS-CON-001-PLAN3` is reopened only for current-main reconciliation after merged -REV PR #128 at `0302bcf`, which also contains AUTH-09A after AUTH PR #140. The -prior planning snapshot `09128ee1aed941682c7cb59ca04698de496de682` remains -historically reviewed but no longer controls publication. The refresh corrects -the AUTH catalogue baseline, replaces the obsolete omnibus nullable CON +`WS-CON-001-PLAN3` completed exact-SHA internal review at +`e968430b0c3b5f1432899c9aa31ef209b774eae0` after current-main reconciliation +with merged REV PR #128 at `0302bcf`, which also contains AUTH-09A after AUTH PR +#140. The prior planning snapshot `09128ee1aed941682c7cb59ca04698de496de682` +remains historical and no longer controls publication. The reviewed refresh +corrects the AUTH catalogue baseline, replaces the obsolete omnibus nullable CON decision input with two ordered operations, and adopts REV-12A's exact -obligation-writer/ordinal/cutoff hooks. Runtime code remains unchanged. PLAN2 -already reconciled the -human-approved v0.1 -`Review(accept) -> FinalAcceptance -> accepted_submission` boundary against the -previously reviewed WS-XINT plan. Runtime code is unchanged. +obligation-writer/ordinal/cutoff hooks. PLAN2's human-approved v0.1 +`Review(accept) -> FinalAcceptance -> accepted_submission` boundary remains +intact. Runtime code is unchanged. The prior plan is superseded where it used the older policy aggregate, made ART evidence mandatory, described service action rows as persisted assignments, allowed partial activation-custody transfer, or let outbox dispatch imply @@ -50,14 +49,14 @@ feature-handler authority. ## Active chunk -`WS-CON-001-PLAN3` current-main refresh only. No implementation chunk is active -or starts automatically. +No implementation chunk is active or starts automatically. PLAN3 is complete +and may only refresh draft PR #142; it does not authorize merge or CON-01. | Chunk | Status | Notes | |---|---|---| | `WS-CON-001-PLAN` | Complete; superseded baseline | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | | `WS-CON-001-PLAN2` | Complete; unpublished | FinalAcceptance is REV-owned; CON trigger changes only; all required internal tracks pass | -| `WS-CON-001-PLAN3` | Current-main refresh in review | AUTH PR #140 PREP/custody plus merged REV PR #128 participant/release-control reconciliation | +| `WS-CON-001-PLAN3` | Complete; internally reviewed | Exact AUTH/REV current-main participant, FinalAcceptance, and release-control reconciliation at `e968430` | | `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN3 and upstream merge refresh | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | @@ -81,6 +80,6 @@ or starts automatically. ## Stop condition -Do not edit runtime code, start CON-01, push, open, or merge a PR without -explicit human direction. PLAN3 may prepare its trust bundle and merge intent -for review readiness only. +Do not edit runtime code, start CON-01, or merge PR #142 without explicit human +direction. The reviewed PLAN3 may refresh the existing draft PR only; it does +not authorize its merge or any successor start. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index 96204278..84cc3e8d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -1,27 +1,28 @@ # Internal Review Evidence: WS-CON-001-PLAN -## 2026-07-17 Final PR Provenance Rebind +## 2026-07-17 AUTH And REV Current-Main Provenance Rebind -Reviewed code SHA: 09128ee1aed941682c7cb59ca04698de496de682 -Reviewed at: 2026-07-17T09:22:25Z -Reviewer run IDs: auth08_arch_review/rebind-09128ee, auth08_qa_product_review/rebind-09128ee, auth08_security_review/rebind-09128ee +Reviewed code SHA: e968430b0c3b5f1432899c9aa31ef209b774eae0 +Reviewed at: 2026-07-17T15:17:58Z +Reviewer run IDs: auth08_arch_review/final-e968430, auth08_qa_product_review/final-e968430, auth08_security_review/final-e968430 This provenance-only addendum binds the earlier substantive PLAN review chain to the final reviewed cumulative planning snapshot. PLAN3 authorizes this evidence rebind because the PR-level gate validates every evidence file added by the branch. It changes no historical finding or product conclusion. The exact-SHA -re-review confirmed that the merged AUTH boundary, later FinalAcceptance -reconciliation, and evidence-schema update introduce no remaining blocker. +re-review confirmed that the merged AUTH runtime and REV plan, exact +FinalAcceptance/CON participant boundary, joint release-control contract, and +evidence-schema update introduce no remaining blocker. | Reviewer | Result | Blocking findings | Notes | |---|---|---|---| -| senior engineering | PASS | None | The cumulative specification remains coherent and PLAN3 is a bounded process/specification correction. | -| qa/test | PASS AFTER FIXES | None | The task-claim ActionId error and missing-evidence process gap are resolved. | -| security/auth | PASS AFTER FIXES | None | Exact AUTH-PREP semantics and AUTH-only identifier/evaluator/activation ownership pass. | -| product/ops | PASS AFTER FIXES | None | Review outcomes, FinalAcceptance lineage, contribution atomicity, and no-adjudication boundary pass. | -| architecture | PASS | None | Ownership, transaction, rollout, and same-initiative successor boundaries remain coherent. | +| senior engineering | PASS AFTER FIXES | None | The cumulative specification remains coherent after the PLAN3 title and duplicate allowed-file repairs. | +| qa/test | PASS | None | Exact two-operation ordering, branch effects, rollback coverage, and deterministic gates pass. | +| security/auth | PASS | None | Current AUTH catalogue facts, prepared semantics, and AUTH-only identifier/evaluator/activation ownership pass. | +| product/ops | PASS | None | Review outcomes, FinalAcceptance lineage, contribution atomicity, release cutoff, and no-adjudication boundary pass. | +| architecture | PASS AFTER FIXES | None | Ownership, transaction, rollout, joint release control, and same-initiative successor boundaries remain coherent. | | ci integrity | PASS | None | The rebind changes evidence only; no CI, runtime, test, script, workflow, dependency, or threshold changes. | -| docs | PASS AFTER FIXES | None | Runtime-versus-planned identifiers and cumulative evidence provenance are explicit. | +| docs | PASS AFTER FIXES | None | Runtime-versus-planned identifiers, merged REV dependencies, contract title, and cumulative evidence provenance are explicit. | | reuse/dedup | PASS | None | No duplicate service, evaluator, registry, or transaction abstraction is introduced. | | test delta | PASS | None | No test delta; all 80 agent-gate tests pass. | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md index bd52fe5a..8de8a4e3 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md @@ -1,27 +1,27 @@ # WS-CON-001-PLAN2 Internal Review Evidence -## Final PR provenance rebind +## AUTH And REV current-main provenance rebind -Reviewed code SHA: 09128ee1aed941682c7cb59ca04698de496de682 -Reviewed at: 2026-07-17T09:22:25Z -Reviewer run IDs: auth08_arch_review/rebind-09128ee, auth08_qa_product_review/rebind-09128ee, auth08_security_review/rebind-09128ee +Reviewed code SHA: e968430b0c3b5f1432899c9aa31ef209b774eae0 +Reviewed at: 2026-07-17T15:17:58Z +Reviewer run IDs: auth08_arch_review/final-e968430, auth08_qa_product_review/final-e968430, auth08_security_review/final-e968430 This provenance-only addendum binds the reviewed FinalAcceptance reconciliation to the final cumulative planning snapshot. It changes no PLAN2 lifecycle fact. The exact-SHA re-review confirms that PLAN3 preserves REV-owned FinalAcceptance, CON flush-only participation, all three review outcomes, and -the no-adjudication boundary while correcting only AUTH sequencing and evidence -provenance. +the no-adjudication boundary while adopting merged REV's exact two-operation +ordering and joint release-control contract. | Reviewer | Result | Blocking findings | Notes | |---|---|---|---| -| senior engineering | PASS | None | FinalAcceptance and contribution responsibilities retain single owners and one commit. | -| qa/test | PASS AFTER FIXES | None | Accept, needs-revision, reject, lineage, rollback, and evidence completeness pass. | -| security/auth | PASS AFTER FIXES | None | No FinalAcceptance action/API, adjudication path, authorization bypass, or CON evaluator is introduced. | -| product/ops | PASS AFTER FIXES | None | Reviewer and submitter contribution triggers remain Review and FinalAcceptance respectively. | -| architecture | PASS | None | REV persistence, CON participant, REV composition, and later AUTH activation remain correctly ordered. | +| senior engineering | PASS AFTER FIXES | None | FinalAcceptance and contribution responsibilities retain single owners and one commit after contract metadata repair. | +| qa/test | PASS | None | Accept, needs-revision, reject, lineage, rollback, and evidence completeness pass. | +| security/auth | PASS | None | No FinalAcceptance action/API, adjudication path, authorization bypass, or CON evaluator is introduced. | +| product/ops | PASS | None | Reviewer and submitter contribution triggers remain Review and FinalAcceptance respectively. | +| architecture | PASS AFTER FIXES | None | REV persistence, two CON operations, REV composition, joint release control, and later AUTH activation remain correctly ordered. | | ci integrity | PASS | None | The rebind changes evidence only and weakens no gate. | -| docs | PASS AFTER FIXES | None | Historical PLAN2 conclusions and final provenance are explicit. | +| docs | PASS AFTER FIXES | None | Historical PLAN2 conclusions, merged REV refinements, and final provenance are explicit. | | reuse/dedup | PASS | None | Existing REV/AUTH contracts are referenced without a parallel path. | | test delta | PASS | None | No test delta; all 80 agent-gate tests pass. | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md index a0fabcfc..b4715edf 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md @@ -1,35 +1,45 @@ # WS-CON-001-PLAN3 Internal Review Evidence -Reviewed code SHA: 09128ee1aed941682c7cb59ca04698de496de682 -Reviewed at: 2026-07-17T09:22:25Z -Reviewer run IDs: auth08_arch_review/rebind-09128ee, auth08_qa_product_review/rebind-09128ee, auth08_security_review/rebind-09128ee +Reviewed code SHA: e968430b0c3b5f1432899c9aa31ef209b774eae0 +Reviewed at: 2026-07-17T15:17:58Z +Reviewer run IDs: auth08_arch_review/final-e968430, auth08_qa_product_review/final-e968430, auth08_security_review/final-e968430 ## Reviewed boundary -The exact reviewed snapshot reconciles CON planning with merged AUTH PR #140 -and authorizes the provenance-only rebind of the older PLAN/PLAN2 evidence that -the cumulative PR gate requires. Its substantive PLAN3 commit changes 24 -planning/merge-intent files with 412 insertions and 143 deletions and changes no +The exact reviewed snapshot reconciles CON planning with merged AUTH PR #140, +AUTH-09A runtime, and REV PR #128 at trusted `main` `0302bcf`. It authorizes the +provenance-only rebind of the older PLAN/PLAN2 evidence required by the +cumulative PR gate. The current-main reconciliation changes 22 +planning/merge-intent files with 429 insertions and 178 deletions and changes no backend, migration, runtime catalogue, test, script, workflow, or dependency file. The reviewed boundary establishes: -- 74 runtime PermissionIds and 57 ActionIds, with nine active and 48 planned; +- 74 runtime PermissionIds and 65 ActionIds, with nine active and 56 planned; - no registered CON-specific ActionId and no task-claim ActionId; - stable PermissionId `task.claim` followed by the safe order AUTH-10/PREP and task seam, CON-05A hidden freeze and task composition, then AUTH-13 action enumeration/registration/evaluator integration/activation; - planned `review.claim` and `review.decision` actions gated on the merged - hidden CON participants, REV-owned composition, and later AUTH activation; + mandatory CON participant, REV-owned composition, and later AUTH activation; - exact AUTH-PREP authority-first lock, opaque-handle binding, feature-lock, recomposition, single AUTH evaluation, flush-only participant, and caller-owned commit semantics; - 22 explicitly unregistered, non-final CON surface mappings and no speculative `AUTH_CON_*` ActionOwner candidates; +- a mandatory CON flush-only participant with a reviewer operation after + immutable Review/findings/resolutions and lease/queue closure but before the + decision branch, plus an accept-only submitter operation after exact + FinalAcceptance and accepted task/assignment effects; +- exact REV-owned FinalAcceptance fields `submission_id`, `recorded_by`, and + `policy_context_ref`, with submitter contribution sourced only from that fact; +- REV-12A as the sole joint release controller/fence, with every CON + obligation writer fenced before monotonic root ordinal allocation and + same-generation at-or-below-cutoff completion during delivery drain; - `Review(accept) -> FinalAcceptance -> accepted_submission`, with REV as the - transaction owner, CON as a mandatory flush-only participant, no separate - FinalAcceptance action/API, and no adjudication dependency; and + transaction owner, no separate FinalAcceptance action/API, no adjudication + dependency, and no independent CON commit; and - one schema-v2 merge intent naming `WS-CON-001-01` as an explicit-start same-initiative successor. @@ -37,13 +47,13 @@ The reviewed boundary establishes: | Reviewer | Result | Blocking findings | Notes | |---|---|---|---| -| senior engineering | PASS | None | The 24-file reconciliation is coherent, bounded to planning, and preserves single ownership for AUTH, REV, and CON responsibilities. | -| qa/test | PASS AFTER FIXES | None | The false task-claim ActionId statement was corrected; lifecycle outcomes, 22-mapping count, and deterministic gates pass. | -| security/auth | PASS AFTER FIXES | None | Exact prepared-handle semantics and AUTH-only identifier/evaluator/activation ownership pass after the task-claim correction. | -| product/ops | PASS AFTER FIXES | None | Accept, needs-revision, reject, FinalAcceptance, contribution, compensation, and no-adjudication boundaries remain correct. | -| architecture | PASS | None | Safe task/review sequencing, complete custody references, flush-only CON participation, and same-initiative successor all pass. | +| senior engineering | PASS AFTER FIXES | None | The 22-file reconciliation is coherent and bounded after its title and duplicate allowed-file repairs. | +| qa/test | PASS | None | All three lifecycle outcomes, exact source cardinality, rollback stages, REV interleaving, and deterministic gates pass. | +| security/auth | PASS | None | Current catalogue facts, prepared semantics, same-decision lineage, and AUTH-only identifier/evaluator/activation ownership pass. | +| product/ops | PASS | None | FinalAcceptance, contribution, compensation, fulfillment cutoff, and no-adjudication boundaries remain correct. | +| architecture | PASS AFTER FIXES | None | Two-operation sequencing, single ownership, joint release control, and same-initiative successor all pass after metadata repairs. | | ci integrity | PASS | None | PLAN3 changes no CI, workflow, threshold, runner, script, dependency, test, or runtime file and adds no bypass. | -| docs | PASS AFTER FIXES | None | Runtime versus planned identifiers, PR #140 provenance, and non-final proposals are explicit; required evidence and trust bundle were then added through allowed post-review paths. | +| docs | PASS AFTER FIXES | None | Runtime versus planned identifiers, merged AUTH/REV provenance, canonical names, and evidence are explicit after contract metadata repair. | | reuse/dedup | PASS | None | No duplicate runtime abstraction or alternative authorization path is introduced; common AUTH/REV contracts are referenced. | | test delta | PASS | None | No tests changed or were required for the planning-only reconciliation; 80 existing agent-gate tests pass. | @@ -68,6 +78,14 @@ The final exact-SHA rebind then added the two older evidence paths to PLAN3's allowed scope so every evidence file added by the cumulative branch can carry current, parser-complete provenance without rewriting historical conclusions. +### Resolved current-main architecture finding + +The first current-main architecture review found that the PLAN3 title still +named only AUTH PR #140 and that its allowed-file list repeated CON-07. The +contract title now matches the AUTH-and-REV current-main merge intent and the +duplicate row is removed. All required reviewers re-ran against exact SHA +`e968430b0c3b5f1432899c9aa31ef209b774eae0`. + ### Confirmed non-findings - A failed same-session/action substitution does not consume an otherwise valid @@ -77,6 +95,10 @@ current, parser-complete provenance without rewriting historical conclusions. - CON imports no AUTH persistence, grant query, evaluator, registration, ActionOwner, or availability writer. - FinalAcceptance has no public API or independent authorization action. +- FinalAcceptance uses REV's canonical `submission_id`, `recorded_by`, and + `policy_context_ref` names; CON does not redefine the entity. +- REV owns the sole joint release controller/fence; CON adds no parallel + controller or lifecycle state. - No adjudication lifecycle or dependency was introduced. - The archival PDF deletion is user-owned, unstaged, and excluded from every reviewed commit. @@ -85,7 +107,7 @@ current, parser-complete provenance without rewriting historical conclusions. ```text python3 scripts/check_markdown_links.py - PASS - 57 changed Markdown files before evidence addenda + PASS - 59 changed Markdown files before evidence refresh python3 scripts/check_stale_workstream_wording.py PASS python3 scripts/check_stale_authorization_docs.py @@ -96,11 +118,11 @@ python3 scripts/check_loop_memory_state.py PASS PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py PASS - 80 tests -git diff --check 545f250^..545f250 +git diff --check 5e1311c^..e968430 PASS git diff --check PASS -PLAN3 backend/.github/scripts delta +current-main CON reconciliation backend/.github/scripts delta none python3 scripts/update_post_merge_memory.py validate-merge-intent --base-ref origin/main PASS - WS-CON-001-PLAN3 @@ -108,8 +130,8 @@ python3 scripts/update_post_merge_memory.py validate-merge-intent --base-ref ori The circuit-breaker passed with a documentation-only size exception. The full branch is large because it contains the original reference transcription and -durable planning/review history, but PLAN3 is one bounded 24-file planning -correction, has no runtime boundary, and required no split. +durable planning/review history, but the current-main refresh is one bounded +22-file planning correction, has no runtime boundary, and required no split. Valid findings addressed: yes @@ -117,6 +139,6 @@ Open sub-agent sessions: none ## Stop -PLAN3 is reviewed and PR-ready but unpublished. No push, PR, merge, or CON-01 -start is authorized by this evidence. The user retains the human checkpoint and -must explicitly approve the specific PR before merge. +PLAN3 is reviewed for draft PR #142 refresh. This evidence authorizes no merge +or CON-01 start. The user retains the human checkpoint and must explicitly +approve PR #142 before merge. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md index 761c7261..c54837ab 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md @@ -2,12 +2,13 @@ ## Chunk -`WS-CON-001-PLAN3` - AUTH PR 140 Reconciliation. +`WS-CON-001-PLAN3` - AUTH And REV Current-Main Reconciliation. ## Goal Reconcile the contribution and compensation plan with trusted `main` at merged -AUTH PR #140 (`d541521`) before any CON runtime implementation begins. +REV PR #128 (`0302bcf`), which contains AUTH-09A after AUTH PR #140, before any +CON runtime implementation begins. ## Human-approved intent @@ -22,11 +23,13 @@ AUTH PR #140 (`d541521`) before any CON runtime implementation begins. copy speculative identifiers. - Pull and reconcile merged AUTH work before publishing this plan; do not start CON runtime work automatically. +- Consume merged REV's exact FinalAcceptance shape, two-operation CON + participant, initiative interleaving, and sole joint release-control contract. ## What changed -- Rebased CON authorization assumptions on AUTH PR #140 while preserving PR - #139 as the underlying cross-initiative boundary. +- Rebased CON authorization assumptions on AUTH PR #140 and AUTH-09A's current + runtime catalogue while preserving PR #139 as the underlying boundary. - Replaced the older prepared-authorization description with the exact opaque, single-use handle binding and authority-first lock protocol. - Corrected `task.claim`: only its stable PermissionId exists; no task-claim @@ -37,6 +40,12 @@ AUTH PR #140 (`d541521`) before any CON runtime implementation begins. - Preserved planned `review.claim` and `review.decision` actions and their dependency on hidden CON participants, REV composition, and later AUTH activation. +- Replaced the obsolete nullable omnibus review participant with reviewer and + accept-only submitter operations at REV's exact lifecycle points. +- Adopted REV's canonical FinalAcceptance field names and exact REV/CON chunk + interleaving. +- Made REV-12A the sole joint release controller/fence and specified CON's + root-ordinal, maximum-ordinal, drain, dispatch, callback, and writer hooks. - Removed speculative `AUTH_CON_*` ActionOwner candidates. The 22 CON surface mappings remain unregistered, non-final proposals. - Added the reviewed PLAN3 contract and one schema-v2 merge intent naming @@ -63,9 +72,20 @@ code-owned validations, not database lock targets. No AUTH persistence, grant query, evaluator, identifier registration, or availability writer moves into CON. -FinalAcceptance remains an internal REV-derived fact with no public API or -separate authorization action. No adjudication policy, state, action, queue, -lease, contribution, or release dependency is added. +FinalAcceptance remains an internal REV-derived fact with canonical +`submission_id`, `recorded_by`, and `policy_context_ref`, no public API, and no +separate authorization action. The mandatory CON participant receives a +reviewer operation before the branch and, only for accept, a submitter operation +after FinalAcceptance and accepted Task/Assignment effects. No adjudication +policy, state, action, queue, lease, contribution, or release dependency is +added. + +REV owns the sole `JointLifecycleReleaseControl` and +`JointLifecycleMutationFence`. CON fences every fulfillment-obligation root +creation/requeue/successor/repair writer before immutable monotonic ordinal +allocation. Delivery-draining completion is limited to same-generation roots +at or below the persisted cutoff; provider I/O occurs outside the transaction +and fence. ## Alternatives rejected @@ -82,12 +102,12 @@ lease, contribution, or release dependency is added. ## Scope -PLAN3 itself changes 24 planning/merge-intent files with 412 insertions and 143 -deletions. It changes no backend, migration, test, workflow, script, dependency, -runtime catalogue, or active product document. The full planning branch is 65 -files with 7,633 insertions and 91 deletions against `origin/main`; most of that -delta is the original reference transcription and durable planning/review -record. +The current-main reconciliation changes 22 planning/merge-intent files with 429 +insertions and 178 deletions. It changes no backend, migration, test, workflow, +script, dependency, runtime catalogue, or active product document. Before this +evidence refresh, the full planning branch is 67 files with 8,235 insertions and +90 deletions against `origin/main`; most of that delta is the original reference +transcription and durable planning/review record. The circuit-breaker passed with a documentation-only size exception: the branch is one coherent specification initiative, its runtime boundary is empty, and @@ -96,13 +116,16 @@ deletion of the archival CON PDF is unstaged and excluded. ## Acceptance-criteria proof -- Runtime catalogue verified at 74 PermissionIds and 57 ActionIds: nine active, - 48 planned, no CON-specific ActionId, and no task-claim ActionId. +- Runtime catalogue verified at 74 PermissionIds and 65 ActionIds: nine active, + 56 planned, no CON-specific ActionId, and no task-claim ActionId. - Prepared-handle wording matches merged AUTH PR #140. - The task and review activation sequences explicitly require hidden feature behavior before AUTH-only activation. - Reviewer and submitter contribution lineage remains Review and FinalAcceptance respectively, inside the REV-owned transaction. +- FinalAcceptance names and CON operation ordering match merged REV PR #128. +- One shared release controller/fence, monotonic root ordinal, cutoff capture, + and same-generation at-or-below-cutoff completion match REV-12A. - The 22 CON mappings are explicitly unregistered/non-final; only the two proposed service PermissionIds remain identified as proposals. - Merge-intent validation passes for successor `WS-CON-001-01`. @@ -110,15 +133,15 @@ deletion of the archival CON PDF is unstaged and excluded. ## Tests and checks ```text -Markdown link check: PASS (57 changed Markdown files) +Markdown link check: PASS (59 changed Markdown files before evidence refresh) Stale Workstream wording: PASS Stale authorization documentation: PASS Stale artifact contracts: PASS at foundation phase Loop-memory state: PASS Agent gates: PASS (80 tests) -PLAN3 commit diff check: PASS +Current-main reconciliation diff check: PASS Working-tree diff check: PASS -PLAN3 backend/.github/scripts delta: none +Current-main CON reconciliation backend/.github/scripts delta: none Merge-intent schema-v2 validation: PASS Local roadmap workbook: not present, so no sheet-export check applies ``` @@ -130,17 +153,18 @@ no threshold, and adds no bypass. Existing agent-gate coverage remains intact. ## Internal reviewer results -The exact reviewed code SHA and complete reviewer table are recorded in -`WS-CON-001-PLAN3-internal-review-evidence.md`. The initial QA/security finding -that `task.claim` was incorrectly described as an existing ActionId was fixed -before the exact-SHA review. A final process-only rebind authorized -parser-complete provenance addenda for the older PLAN/PLAN2 evidence files -validated by the cumulative PR gate. No blocking finding remains. +The exact reviewed code SHA `e968430b0c3b5f1432899c9aa31ef209b774eae0` +and complete reviewer table are recorded in +`WS-CON-001-PLAN3-internal-review-evidence.md`. Earlier task-claim and evidence +findings remain resolved. The current-main architecture review additionally +required the PLAN3 title to name AUTH and REV and removal of a duplicate CON-07 +allowed-file row; all required tracks passed the repaired exact SHA. No blocking +finding remains. ## External review -Pending PR publication. CodeRabbit, GitHub checks, and human PR review supplement -but do not replace the completed internal review. +Draft PR #142 awaits refresh to this reviewed snapshot. CodeRabbit, GitHub +checks, and human PR review supplement but do not replace internal review. ## Risks and follow-up @@ -154,12 +178,12 @@ but do not replace the completed internal review. ## Human review focus -Confirm the corrected task-claim ordering, the exact prepared-handle contract, -the removal of speculative ActionOwner labels, and the unchanged -Review/FinalAcceptance/contribution transaction. Also confirm that the 65-file -planning PR is acceptable as one coherent specification record. +Confirm the corrected task-claim ordering, exact prepared-handle contract, +two-operation Review/FinalAcceptance/contribution transaction, canonical +FinalAcceptance names, and sole REV-12A release controller/fence. Also confirm +that the 67-file planning PR is acceptable as one coherent specification record. ## Human merge ownership -This bundle does not authorize publication or merge. The user must explicitly -approve this specific PR for merge. No successor chunk starts automatically. +This bundle authorizes refreshing draft PR #142, not merging it. The user must +explicitly approve PR #142 for merge. No successor chunk starts automatically. From e07349ed7f8230a96fb3a175da16e99150d3d35f Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 18:37:50 +0100 Subject: [PATCH 19/22] Address CON plan review findings --- .../STATUS.md | 15 ++-- ...-CON-001-01-canonical-contract-adoption.md | 26 +++++-- ...S-CON-001-02A-shared-outbox-persistence.md | 19 ++++-- ...WS-CON-001-02B-shared-outbox-dispatcher.md | 45 +++++++++--- ...-02C-shared-lifecycle-audit-participant.md | 19 ++++-- ...-04B-hidden-contribution-policy-service.md | 32 +++++++-- ...-economic-terms-cutover-and-task-freeze.md | 22 ++++++ ...-001-05B-legacy-economic-schema-removal.md | 19 ++++++ ...review-lease-contribution-policy-freeze.md | 17 +++++ ...c-review-contribution-award-participant.md | 19 ++++++ ...-001-08A-outbound-compensation-delivery.md | 20 ++++++ ...ON-001-08B-inbound-fulfillment-callback.md | 18 +++++ ...-CON-001-08R-bound-service-rate-control.md | 19 +++++- ...B-authorized-contribution-evidence-read.md | 68 +++++++++++++++++-- ...01-10A-contribution-award-product-reads.md | 31 ++++++++- ...1-10B-operations-reconciliation-rebuild.md | 38 +++++++++-- .../WS-CON-001-10C-operations-executors.md | 20 ++++++ .../WS-CON-001-11-hidden-release-readiness.md | 23 ++++++- ...CON-001-PLAN3-auth-pr140-reconciliation.md | 12 ++++ ...-CON-001-PLAN3-external-review-response.md | 60 ++++++++++++++++ .../WS-CON-001-PLAN3-pr-trust-bundle.md | 36 ++++++---- 21 files changed, 514 insertions(+), 64 deletions(-) create mode 100644 .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index d799a912..44744bca 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -2,7 +2,7 @@ ## Current status -`WS-CON-001-PLAN3` completed exact-SHA internal review at +`WS-CON-001-PLAN3` completed its pre-external-review exact-SHA review at `e968430b0c3b5f1432899c9aa31ef209b774eae0` after current-main reconciliation with merged REV PR #128 at `0302bcf`, which also contains AUTH-09A after AUTH PR #140. The prior planning snapshot `09128ee1aed941682c7cb59ca04698de496de682` @@ -12,6 +12,11 @@ decision input with two ordered operations, and adopts REV-12A's exact obligation-writer/ordinal/cutoff hooks. PLAN2's human-approved v0.1 `Review(accept) -> FinalAcceptance -> accepted_submission` boundary remains intact. Runtime code is unchanged. +CodeRabbit then opened five consolidated contract-quality threads. PLAN3 is +temporarily reopened only to add executable verification gates, restore exact +AUTH prerequisite ownership, reclassify optional CON-09B as a deferred proposal, +and record the external response. A new exact-SHA internal review is required +before the repair is pushed. The prior plan is superseded where it used the older policy aggregate, made ART evidence mandatory, described service action rows as persisted assignments, allowed partial activation-custody transfer, or let outbox dispatch imply @@ -49,14 +54,14 @@ feature-handler authority. ## Active chunk -No implementation chunk is active or starts automatically. PLAN3 is complete -and may only refresh draft PR #142; it does not authorize merge or CON-01. +No implementation chunk is active or starts automatically. PLAN3 external +review repair is active only; it does not authorize merge or CON-01. | Chunk | Status | Notes | |---|---|---| | `WS-CON-001-PLAN` | Complete; superseded baseline | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | | `WS-CON-001-PLAN2` | Complete; unpublished | FinalAcceptance is REV-owned; CON trigger changes only; all required internal tracks pass | -| `WS-CON-001-PLAN3` | Complete; internally reviewed | Exact AUTH/REV current-main participant, FinalAcceptance, and release-control reconciliation at `e968430` | +| `WS-CON-001-PLAN3` | External review repair in progress | CodeRabbit contract gates/AUTH scope/09B classification; exact-SHA re-review required | | `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN3 and upstream merge refresh | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | @@ -81,5 +86,5 @@ and may only refresh draft PR #142; it does not authorize merge or CON-01. ## Stop condition Do not edit runtime code, start CON-01, or merge PR #142 without explicit human -direction. The reviewed PLAN3 may refresh the existing draft PR only; it does +direction. The reviewed PLAN3 repair may refresh the existing PR only; it does not authorize its merge or any successor start. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index 8cb61e18..b15eb772 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -74,10 +74,28 @@ roadmap changes without synchronized local XLSX/CSV exports ## Verification -Run all repository stale/link/agent gates, SHA verification for files actually -present, active-doc inventory checks, and git diff checks. Required reviewers: -senior, QA, security, product, architecture, docs, reuse, CI integrity, and test -delta when scanners/tests change. +Run from the repository root: + +```bash +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py +test -f docs/spec_contribution_compensation.md +test -f docs/decision_0016_contribution_compensation_boundary.md +test "$(rg -c 'docs/spec_contribution_compensation\.md' README.md)" -eq 1 +test -z "$(git diff --name-only origin/main...HEAD -- docs/reference_specs)" +test "$(sha256sum 'docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md' | cut -d ' ' -f1)" = cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640 +test "$(sha256sum 'docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf' | cut -d ' ' -f1)" = ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457 +git diff --check +``` + +Pass requires every command to exit zero, both active documents to exist, one +README canonical link, no reference-input delta, both present archival hashes +to match, and all repository gates to pass. Required reviewers: senior, QA, +security, product, architecture, docs, reuse, CI integrity, and test delta when +scanners/tests change. ## Stop diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md index f3a81b75..2a96d12e 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md @@ -37,7 +37,18 @@ new JSON canonicalizer, idempotency framework, dependency or CI weakening ## Verification and reviewers -Execute the exact CON-02A expansion in `../RUNTIME_VERIFICATION.md`. -Same-run outbox coverage is at least 90 percent. Baseline plus architecture, -security/auth, product/ops, docs, reuse/dedup, test-delta, and CI integrity. -Stop before dispatcher behavior. +Execute the exact clean isolated CON-02A row in `../RUNTIME_VERIFICATION.md`, +replace its migration placeholder with the one new revision, then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_outbox.py tests/test_alembic.py -k 'outbox and (migration or append or idempotency or duplicate or race or rollback)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/outbox/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/outbox app/db/models.py tests/test_outbox.py tests/test_alembic.py) +``` + +Pass requires a non-empty selected test set, PostgreSQL migration and duplicate +race proof, stable exact replay, changed-payload conflict, caller rollback with +no commit/publish, repository coverage at least 78 percent in the same clean +run, and focused outbox coverage at least 90 percent. Baseline plus +architecture, security/auth, product/ops, docs, reuse/dedup, test-delta, and CI +integrity are required. Stop before dispatcher behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md index 69b8019b..c47234b6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md @@ -31,18 +31,25 @@ AUTH implementation edits; dynamic registry/plugins; second outbox test/coverage/CI weakening ``` -## Acceptance criteria +## Approved AUTH prerequisites and handoff inputs -- [ ] AUTH registers planned `outbox.dispatch` plus its PermissionId and AUTH - custodian, closed `workstream.outbox.dispatcher` ServiceIdentity with exact +- AUTH must first merge the planned `outbox.dispatch` ActionId/PermissionId, + AUTH custodian, closed `workstream.outbox.dispatcher` ServiceIdentity and singleton static row, controlled ActorProfile/link provisioning, AUTH-09E - admission, typed context, and prepared protocol. Hidden dispatcher remains - disabled until later AUTH evaluator integration/activation. -- [ ] Prepared dispatch follows PR #140 exactly: AUTH locks service profile/link - and prepares the session/action/actor-ref/idempotency/request-digest-bound - handle; the dispatcher locks and recomposes canonical claim facts; AUTH - consumes/evaluates once before claim mutation. Matrix/availability are - code-owned validations, not database lock targets. + admission, typed context, and PR #140 prepared-mutation protocol. +- The handoff supplies AUTH-owned prepare/consume/evaluate ports and the exact + session/action/actor-reference/idempotency/request-digest binding. CON does + not register those identifiers, provision service authority, query grants, + or implement the AUTH evaluator. Matrix and availability remain code-owned + AUTH validations. The hidden dispatcher stays disabled until later AUTH + evaluator integration and activation. + +## Acceptance criteria + +- [ ] Using the approved AUTH handoff, dispatcher claim composition locks and + recomposes canonical claim facts between AUTH prepare and AUTH + consume/evaluate; no claim mutation occurs before the supplied authorization + succeeds. - [ ] Dispatcher claims with lease/generation fencing, commits and releases all locks before invoking a handler, and alone applies typed outcomes to retry/ dead-letter/final state. @@ -63,6 +70,24 @@ test/coverage/CI weakening fail app startup or administrative provisioning. - [ ] Changed subsystem coverage is at least 90 percent; global floor 78. +## Verification + +Execute the exact clean isolated CON-02B row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_outbox.py tests/test_authorization.py tests/test_config.py -k 'dispatcher and (claim or authorization or deny or lease or generation or retry or dead_letter or replay or recovery or drain)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/outbox/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/workers/outbox.py' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/outbox app/workers/outbox.py app/workers/celery_app.py app/core/config.py tests/test_outbox.py tests/test_authorization.py tests/test_config.py) +``` + +Pass requires a non-empty selected test set, real-kernel denial without the +approved AUTH handoff, claim-generation fencing, crash recovery, bounded +retry/dead-letter/replay, accurate drain counts, no handler authority +inheritance, repository coverage at least 78 percent in the same clean run, and +both focused coverage reports at least 90 percent. + ## Review and stop Required tracks include all baseline, architecture, security, product, docs, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md index ceba8ed2..816a992c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md @@ -37,7 +37,18 @@ commit ownership, route, background executor, dependency or CI weakening ## Verification and reviewers -Execute CON-02C in `../RUNTIME_VERIFICATION.md`; changed audit code is at least -90 percent. Senior engineering, QA/test, security/auth, product/ops, -architecture, docs, reuse/dedup and test-delta are required. Stop after the -feature-neutral participant. +Execute the exact clean isolated CON-02C row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_audit.py -k 'participant and (rollback or payload or boundary or idempotency or replay)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/audit/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/audit tests/test_audit.py) +``` + +Pass requires a non-empty selected test set, flush-only rollback, closed typed +payload enforcement, exact replay idempotency, changed-payload conflict, +repository coverage at least 78 percent in the same clean run, and focused +audit coverage at least 90 percent. Senior engineering, QA/test, security/auth, +product/ops, architecture, docs, reuse/dedup and test-delta are required. Stop +after the feature-neutral participant. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md index 00d2fa80..919139c0 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md @@ -26,11 +26,19 @@ AUTH catalogue/grant/kernel/static-matrix edits, adapter/provider calls legacy fallback, dependency or CI weakening ``` +## Approved AUTH prerequisites and deferred activation gate + +- Before this chunk starts, AUTH must supply reviewed typed contexts and the + PR #140 prepared-mutation ports used by the hidden service. CON does not edit + the AUTH catalogue, grants, kernel, ActionOwner custody, or static matrix. +- The proposed `contribution.policy.*` actions remain unregistered and + inactive unless a separate AUTH registration chunk has merged them. Whether + registration precedes or follows this hidden implementation, AUTH alone + integrates evaluators and activates the actions after the feature manifest + passes; CON-05A waits for that activation. + ## Acceptance criteria -- [ ] AUTH registration is merged for planned `contribution.policy.*` actions, - each mapped to stable `compensation.policy.manage`, with typed contexts, - Finance candidates, AUTH ActionOwner, and prepared T protocol. - [ ] AUTH prepares its exact bound handle first. Publish then locks project, active policy, version, rules, definitions, and bindings; recomposes final facts; AUTH consumes the handle and evaluates once; only then may the caller @@ -41,11 +49,23 @@ legacy fallback, dependency or CI weakening stable failure. No legacy authority executes. - [ ] Concurrent draft/publish/retire/selector/binding changes are deterministic. Production OpenAPI remains unchanged. -- [ ] AUTH later integrates exact evaluators and alone activates the actions; - CON-05A waits for activation. +- [ ] The feature manifest is sufficient for later AUTH registration/evaluator + integration and activation without transferring any AUTH-owned work to CON. ## Verification and reviewers -Execute CON-04B in `../RUNTIME_VERIFICATION.md`; changed code is at least 90 +Execute the exact clean isolated CON-04B row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_contributions.py tests/test_projects.py tests/test_authorization.py tests/test_api_contract_e2e.py -k '(policy or publish or retire or binding) and (authorization or rollback or concurrency or idempotency or missing or invalid or openapi)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/contributions/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/contributions app/modules/projects/repository.py app/composition/contributions.py tests/test_contributions.py tests/test_projects.py tests/test_authorization.py tests/test_api_contract_e2e.py) +``` + +Pass requires a non-empty selected test set, supplied prepared-authorization +ordering, flush-only rollback, deterministic concurrent publication/binding +changes, missing-policy failure, hidden OpenAPI, repository coverage at least +78 percent in the same clean run, and focused contribution coverage at least 90 percent. Required tracks: senior, QA, security, product, architecture, docs, reuse, and test-delta. Stop after hidden behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md index e6f82fb6..06aede24 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md @@ -71,6 +71,28 @@ provider/artifact calls; unrelated checker behavior ambiguity and downgrade refuses post-cutover data loss. - [ ] Changed subsystems remain at least 90 percent; global floor remains 78. +## Verification + +Execute the exact clean isolated CON-05A row in `../RUNTIME_VERIFICATION.md`, +replace its migration placeholder with the one new revision, then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_contributions.py tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_authorization.py tests/test_alembic.py tests/test_api_contract_e2e.py -k '(policy or assignment or claim or migration or downgrade) and (freeze or rollback or race or lock or ambiguous or authorization or lineage)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/contributions/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/projects/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/tasks/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/checkers/*' --fail-under=90) +legacy_pattern='locked_''payment_''policy_version|payment_''policies|accepted_''payment_rule|revision_''payment_rule|rejection_''payment_rule' +! rg -n "$legacy_pattern" backend/app --glob '*.py' --glob '!**/models.py' --glob '!db/models.py' +``` + +Pass requires a non-empty selected test set, upgrade and guarded downgrade, +exact assignment freeze and Submission lineage, full rollback on missing or +ambiguous policy, both publication/claim and binding/claim race orders, +real-kernel denial before activation, no runtime legacy-policy consumer, +repository coverage at least 78 percent in the same clean run, and every +focused report at least 90 percent. + ## Review and stop Required tracks: senior, QA, security, product, architecture, docs, reuse, test- diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md index 4382065f..38e9a778 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md @@ -40,6 +40,25 @@ AUTH, ART, provider, frontend, dependency or CI changes - [ ] PostgreSQL upgrade/downgrade and fresh install pass; changed code remains at least 90 percent and repository coverage at least 78 percent. +## Verification + +Execute the exact clean isolated CON-05B row in `../RUNTIME_VERIFICATION.md`, +replace its migration placeholder with the one removal revision, then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_alembic.py tests/test_api_contract_e2e.py -k '(upgrade or downgrade or fresh or migration or schema) and (legacy or economic or contribution_policy)') +legacy_pattern='Payment''Policy|payment_''policies|locked_''payment_''policy_version|accepted_''payment_rule|revision_''payment_rule|rejection_''payment_rule' +! rg -n "$legacy_pattern" backend/app docs/architecture_data_model.md docs/operations_payment_reputation.md docs/spec_contribution_compensation.md +(cd backend && .venv/bin/python -m coverage report --include='app/modules/projects/models.py' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/tasks/models.py' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/checkers/models.py' --fail-under=90) +``` + +Pass requires a non-empty selected test set, PostgreSQL upgrade, guarded +downgrade, fresh install, zero retired schema/API/OpenAPI references, preserved +ContributionPolicy freezes, repository coverage at least 78 percent in the same +clean run, and every focused model report at least 90 percent. + ## Review and stop Required tracks: senior, QA, security, product, architecture, docs, reuse, test- diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md index a3da9cbf..44fe78a8 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md @@ -50,6 +50,23 @@ task assignment changes; provider/artifact/adapter calls - [ ] Policy publish and binding state versus claim pass both lock orders; changed modules stay at least 90 percent and global floor stays 78. +## Verification + +Execute the exact clean isolated CON-06 row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_contributions.py tests/test_authorization.py -k '(review or lease or claim or policy) and (freeze or lock or race or rollback or authorization or deny or no_self_review)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/contributions/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/contributions tests/test_contributions.py tests/test_authorization.py) +``` + +Pass requires a non-empty selected test set, caller-session flush-only freeze, +both publish/claim and binding/claim race orders, missing-policy rollback, +same-project reviewer authorization with unrelated-grant and self-review +denials, repository coverage at least 78 percent in the same clean run, and +focused contribution coverage at least 90 percent. + ## Review and stop Required tracks: senior, QA, security, product, architecture, docs, reuse, and diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md index 0b38127a..750f544d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md @@ -101,6 +101,25 @@ never uses direct Review/ReviewLease contribution-source fields. - [ ] PostgreSQL uniqueness, replay, changed-fact conflict, and concurrency tests pass; changed code is at least 90 percent and repository floor at least 78. +## Verification + +Execute the exact clean isolated CON-07 row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py -k '(review or final_acceptance or contribution or award) and (fault or rollback or replay or idempotency or uniqueness or conflict or concurrency or no_art)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/contributions/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/compensation/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/contributions app/modules/compensation tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py) +``` + +Pass requires a non-empty selected test set, fault injection after every +reviewer/branch/FinalAcceptance/submitter/audit/outbox stage with total +rollback, exact replay idempotency, changed-fact conflict, database uniqueness +under concurrency, all three decision branches, zero ART/provider calls, +repository coverage at least 78 percent in the same clean run, and both focused +reports at least 90 percent. + ## Review and stop Required tracks: senior, QA, security, product, architecture, docs, reuse, and diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md index 349d604a..75793e22 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md @@ -77,6 +77,26 @@ database/fence lock held during external I/O a later checkpoint after this hidden handler and its evaluator composition merge. +## Verification + +Execute the exact clean isolated CON-08A row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_compensation.py tests/test_outbox.py tests/test_authorization.py tests/test_external_service_adapters.py -k '(delivery or adapter or fulfillment) and (fence or cutoff or generation or retry or replay or concurrency or authorization or pre_io or transaction)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/compensation/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/workers/compensation.py' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/interfaces/compensation.py' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/adapters/compensation/*' --fail-under=90) +``` + +Pass requires a non-empty selected test set, pre-I/O durable fencing, no +transaction or lifecycle fence held during adapter I/O, both cutoff race +orders, same-generation pre-cutoff completion, post-cutoff/cross-generation +denial before provider calls, retry/replay and ambiguous-result safety, typed +adapter-factory use, repository coverage at least 78 percent in the same clean +run, and every focused report at least 90 percent. + ## Review and stop All baseline plus architecture, security, product, docs, reuse, CI integrity, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md index b5ccb008..adfa77f4 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -59,6 +59,24 @@ outbox transition ownership; production route registration - [ ] Missing provisioned callback rows deny callback/readiness but do not fail startup/provisioning. AUTH later activates after hidden behavior proof. +## Verification + +Execute the exact clean isolated CON-08B row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_compensation.py tests/test_authorization.py tests/test_api_rate_controls.py tests/test_api_contract_e2e.py -k '(callback or receipt or fulfillment) and (replay or conflict or fence or cutoff or generation or rate or authorization or signature or concurrency)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/compensation/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/compensation app/api/internal_compensation.py app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_rate_controls.py tests/test_api_contract_e2e.py) +``` + +Pass requires a non-empty selected test set, exact callback replay and changed +replay conflict, signature and authorization negatives, actor-plus-binding rate +isolation, both fence race orders, same-generation at-or-below-cutoff +finalization only, no follow-on obligation while draining, repository coverage +at least 78 percent in the same clean run, and focused compensation coverage at +least 90 percent. + ## Review and stop All baseline plus architecture, security, product, docs, reuse, test-delta, and diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md index db6f2388..bd2afa95 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md @@ -39,6 +39,19 @@ in-memory/shared-IP-only limiter, new rate-control framework, dependency/CI weak ## Verification and reviewers -Execute CON-08R in `../RUNTIME_VERIFICATION.md`; changed api-controls code is at -least 90 percent. Senior engineering, QA/test, security/auth, product/ops, -architecture, docs, reuse/dedup and test-delta are required. Stop before callback. +Execute the exact clean isolated CON-08R row in `../RUNTIME_VERIFICATION.md`, +replace its migration placeholder with the one new revision, then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_api_rate_controls.py tests/test_config.py tests/test_alembic.py -k '(compensation_fulfillment_report or rate) and (atomic or window or concurrent or isolation or upgrade or downgrade or fail_closed or retry_after)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/api_controls/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/api/deps/api_controls.py' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/core/config.py' --fail-under=90) +``` + +Pass requires a non-empty selected test set, atomic PostgreSQL window races, +actor and binding isolation, upgrade/downgrade proof, bounded configuration, +fail-closed storage errors, deterministic retry-after, repository coverage at +least 78 percent in the same clean run, and every focused report at least 90 +percent. Senior engineering, QA/test, security/auth, product/ops, architecture, +docs, reuse/dedup and test-delta are required. Stop before callback. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md index 971a5770..8bdee2f6 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -1,15 +1,50 @@ -# Chunk Contract: WS-CON-001-09B - Optional Authorized Contribution Evidence Read +# Deferred Proposal: WS-CON-001-09B - Optional Authorized Contribution Evidence Read ## Status Deferred optional successor after separately approved and merged CON-09A. It is -not a prerequisite for core contribution/award reads. +not a prerequisite for core contribution/award reads. This file is deliberately +not an implementation contract and authorizes no file changes. + +## Prospective risk + +L1 disclosure, authorization, artifact-retention, and cross-subsystem read +boundary. Risk and scope must be reclassified against then-current ART/AUTH +contracts before promotion. ## Goal if separately approved Expose a bounded evidence-export read through a separately proven ART read capability and exact AUTH disclosure contract. +## Allowed files now + +None. A separately human-approved, internally reviewed replacement chunk +contract must name exact allowed files before implementation. + +## Prohibited changes + +```text +runtime, route, schema, migration, dependency, workflow, AUTH, ART, or activation changes +CON-10A contribution/award truth or availability dependencies +public evidence route or provider/credential disclosure +reuse of the CON-09A write capability as an implicit read capability +``` + +## Promotion acceptance criteria + +- [ ] CON-09A is separately approved, merged, and refreshed against trusted + main; its absence or failure still cannot affect CON-10A. +- [ ] The replacement contract names exact ART read capability, projection + schema/binding/retention, AUTH disclosure ActionIds/contexts/candidates, and + self/project concealment rules without reviewer-private/provider/credential + disclosure. +- [ ] Exact allowed files, prohibited changes, runtime tests, migration impact, + coverage targets, reviewers, and stop conditions are approved before any + implementation. +- [ ] Routes stay hidden until their own merged AUTH evaluator/activation and + optional release gate pass. + ## Mandatory refresh gate - Re-review the then-current projection schema/binding/retention state and ART @@ -21,7 +56,32 @@ capability and exact AUTH disclosure contract. - Keep routes hidden until its own AUTH evaluator/activation and optional release gate pass. +## Verification before promotion + +Run from the repository root against the proposed replacement contract: + +```bash +test -f docs/spec_artifact_storage_service.md +test -f docs/spec_authorization_service.md +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +git diff --check +test -z "$(git diff --name-only origin/main...HEAD -- backend .github)" +``` + +Pass only proves that a planning-only replacement contract is eligible for +internal review: every command exits zero, no runtime/workflow delta exists, +and the contract closes every promotion criterion above. It does not authorize +implementation. + +## Required reviewers before promotion + +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +reuse/dedup, ART boundary, AUTH boundary, CI integrity, and test delta. + ## Stop -Do not start without separate human approval and a refreshed internally reviewed -chunk contract. CON-10A proceeds independently. +Do not start without separate human approval and a replacement internally +reviewed chunk contract. CON-10A proceeds independently. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md index 2415122a..79735c5b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md @@ -26,11 +26,18 @@ operations mutation/rebuild/reconciliation; AUTH edit balance/ledger; production route registration; CI weakening ``` +## Approved AUTH prerequisites and handoff inputs + +- AUTH must first merge the approved contribution/award self/project + ActionIds, typed contexts, ActionOwner custody, and real-kernel decision + ports. CON neither registers nor activates them. +- The actions remain planned until CON's hidden read composition and negative + proof merge; AUTH alone performs later evaluator integration and activation. + ## Acceptance criteria -- [ ] AUTH registers planned contribution/award self/project actions and typed - contexts. CON composes canonical PostgreSQL facts while real kernel denies; - AUTH later integrates evaluators/activation. +- [ ] CON composes canonical PostgreSQL resource facts for the supplied AUTH + decision ports while the real kernel continues to deny planned actions. - [ ] D11 exact award-detail candidate set is approved before implementation. CON contains no role logic and never infers access from broad PermissionId. - [ ] Self reads require exact contributor/beneficiary. Project reads use exact @@ -43,6 +50,24 @@ balance/ledger; production route registration; CI weakening - [ ] CON-09A/09B absence or failure has no effect. OpenAPI remains hidden; coverage stays at required floors. +## Verification + +Execute the exact clean isolated CON-10A row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py -k '(contribution or award) and (read or list or pagination or conceal or cross_project or unauthorized or stale or openapi)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/contributions/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/compensation/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/contributions app/modules/compensation app/api/internal_contributions.py app/api/internal_compensation.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py) +``` + +Pass requires a non-empty selected test set, stable pre-filtered pagination, +self/project authorization negatives, cross-project concealment, stale-decision +denial, hidden OpenAPI routes, no evidence/provider disclosure, repository +coverage at least 78 percent in the same clean run, and both focused reports at +least 90 percent. + ## Review and stop Required tracks: senior, QA, security, product, architecture, docs, reuse, and diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md index 946be77d..93dc0401 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -28,14 +28,21 @@ outbox dispatcher/transition implementation; immutable truth repair AUTH implementation; production router registration; CI weakening ``` +## Approved AUTH prerequisites and handoff inputs + +- D11 must be final and AUTH must first merge the approved binding-retire, + delivery-reconcile, status, reconcile-request, rebuild-request, and audit + ActionIds with exact candidates, typed contexts, prepared protocol, and AUTH + custodians. CON neither registers nor activates them. +- The handoff supplies AUTH-owned prepare/consume/evaluate ports. AUTH prepares + authority first and consumes/evaluates the recomposed facts; the route owns + the single commit. + ## Acceptance criteria -- [ ] D11 is final. AUTH registers binding-retire, delivery-reconcile, status, - reconcile-request, rebuild-request, and audit actions with exact candidates, - contexts, prepared protocol, and AUTH custodians. -- [ ] Every mutation uses the exact PR #140 prepared protocol: AUTH prepares - authority first; CON locks and recomposes final facts; AUTH consumes/evaluates - once before request/retirement mutation; the route commits once. +- [ ] Every mutation uses the supplied PR #140 handoff: CON locks and + recomposes final product facts between AUTH prepare and AUTH + consume/evaluate, and stages no request/retirement mutation beforehand. - [ ] Human operations create bounded durable idempotent requests only; they do not execute reconciliation/rebuild under human or dispatcher authority. - [ ] Binding retirement locks policy/assignment/lease/award/delivery/receipt @@ -55,6 +62,25 @@ AUTH implementation; production router registration; CI weakening - [ ] AUTH later activates after hidden behavior; 10C waits for approved executor identities/actions/static rows. +## Verification + +Execute the exact clean isolated CON-10B row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py tests/test_audit.py -k '(operation or retirement or reconcile or rebuild or audit or drain) and (race or lock or authorization or idempotency or ordinal or false_zero or provider)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/contributions/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/compensation/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/audit/*' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/contributions app/modules/compensation app/modules/audit app/api/internal_operations.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py tests/test_audit.py) +``` + +Pass requires a non-empty selected test set, both retirement race orders, +prepared-authorization negatives, idempotent bounded requests, exact drain +counts and maximum ordinal without false zero, zero provider calls, repository +coverage at least 78 percent in the same clean run, and every focused report at +least 90 percent. + ## Review and stop Required tracks: senior, QA, security, product, architecture, docs, reuse, and diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md index d4d7c033..659c21ba 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md @@ -65,6 +65,26 @@ outbox claim/finalization transitions; AUTH implementation activation is a later checkpoint after hidden behavior and exact evaluator composition merge. +## Verification + +Execute the exact clean isolated CON-10C row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_contributions.py tests/test_compensation.py tests/test_outbox.py tests/test_authorization.py -k '(executor or reconcile or rebuild) and (fence or ordinal or retry or replay or crash or concurrency or unauthorized or deny)') +(cd backend && .venv/bin/python -m coverage report --include='app/modules/contributions/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/modules/compensation/*' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/workers/contributions.py' --fail-under=90) +(cd backend && .venv/bin/python -m coverage report --include='app/workers/compensation.py' --fail-under=90) +(cd backend && .venv/bin/ruff check app/modules/contributions app/modules/compensation app/modules/outbox/handlers.py app/workers/contributions.py app/workers/compensation.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_outbox.py tests/test_authorization.py) +``` + +Pass requires a non-empty selected test set, exact executor isolation, +claim-generation validation, shared-fence-before-ordinal ordering, retry/replay +and crash idempotency, concurrent drain denial of new obligation work, +repository coverage at least 78 percent in the same clean run, and every +focused report at least 90 percent. + ## Review and stop All baseline plus architecture, security, product, docs, reuse, CI integrity, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md index 7a757eca..576ac16c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-11-hidden-release-readiness.md @@ -88,9 +88,26 @@ archival input edits ## Verification -Run the initiative runtime commands plus Markdown links, stale wording, -authorization/artifact scanners, loop-memory check, internal evidence check, and -git diff check. +Execute the exact clean isolated CON-11 row in `../RUNTIME_VERIFICATION.md`, +then run: + +```bash +(cd backend && .venv/bin/python -m pytest -q tests/test_api_contract_e2e.py tests/test_authorization.py tests/test_contributions.py tests/test_compensation.py tests/test_outbox.py tests/test_audit.py -k '(manifest or readiness or openapi or isolation or fence or cutoff or generation or drain or provider)') +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +python3 scripts/check_loop_memory_state.py +python3 scripts/check_internal_review_evidence.py +git diff --check +``` + +Pass requires a non-empty selected test set, a complete exact AUTH/REV/CON +manifest, no public OpenAPI registration, service/action isolation, every +writer/dispatch/callback fence race in both orders, same-generation +at-or-below-cutoff completion only, provider I/O outside transaction/fence, +repository coverage at least 78 percent and each CON-11 focused subsystem at +least 90 percent in the same clean run, plus every repository gate above. ## Review and stop diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md index 05a9c85a..8b0e6f1c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md @@ -26,16 +26,21 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02B-shared-outbox-dispatcher.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02C-shared-lifecycle-audit-participant.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03C-contribution-award-persistence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-03D-delivery-receipt-status-persistence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04A-hidden-adapter-binding-service.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-06-review-lease-contribution-policy-freeze.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-07-atomic-review-contribution-award-participant.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md @@ -43,6 +48,7 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md .agent-loop/merge-intents/WS-CON-001-PLAN3.json ``` @@ -103,6 +109,12 @@ reference specification/PDF edits, restoration, rename, or replacement allocating a monotonic root ordinal; the same-session drain port returns the maximum ordinal; and delivery-draining dispatch/callback paths are limited to same-generation roots at or below the persisted cutoff. +- [x] Every unresolved CodeRabbit thread is dispositioned: active chunks name + deterministic runnable verification commands and pass criteria; AUTH-owned + registration, context, custody, and activation remain prerequisites rather + than CON-owned acceptance work; optional CON-09B is explicitly a deferred + proposal pending a fresh contract; and the PR description carries the full + trust bundle. ## Verification diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md new file mode 100644 index 00000000..9173b4db --- /dev/null +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md @@ -0,0 +1,60 @@ +# WS-CON-001-PLAN3 External Review Response + +## Review source + +CodeRabbit review of PR #142, run +`26a5debe-60e5-445a-840c-f7155725fd90`, against `0302bcf...adf5cc1`. +Five unresolved consolidated threads and one PR-description warning were +triaged on 2026-07-17. + +## Comments addressed + +1. `PRRT_kwDOSwL_U86R1pF_`: added deterministic runnable verification commands, + coverage targets, and explicit pass criteria to CON-01, 02A, 02B, 02C, 10A, + 10B, 10C, and 11. +2. `PRRT_kwDOSwL_U86R1pGB`: moved AUTH registration, ServiceIdentity/static + authority, typed-context, custodian, and prepared-protocol ownership into + approved prerequisites/handoff inputs for CON-02B, 10A, and 10B. Acceptance + criteria now cover only CON-owned composition and behavior. +3. `PRRT_kwDOSwL_U86R1pGD`: moved contribution-policy action registration out + of CON-04B. The hidden feature may consume reviewed AUTH ports, but AUTH + alone owns later registration, evaluator integration, and activation. +4. `PRRT_kwDOSwL_U86R1pGE`: added deterministic runnable verification commands, + coverage targets, and explicit pass criteria to CON-04B, 05A, 05B, 06, 07, + 08A, 08B, and 08R. +5. `PRRT_kwDOSwL_U86R1pGI`: corrected CON-09B from an incomplete “Chunk + Contract” to a non-executable “Deferred Proposal.” It now has prospective + risk, zero current allowed files, explicit prohibitions, promotion criteria, + planning-only promotion checks, required reviewers, and a mandatory fresh + replacement contract after separate human/ART/AUTH approval. This preserves + the intentional deferral instead of freezing stale implementation scope. +6. CodeRabbit description warning: the PR body is replaced with the complete + PLAN3 trust-bundle structure after the reviewed repair is pushed. + +## Comments deferred + +None. CON-09B implementation remains intentionally deferred by product scope, +but the review concern about presenting an incomplete actionable contract is +addressed now. + +## Human decisions needed + +None for this repair. The human directed that all CodeRabbit findings be fixed. +Existing separate approval gates for CON-01, optional CON-09A/09B, and PR merge +remain unchanged. + +## Commands rerun + +Pending final candidate: Markdown links, stale Workstream wording, stale +authorization docs, stale artifact contracts, loop-memory state, agent gates, +merge-intent validation, internal-review evidence gate, diff integrity, and +all required internal reviewer tracks. + +## Remaining risks + +- Future implementation filenames and migrations must replace each contract's + explicit placeholder without broadening its allowed scope. +- Focused pytest selectors are required to select at least one test; a zero-test + selection is a failure, not a pass. +- CON-09B remains non-executable until a fresh replacement contract is + separately approved and reviewed against then-current ART/AUTH boundaries. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md index c54837ab..6761f1ec 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md @@ -114,6 +114,12 @@ is one coherent specification initiative, its runtime boundary is empty, and the earlier planning snapshots retain their own review evidence. The user-owned deletion of the archival CON PDF is unstaged and excluded. +The PR #142 external-review repair updates 17 future chunk/deferred-proposal +files plus the PLAN3 scope, status, trust bundle, and external-response log. It +adds no runtime, AUTH/REV/ART-owned, workflow, dependency, migration, or test +change. The repair makes verification executable and preserves upstream AUTH +ownership rather than changing product behavior. + ## Acceptance-criteria proof - Runtime catalogue verified at 74 PermissionIds and 65 ActionIds: nine active, @@ -153,18 +159,21 @@ no threshold, and adds no bypass. Existing agent-gate coverage remains intact. ## Internal reviewer results -The exact reviewed code SHA `e968430b0c3b5f1432899c9aa31ef209b774eae0` -and complete reviewer table are recorded in -`WS-CON-001-PLAN3-internal-review-evidence.md`. Earlier task-claim and evidence -findings remain resolved. The current-main architecture review additionally -required the PLAN3 title to name AUTH and REV and removal of a duplicate CON-07 -allowed-file row; all required tracks passed the repaired exact SHA. No blocking -finding remains. +The pre-external-review snapshot +`e968430b0c3b5f1432899c9aa31ef209b774eae0` passed every required track. The +CodeRabbit repair requires a new exact-SHA internal re-review before push; the +final evidence rebind will be recorded in +`WS-CON-001-PLAN3-internal-review-evidence.md`. ## External review -Draft PR #142 awaits refresh to this reviewed snapshot. CodeRabbit, GitHub -checks, and human PR review supplement but do not replace internal review. +CodeRabbit posted five unresolved consolidated threads and one description +warning after PR #142 became ready for review. All five are addressed in +`WS-CON-001-PLAN3-external-review-response.md`: 16 active chunks gain exact +focused commands/pass criteria, AUTH requirements move to explicit upstream +prerequisites, and optional CON-09B is correctly reclassified as a deferred +proposal requiring a fresh contract. The PR body will be replaced with this +full trust-bundle structure after the reviewed repair is pushed. ## Risks and follow-up @@ -180,10 +189,13 @@ checks, and human PR review supplement but do not replace internal review. Confirm the corrected task-claim ordering, exact prepared-handle contract, two-operation Review/FinalAcceptance/contribution transaction, canonical -FinalAcceptance names, and sole REV-12A release controller/fence. Also confirm -that the 67-file planning PR is acceptable as one coherent specification record. +FinalAcceptance names, sole REV-12A release controller/fence, executable future +chunk gates, and upstream-only AUTH registration/activation ownership. Also +confirm that optional CON-09B remains non-executable until fresh approval and +that the cumulative planning PR is acceptable as one coherent specification +record. ## Human merge ownership -This bundle authorizes refreshing draft PR #142, not merging it. The user must +This bundle authorizes refreshing PR #142, not merging it. The user must explicitly approve PR #142 for merge. No successor chunk starts automatically. From bf7f54e29e443d8945eb1f823ebb1faf3aefc1b7 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 18:59:09 +0100 Subject: [PATCH 20/22] Repair CON review gate defects --- .agent-loop/REVIEW_LOG.md | 14 ++ .../RUNTIME_VERIFICATION.md | 2 +- ...-CON-001-01-canonical-contract-adoption.md | 2 +- ...S-CON-001-02A-shared-outbox-persistence.md | 9 +- ...-04B-hidden-contribution-policy-service.md | 15 +- ...-economic-terms-cutover-and-task-freeze.md | 7 +- ...-001-05B-legacy-economic-schema-removal.md | 7 +- ...ON-001-08B-inbound-fulfillment-callback.md | 6 +- ...CON-001-PLAN3-auth-pr140-reconciliation.md | 4 +- ...B-authorized-contribution-evidence-read.md | 11 +- .../WS-CON-001-PLAN3-pr-trust-bundle.md | 158 ++++++++++++++---- 11 files changed, 185 insertions(+), 50 deletions(-) rename .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/{chunks => deferred}/WS-CON-001-09B-authorized-contribution-evidence-read.md (90%) diff --git a/.agent-loop/REVIEW_LOG.md b/.agent-loop/REVIEW_LOG.md index c785d0f1..e5070555 100644 --- a/.agent-loop/REVIEW_LOG.md +++ b/.agent-loop/REVIEW_LOG.md @@ -1,5 +1,19 @@ # Review Log +## 2026-07-17 - WS-CON-001-PLAN3 External Review Repair Started + +CodeRabbit posted five consolidated actionable threads and one PR-description +warning on PR #142 after the AUTH/REV current-main reconciliation became ready +for review. The bounded planning-only repair adds deterministic executable +verification gates to 16 active future chunks, moves AUTH registration/context/ +custody/prepared-port requirements into upstream handoffs, preserves the +canonical registration -> hidden behavior -> activation order, and moves +optional CON-09B out of executable `chunks/` as a zero-file deferred proposal +pending separate ART/AUTH/human approval and a fresh contract. It also aligns +the PR trust bundle with the repository template. No runtime successor is +active; exact-SHA internal re-review, evidence rebind, external check rerun, and +thread disposition remain required before merge readiness. + ## 2026-07-17 - WS-AUTH-001-09A Convergence Started After PR #140 merged as `d541521` and signed memory stopped, the user explicitly diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md index db18fa12..f017b5c2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md @@ -37,7 +37,7 @@ git diff --check | CON-07 | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py` | | CON-08A | `app/modules/compensation/*`; `app/workers/compensation.py`; `app/interfaces/compensation.py`; `app/adapters/compensation/*` | `app/interfaces/compensation.py app/adapters/compensation app/modules/compensation app/modules/outbox/handlers.py app/workers/compensation.py app/workers/celery_app.py app/composition/compensation.py tests/test_compensation.py tests/test_outbox.py tests/test_external_service_adapters.py` | | CON-08R | `app/modules/api_controls/*`; `app/api/deps/api_controls.py`; `app/core/config.py` | `app/modules/api_controls app/api/deps/api_controls.py app/core/config.py tests/test_api_rate_controls.py tests/test_config.py tests/test_alembic.py alembic/versions/.py` | -| CON-08B | `app/modules/compensation/*` | `app/modules/compensation app/api/internal_compensation.py app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | +| CON-08B | `app/modules/compensation/*` | `app/modules/compensation app/api/internal_compensation.py app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_controls.py tests/test_api_rate_controls.py tests/test_api_contract_e2e.py` | | CON-09A (optional) | Defined only by a separately approved refreshed contract | Do not execute from this table alone | | CON-09B (optional) | Defined only by a separately approved refreshed contract | Do not execute from this table alone | | CON-10A | `app/modules/contributions/*`; `app/modules/compensation/*` | `app/modules/contributions app/modules/compensation app/api/internal_contributions.py app/api/internal_compensation.py app/composition/contributions.py app/composition/compensation.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_api_contract_e2e.py` | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md index b15eb772..d938811b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -85,7 +85,7 @@ PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.p test -f docs/spec_contribution_compensation.md test -f docs/decision_0016_contribution_compensation_boundary.md test "$(rg -c 'docs/spec_contribution_compensation\.md' README.md)" -eq 1 -test -z "$(git diff --name-only origin/main...HEAD -- docs/reference_specs)" +git diff --quiet origin/main...HEAD -- docs/reference_specs test "$(sha256sum 'docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification.md' | cut -d ' ' -f1)" = cddbe20f4fadf5307f68519347bdd9520ef49b23fb0b92cad24c31fc9b34c640 test "$(sha256sum 'docs/reference_specs/WS-CON-001-contribution-record-and-compensation-boundary-specification(2).pdf' | cut -d ' ' -f1)" = ce65e208076769f0bafb09779d60ab6f5fc0c596514d4e8f4cc03690c6e6d457 git diff --check diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md index 2a96d12e..a7ed8ce3 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-02A-shared-outbox-persistence.md @@ -46,9 +46,10 @@ replace its migration placeholder with the one new revision, then run: (cd backend && .venv/bin/ruff check app/modules/outbox app/db/models.py tests/test_outbox.py tests/test_alembic.py) ``` -Pass requires a non-empty selected test set, PostgreSQL migration and duplicate -race proof, stable exact replay, changed-payload conflict, caller rollback with -no commit/publish, repository coverage at least 78 percent in the same clean -run, and focused outbox coverage at least 90 percent. Baseline plus +Pass requires a non-empty selected test set, PostgreSQL upgrade and guarded +downgrade plus duplicate-race proof, stable exact replay, changed-payload +conflict, caller rollback with no commit/publish, repository coverage at least +78 percent in the same clean run, and focused outbox coverage at least 90 +percent. Baseline plus architecture, security/auth, product/ops, docs, reuse/dedup, test-delta, and CI integrity are required. Stop before dispatcher behavior. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md index 919139c0..b2668f5a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md @@ -28,14 +28,13 @@ legacy fallback, dependency or CI weakening ## Approved AUTH prerequisites and deferred activation gate -- Before this chunk starts, AUTH must supply reviewed typed contexts and the - PR #140 prepared-mutation ports used by the hidden service. CON does not edit - the AUTH catalogue, grants, kernel, ActionOwner custody, or static matrix. -- The proposed `contribution.policy.*` actions remain unregistered and - inactive unless a separate AUTH registration chunk has merged them. Whether - registration precedes or follows this hidden implementation, AUTH alone - integrates evaluators and activates the actions after the feature manifest - passes; CON-05A waits for that activation. +- Before this chunk starts, AUTH must merge reviewed registration of the + planned `contribution.policy.*` actions, stable permission mapping, typed + contexts, ActionOwner custody, and PR #140 prepared-mutation ports. The + actions remain planned. CON does not edit the AUTH catalogue, grants, kernel, + ActionOwner custody, or static matrix. +- After this hidden feature manifest merges, AUTH alone integrates evaluators + and activates the actions. CON-05A waits for that activation. ## Acceptance criteria diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md index 06aede24..c5c836ca 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05A-legacy-economic-terms-cutover-and-task-freeze.md @@ -83,7 +83,12 @@ replace its migration placeholder with the one new revision, then run: (cd backend && .venv/bin/python -m coverage report --include='app/modules/tasks/*' --fail-under=90) (cd backend && .venv/bin/python -m coverage report --include='app/modules/checkers/*' --fail-under=90) legacy_pattern='locked_''payment_''policy_version|payment_''policies|accepted_''payment_rule|revision_''payment_rule|rejection_''payment_rule' -! rg -n "$legacy_pattern" backend/app --glob '*.py' --glob '!**/models.py' --glob '!db/models.py' +if rg -n "$legacy_pattern" backend/app --glob '*.py' --glob '!**/models.py' --glob '!db/models.py'; then + exit 1 +else + rg_status=$? + test "$rg_status" -eq 1 +fi ``` Pass requires a non-empty selected test set, upgrade and guarded downgrade, diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md index 38e9a778..068869a2 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-05B-legacy-economic-schema-removal.md @@ -48,7 +48,12 @@ replace its migration placeholder with the one removal revision, then run: ```bash (cd backend && .venv/bin/python -m pytest -q tests/test_projects.py tests/test_tasks.py tests/test_checkers.py tests/test_alembic.py tests/test_api_contract_e2e.py -k '(upgrade or downgrade or fresh or migration or schema) and (legacy or economic or contribution_policy)') legacy_pattern='Payment''Policy|payment_''policies|locked_''payment_''policy_version|accepted_''payment_rule|revision_''payment_rule|rejection_''payment_rule' -! rg -n "$legacy_pattern" backend/app docs/architecture_data_model.md docs/operations_payment_reputation.md docs/spec_contribution_compensation.md +if rg -n "$legacy_pattern" backend/app docs/architecture_data_model.md docs/operations_payment_reputation.md docs/spec_contribution_compensation.md; then + exit 1 +else + rg_status=$? + test "$rg_status" -eq 1 +fi (cd backend && .venv/bin/python -m coverage report --include='app/modules/projects/models.py' --fail-under=90) (cd backend && .venv/bin/python -m coverage report --include='app/modules/tasks/models.py' --fail-under=90) (cd backend && .venv/bin/python -m coverage report --include='app/modules/checkers/models.py' --fail-under=90) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md index adfa77f4..1cb47f88 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md @@ -11,7 +11,7 @@ receipts/status updates. L1 auth/economic/replay risk. backend/app/modules/compensation/{schemas,repository,service,ports}.py backend/app/api/internal_compensation.py backend/app/composition/compensation.py -backend/tests/{test_compensation,test_authorization,test_api_controls}.py +backend/tests/{test_compensation,test_authorization,test_api_controls,test_api_rate_controls,test_api_contract_e2e}.py docs/spec_contribution_compensation.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/** .agent-loop/merge-intents/WS-CON-001-08B.json @@ -65,9 +65,9 @@ Execute the exact clean isolated CON-08B row in `../RUNTIME_VERIFICATION.md`, then run: ```bash -(cd backend && .venv/bin/python -m pytest -q tests/test_compensation.py tests/test_authorization.py tests/test_api_rate_controls.py tests/test_api_contract_e2e.py -k '(callback or receipt or fulfillment) and (replay or conflict or fence or cutoff or generation or rate or authorization or signature or concurrency)') +(cd backend && .venv/bin/python -m pytest -q tests/test_compensation.py tests/test_authorization.py tests/test_api_controls.py tests/test_api_rate_controls.py tests/test_api_contract_e2e.py -k '(callback or receipt or fulfillment) and (replay or conflict or fence or cutoff or generation or rate or authorization or signature or concurrency or openapi)') (cd backend && .venv/bin/python -m coverage report --include='app/modules/compensation/*' --fail-under=90) -(cd backend && .venv/bin/ruff check app/modules/compensation app/api/internal_compensation.py app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_rate_controls.py tests/test_api_contract_e2e.py) +(cd backend && .venv/bin/ruff check app/modules/compensation app/api/internal_compensation.py app/composition/compensation.py tests/test_compensation.py tests/test_authorization.py tests/test_api_controls.py tests/test_api_rate_controls.py tests/test_api_contract_e2e.py) ``` Pass requires a non-empty selected test set, exact callback replay and changed diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md index 8b0e6f1c..1839bb3a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md @@ -23,6 +23,7 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/JOINT_RELEASE_HANDOFF.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/PLAN.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RISKS.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/RUNTIME_VERIFICATION.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/SOURCE_MANIFEST.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-01-canonical-contract-adoption.md @@ -40,7 +41,7 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md -.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10C-operations-executors.md @@ -50,6 +51,7 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +.agent-loop/REVIEW_LOG.md .agent-loop/merge-intents/WS-CON-001-PLAN3.json ``` diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md similarity index 90% rename from .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md rename to .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md index 8bdee2f6..23653f9b 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -68,7 +68,16 @@ python3 scripts/check_stale_workstream_wording.py python3 scripts/check_stale_authorization_docs.py python3 scripts/check_stale_artifact_contracts.py git diff --check -test -z "$(git diff --name-only origin/main...HEAD -- backend .github)" +if ! changed_files="$(git diff --name-only origin/main...HEAD)"; then + exit 1 +fi +if unexpected="$(printf '%s\n' "$changed_files" | rg -v '^\.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/|^\.agent-loop/merge-intents/WS-CON-001-09B\.json$')"; then + printf '%s\n' "$unexpected" + exit 1 +else + rg_status=$? + test "$rg_status" -eq 1 +fi ``` Pass only proves that a planning-only replacement contract is eligible for diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md index 6761f1ec..25b0bc56 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md @@ -1,16 +1,21 @@ -# WS-CON-001-PLAN3 PR Trust Bundle +# Workstream PR Trust Bundle: WS-CON-001-PLAN3 ## Chunk `WS-CON-001-PLAN3` - AUTH And REV Current-Main Reconciliation. +Merge intent: `.agent-loop/merge-intents/WS-CON-001-PLAN3.json` + ## Goal Reconcile the contribution and compensation plan with trusted `main` at merged REV PR #128 (`0302bcf`), which contains AUTH-09A after AUTH PR #140, before any CON runtime implementation begins. -## Human-approved intent +## Human-Approved Intent + +- Intent: `.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/INTENT.md` +- Chunk contract: `.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md` - The current compensation-policy model completely supersedes the retired policy model; no compatibility path returns. @@ -26,7 +31,7 @@ CON runtime implementation begins. - Consume merged REV's exact FinalAcceptance shape, two-operation CON participant, initiative interleaving, and sole joint release-control contract. -## What changed +## What Changed - Rebased CON authorization assumptions on AUTH PR #140 and AUTH-09A's current runtime catalogue while preserving PR #139 as the underlying boundary. @@ -51,14 +56,14 @@ CON runtime implementation begins. - Added the reviewed PLAN3 contract and one schema-v2 merge intent naming `WS-CON-001-01` as the same-initiative successor with an explicit start gate. -## Why +## Why It Changed Treating a PermissionId as an existing ActionId would invert the safe rollout: AUTH could activate task claim before the assignment captured its immutable contribution-policy version. The corrected order keeps the feature unavailable until hidden behavior and rollback proof are merged. -## Design and boundaries +## Design Chosen AUTH locks current actor/link/exact-grant authority first and prepares one opaque handle bound to session, ActionId, actor-reference kind/reference, @@ -87,7 +92,7 @@ allocation. Delivery-draining completion is limited to same-generation roots at or below the persisted cutoff; provider I/O occurs outside the transaction and fence. -## Alternatives rejected +## Alternatives Rejected - Activating task claim before CON-05A: rejected because assignment policy lineage would not be guaranteed. @@ -100,7 +105,18 @@ and fence. - Adding a FinalAcceptance action or adjudication branch: rejected by the approved v0.1 lifecycle. -## Scope +## Scope Control + +### Allowed Files Changed + +- Seventeen WS-CON future chunk/deferred-proposal files. +- PLAN3 contract, STATUS, trust bundle, internal evidence, and external response + under the WS-CON initiative. +- Exactly one existing PLAN3 schema-v2 merge intent for the cumulative PR. + +### Files Outside Contract + +- None. The user-owned archival PDF deletion is unstaged and excluded. The current-main reconciliation changes 22 planning/merge-intent files with 429 insertions and 178 deletions. It changes no backend, migration, test, workflow, @@ -120,7 +136,16 @@ adds no runtime, AUTH/REV/ART-owned, workflow, dependency, migration, or test change. The repair makes verification executable and preserves upstream AUTH ownership rather than changing product behavior. -## Acceptance-criteria proof +## Product Behavior + +- [x] No Workstream product behavior changed. +- [ ] Product behavior changed and is explained here. + +This PR changes planning, lifecycle wording, future chunk contracts, and review +evidence only. It adds no runtime route, model, migration, action, permission, +grant, worker, provider call, or activation. + +## Acceptance Criteria Proof - Runtime catalogue verified at 74 PermissionIds and 65 ActionIds: nine active, 56 planned, no CON-specific ActionId, and no task-claim ActionId. @@ -135,47 +160,116 @@ ownership rather than changing product behavior. - The 22 CON mappings are explicitly unregistered/non-final; only the two proposed service PermissionIds remain identified as proposals. - Merge-intent validation passes for successor `WS-CON-001-01`. +- Every CodeRabbit contract finding is dispositioned without moving AUTH-owned + registration, evaluation, or activation into CON. +- Sixteen active future chunks name runnable focused commands, non-empty test + selection, repository coverage 78, focused coverage 90, and explicit pass + criteria. +- Optional CON-09B is a zero-file deferred proposal until a separately approved + replacement contract closes then-current ART/AUTH disclosure scope. + +## Evidence + +### Commands Run + +```bash +python3 scripts/check_markdown_links.py +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +python3 scripts/check_loop_memory_state.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py +python3 scripts/update_post_merge_memory.py validate-merge-intent --base-ref origin/main +git diff --check +``` -## Tests and checks +### Result Summary ```text -Markdown link check: PASS (59 changed Markdown files before evidence refresh) +Markdown link check: PASS (60 changed Markdown files before final evidence refresh) Stale Workstream wording: PASS Stale authorization documentation: PASS Stale artifact contracts: PASS at foundation phase Loop-memory state: PASS Agent gates: PASS (80 tests) -Current-main reconciliation diff check: PASS +External-review repair diff check: PASS Working-tree diff check: PASS -Current-main CON reconciliation backend/.github/scripts delta: none +External-review repair backend/.github/scripts delta: none Merge-intent schema-v2 validation: PASS Local roadmap workbook: not present, so no sheet-export check applies ``` -## Test delta and CI integrity +## Test Delta + +### Tests Added + +- None; this planning repair defines mandatory commands for future chunks. + +### Tests Modified + +- None. + +### Tests Removed Or Skipped + +- None. + +## CI And Gate Integrity + +- [x] No workflow weakening. +- [x] No lint/test/docstring gate weakening. +- [x] No coverage threshold weakening. +- [x] No package script weakening. +- [x] No unpinned new GitHub Action. +- [x] Checkout credential persistence remains unchanged; no workflow changed. + +### Integrity Detail PLAN3 changes no test or CI file, removes no assertion, skips no test, changes no threshold, and adds no bypass. Existing agent-gate coverage remains intact. -## Internal reviewer results +## Internal Reviewer Results + +Reviewed code SHA: pending final repair SHA + +Reviewed at: pending + +Reviewer run IDs: pending final re-review + +| Reviewer | Result | Blocking Findings | Notes | +|---|---:|---|---| +| Senior engineering | Pending | | Final exact-SHA repair review required. | +| QA/test | Pending | | Final exact-SHA repair review required. | +| Security/auth | Pending | | Final exact-SHA repair review required. | +| Product/ops | Pending | | Final exact-SHA repair review required. | +| Architecture | Pending | | Final exact-SHA repair review required. | +| CI integrity | Pending | | Final exact-SHA repair review required. | +| Docs | Pending | | Final exact-SHA repair review required. | +| Reuse/dedup | Pending | | Final exact-SHA repair review required. | +| Test delta | Pending | | Final exact-SHA repair review required. | The pre-external-review snapshot -`e968430b0c3b5f1432899c9aa31ef209b774eae0` passed every required track. The -CodeRabbit repair requires a new exact-SHA internal re-review before push; the -final evidence rebind will be recorded in -`WS-CON-001-PLAN3-internal-review-evidence.md`. +`e968430b0c3b5f1432899c9aa31ef209b774eae0` passed every required track. Final +repair results will be rebound in `WS-CON-001-PLAN3-internal-review-evidence.md`. + +## External Review + +External review response file: -## External review +- `.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md` -CodeRabbit posted five unresolved consolidated threads and one description -warning after PR #142 became ready for review. All five are addressed in -`WS-CON-001-PLAN3-external-review-response.md`: 16 active chunks gain exact -focused commands/pass criteria, AUTH requirements move to explicit upstream -prerequisites, and optional CON-09B is correctly reclassified as a deferred -proposal requiring a fresh contract. The PR body will be replaced with this -full trust-bundle structure after the reviewed repair is pushed. +| Source | Status | Notes | +|---|---:|---| +| CodeRabbit | Addressed locally; push pending | Five consolidated threads and the description warning are repaired. | +| GitHub checks | Pending rerun | Agent Gates and Backend passed before this repair. | -## Risks and follow-up +## Remaining Risks + +- Future test selectors must select at least one test and future migration + placeholders must be replaced by exact reviewed filenames. +- Optional CON-09B could drift unless its fresh contract repeats the separate + ART/AUTH/human approval gate. + +## Follow-Up Work - AUTH-13 must be refreshed to consume the merged CON-05A/task-composition manifest before task-claim registration or activation. @@ -185,7 +279,7 @@ full trust-bundle structure after the reviewed repair is pushed. REV/CON composition and AUTH gates merge. - CON-01 remains a separate explicit human start after this planning PR. -## Human review focus +## Human Review Focus Confirm the corrected task-claim ordering, exact prepared-handle contract, two-operation Review/FinalAcceptance/contribution transaction, canonical @@ -195,7 +289,13 @@ confirm that optional CON-09B remains non-executable until fresh approval and that the cumulative planning PR is acceptable as one coherent specification record. -## Human merge ownership +## Human Merge Ownership This bundle authorizes refreshing PR #142, not merging it. The user must explicitly approve PR #142 for merge. No successor chunk starts automatically. + +- [ ] I can explain what changed. +- [ ] I can explain why it changed. +- [ ] I know what could break. +- [ ] I accept the remaining risks. +- [ ] The user explicitly approved this specific PR for merge. From a69fad3a32ad47e3bd60a79cd75f5867eefc52b3 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 19:09:50 +0100 Subject: [PATCH 21/22] Close CON review repair findings --- ...-04B-hidden-contribution-policy-service.md | 4 +- ...CON-001-PLAN3-auth-pr140-reconciliation.md | 3 +- ...B-authorized-contribution-evidence-read.md | 3 +- .../WS-CON-001-PLAN3-pr-trust-bundle.md | 98 ++++++++++--------- 4 files changed, 58 insertions(+), 50 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md index b2668f5a..190a3ae7 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-04B-hidden-contribution-policy-service.md @@ -48,8 +48,8 @@ legacy fallback, dependency or CI weakening stable failure. No legacy authority executes. - [ ] Concurrent draft/publish/retire/selector/binding changes are deterministic. Production OpenAPI remains unchanged. -- [ ] The feature manifest is sufficient for later AUTH registration/evaluator - integration and activation without transferring any AUTH-owned work to CON. +- [ ] The feature manifest is sufficient for later AUTH evaluator integration + and activation without transferring any AUTH-owned work to CON. ## Verification and reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md index 1839bb3a..7dcad013 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-PLAN3-auth-pr140-reconciliation.md @@ -41,6 +41,7 @@ L0/L1 authorization, transaction, and release specification; P1. .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08A-outbound-compensation-delivery.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08B-inbound-fulfillment-callback.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-08R-bound-service-rate-control.md +.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-09B-authorized-contribution-evidence-read.md (deletion only; moved to deferred/) .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10A-contribution-award-product-reads.md .agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/chunks/WS-CON-001-10B-operations-reconciliation-rebuild.md @@ -127,7 +128,7 @@ python3 scripts/check_stale_authorization_docs.py python3 scripts/check_stale_artifact_contracts.py PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py git diff --check -test -z "$(git diff origin/main --name-only -- backend)" +git diff --quiet origin/main -- backend ``` ## Required reviewers diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md index 23653f9b..1c5bff8a 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/deferred/WS-CON-001-09B-authorized-contribution-evidence-read.md @@ -71,7 +71,8 @@ git diff --check if ! changed_files="$(git diff --name-only origin/main...HEAD)"; then exit 1 fi -if unexpected="$(printf '%s\n' "$changed_files" | rg -v '^\.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/|^\.agent-loop/merge-intents/WS-CON-001-09B\.json$')"; then +allowed_paths='^\.agent-loop/REVIEW_LOG\.md$|^\.agent-loop/merge-intents/WS-CON-001-09B\.json$|^\.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/(CHUNK_MAP\.md|STATUS\.md|(chunks|deferred)/WS-CON-001-09B-authorized-contribution-evidence-read\.md|reviews/WS-CON-001-09B-[^/]+\.md)$' +if unexpected="$(printf '%s\n' "$changed_files" | rg -v "$allowed_paths")"; then printf '%s\n' "$unexpected" exit 1 else diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md index 25b0bc56..0f625db9 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md @@ -109,10 +109,14 @@ and fence. ### Allowed Files Changed -- Seventeen WS-CON future chunk/deferred-proposal files. -- PLAN3 contract, STATUS, trust bundle, internal evidence, and external response - under the WS-CON initiative. -- Exactly one existing PLAN3 schema-v2 merge intent for the cumulative PR. +- Sixteen active WS-CON future chunk contracts. +- CON-09B moved from `chunks/` to `deferred/` as one non-executable proposal. +- PLAN3 contract, STATUS, RUNTIME_VERIFICATION, trust bundle, and external + response under the WS-CON initiative. +- Root `.agent-loop/REVIEW_LOG.md` for the required durable external-review + record. +- No merge-intent content changed; the cumulative PR still contains exactly one + existing PLAN3 schema-v2 merge intent. ### Files Outside Contract @@ -130,11 +134,13 @@ is one coherent specification initiative, its runtime boundary is empty, and the earlier planning snapshots retain their own review evidence. The user-owned deletion of the archival CON PDF is unstaged and excluded. -The PR #142 external-review repair updates 17 future chunk/deferred-proposal -files plus the PLAN3 scope, status, trust bundle, and external-response log. It -adds no runtime, AUTH/REV/ART-owned, workflow, dependency, migration, or test -change. The repair makes verification executable and preserves upstream AUTH -ownership rather than changing product behavior. +The PR #142 external-review repair has 24 changed-path entries relative to the +pre-review head: 16 active chunk contracts; the old/new paths for one CON-09B +move; PLAN3, STATUS, RUNTIME_VERIFICATION, trust bundle, external-response log, +and root REVIEW_LOG. It adds no runtime, AUTH/REV/ART-owned, workflow, +dependency, migration, test, or merge-intent content change. The repair makes +verification executable and preserves upstream AUTH ownership rather than +changing product behavior. ## Product Behavior @@ -145,29 +151,6 @@ This PR changes planning, lifecycle wording, future chunk contracts, and review evidence only. It adds no runtime route, model, migration, action, permission, grant, worker, provider call, or activation. -## Acceptance Criteria Proof - -- Runtime catalogue verified at 74 PermissionIds and 65 ActionIds: nine active, - 56 planned, no CON-specific ActionId, and no task-claim ActionId. -- Prepared-handle wording matches merged AUTH PR #140. -- The task and review activation sequences explicitly require hidden feature - behavior before AUTH-only activation. -- Reviewer and submitter contribution lineage remains Review and - FinalAcceptance respectively, inside the REV-owned transaction. -- FinalAcceptance names and CON operation ordering match merged REV PR #128. -- One shared release controller/fence, monotonic root ordinal, cutoff capture, - and same-generation at-or-below-cutoff completion match REV-12A. -- The 22 CON mappings are explicitly unregistered/non-final; only the two - proposed service PermissionIds remain identified as proposals. -- Merge-intent validation passes for successor `WS-CON-001-01`. -- Every CodeRabbit contract finding is dispositioned without moving AUTH-owned - registration, evaluation, or activation into CON. -- Sixteen active future chunks name runnable focused commands, non-empty test - selection, repository coverage 78, focused coverage 90, and explicit pass - criteria. -- Optional CON-09B is a zero-file deferred proposal until a separately approved - replacement contract closes then-current ART/AUTH disclosure scope. - ## Evidence ### Commands Run @@ -199,6 +182,29 @@ Merge-intent schema-v2 validation: PASS Local roadmap workbook: not present, so no sheet-export check applies ``` +## Acceptance Criteria Proof + +- Runtime catalogue verified at 74 PermissionIds and 65 ActionIds: nine active, + 56 planned, no CON-specific ActionId, and no task-claim ActionId. +- Prepared-handle wording matches merged AUTH PR #140. +- The task and review activation sequences explicitly require hidden feature + behavior before AUTH-only activation. +- Reviewer and submitter contribution lineage remains Review and + FinalAcceptance respectively, inside the REV-owned transaction. +- FinalAcceptance names and CON operation ordering match merged REV PR #128. +- One shared release controller/fence, monotonic root ordinal, cutoff capture, + and same-generation at-or-below-cutoff completion match REV-12A. +- The 22 CON mappings are explicitly unregistered/non-final; only the two + proposed service PermissionIds remain identified as proposals. +- Merge-intent validation passes for successor `WS-CON-001-01`. +- Every CodeRabbit contract finding is dispositioned without moving AUTH-owned + registration, evaluation, or activation into CON. +- Sixteen active future chunks name runnable focused commands, non-empty test + selection, repository coverage 78, focused coverage 90, and explicit pass + criteria. +- Optional CON-09B is a zero-file deferred proposal until a separately approved + replacement contract closes then-current ART/AUTH disclosure scope. + ## Test Delta ### Tests Added @@ -213,20 +219,6 @@ Local roadmap workbook: not present, so no sheet-export check applies - None. -## CI And Gate Integrity - -- [x] No workflow weakening. -- [x] No lint/test/docstring gate weakening. -- [x] No coverage threshold weakening. -- [x] No package script weakening. -- [x] No unpinned new GitHub Action. -- [x] Checkout credential persistence remains unchanged; no workflow changed. - -### Integrity Detail - -PLAN3 changes no test or CI file, removes no assertion, skips no test, changes -no threshold, and adds no bypass. Existing agent-gate coverage remains intact. - ## Internal Reviewer Results Reviewed code SHA: pending final repair SHA @@ -262,6 +254,20 @@ External review response file: | CodeRabbit | Addressed locally; push pending | Five consolidated threads and the description warning are repaired. | | GitHub checks | Pending rerun | Agent Gates and Backend passed before this repair. | +## CI And Gate Integrity + +- [x] No workflow weakening. +- [x] No lint/test/docstring gate weakening. +- [x] No coverage threshold weakening. +- [x] No package script weakening. +- [x] No unpinned new GitHub Action. +- [x] Checkout credential persistence remains unchanged; no workflow changed. + +### Integrity Detail + +PLAN3 changes no test or CI file, removes no assertion, skips no test, changes +no threshold, and adds no bypass. Existing agent-gate coverage remains intact. + ## Remaining Risks - Future test selectors must select at least one test and future migration From 4b13c3ee28ecddd7c92be70ad2059c130604f9d1 Mon Sep 17 00:00:00 2001 From: Abiorh001 Date: Fri, 17 Jul 2026 19:20:16 +0100 Subject: [PATCH 22/22] Bind CON external review repair evidence --- .../STATUS.md | 14 ++-- ...S-CON-001-PLAN-internal-review-evidence.md | 17 +++-- ...-CON-001-PLAN2-internal-review-evidence.md | 10 ++- ...-CON-001-PLAN3-external-review-response.md | 34 ++++++--- ...-CON-001-PLAN3-internal-review-evidence.md | 75 +++++++++++++------ .../WS-CON-001-PLAN3-pr-trust-bundle.md | 38 +++++----- 6 files changed, 118 insertions(+), 70 deletions(-) diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md index 44744bca..6338a39d 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/STATUS.md @@ -12,11 +12,11 @@ decision input with two ordered operations, and adopts REV-12A's exact obligation-writer/ordinal/cutoff hooks. PLAN2's human-approved v0.1 `Review(accept) -> FinalAcceptance -> accepted_submission` boundary remains intact. Runtime code is unchanged. -CodeRabbit then opened five consolidated contract-quality threads. PLAN3 is -temporarily reopened only to add executable verification gates, restore exact -AUTH prerequisite ownership, reclassify optional CON-09B as a deferred proposal, -and record the external response. A new exact-SHA internal review is required -before the repair is pushed. +CodeRabbit then opened five consolidated contract-quality threads. PLAN3's +planning-only repair added executable verification gates, restored exact AUTH +prerequisite ownership, moved optional CON-09B to a deferred proposal, aligned +the PR trust bundle, and recorded the external response/review log. All required +tracks passed exact SHA `a69fad3a32ad47e3bd60a79cd75f5867eefc52b3`. The prior plan is superseded where it used the older policy aggregate, made ART evidence mandatory, described service action rows as persisted assignments, allowed partial activation-custody transfer, or let outbox dispatch imply @@ -55,13 +55,13 @@ feature-handler authority. ## Active chunk No implementation chunk is active or starts automatically. PLAN3 external -review repair is active only; it does not authorize merge or CON-01. +review repair is complete; it does not authorize merge or CON-01. | Chunk | Status | Notes | |---|---|---| | `WS-CON-001-PLAN` | Complete; superseded baseline | Based on PR #139 / `5d353b6`; reviewed content `c4242e0` | | `WS-CON-001-PLAN2` | Complete; unpublished | FinalAcceptance is REV-owned; CON trigger changes only; all required internal tracks pass | -| `WS-CON-001-PLAN3` | External review repair in progress | CodeRabbit contract gates/AUTH scope/09B classification; exact-SHA re-review required | +| `WS-CON-001-PLAN3` | Complete; externally repaired and internally reviewed | CodeRabbit gates/AUTH scope/09B/trust repairs pass at `a69fad3` | | `WS-CON-001-01` through `08B`, `10A` through `11` | Proposed | Separate explicit start required after PLAN3 and upstream merge refresh | | `WS-CON-001-09A/09B` | Deferred optional | Separate approval and fresh ART/AUTH review required | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md index 84cc3e8d..4f72b8c1 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN-internal-review-evidence.md @@ -2,27 +2,28 @@ ## 2026-07-17 AUTH And REV Current-Main Provenance Rebind -Reviewed code SHA: e968430b0c3b5f1432899c9aa31ef209b774eae0 -Reviewed at: 2026-07-17T15:17:58Z -Reviewer run IDs: auth08_arch_review/final-e968430, auth08_qa_product_review/final-e968430, auth08_security_review/final-e968430 +Reviewed code SHA: a69fad3a32ad47e3bd60a79cd75f5867eefc52b3 +Reviewed at: 2026-07-17T18:14:54Z +Reviewer run IDs: auth08_arch_review/final-a69fad3, auth08_qa_product_review/final-a69fad3, auth08_security_review/final-a69fad3 This provenance-only addendum binds the earlier substantive PLAN review chain to the final reviewed cumulative planning snapshot. PLAN3 authorizes this evidence rebind because the PR-level gate validates every evidence file added by the branch. It changes no historical finding or product conclusion. The exact-SHA re-review confirmed that the merged AUTH runtime and REV plan, exact -FinalAcceptance/CON participant boundary, joint release-control contract, and -evidence-schema update introduce no remaining blocker. +FinalAcceptance/CON participant boundary, joint release-control contract, +CodeRabbit contract repairs, and evidence-schema update introduce no remaining +blocker. | Reviewer | Result | Blocking findings | Notes | |---|---|---|---| -| senior engineering | PASS AFTER FIXES | None | The cumulative specification remains coherent after the PLAN3 title and duplicate allowed-file repairs. | +| senior engineering | PASS AFTER FIXES | None | The cumulative specification remains coherent after current-main and external-review repairs. | | qa/test | PASS | None | Exact two-operation ordering, branch effects, rollback coverage, and deterministic gates pass. | | security/auth | PASS | None | Current AUTH catalogue facts, prepared semantics, and AUTH-only identifier/evaluator/activation ownership pass. | | product/ops | PASS | None | Review outcomes, FinalAcceptance lineage, contribution atomicity, release cutoff, and no-adjudication boundary pass. | -| architecture | PASS AFTER FIXES | None | Ownership, transaction, rollout, joint release control, and same-initiative successor boundaries remain coherent. | +| architecture | PASS AFTER FIXES | None | Ownership, executable chunk gates, transaction, rollout, joint release control, and successor boundaries remain coherent. | | ci integrity | PASS | None | The rebind changes evidence only; no CI, runtime, test, script, workflow, dependency, or threshold changes. | -| docs | PASS AFTER FIXES | None | Runtime-versus-planned identifiers, merged REV dependencies, contract title, and cumulative evidence provenance are explicit. | +| docs | PASS AFTER FIXES | None | Runtime-versus-planned identifiers, merged REV dependencies, CodeRabbit dispositions, and cumulative evidence provenance are explicit. | | reuse/dedup | PASS | None | No duplicate service, evaluator, registry, or transaction abstraction is introduced. | | test delta | PASS | None | No test delta; all 80 agent-gate tests pass. | diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md index 8de8a4e3..4a873134 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN2-internal-review-evidence.md @@ -2,16 +2,18 @@ ## AUTH And REV current-main provenance rebind -Reviewed code SHA: e968430b0c3b5f1432899c9aa31ef209b774eae0 -Reviewed at: 2026-07-17T15:17:58Z -Reviewer run IDs: auth08_arch_review/final-e968430, auth08_qa_product_review/final-e968430, auth08_security_review/final-e968430 +Reviewed code SHA: a69fad3a32ad47e3bd60a79cd75f5867eefc52b3 +Reviewed at: 2026-07-17T18:14:54Z +Reviewer run IDs: auth08_arch_review/final-a69fad3, auth08_qa_product_review/final-a69fad3, auth08_security_review/final-a69fad3 This provenance-only addendum binds the reviewed FinalAcceptance reconciliation to the final cumulative planning snapshot. It changes no PLAN2 lifecycle fact. The exact-SHA re-review confirms that PLAN3 preserves REV-owned FinalAcceptance, CON flush-only participation, all three review outcomes, and the no-adjudication boundary while adopting merged REV's exact two-operation -ordering and joint release-control contract. +ordering and joint release-control contract. The external-review repair changes +only future chunk executability, AUTH prerequisite placement, and deferred +proposal classification; it does not alter PLAN2 lifecycle facts. | Reviewer | Result | Blocking findings | Notes | |---|---|---|---| diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md index 9173b4db..8fcaeb2c 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-external-review-response.md @@ -22,12 +22,12 @@ triaged on 2026-07-17. 4. `PRRT_kwDOSwL_U86R1pGE`: added deterministic runnable verification commands, coverage targets, and explicit pass criteria to CON-04B, 05A, 05B, 06, 07, 08A, 08B, and 08R. -5. `PRRT_kwDOSwL_U86R1pGI`: corrected CON-09B from an incomplete “Chunk - Contract” to a non-executable “Deferred Proposal.” It now has prospective - risk, zero current allowed files, explicit prohibitions, promotion criteria, - planning-only promotion checks, required reviewers, and a mandatory fresh - replacement contract after separate human/ART/AUTH approval. This preserves - the intentional deferral instead of freezing stale implementation scope. +5. `PRRT_kwDOSwL_U86R1pGI`: moved CON-09B out of executable `chunks/` and + corrected it from an incomplete “Chunk Contract” to a non-executable + “Deferred Proposal.” It now has prospective risk, zero current allowed + files, explicit prohibitions, exact-whitelist promotion checks, required + reviewers, and a mandatory fresh replacement contract after separate + human/ART/AUTH approval. 6. CodeRabbit description warning: the PR body is replaced with the complete PLAN3 trust-bundle structure after the reviewed repair is pushed. @@ -45,10 +45,22 @@ remain unchanged. ## Commands rerun -Pending final candidate: Markdown links, stale Workstream wording, stale -authorization docs, stale artifact contracts, loop-memory state, agent gates, -merge-intent validation, internal-review evidence gate, diff integrity, and -all required internal reviewer tracks. +```text +Markdown links: PASS (61 changed Markdown files before evidence refresh) +Stale Workstream wording: PASS +Stale authorization docs: PASS +Stale artifact contracts: PASS at foundation phase +Loop-memory state: PASS +Agent gates: PASS (80 tests) +Merge-intent validation: PASS +Bash syntax for every new verification block: PASS +Diff integrity: PASS +Repair backend/.github/scripts delta: none +Required exact-SHA internal tracks: PASS at a69fad3a32ad47e3bd60a79cd75f5867eefc52b3 +``` + +The internal-review evidence gate is run in a clean worktree after this +provenance-only rebind commit; it must pass before push. ## Remaining risks @@ -58,3 +70,5 @@ all required internal reviewer tracks. selection is a failure, not a pass. - CON-09B remains non-executable until a fresh replacement contract is separately approved and reviewed against then-current ART/AUTH boundaries. +- GitHub threads remain open until the reviewed repair is pushed; they are + resolved only after the remote diff contains these fixes. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md index b4715edf..5082aaf0 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-internal-review-evidence.md @@ -1,18 +1,18 @@ # WS-CON-001-PLAN3 Internal Review Evidence -Reviewed code SHA: e968430b0c3b5f1432899c9aa31ef209b774eae0 -Reviewed at: 2026-07-17T15:17:58Z -Reviewer run IDs: auth08_arch_review/final-e968430, auth08_qa_product_review/final-e968430, auth08_security_review/final-e968430 +Reviewed code SHA: a69fad3a32ad47e3bd60a79cd75f5867eefc52b3 +Reviewed at: 2026-07-17T18:14:54Z +Reviewer run IDs: auth08_arch_review/final-a69fad3, auth08_qa_product_review/final-a69fad3, auth08_security_review/final-a69fad3 ## Reviewed boundary The exact reviewed snapshot reconciles CON planning with merged AUTH PR #140, AUTH-09A runtime, and REV PR #128 at trusted `main` `0302bcf`. It authorizes the provenance-only rebind of the older PLAN/PLAN2 evidence required by the -cumulative PR gate. The current-main reconciliation changes 22 -planning/merge-intent files with 429 insertions and 178 deletions and changes no -backend, migration, runtime catalogue, test, script, workflow, or dependency -file. +cumulative PR gate. After that reconciliation, the CodeRabbit repair changes 24 +planning-path entries with 713 insertions and 120 deletions relative to +`adf5cc1`. It changes no backend, migration, runtime catalogue, test, script, +workflow, dependency, or merge-intent content. The reviewed boundary establishes: @@ -41,21 +41,27 @@ The reviewed boundary establishes: transaction owner, no separate FinalAcceptance action/API, no adjudication dependency, and no independent CON commit; and - one schema-v2 merge intent naming `WS-CON-001-01` as an explicit-start - same-initiative successor. + same-initiative successor; +- executable, fail-closed verification commands and pass criteria for 16 active + future chunks, with 78 percent repository and 90 percent focused coverage; +- AUTH registration/context/custody/prepared-port inputs as merged upstream + prerequisites, never CON-owned acceptance work; and +- optional CON-09B outside `chunks/` as a zero-file deferred proposal requiring + separate ART/AUTH/human approval and a fresh reviewed replacement contract. ## Reviewer results | Reviewer | Result | Blocking findings | Notes | |---|---|---|---| -| senior engineering | PASS AFTER FIXES | None | The 22-file reconciliation is coherent and bounded after its title and duplicate allowed-file repairs. | -| qa/test | PASS | None | All three lifecycle outcomes, exact source cardinality, rollback stages, REV interleaving, and deterministic gates pass. | -| security/auth | PASS | None | Current catalogue facts, prepared semantics, same-decision lineage, and AUTH-only identifier/evaluator/activation ownership pass. | -| product/ops | PASS | None | FinalAcceptance, contribution, compensation, fulfillment cutoff, and no-adjudication boundaries remain correct. | -| architecture | PASS AFTER FIXES | None | Two-operation sequencing, single ownership, joint release control, and same-initiative successor all pass after metadata repairs. | -| ci integrity | PASS | None | PLAN3 changes no CI, workflow, threshold, runner, script, dependency, test, or runtime file and adds no bypass. | -| docs | PASS AFTER FIXES | None | Runtime versus planned identifiers, merged AUTH/REV provenance, canonical names, and evidence are explicit after contract metadata repair. | +| senior engineering | PASS AFTER FIXES | None | The 24-path external repair is cohesive, bounded, executable, and planning-only after all review findings. | +| qa/test | PASS AFTER FIXES | None | Focused selectors, migrations, rollback/race proof, coverage, 08B scope, and deferred 09B semantics pass. | +| security/auth | PASS AFTER FIXES | None | AUTH prerequisites, registration order, fail-closed commands, 09B whitelist, and template CI controls pass. | +| product/ops | PASS AFTER FIXES | None | FinalAcceptance, contribution, compensation, fulfillment cutoff, and no-adjudication behavior remain unchanged. | +| architecture | PASS AFTER FIXES | None | Two-operation sequencing, upstream AUTH ownership, executable gates, 09B deferral, and release control pass. | +| ci integrity | PASS AFTER FIXES | None | No CI/workflow/test/runtime delta or bypass; repository 78 and focused 90 percent floors remain mandatory. | +| docs | PASS AFTER FIXES | None | PR-template structure, external response, review log, allowed scope, canonical names, and provenance are explicit. | | reuse/dedup | PASS | None | No duplicate runtime abstraction or alternative authorization path is introduced; common AUTH/REV contracts are referenced. | -| test delta | PASS | None | No tests changed or were required for the planning-only reconciliation; 80 existing agent-gate tests pass. | +| test delta | PASS | None | No tests changed; 80 existing agent-gate tests and all static gates pass. | ## Findings and repairs @@ -86,6 +92,31 @@ contract title now matches the AUTH-and-REV current-main merge intent and the duplicate row is removed. All required reviewers re-ran against exact SHA `e968430b0c3b5f1432899c9aa31ef209b774eae0`. +### Resolved external-review findings + +CodeRabbit's five consolidated threads and description warning were valid at +the contract/process level. The repair: + +- adds exact focused commands, non-empty selection, coverage floors, and pass + criteria to all 16 affected active chunks; +- moves AUTH registration/context/custody/prepared-port requirements to + upstream prerequisites while retaining registration -> hidden behavior -> + evaluator/activation ordering; +- moves CON-09B from `chunks/` to `deferred/`, gives it no current allowed + implementation files, and fail-closes promotion to an exact planning-path + whitelist; +- aligns CON-08B allowed tests, runtime-verification row, selector, and Ruff + targets; +- replaces fail-open Git/Ripgrep absence checks with status-sensitive checks; + and +- mirrors the repository PR template and records the repair in the external + response and root review log. + +Initial internal re-review found and repaired the remaining 04B ordering, +09B whitelist/location, 08B scope, review-log, allowlist, shell-failure, and +trust-template defects. All required tracks then passed exact SHA +`a69fad3a32ad47e3bd60a79cd75f5867eefc52b3`. + ### Confirmed non-findings - A failed same-session/action substitution does not consume an otherwise valid @@ -107,7 +138,7 @@ duplicate row is removed. All required reviewers re-ran against exact SHA ```text python3 scripts/check_markdown_links.py - PASS - 59 changed Markdown files before evidence refresh + PASS - 61 changed Markdown files before evidence refresh python3 scripts/check_stale_workstream_wording.py PASS python3 scripts/check_stale_authorization_docs.py @@ -118,11 +149,11 @@ python3 scripts/check_loop_memory_state.py PASS PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_agent_gates.py PASS - 80 tests -git diff --check 5e1311c^..e968430 +git diff --check adf5cc1..a69fad3 PASS git diff --check PASS -current-main CON reconciliation backend/.github/scripts delta +external-review repair backend/.github/scripts delta none python3 scripts/update_post_merge_memory.py validate-merge-intent --base-ref origin/main PASS - WS-CON-001-PLAN3 @@ -130,8 +161,8 @@ python3 scripts/update_post_merge_memory.py validate-merge-intent --base-ref ori The circuit-breaker passed with a documentation-only size exception. The full branch is large because it contains the original reference transcription and -durable planning/review history, but the current-main refresh is one bounded -22-file planning correction, has no runtime boundary, and required no split. +durable planning/review history, but the external repair is one bounded 24-path +planning correction, has no runtime boundary, and required no split. Valid findings addressed: yes @@ -139,6 +170,6 @@ Open sub-agent sessions: none ## Stop -PLAN3 is reviewed for draft PR #142 refresh. This evidence authorizes no merge +PLAN3 is reviewed for PR #142 refresh. This evidence authorizes no merge or CON-01 start. The user retains the human checkpoint and must explicitly approve PR #142 before merge. diff --git a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md index 0f625db9..f222ede8 100644 --- a/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md +++ b/.agent-loop/initiatives/WS-CON-001-contribution-compensation-boundary/reviews/WS-CON-001-PLAN3-pr-trust-bundle.md @@ -124,9 +124,9 @@ and fence. The current-main reconciliation changes 22 planning/merge-intent files with 429 insertions and 178 deletions. It changes no backend, migration, test, workflow, -script, dependency, runtime catalogue, or active product document. Before this -evidence refresh, the full planning branch is 67 files with 8,235 insertions and -90 deletions against `origin/main`; most of that delta is the original reference +script, dependency, runtime catalogue, or active product document. Before the +final evidence rebind, the full planning branch is 69 files with 8,874 +insertions and 90 deletions against `origin/main`; most of that delta is the original reference transcription and durable planning/review record. The circuit-breaker passed with a documentation-only size exception: the branch @@ -221,27 +221,27 @@ Local roadmap workbook: not present, so no sheet-export check applies ## Internal Reviewer Results -Reviewed code SHA: pending final repair SHA +Reviewed code SHA: a69fad3a32ad47e3bd60a79cd75f5867eefc52b3 -Reviewed at: pending +Reviewed at: 2026-07-17T18:14:54Z -Reviewer run IDs: pending final re-review +Reviewer run IDs: auth08_arch_review/final-a69fad3, auth08_qa_product_review/final-a69fad3, auth08_security_review/final-a69fad3 | Reviewer | Result | Blocking Findings | Notes | |---|---:|---|---| -| Senior engineering | Pending | | Final exact-SHA repair review required. | -| QA/test | Pending | | Final exact-SHA repair review required. | -| Security/auth | Pending | | Final exact-SHA repair review required. | -| Product/ops | Pending | | Final exact-SHA repair review required. | -| Architecture | Pending | | Final exact-SHA repair review required. | -| CI integrity | Pending | | Final exact-SHA repair review required. | -| Docs | Pending | | Final exact-SHA repair review required. | -| Reuse/dedup | Pending | | Final exact-SHA repair review required. | -| Test delta | Pending | | Final exact-SHA repair review required. | - -The pre-external-review snapshot -`e968430b0c3b5f1432899c9aa31ef209b774eae0` passed every required track. Final -repair results will be rebound in `WS-CON-001-PLAN3-internal-review-evidence.md`. +| Senior engineering | PASS AFTER FIXES | None | Scope, executable gates, deferred proposal, and durable review record pass. | +| QA/test | PASS AFTER FIXES | None | Selectors, migrations, rollback/races, 08B scope, and coverage criteria pass. | +| Security/auth | PASS AFTER FIXES | None | AUTH ownership/order, fail-closed checks, 09B whitelist, and trust controls pass. | +| Product/ops | PASS AFTER FIXES | None | No contribution, compensation, review, or release behavior changed. | +| Architecture | PASS AFTER FIXES | None | Boundaries and future chunk ordering remain coherent. | +| CI integrity | PASS AFTER FIXES | None | No CI/test/runtime delta or threshold/bypass weakening. | +| Docs | PASS AFTER FIXES | None | PR template, external response, scope, review log, and provenance pass. | +| Reuse/dedup | PASS | None | Existing runtime-verification and AUTH/REV contracts are reused. | +| Test delta | PASS | None | No tests changed; 80 agent-gate tests pass. | + +The final repair results are rebound in +`WS-CON-001-PLAN3-internal-review-evidence.md` without changing reviewed +planning content after exact-SHA review. ## External Review