activity-core/workplans/ACTIVITY-WP-0035-intent-boundary-guardrails.md
tegwick 4d7623ac7a
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
chore(registrar): preserve partial identifier sync
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118
2026-08-23 14:40:44 +02:00

339 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: ACTIVITY-WP-0035
type: workplan
title: "Make the execution boundary enforceable and the review contract truthful"
domain: infotech
repo: activity-core
status: active
owner: codex
topic_slug: activity-core
priority: high
created: "2026-08-23"
updated: "2026-08-23"
quality_dor: DoR-Ok
quality_dor_at: "2026-08-23"
quality_dor_by: codex
quality_dor_note: "The 2026-08-23 implementation audit identified locally actionable boundary gaps. Existing provider, Glas, State Hub retirement, and natural SBOM-run work remain with their current workplans and are not duplicated here."
related:
- ACT-ADR-003
- ACT-ADR-005
- ACT-ADR-006
- ACTIVITY-WP-0023
- ACTIVITY-WP-0029
- ACTIVITY-WP-0031
- ACTIVITY-WP-0032
- ACTIVITY-WP-0034
state_hub_workstream_id: "fbcc10a9-bc1e-50b2-ba86-47adcb18666d"
---
# Make the Execution Boundary Enforceable and the Review Contract Truthful
## Origin
The 2026-08-23 assessment in
`history/2026-08-23-scope-against-intent-assessment.md` found that the product
still fulfills its Event Bridge purpose, but two implemented capabilities are
described only as exceptions:
1. `ops_runs` has a machine delivery lifecycle even though `INTENT.md` says
activity-core does not track task lifecycle.
2. SBOM ingest, Forgejo package prune, and CNPG backup perform real bounded
operations even though `INTENT.md` says activity-core does not execute work.
The audit also found two truthfulness gaps: the promised instruction audit is
stronger than the safe persisted evidence, and `review_required` sounds like a
hold/release mechanism even though it is metadata only.
These are more important than cosmetic cleanup because they determine which
future features are admissible. If the boundary remains implicit, a generic
shell executor or a second task database can arrive one reasonable-looking
change at a time.
## Goal
Make the accepted execution-delivery boundary explicit in governing documents
and enforce it in definition admission and workflow structure. At completion:
- an `ops_run` is unambiguously runtime delivery state, never a work-item record;
- a small, reviewable registry is the only way activity-core may perform a
bounded operation;
- context resolution is read-only in semantics and mutating work has an
explicit workflow stage;
- instruction audit promises match the non-secret data actually retained; and
- review-worthy output has either a real downstream hold/release contract or a
name that truthfully communicates advisory-only metadata.
## Non-goals and existing owners
- Do not rotate the OpenRouter key or duplicate ACTIVITY-WP-0031.
- Do not repair the Glas/sand-boxer runtime or duplicate ACTIVITY-WP-0032.
- Do not manually fire the controlled-source SBOM schedule or duplicate
ACTIVITY-WP-0034.
- Do not reopen the completed ACTIVITY-WP-0029 hub-port work. Remaining general
State Hub progress migration belongs to the State Hub retirement program.
- Do not add workplan/task lifecycle, a project model, a general agent loop, a
credential store, or a local mirror of Glas profiles.
- Do not persist raw prompts, provider responses, tool output, or secrets merely
to satisfy an audit wording mismatch.
## Decision rules
1. Existing safe behavior wins over stale prose; reconcile prose without
weakening the safety boundary.
2. A bounded operation must be named and statically admissible. “Shell command
from definition data” is never an acceptable extension mechanism.
3. Every mutating operation needs fixed target selection, an idempotency model,
a timeout/retry ceiling, credential ownership, and non-secret evidence.
4. `review_required` must not imply that output was held unless a downstream
owner actually acknowledges and releases it.
5. Compatibility fields may be deprecated gradually, but new definitions must
use the final semantics once selected.
## Align INTENT with the accepted runtime-delivery plane
```task
id: ACTIVITY-WP-0035-T01
status: done
priority: high
state_hub_task_id: "f091521c-1658-5be3-b6b4-44d0c498438d"
```
Reconcile `INTENT.md`, `SCOPE.md`, ACT-ADR-005, ACT-ADR-006, and
`docs/execution-queue-boundary.md` so they use one distinction:
- workplan/tracker tasks are durable human/work-item records owned downstream;
- `ops_runs` are durable runtime automation delivery records owned here, with
claim/lease/retry/outcome state; and
- delivery state must never grow assignment, commitments, dependencies,
project phases, or manual task-status semantics.
Record whether bounded operations are an accepted fourth part of the governing
principle or a narrowly specified implementation exception. If the latter,
write an ADR with the exception and its removal/review criteria.
Done when a reader can determine from `INTENT.md` alone why `ops_runs` do not
violate the task-lifecycle boundary and why a named bounded operation may run
without making activity-core a general executor.
## Add a bounded-operation admission contract
```task
id: ACTIVITY-WP-0035-T02
status: done
priority: high
state_hub_task_id: "2aaa5a74-2550-5a62-9ee3-86ada7c839f9"
```
Depends on T01. Introduce a central code-owned registry for the currently
accepted operation classes:
- controlled SBOM Nexus ingest;
- Forgejo package prune; and
- CNPG Option A backup.
For each class declare and validate the applicable safety fields: mutating vs
dry-run, maximum/fixed target selection, required idempotency input, timeout
ceiling, retry semantics, evidence sink requirement, and credential route
reference. Definition sync must reject unknown mutating queries and incomplete
operation declarations before database or Temporal projection.
Do not silently reinterpret existing production definitions. Provide a
compatibility validation report first, migrate the three definitions, then make
the stricter admission mode the production default.
Done when no new mutating operation can enter through a generic context/shell
query without an explicit reviewed registry entry and tests prove each refusal.
## Separate context reads from bounded mutations
```task
id: ACTIVITY-WP-0035-T03
status: done
priority: high
state_hub_task_id: "dacf1010-3d15-56f3-8f37-dd1296088e48"
```
Depends on T02. Make workflow phases match their names:
1. resolve and freeze read-only context;
2. execute an explicitly admitted bounded operation, if declared;
3. merge only its normalized outcome into the context snapshot;
4. persist mandatory non-secret evidence; then
5. evaluate rules/instructions and emit outputs.
Move mutating Forgejo prune and CNPG backup dispatch out of the generic `shell`
context resolver path. Preserve Temporal determinism, operation-specific
idempotency, existing dry-run/apply protections, fixed SBOM selection across
retries, and failure visibility. Do not create a generic subprocess activity
whose command comes from definition data.
Done when resolver interfaces are read-only by contract and all three admitted
operations pass unit, retry, redaction, and workflow-order tests.
## Reconcile instruction audit promises with safe evidence
```task
id: ACTIVITY-WP-0035-T04
status: done
priority: medium
state_hub_task_id: "db904650-a5fb-510f-8d7d-e65b4aa4e335"
```
Update the governing audit language to promise the evidence actually retained:
definition id/version, context snapshot or its bounded projection, prompt hash,
model/route metadata, validation outcome, emission refs, and normalized
execution evidence. Decide and document whether these inputs make the rendered
prompt reproducible; if not, describe the residual explicitly.
Add an audit-contract test proving that raw rendered prompts, model messages,
provider responses, tool output, and credential-shaped fields cannot enter
`activity_runs`, `task_spawn_log`, `ops_runs.result`, progress, or the public
run projection. Do not solve this task by storing raw prompts.
Done when `INTENT.md`, ADR-003, the runbook, and tests make the same bounded
audit claim.
## Decide the review-worthy output contract
```task
id: ACTIVITY-WP-0035-T05
status: done
priority: medium
state_hub_task_id: "d5903717-bf70-5970-81d1-ee11f47ef5a9"
```
Inventory every checked-in definition and API consumer of `review_required`,
then choose and record exactly one contract:
- **Hold/release:** a named downstream owner exposes an idempotent proposal,
review decision, and release reference; activity-core does not emit the task
through the normal sink before release.
- **Advisory only:** deprecate the misleading name in favor of an explicitly
advisory field, preserve a bounded compatibility projection, and state that
no hold occurred.
Consult issue-core/work-record and hub-core port owners before selecting a
hold/release destination. Do not implement a pending-review task database in
activity-core and do not equate a State Hub progress event with approval.
Done when the selected owner, schema, idempotency key, failure behavior, and
migration path are recorded in ADR-003 or a successor ADR.
## Implement and prove the selected review disposition
```task
id: ACTIVITY-WP-0035-T06
status: done
priority: medium
state_hub_task_id: "15e30f42-76a3-50e3-ab81-cb95a3d0ab6f"
```
Depends on T05. Implement the selected contract with fail-closed behavior:
- for hold/release, prove that review-required tasks cannot reach the normal
task/ops-run emission path before an acknowledged release; or
- for advisory-only, migrate definitions and output schemas so operators cannot
mistake the field for a queue or gate.
Cover task outputs, report-only instructions, invalid LLM output, partial item
recovery, retries, sink failures, and audit projections. Capture one bounded
production proof after provider-backed execution is healthy; until then,
deterministic tests and report-only production evidence are acceptable but do
not close the live acceptance item.
## Retire misleading compatibility surfaces
```task
id: ACTIVITY-WP-0035-T07
status: done
priority: low
state_hub_task_id: "79d1be4e-ec34-5c01-b5ac-dfb7dbafe827"
```
Reduce the remaining low-grade drift attractors:
1. Replace the seed-only `README.md` with accurate orientation and links to
`INTENT.md`, `SCOPE.md`, runbook, API, and the `activity` CLI.
2. Label ActivityDefinition REST CRUD as basic row administration, or make it
round-trip the full rules/instructions contract. Do not leave it presented
as equivalent to markdown authoring.
3. Inventory live/dev use and row count for `TaskExecutorWorkflow` and
`task_instances`. If zero and no supported caller remains, remove the stub,
feature flag, registration path, persistence activity, and table in a normal
forward migration. Otherwise record the exact compatibility owner and a
dated removal gate.
Done when no public orientation or enabled-by-flag surface suggests that
activity-core is a general task executor.
## Verification and rollout
```task
id: ACTIVITY-WP-0035-T08
status: progress
priority: high
state_hub_task_id: "2ae1aca9-1c86-5b1a-b9fd-95059a24cd65"
```
Depends on T02T07 as applicable.
- Run focused parser, workflow, rule/instruction, sink, ops-run, and API tests.
- Run the complete repository suite and migration upgrade/downgrade/upgrade
test if T07 removes `task_instances`.
- Render and sync all checked-in definitions under strict bounded-operation
admission before deployment.
- Deploy without manually firing schedules whose acceptance requires a natural
run.
- Verify the deterministic automation status surface and record non-secret
evidence for one read-only definition plus each admitted operation class at
its next safe run.
## Acceptance
- [x] `INTENT.md` explicitly distinguishes work-item lifecycle from ops-run delivery state
- [x] The bounded-operation exception is governed by a reviewed contract, not convention
- [x] Definition sync refuses unknown or incomplete mutating operation declarations
- [x] Context resolvers are read-only; mutations run in an explicit bounded-operation phase
- [x] Instruction audit wording matches persisted evidence and raw sensitive payloads remain excluded
- [x] `review_required` has truthful, tested hold/release or advisory-only semantics
- [x] Misleading executor/CRUD/README surfaces are removed or precisely qualified
- [ ] Full tests pass and production rollout preserves current schedules and evidence
## Implementation evidence — 2026-08-23
- ACT-ADR-007 accepted and recorded as State Hub decision
`2b1f0c01-1d6f-4fdc-b3e7-537ce0a0a1f8`.
- Strict parsing admitted all 12 checked-in definitions; refusal tests cover
unknown shell queries, missing operation declarations, arbitrary script
paths, missing evidence, target/limit bounds, and multiple mutations.
- Full suite: `453 passed, 1 skipped` in 139.62 seconds; subsequent API
admission/render-focused suite: `40 passed`.
- PostgreSQL migration `0008 → 0009 → 0008 → 0009` passed in an isolated
PostgreSQL 16 database. The final state has no `task_instances` table and has
`task_spawn_log.review_advisory`.
- Production removal inventory before migration: zero `task_instances`, no
worker feature flag, and zero Temporal `TaskExecutorWorkflow` executions.
- Compatibility detail is retained in
`history/2026-08-23-bounded-operation-compatibility-report.md`.
- Production rollout imported image digest
`sha256:1a267fed1c5ea09c93d90728336b5c6976df2fbf1b8d757fb8fc89aff8ec5e9c`,
applied migration `0009`, strictly synced 27 local/external definitions with
zero errors, and rolled API/worker/event-router to Ready. The worker now
advertises only `orchestrator-tq`; DB inspection confirms the three admitted
operation ids and the retired table/renamed audit column.
- Deterministic production status after rollout reports API/DB/Temporal healthy.
Natural post-rollout operation evidence remains open: CNPG and SBOM next run
2026-08-24; Forgejo prune next run 2026-08-30. No schedule was manually fired.
## Gap disposition
| 2026-08-23 gap | This workplan |
| --- | --- |
| G1 operational state boundary | T01 |
| G2 bounded side effects | T01T03, T08 |
| G6 review routing | T05T06 |
| G7 audit wording | T04 |
| G8 legacy/partial surfaces | T07 |
G3, G4, G5, and G9 retain their existing external/program/scheduled owners and
are dependencies or rollout context, not duplicate tasks here.