activity-core/docs/adr/adr-006-glas-profile-execution.md
tegwick 1c4b3c592c
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
docs: accept ACT-ADR-006, profile-driven execution over the pull queue
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>
2026-08-21 13:57:48 +02:00

5.7 KiB

id type title status owner revision last_reviewed review_interval decided_by date scope affects tags supersedes_notes
ACT-ADR-006 architecture-decision-record Profile-driven execution selection over the ops_run pull queue accepted activity-core accepted-1 2026-08-21 6m Bernd Worsch 2026-08-21 cross-repo
activity-core
glas-harness
rein-aharness
sand-boxer
architecture
activity-core
ops-run
glas-harness
execution
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).

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.