Enforce bounded operation guardrails
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a028de-e2c8-7732-8521-46a7fc5db82f
This commit is contained in:
parent
c384f60530
commit
26934e25b9
51 changed files with 1843 additions and 472 deletions
128
docs/adr/adr-007-bounded-operations.md
Normal file
128
docs/adr/adr-007-bounded-operations.md
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
id: ACT-ADR-007
|
||||
type: architecture-decision-record
|
||||
title: "Code-registered bounded operations are the only local mutation exception"
|
||||
status: accepted
|
||||
state_hub_decision_id: "2b1f0c01-1d6f-4fdc-b3e7-537ce0a0a1f8"
|
||||
owner: activity-core
|
||||
revision: "accepted-1"
|
||||
last_reviewed: "2026-08-23"
|
||||
review_interval: 6m
|
||||
decided_by: Bernd Worsch
|
||||
date: "2026-08-23"
|
||||
scope: repo
|
||||
affects:
|
||||
- activity-core
|
||||
- sbom-nexus
|
||||
- railiance-platform
|
||||
tags:
|
||||
- architecture
|
||||
- activity-core
|
||||
- bounded-operation
|
||||
- execution-boundary
|
||||
---
|
||||
|
||||
# ACT-ADR-007: Code-registered Bounded Operations
|
||||
|
||||
## Status
|
||||
|
||||
**Accepted** (2026-08-23) for ACTIVITY-WP-0035.
|
||||
|
||||
## Context
|
||||
|
||||
The Event Bridge principle says activity-core answers when, what, and where and
|
||||
does not execute domain work. Production nevertheless contains three useful
|
||||
operations whose complete outcome is a small scheduled maintenance action:
|
||||
|
||||
- ingest at most three Repo Manager-selected immutable sources into SBOM Nexus;
|
||||
- prune Forgejo package versions under live-image protection; and
|
||||
- invoke the fixed CNPG Option A backup tool for an explicit target list.
|
||||
|
||||
Historically the latter two ran through a generic `shell` context resolver.
|
||||
That made a mutating subprocess look like a read and left extension policy to
|
||||
convention. Removing the operations would recreate bespoke cron; accepting
|
||||
arbitrary shell would make activity-core a general executor.
|
||||
|
||||
## Decision
|
||||
|
||||
### 1. Bounded operations are a narrow implementation exception
|
||||
|
||||
The governing when/what/where responsibility does not gain a general “how.” A
|
||||
bounded operation is allowed only when the operation itself is the declared
|
||||
automation outcome and all admission requirements below are code-reviewable.
|
||||
|
||||
The initial allowlist is exactly:
|
||||
|
||||
1. `sbom_nexus_ingest`
|
||||
2. `forgejo_package_prune`
|
||||
3. `cnpg_option_a_backup`
|
||||
|
||||
Adding an operation requires updating the code-owned registry, this ADR (or a
|
||||
successor), tests, credential route, and evidence contract. A string in a
|
||||
definition cannot register an operation.
|
||||
|
||||
### 2. Admission is fail closed during file sync
|
||||
|
||||
Each registry entry declares:
|
||||
|
||||
- source type and query;
|
||||
- whether mutation intent is `apply` or `dry_run` and that it is explicit;
|
||||
- fixed or maximum target bounds;
|
||||
- canonical implementation and allowed configuration;
|
||||
- idempotency and Temporal retry semantics;
|
||||
- maximum execution timeout;
|
||||
- credential owner/route; and
|
||||
- mandatory non-secret evidence mode.
|
||||
|
||||
Unknown `shell` queries are refused unless separately registered as read-only.
|
||||
Known operation queries with missing, malformed, or over-limit safety fields
|
||||
are refused before database projection or Temporal schedule reconciliation.
|
||||
|
||||
### 3. Context resolution is read-only
|
||||
|
||||
The workflow first resolves and freezes context. Mutations then run in an
|
||||
explicit bounded-operation stage and merge only normalized outcomes into the
|
||||
snapshot before evidence and rule/instruction evaluation.
|
||||
|
||||
SBOM selection remains a read in the context phase; its fixed selection is the
|
||||
input to the operation stage. Package prune and backup have no discovery read
|
||||
inside activity-core and bind a pending marker until their operation completes.
|
||||
|
||||
### 4. Retry behavior is operation-specific
|
||||
|
||||
- SBOM ingest uses stable per-run/per-repository idempotency keys and heartbeat
|
||||
checkpoints, so Activity retries resume the frozen batch.
|
||||
- Forgejo prune and CNPG backup have no activity-core-verifiable remote
|
||||
idempotency receipt. Their operation activity therefore has one Temporal
|
||||
attempt; a failure remains visible for operator reconciliation rather than
|
||||
risking an automatic second mutation.
|
||||
|
||||
This does not preclude future safe retries after the platform tools expose a
|
||||
durable operation receipt.
|
||||
|
||||
### 5. Evidence is mandatory and bounded
|
||||
|
||||
Every operation must produce an allowlisted summary through a configured
|
||||
report/evidence sink. Raw subprocess output, tokens, provider payloads, archive
|
||||
URLs, kubeconfigs, and credential material are not evidence.
|
||||
|
||||
## Rejected alternatives
|
||||
|
||||
- **Keep mutating shell resolvers.** Rejected because resolution should be a
|
||||
replayable read and the generic dispatcher hides mutation admission.
|
||||
- **Generic command activity.** Rejected because command text/path from a
|
||||
definition is remote code execution by configuration.
|
||||
- **Move every operation to a rein.** Rejected for these fixed platform
|
||||
operations; it adds an agent execution constellation without judgement or
|
||||
repository work. Operations that exceed this ADR's bounds do belong there.
|
||||
- **Remove all local operations.** Rejected because it recreates scattered cron
|
||||
and loses Temporal/evidence guarantees for established maintenance.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Definition parsing gains a central operation-policy validator.
|
||||
- The workflow gains an explicit operation stage.
|
||||
- The generic `shell` resolver becomes read-only.
|
||||
- Existing definitions migrate without widening targets or permissions.
|
||||
- The registry is intentionally small and architectural review is required to
|
||||
expand it.
|
||||
Loading…
Add table
Add a link
Reference in a new issue