diff --git a/workplans/SECRETS-WP-0009-glas-claude-native-delivery.md b/workplans/SECRETS-WP-0009-glas-claude-native-delivery.md index 9016b3b..59239e5 100644 --- a/workplans/SECRETS-WP-0009-glas-claude-native-delivery.md +++ b/workplans/SECRETS-WP-0009-glas-claude-native-delivery.md @@ -346,3 +346,102 @@ Intermediate `95c9edb1` is installed but refused: a sandboxer bwrap info-fd partial-read race, fixed in `221126c`. Receipt: prj-helixforge-factory `evidence/2026-09-22-runtime-placement.json`. The exec_owner argv will use `2cfc7b5f`. Next: B3 fixture repo, repository grant, ActivityDefinition, worker id. + +### 2026-09-23 B3 scope correction and model choice + +Operator chose `claude-sonnet-5` for MessagesOwner and a throwaway fixture repo +with no remote. Reading the owner contracts corrected the B3 framing above: + +- The Glas acceptance run (`glas-harness/docs/local-profile-acceptance.md`, + `scripts/prove-local-profile.py`) creates its own disposable fixture repo + (one `PROOF.md`, one local commit, no push remote). No repo is pre-created. +- That path runs with `--no-metrics` and carries no repository grant, so it + needs no grant, ActivityDefinition or queue worker id. Those belong to the + Activity Core queue loop (HFACT-WP-0001-T05), not to this first run. +- The candidate `harness.agent-dev-local@1.1.0` pins `claude-sonnet-4-6`. + Moving to `claude-sonnet-5` is a glas-harness profile change, reviewed as a + new compatibility set, and must be checked against the pinned Claude CLI + 2.1.263 in runtime `2cfc7b5f` before the attended run. + +No repo, grant, definition, credential or approval was created. + +### 2026-09-23 Sonnet 5 compatibility check + +Correction: runtime `2cfc7b5f` ships Claude CLI **2.1.266** (binary +`19842705e989…`, per `prj-helixforge-factory/evidence/2026-09-22-runtime-placement.json`), +not 2.1.263 (that was the earlier `5cf9a16c` candidate). The same binary in the +local `5371156d` store matches that digest. Its built-in model registry lists +`claude-sonnet-5` as a first-class entry (`{"name": "claude-sonnet-5", +"supports1m": true}`), and it is the CLI's own example model for hooks. No +deprecation marker references it. No runtime rebuild is needed. This was a static +check of the binary, not a provider request. The first real call is still +the attended exec. Remaining model work: a glas-harness profile change from +`claude-sonnet-4-6` to `claude-sonnet-5`, reviewed as a new compatibility set. + +### 2026-09-23 Sonnet 5 runtime placed + +Operator chose a 1.1.1 bump. glas-harness `30be818` adds +`harness.agent-dev-local@1.1.1` (`claude-sonnet-5`) and blocks 1.1.0. rein-aharness +`fdc07ee` pins it in the runtime contract lock (llm-connect `37436bb`, workplan-only). +Owner runtime `b6e4e8a429393d68831c996a65c0489664205df969ac9882e581983ec2da4969` +(Claude CLI 2.1.266) is installed on railiance01 beside `2cfc7b5f` and `5371156d` +(rollback). Synthetic metered proof passes locally and on railiance01 (one fake +provider request, zero on refusal, artifact unchanged). Receipt: +`prj-helixforge-factory/evidence/2026-09-23-runtime-placement.json`. The +`exec_owner` argv and the owner config `runtime` block will use `b6e4e8a4`, and +`messages_policy.model` will be `claude-sonnet-5`. Next: private SpendPolicy, ledger +`spend init` and owner config on railiance01 (HFACT-WP-0001-T01/T04). +No credential, approval, profile activation or worker change. + +### 2026-09-23 correction: the paid run is a queue claim + +The earlier B3 correction was wrong for this task. It read the Glas acceptance +runner, which makes its own fixture. The T03 exec path is different: +`rein-aharness metered-once` runs one Activity Core claim cycle +(`docs/owner-bootstrap.md`), and the SpendPolicy binds `worker_id`, +`activity_definition_id`, `target_repo`, `project` and `repository_grant_id` +(`docs/spend-admission.md`). The policy is immutable once `spend init` runs, so +all of these must be fixed first: + +- target repo: a throwaway git repo on railiance01, no remote (operator-approved); +- repository grant v1: `PROOF.md` only, exactly one commit, `publish: false`; +- a production Activity Core definition carrying that grant and + `harness.agent-dev-local@1.1.1`, left disabled until the attended run; +- a worker identity and worker token for the metered owner. The existing + `rein-aharness-claim-loop.service` on railiance01 claims by label, so the run + needs a label it does not claim, or it could take the paid run. + +No SpendPolicy, ledger, owner config, repo or definition was created. + +### 2026-09-23 option 1 preparation (partial) + +Operator chose: request multi-worker identities from activity-core (message +`914853d9`), and run now under `rein-aharness@railiance01` isolated by label. + +- activity-core `6002d5c`: disabled definition `hfact-glas-metered-proof` + (id `5bae5505-77f1-5ba3-8dfa-2e10ed15531e`), label `hfact-metered`, profile + 1.1.1, grant `PROOF.md` / one commit / no publish. The parser accepts it; the + live ConfigMap diff is additive only. **Not applied:** the harness classifier + blocked the ConfigMap apply and sync Job on railiance01. +- Fixture repo on railiance01: `/home/tegwick/hfact/targets/hfact-glas-proof` + (mode 0700, no remote, base `679d23e0`). +- SpendPolicy inputs: profile_sha256 `10e423fe…83ca65`, descriptor_sha256 + `4f151744…3a9b`, repository_grant_id `656911f7dff83e871434b415f0cee685`, + max_turns 30. No `project` value is on record yet. + +No SpendPolicy, ledger or owner config was written. No credential was read. + +### 2026-09-23 definition live; owner provisioning prepared + +The operator ran the ConfigMap apply and sync Job. The sync log shows +`hfact-glas-metered-proof` upserted (29 definitions). Operator chose project +`prj-helixforge-factory` and list-price bounds for `claude-sonnet-5` +(claude-api reference, cached 2026-06-24: USD 2 / 10 per MTok). The owner +MessagesPolicy uses an input bound of 4 micro-USD per token (covers the 1h cache +write), output 10, context 200000, output 32000, and the betas the CLI passed in +the synthetic proof. The worst-case hold per request is USD 1.12. + +A provisioning script (SpendPolicy, `spend init`, request tables, mode-0600 +owner config under `~/hfact/owner`) validates in memory. Staging it on +railiance01 was blocked by the harness classifier as a real-world transaction. +It has not been run. No policy, ledger or owner config exists yet. diff --git a/workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md b/workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md new file mode 100644 index 0000000..c32b4f0 --- /dev/null +++ b/workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md @@ -0,0 +1,100 @@ +--- +id: SECRETS-WP-0011 +type: workplan +title: "Multi-lane exec-owner delivery" +domain: infotech +repo: secrets-engine +status: ready +flavor: implementation +owner: claude-code +topic_slug: netkingdom +created: "2026-09-23" +updated: "2026-09-23" +related_workplans: + - SECRETS-WP-0009 + - HFACT-WP-0001 +--- + +Demand: SECRETS-WP-0009-T03. A configured `exec_owner` child today receives +only the catalog's fixed non-secret environment plus one delivered field +(`exec_delivery.py:233`). The Glas metered owner (`rein-aharness metered-once`) +also needs the Activity Core worker token to claim its queue row. Operator +decision 2026-09-23: generalize secrets-engine delivery rather than add a +rein-side token-file reader. + +Operator decisions 2026-09-23: one decision chain per lane (no flex-auth +package change), and the worker-token lane uses ordinary lane approval, not +human control, since it only lets a worker claim jobs. + +Scope: one exec may deliver fields from more than one cataloged lane into one +catalog-bound owner. The primary lane stays the one named by `--catalog`; +the others are companions declared on the primary's `exec_owner`. + +Invariants carried over unchanged: + +- Every delivered value comes from a cataloged lane through that lane's own + AppRole, in memory only, with self-revoking sessions and redaction. +- Each lane's read is its own protected action. No lane's approval, decision + or consume covers another lane. +- The binding stays exact. Companion lanes, fields and env names are part of + the `exec_owner` digest, and the command is refused if any differ. +- Fail closed as a set. If any lane is unapproved, missing, denied or fails, + no child is started and no value is kept. + +## Define the companion contract + +```task +id: SECRETS-WP-0011-T01 +status: todo +priority: high +``` + +Extend `exec_owner` with `companions: [{catalog, field, env}]`. Validate at +catalog load: each companion is an existing `kv` lane with the same stage, a +declared field, an env name that doesn't collide with the fixed environment or +another delivery, and `exec-env` in its delivery modes. Companions are +refused on pending owners. Document the contract in `docs/` and the SCOPE +exec-time delivery section. + +## Gate and fetch each lane separately + +```task +id: SECRETS-WP-0011-T02 +status: todo +priority: high +``` + +Run the existing approval-claim / CheckRequest / consume chain once per lane, +with each lane's own action and resource, before any value is fetched. Then +fetch every value, re-check the binding digest, and spawn once with all values +injected and redacted. Evidence records each lane's decision reference and +session cleanup. Any failure starts no child and reports which lane refused. + +## Tests and throwaway OpenBao proof + +```task +id: SECRETS-WP-0011-T03 +status: todo +priority: high +``` + +Unit tests: validation, digest coverage, collision, stage mismatch, partial +approval, one lane denied after another is fetched, redaction of every value, +cleanup of every session. Integration: two KV lanes delivered to one owner on +a throwaway OpenBao dev server. + +## Catalog the Activity Core worker token lane + +```task +id: SECRETS-WP-0011-T04 +status: wait +priority: high +blocking_reason: "Needs activity-core owner assent to source ACTIVITY_CORE_WORKER_TOKEN from OpenBao (ESO) instead of a hand-generated Kubernetes Secret." +``` + +Request activity-core to move the worker token into OpenBao custody, synced to +`actcore-runtime-secret` by their existing `openbao-activity-core` store. Then +catalog a read lane for the metered owner and add it as the Glas lane's +companion. This coordinates with activity-core's multi-worker request (hub +message `914853d9`): a dedicated metered worker token would use the same lane +shape.