docs: accept ACT-ADR-006, profile-driven execution over the pull queue
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

glas-harness answered both open questions from ACTIVITY-WP-0032, so T01 is
resolved as option A: the ops_run pull queue stays and carries the versioned
harness_profile_ref plus attribution refs. The claiming executor passes the
request into Glas, which resolves or refuses before sandbox creation. This
changes the execution contract without also changing scheduling topology.

Two answers shaped the plan:
- harness_profile_ref and approach_hint coexist with distinct semantics.
  approach_hint must never override, synthesize, or fall back from an absent or
  invalid profile ref on governed execution — T02 must enforce that in code.
- The glas-harness catalog is authoritative and must not be mirrored. Glas has
  no network validation service today, so emit-time remote validation is not
  available.

T03 is corrected accordingly: validate locally and structurally, rely on the
execution-side Glas resolver as the mandatory fail-closed check, and record the
residual gap rather than papering over it with a mirrored catalogue.

Hub decision 147beec6-7fe7-4837-8e3a-4264a240379d.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-21 13:57:48 +02:00
parent 5793eb3cd4
commit 1c4b3c592c
3 changed files with 204 additions and 41 deletions

View file

@ -4,13 +4,14 @@ type: workplan
title: "Adopt the Glas profile-driven execution contract"
domain: infotech
repo: activity-core
status: proposed
status: active
owner: claude
topic_slug: activity-core
priority: medium
created: "2026-08-21"
updated: "2026-08-21"
related:
- ACT-ADR-006
- ACTIVITY-WP-0026
- ACTIVITY-WP-0029
- ACTIVITY-WP-0031
@ -69,77 +70,98 @@ We also do not author the attribution refs the contract accepts
`info-tech-canon`; activity-core carries them through, and must not invent org
roles here (ACTIVITY-WP-0029 responsibility map).
## Open questions (asked of glas-harness 2026-08-21, not yet answered)
## Answered by glas-harness (2026-08-21)
1. Is `approach_hint` expected to be **replaced** by `harness_profile_ref`, or
to coexist?
2. Is the profile registry authoritative in glas-harness, so we validate refs by
calling them rather than mirroring a catalogue that can drift?
Both questions are settled; recorded as **ACT-ADR-006**, hub decision
`147beec6-7fe7-4837-8e3a-4264a240379d`.
T01 is blocked on these; the rest follows the answer.
1. **Coexistence with distinct semantics.** `harness_profile_ref` is the
authoritative execution-constellation selector. `approach_hint` stays only as
a legacy activity/definition-matching hint and must **not** override,
synthesize, or fall back from an absent/invalid profile ref on governed
execution. Deprecate that use once inventory shows no caller depends on it.
2. **The glas-harness catalog is authoritative — do not mirror it.** Glas
exposes deterministic validation through its package and CLI but **no network
validation service** today. Emit-time remote validation would need a
separately scoped Glas API. The execution-side Glas resolver is the mandatory
fail-closed check.
Transport: **preserve the pull queue** in the first migration slice. The exact
versioned profile ref and attribution refs go in the queued payload; the
claiming executor passes the request into Glas, which resolves or refuses before
sandbox creation. This changes the execution contract without also changing
scheduling topology. A direct activity-core → Glas call can be evaluated
independently later.
## Decide the invocation shape
```task
id: ACTIVITY-WP-0032-T01
status: wait
status: done
priority: high
```
Our claim path is **pull-based**: we insert `ops_run(open)` and
rein-aharness claims it. The Glas contract is shaped as a **call**. Those do not
compose automatically, and the choice is architectural, not mechanical. Record
a decision (ACT-ADR) between:
Resolved 2026-08-21 as **option A — the queue carries the profile**, on the
advice of glas-harness as contract owner. `ops_run` grows `harness_profile_ref`
plus attribution refs; lease semantics, durability, and the operator console are
unchanged; activity-core stays behind the executor boundary.
- **A — queue carries the profile.** `ops_run` grows `harness_profile_ref` plus
the attribution refs; a Glas-aware claimer resolves the profile. Keeps lease
semantics, durability, and the operator console unchanged. Keeps one more
indirection between authorization and execution.
- **B — activity-core calls the Glas gateway.** Direct invocation with the
approved profile. Matches the contract as designed and fails unroutable
requests before sandbox creation. Costs us the claim/lease/retry machinery
ACTIVITY-WP-0026 just built, and moves activity-core closer to the executor
boundary we deliberately hold.
Option B (activity-core calls the Glas gateway directly) was rejected for this
slice: it would discard the claim/lease/retry machinery ACTIVITY-WP-0026 just
built and change scheduling topology at the same time as the execution contract.
It remains available as an independent later evaluation.
Do not start T02+ before this is resolved. Prefer A unless glas-harness states
the profile must be resolved at emission time to keep its refusal guarantee.
Written up as `docs/adr/adr-006-glas-profile-execution.md`.
## Carry the profile and attribution refs
```task
id: ACTIVITY-WP-0032-T02
status: wait
priority: medium
status: todo
priority: high
```
Depends on T01. Add `harness_profile_ref` and the correlation/attribution refs
Add `harness_profile_ref` and the correlation/attribution refs
to the ops_run model, emission path (`activities.py`), queue projection
(`ops_run_queue.py`), and run artefacts (`run_artifacts.py`), with a migration.
Definitions declare the profile; rules pass it through. Decide `approach_hint`'s
fate per open question 1 — if it coexists, document which wins; if it is
replaced, strangle it rather than leaving two routing fields.
Definitions declare the profile; rules pass it through. Per ACT-ADR-006 the two
fields **coexist with distinct semantics**: enforce in code that `approach_hint`
cannot override, synthesize, or fall back from an absent/invalid
`harness_profile_ref` on governed execution, and cover that with a test — a
silent fallback is exactly the failure this workplan removes.
## Validate refs at emission
## Validate what we can, fail closed on the rest
```task
id: ACTIVITY-WP-0032-T03
status: wait
status: todo
priority: medium
```
Depends on T01/T02. An unknown or incompatible profile must be refused when the
ActivityDefinition is synced or the run is emitted — not discovered at claim
time, which is the failure mode this workplan exists to remove. Per open
question 2, prefer calling the glas-harness registry over mirroring it. Include
the offline/unreachable behaviour: a registry we cannot reach must not silently
downgrade to "emit anything".
Depends on T02. **Corrected after the glas-harness answer:** emit-time *remote*
validation is not available — Glas has no network validation service, and
mirroring its catalogue is explicitly forbidden. So:
- Validate locally and structurally at definition sync and run emission: a
governed run has a profile ref, and it is well-formed and versioned.
- Do **not** resolve the ref against a mirrored list. The execution-side Glas
resolver is the authority and the mandatory fail-closed check.
- An absent or malformed ref is an error at emission. It must never degrade into
"emit anything" or fall back to `approach_hint`.
Record the residual gap honestly: a well-formed but unknown profile is still
caught at execution rather than emission. That is weaker than refusing at emit,
and still strictly better than the claim-time failure of 2026-08-17, because
Glas refuses before sandbox creation. If emit-time remote validation becomes
necessary, raise it as a capability request against glas-harness rather than
solving it locally.
## Record normalized execution evidence
```task
id: ACTIVITY-WP-0032-T04
status: wait
priority: low
priority: medium
```
Depends on T02. Glas emits normalized, non-secret execution evidence. Land it in
@ -164,10 +186,12 @@ provider-credential failures and would mask the result.
## Acceptance
- [ ] Invocation shape decided and recorded as an ADR, with the boundary stated
- [x] Invocation shape decided and recorded as an ADR, with the boundary stated
(ACT-ADR-006; pull queue preserved)
- [ ] ops_run carries an approved `harness_profile_ref`; no definition names a
concrete rein
- [ ] Unroutable profiles are refused at emission, not at claim
- [ ] `approach_hint` is either strangled or documented as subordinate
- [ ] Malformed/absent profile refs are refused at emission; unknown-but-well-formed
refs are refused by Glas before sandbox creation, never at claim
- [ ] `approach_hint` cannot override or substitute for a profile ref, proven by test
- [ ] Normalized Glas evidence is visible in production status
- [ ] One definition proven on railiance01 end to end