Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a028de-e2c8-7732-8521-46a7fc5db82f
142 lines
5.9 KiB
Markdown
142 lines
5.9 KiB
Markdown
---
|
|
id: ACT-ADR-006
|
|
type: architecture-decision-record
|
|
title: "Profile-driven execution selection over the ops_run pull queue"
|
|
status: accepted
|
|
owner: activity-core
|
|
revision: "accepted-1"
|
|
last_reviewed: "2026-08-21"
|
|
review_interval: 6m
|
|
decided_by: Bernd Worsch
|
|
date: "2026-08-21"
|
|
scope: cross-repo
|
|
affects:
|
|
- activity-core
|
|
- glas-harness
|
|
- rein-aharness
|
|
- sand-boxer
|
|
tags:
|
|
- architecture
|
|
- activity-core
|
|
- ops-run
|
|
- glas-harness
|
|
- execution
|
|
supersedes_notes: >
|
|
Extends ACT-ADR-005. Does not change the ops_run claim/lease plane; it
|
|
changes what a queued run says about how it should execute.
|
|
---
|
|
|
|
# ACT-ADR-006: Profile-driven execution selection over the ops_run pull queue
|
|
|
|
## Status
|
|
|
|
**Accepted** (2026-08-21). Hub decision `147beec6-7fe7-4837-8e3a-4264a240379d`
|
|
("Glas contract 1.0 makes execution constellation selection explicit").
|
|
|
|
## Context
|
|
|
|
ACT-ADR-005 gave internal scheduled automation a claimable `ops_run` plane.
|
|
What an ops_run said about *how* to execute was `approach_hint` — free text,
|
|
interpreted by the claiming executor at claim time.
|
|
|
|
That binding is too late. Live failure, railiance01 2026-08-17:
|
|
|
|
```
|
|
state=failed attempt=1 claim_owner=rein-aharness@railiance01
|
|
title=Run SBOM rescan for binect-js
|
|
failure=no approach matched labels/definition;
|
|
labels=['sbom','security','automated']
|
|
```
|
|
|
|
The run was claimed and leased, *then* died because nothing could execute it.
|
|
A claim was consumed to discover the request was unroutable.
|
|
|
|
`glas-harness` GLAS-WP-0004 closed contract 1.0 and proved it by running one
|
|
bounded task through two different reins (`rein-aharness`, `rein-openweights`)
|
|
via an explicit `harness_profile_ref`, with real commits and verified sandbox
|
|
destruction. Meanwhile every activity-core claim in the week to 2026-08-21 was
|
|
`rein-aharness@railiance01` — a coupling that is now avoidable rather than
|
|
inherent.
|
|
|
|
Two shapes were considered: keep the pull queue and carry the profile as
|
|
payload, or have activity-core call the Glas gateway directly. glas-harness,
|
|
which owns the contract, advised the first for the initial migration.
|
|
|
|
## Decision
|
|
|
|
### 1. The queue stays; the payload changes
|
|
|
|
activity-core continues to insert `ops_run(open)` and executors continue to
|
|
claim under lease. Scheduling topology does not change. What changes is that a
|
|
queued run carries an exact **versioned `harness_profile_ref`** plus the
|
|
correlation / assignment / role / duty / goal / resource-envelope references.
|
|
The claiming executor passes that request into Glas, which resolves or refuses
|
|
it **before sandbox creation**.
|
|
|
|
This changes the execution contract without simultaneously changing the
|
|
scheduling topology — one variable at a time. A direct activity-core → Glas
|
|
call may be evaluated later, independently, if pull delivery stops meeting
|
|
operational needs.
|
|
|
|
### 2. `harness_profile_ref` is authoritative; `approach_hint` is legacy
|
|
|
|
The two coexist with **distinct semantics**, not as fallbacks for one another:
|
|
|
|
- `harness_profile_ref` is the authoritative execution-constellation selector.
|
|
- `approach_hint` remains only a legacy activity/definition-matching hint while
|
|
producers and consumers migrate.
|
|
|
|
`approach_hint` must **not** override, synthesize, or fall back from an absent
|
|
or invalid `harness_profile_ref` on governed execution. A missing profile is an
|
|
error, never an invitation to guess from a hint. Once inventory shows no caller
|
|
depends on `approach_hint` for runtime selection, that use is deprecated.
|
|
|
|
### 3. activity-core does not mirror the profile catalog
|
|
|
|
The catalog in glas-harness is authoritative. activity-core must not maintain
|
|
an independent list, which would drift and produce a second, disagreeing
|
|
opinion about what is executable.
|
|
|
|
Consequence, accepted knowingly: Glas exposes deterministic validation through
|
|
its package and CLI but **no network validation service** today, so
|
|
activity-core cannot remotely validate a profile ref at emission time. We
|
|
therefore validate only what is local and structural — that a ref is present
|
|
and well-formed for governed execution — and rely on the **execution-side Glas
|
|
resolver as the mandatory fail-closed check**.
|
|
|
|
This is weaker than refusing at emission, and deliberately so: an unreachable
|
|
or absent validation service must never downgrade into "emit anything". If
|
|
emit-time remote validation is later required, it needs a separately scoped
|
|
Glas API and its own decision — not a mirrored catalogue here.
|
|
|
|
Even unvalidated at emit, this is strictly better than the 2026-08-17 failure:
|
|
refusal happens deterministically before sandbox creation rather than after a
|
|
claim and lease were consumed.
|
|
|
|
### 4. activity-core does not become an executor
|
|
|
|
We emit an authorized, profile-named request and record normalized evidence.
|
|
We do not select reins, provision sandboxes, acquire credentials, or run any
|
|
inner agentic loop. Glas owns profile resolution and the outer loop; the rein
|
|
owns its inner loop; `sand-boxer` owns isolation. This is SCOPE drift risk #1
|
|
("convenience execution") and this ADR does not relax it.
|
|
|
|
The attribution references we carry (`assignment_ref`, `role_ref`, `duty_ref`,
|
|
`goal_refs`, `resource_envelope_refs`) are **passed through**, not authored
|
|
here. Their vocabulary belongs to `info-tech-canon`; activity-core must not
|
|
invent org roles (ACTIVITY-WP-0029 responsibility map).
|
|
|
|
ACT-ADR-007's bounded-operation exception does not alter this decision. A
|
|
code-registered fixed maintenance operation is not a Glas/rein execution
|
|
constellation, and the exception cannot be used to run an agent loop or execute
|
|
an `ops_run` inside activity-core.
|
|
|
|
## Consequences
|
|
|
|
- `ops_runs` grows `harness_profile_ref` and the attribution refs; the emission
|
|
path, queue projection, and run artefacts carry them.
|
|
- Definitions declare a profile; rules pass it through.
|
|
- Unroutable requests fail before sandbox creation instead of at claim time.
|
|
- activity-core is no longer coupled to one rein in practice.
|
|
- Emit-time validation remains a known gap, owned by a future Glas API.
|
|
- Implementation: **ACTIVITY-WP-0032**.
|