Enforce bounded operation guardrails
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 21s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a028de-e2c8-7732-8521-46a7fc5db82f
This commit is contained in:
tegwick 2026-08-23 12:31:13 +02:00
parent c384f60530
commit 26934e25b9
51 changed files with 1843 additions and 472 deletions

View file

@ -185,7 +185,7 @@ trusted_fields: # REQUIRED — explicit allowlist of payload
- event.attributes.domain
- event.attributes.tags
model: claude-sonnet-4-6
review_required: false # true | false — curator gate for output
review_advisory: false # true | false — advisory evidence, not a gate
prompt: |
{prompt template — only trusted_fields may be interpolated}
output_schema: {path to JSON schema file}
@ -218,23 +218,19 @@ created from unvalidated output**.
Structured output mode (tool_use / JSON mode) is used where the model supports
it. The output schema must define `List[TaskSpec]` or a compatible envelope.
#### `review_required: true`
#### `review_advisory: true`
When set today, the instruction's task/report output is marked with
`review_required=true` in activity-core audit metadata. For report-producing
instructions, this flag is also persisted in configured report sinks so an
operator can distinguish validated-but-review-worthy output from routine
output.
ACTIVITY-WP-0035 selected advisory-only semantics because no downstream owner
currently exposes an acknowledged proposal/decision/release contract. The
instruction's task/report evidence is marked `review_advisory=true` and
`review_gate_applied=false` so an operator can distinguish review-worthy output
without interpreting it as held for approval.
activity-core does **not** currently route proposed tasks to a pending review
queue. That queue must be owned by issue-core, because issue-core owns task
lifecycle state. Until issue-core exposes a review contract, `review_required`
is metadata only; it must not be treated as evidence that live task creation was
held for approval.
Future issue-core review integration may use the same field, but that change
must update the issue sink contract and tests before any ActivityDefinition
relies on queue routing.
The legacy input name `review_required` is accepted during migration and
normalized to `review_advisory`; new definitions must not use it. activity-core
does **not** route proposals to a pending-review queue and does not own review
lifecycle state. A future hold/release design requires a named downstream owner,
an idempotent release reference, an ADR update, and fail-closed emission tests.
#### Evaluation semantics
@ -259,11 +255,20 @@ Every task emission records:
| `prompt_hash` | — | SHA-256 of rendered prompt |
| `model` | — | model ID used |
| `output_validated` | — | `true` / `false` |
| `review_required` | — | `true` / `false` |
| `review_advisory` | — | `true` / `false`; no gate applied |
The audit trail is written to the `task_spawn_log` table in activity-core's database
and referenced from the task record in issue-core.
The rendered prompt and provider response are deliberately not persisted. The
prompt hash proves equality when an authorized operator can reconstruct the
same input, but the audit contract does not promise reconstruction after source
definitions or upstream event retention have changed. `activity_runs` retains
the definition version and bounded context snapshot; reports may retain
allowlisted route/usage metadata. Prompts, messages, tool output, credential
fields, and provider blobs are excluded from run, progress, and public API
evidence.
### Testing strategy
**Rules**: every rule can and should be unit-tested with fixture event payloads.