scripts/prod_automation_status.sh took a positional since value, so the
Makefile's own `SINCE=sunday` form passed the literal string into timestamptz:
all five sections errored while the run still looked like it produced a report.
Now `SINCE=` is accepted and the value is parsed and normalised to UTC up
front, failing fast with usage and exit 2 instead of five parse errors.
ACTIVITY-WP-0032 plans adoption of the glas-harness contract 1.0 reported in
GLAS-WP-0004. WP-0026 is finished, so this gets its own plan. The motivation is
concrete: ops_run.approach_hint binds at claim time, which produced a failed
run on 2026-08-17 ("no approach matched labels/definition") after it had
already consumed a claim and a lease.
T01 is deliberately blocking: our claim path is pull-based and the Glas
contract is a call, so the invocation shape is an architectural decision, not a
port. Two questions are outstanding with glas-harness.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.4 KiB
| id | type | title | domain | repo | status | owner | topic_slug | priority | created | updated | related | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ACTIVITY-WP-0032 | workplan | Adopt the Glas profile-driven execution contract | infotech | activity-core | proposed | claude | activity-core | medium | 2026-08-21 | 2026-08-21 |
|
Adopt the Glas profile-driven execution contract
Origin
glas-harness reported (2026-08-20) that GLAS-WP-0004 contract 1.0 is
implemented and proven: the same bounded task completed through two
different reins (rein-aharness, rein-openweights) via an explicit
harness_profile_ref, with real commits and verified sandbox destruction.
Their guidance to us: activity-core stays scheduler and task source, and should
name an approved profile, never a concrete rein.
ACTIVITY-WP-0026 is finished, so this does not belong as an amendment to it.
Why this is worth doing
Today an ops_run carries approach_hint (orm.py:172), a free-text string the
executor interprets at claim time. That binding is too late and too weak. Live
example from 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'] def='2969816c-…'
The run was claimed, then died because nothing could execute it. A
harness_profile_ref is resolved and refused before sandbox creation, so
an unroutable request fails at emission with a clear reason instead of
consuming a claim and a lease.
Second motivation: we are currently coupled to one backend in practice —
every claim in the last week is rein-aharness@railiance01. The dual-rein
proof means that coupling is now avoidable rather than inherent.
Boundary (must not drift)
activity-core stays when / what / where. Adopting this contract must not
turn it into an executor — SCOPE drift risk #1 ("convenience execution"). We
emit an authorized, profile-named request and record normalized evidence. We do
not select reins, provision sandboxes, acquire credentials, or run the inner
agentic loop. Glas owns profile resolution and the outer loop; the rein owns its
own inner loop; sand-boxer owns isolation.
We also do not author the attribution refs the contract accepts
(assignment_ref, role_ref, duty_ref, goal_refs,
resource_envelope_refs). Those come from workforce/leadership vocabulary in
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)
- Is
approach_hintexpected to be replaced byharness_profile_ref, or to coexist? - Is the profile registry authoritative in glas-harness, so we validate refs by calling them rather than mirroring a catalogue that can drift?
T01 is blocked on these; the rest follows the answer.
Decide the invocation shape
id: ACTIVITY-WP-0032-T01
status: wait
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:
- A — queue carries the profile.
ops_rungrowsharness_profile_refplus 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.
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.
Carry the profile and attribution refs
id: ACTIVITY-WP-0032-T02
status: wait
priority: medium
Depends on T01. 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.
Validate refs at emission
id: ACTIVITY-WP-0032-T03
status: wait
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".
Record normalized execution evidence
id: ACTIVITY-WP-0032-T04
status: wait
priority: low
Depends on T02. Glas emits normalized, non-secret execution evidence. Land it in
ops_runs.result and the evidence sink so the production status surface
(ACTIVITY-WP-0031-T03) shows what actually executed, through which profile and
rein. Keep the field allowlist discipline from ACTIVITY-WP-0031: no provider
blobs, no credential material in run artefacts.
Prove on one definition
id: ACTIVITY-WP-0032-T05
status: wait
priority: low
Depends on T03/T04. Convert exactly one low-risk definition, run it on railiance01, and capture evidence. Do not convert the fleet before one definition is proven end to end. Note that FI and Binky are unsuitable as the pilot while ACTIVITY-WP-0031-T01 is unresolved — their failures are currently provider-credential failures and would mask the result.
Acceptance
- Invocation shape decided and recorded as an ADR, with the boundary stated
- ops_run carries an approved
harness_profile_ref; no definition names a concrete rein - Unroutable profiles are refused at emission, not at claim
approach_hintis either strangled or documented as subordinate- Normalized Glas evidence is visible in production status
- One definition proven on railiance01 end to end