Commit Graph

113 Commits

Author SHA1 Message Date
Paul O'Reilly
e64d0a1822 feat(workflow): cpw-smoke@1 one-node cp_write template for Option C smoke run (690b330f)
Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-05 16:18:18 +13:00
Paul O'Reilly
a1c708ac96 fix(harness): add -hatchmate composites for sonnet, haiku, deepseekv4flash (bug 678d4e8e)
Hatchmate templates resolving to claude-sonnet-5, claude-haiku-4-5 or
airouter-deepseekv4flash mounted only gitea-ssh/v1 and could not clone
hatchmate/hatchmate-agents. Mirror the existing -hatchmate composites:
non-hatchmate base layers plus gitea-ssh-hatchmate/v1 after gitea-ssh/v1 (HC-26).

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-04 21:13:32 +13:00
Paul O'Reilly
887578f0eb feat(templates): explicit cp_write on every kind: script node + audit test (WF-COMP-31d, item 26754227)
cp_write: true  -> state-tx (test-validate@1, frozen-fixture-emit@1) and, in
                   the archived bug-ancestor-auto-advance@1, tag-set + state-tx.
cp_write: false -> every other script node (verdict-gate, policy-pick,
                   preflight-*, frozen-fixture-emit, parent-link-check).
tests/invariants/test_cp_write_field_set_correctly.py pins the set.

HOLD: do not merge until the CP release that adds WorkflowNode.cp_write.
The current CP schema is extra="forbid" and rejects the new key
(verified: nodes.0.cp_write extra_forbidden), so on the old CP these
template edits are NOT inert.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-04 09:36:04 +13:00
Paul O'Reilly
08ca057687 feat(harness): workflow-script-nocp/v1 + workflow-script-write/v1 composites (Option C, WF-COMP-31b/31c, item 26754227)
nocp: shared-variables/v1 + repo-readonly/v1 (no CP credential).
write: shared-variables/v1 + cp-write-token/v1 + repo-readonly/v1.
repo-readonly/v1 is last in both (WF-COMP-34); neither layers
cp-service-token/v1 or gitea-ssh/v1.

HOLD: do not merge until the CP release (AU-55/55a/56/57, WF-COMP-31b engine/
dispatch/compiler composite-set changes) and the dispatcher image
(cp-write-token delivery, AU-55b) are deployed. The dispatcher advertises every
composite found in the CRS-synced harnesses/ tree (dispatcher/poller.py
_collect_supported_harnesses), so merging this to origin/main IS the
advertisement event.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-04 09:35:34 +13:00
Paul O'Reilly
3717fc8167 feat(harness): cp-write-token/v1 context layer (Option C, WF-COMP-31c, item 26754227)
Env-only layer exporting CP_WRITE_TOKEN_FILE=/run/agent/cp-write-token/token.
The per-step wfcw_ token is delivered by the dispatcher into the script
container only (AU-55b), so the layer has no secrets_required, init script or
files. Not referenced by any composite yet; safe to merge at any time.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-04 09:35:07 +13:00
Paul O'Reilly
ea7c11265b fix(repo-readonly): own read-only deploy key; workflow-script drops write-capable gitea-ssh/v1
repo-readonly/v1 now declares write_targets: [], an ssh_hosts alias and its
own secrets_required (account platform-readonly.space:platform, a read-only
Gitea deploy key), and stages the key before cloning. workflow-script/v1 no
longer layers gitea-ssh/v1, so script nodes cannot push. Invariants updated:
credential layers in the composite must declare write_targets: [].

Bug 45a48685-23e9-4605-af1f-d93306108cef

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-02 20:09:30 +13:00
Paul O'Reilly
d850a4da68 fix(repo-readonly): clone when /workspace/project is empty, not only when absent (bug eede60c3)
harness_init pre-creates an empty /workspace/project, so the -d guard always skipped the clone.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-02 17:21:35 +13:00
Paul O'Reilly
4b41236e26 feat(harness): repo-readonly/v1 + gitea-ssh layer in workflow-script/v1; agent_repo on test-validate/frozen-fixture-emit (WF-COMP-34, bug 3bee78fa/a3ba44bc) 2026-10-02 16:18:21 +13:00
Paul O'Reilly
8d7b3af77d fix(templates): add AGENT_UPSTREAM_REPO_URL/BRANCH to all workflow templates using the agent fork
Fresh agent branches were seeded from the stale fork main (AR-39 fell through to fork).
Work item 18efa01f-f941-4f16-bb67-9cafbb6d668a.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-02 15:03:34 +13:00
Paul O'Reilly
c91813de96 fix(agent-repo): AR-39b run base selector by absolute path; seed scope-decompose@2 from upstream
init.sh invoked 'python3 -m entrypoint.agent_repo_base' from /workspace/project, so a project
repo's own entrypoint/ shadowed the image's and the selector crashed. Invoke the image copy by
path. scope-decompose-sonnet@2 gains AGENT_UPSTREAM_REPO_URL/BRANCH so fresh spec branches seed
from upstream main instead of the stale fork main.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-02 14:54:37 +13:00
Paul O'Reilly
fce343cea1 test: drop archived bug-ancestor-auto-advance@1 from state-tx/CP_URL discovery sets
Template moved to _archived/ (c7da48d7); glob discovery no longer sees it.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-01 19:37:36 +13:00
Paul O'Reilly
71363a77bb merge: archive bug-ancestor-auto-advance@1 (replaced by CRS patch_item rule bug-milestone-auto-resolve)
Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-01 18:19:23 +13:00
Paul O'Reilly
1e236b07d0 merge: workflow-script/v1, state-tx runtime_env + FROM_STATES, ingress CP_URL
Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-01 18:19:22 +13:00
Paul O'Reilly
e51146fc30 fix: task templates use ingress CP_URL (https://agents.oreillyit.nz/api), not svc.cluster.local:8100
The deploy repo NetworkPolicy admits :8100 only from named apps and the traefik/cms-proxy
namespaces; agent/script pods time out, so state-tx / cp-cli calls silently lost transitions.
Invariant now rejects the in-cluster form and pins the ingress URL.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-01 18:14:30 +13:00
Paul O'Reilly
782eadb615 feat: STATE_TX_FROM_STATES on state-tx nodes; workflow-script composite invariant; refresh legacy-mount NOTE
Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-01 17:02:29 +13:00
Paul O'Reilly
9e2dd681a7 merge: mm/fw-script (workflow-script/v1 composite) 2026-10-01 17:02:01 +13:00
Paul O'Reilly
c5a5293edc fix: declare runtime_env on state-tx nodes in test-validate@1 and frozen-fixture-emit@1
state-tx exits 2 without CP_URL and STATE_TX_NEW_STATE. Each template's
target state is its own output.state (test-validated / test-skeleton-ready).
Adds an invariant test.

Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-10-01 16:08:39 +13:00
Paul O'Reilly
b549a28187 feat(harnesses): shared-variables/v1 context + workflow-script/v1 composite (WF-COMP-31, WV-19) (03878b12-86b5-4b88-86d5-7182ae1c471f) 2026-10-01 15:31:48 +13:00
Paul O'Reilly
d727e17825 chore(workflow-templates): archive bug-ancestor-auto-advance@1.yaml per WT-ANC-15 step 2 (c7da48d7-1688-422b-8108-1119e819f9ea) 2026-10-01 15:25:27 +13:00
Paul O'Reilly
58612d9734 feat: AR-39b — scope-decompose-sonnet@2 + bug-verify-sonnet@2 (WV-36 file-write plan, WF-COMP-25a self-transition) (31553852-e6c7-40e3-8020-b3b65094c1cc) 2026-10-01 14:24:26 +13:00
Paul O'Reilly
da23760e93 fix(models): airouter-qwen3 default_flags.model Qwen3.6 -> Qwen3.8 (live id; agent-runtimes c3551e3a)
Claude-Session: https://claude.ai/code/session_01N218bERyNeLhbLmDRDvbWF
2026-09-30 11:46:24 +13:00
f64be1d467 fix(gitea-ssh-hatchmate): correct account_ref space id (hatchmate, not platform) (#4)
Merge PR #4
2026-09-18 02:18:46 +00:00
c89cb5beab Merge pull request 'feat(forge-credential): hatchmate working-repo key layer + 4 composite forks' (#3) from feat/hatchmate-per-project-fork-key into main
Merge PR #3
2026-09-18 02:05:48 +00:00
Paul O'Reilly
59f7b9e5f8 feat(forge-credential): add gitea-ssh-hatchmate/v1 layer + 4 hatchmate composite forks
M2-CRS W4 unblock: dispatched agents could not clone hatchmate/hatchmate-agents
because the shared gitea-ssh/v1 context mounts the ai_enablement deploy key,
which is scoped to skynet/* only. Same bug would hit every project whose
working repo lives outside the skynet org.

This implements the per-org pattern the framework already uses for accelerators
(gitea-ssh-accelerators/v1) and homelab (gitea-ssh-homelab/v1):

- harnesses/contexts/gitea-ssh-hatchmate/v1/{init.sh,harness.yaml} — NEW
  forge-credential context mirroring accelerators, with account_ref
  'hatchmate.space:platform' and write_targets covering hatchmate/*. The
  init.sh stages the ESO-mounted private key to ~/.ssh/gitea-oreillyit-nz-hatchmate
  (matching the ssh alias declared in harness.yaml). URL host pattern
  'gitea.oreillyit.nz-hatchmate' (per-org alias) drives SSH config block
  selection — already auto-written by harness_init.py from each layer's
  ssh_hosts: declarations.

- harnesses/composites/code-*-tdd-repo-hatchmate/v1/ — NEW composites for
  fable/minimax/airouter/opus that compose BOTH gitea-ssh/v1 (for reference
  clones, skynet org) AND gitea-ssh-hatchmate/v1 (for working-repo clone +
  push, hatchmate org). Composites are unchanged for non-hatchmate projects.

- tests/invariants/test_forge_credentials_declare_write_targets.py — the
  existing xfail(strict=True) marker was wrong: the 4 existing layers all
  declare write_targets today, so the test was XPASSing. Removed the
  xfail marker so HC-11 is now a real positive gate (5 layers instead
  of 4). This was a pre-existing test bug surfaced by the 5th layer.

W4 next step: dispatcher's account_ref resolution needs the hatchmate CP
account + grant to be created (via the new scripts/provision-hatchmate-fork-key.sh
in the hatchmate app repo).
2026-09-18 12:28:06 +12:00
Paul O'Reilly
d19da44f7a feat: AR-39a — templates pass AGENT_UPSTREAM_REPO_URL/BRANCH; agent-repo/v1 init.sh invokes select-base (upstream > reference > fork) (bug 0772408e)
Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
2026-09-16 19:34:47 +12:00
Paul O'Reilly
7e757b0fd9 harness(HC-11): declare write_targets on the four forge-credential layers (gitea-admin, gitea-ssh, gitea-ssh-accelerators, gitea-ssh-homelab) (b1de17b4)
Held locally until the agent-runtimes HC-11 composer change is deployed: the live composer is extra=forbid and would reject the new key.

Claude-Session: https://claude.ai/code/session_018LRh1S2bHJYhEgrMu3UJx8
2026-09-13 20:09:50 +12:00
Paul O'Reilly
b7cf256c44 test(invariants): HC-11 forge-credential layers must declare write_targets (xfail until layers are stamped)
Helper tests/invariants/forge_credentials.py detects credential carriers via
mounts[]/env/secrets_required[]/ssh_hosts[]; today gitea-admin, gitea-ssh,
gitea-ssh-accelerators, gitea-ssh-homelab are found and none declare
write_targets — the invariant xfails(strict) until the CRS-103 rollout stamps them.

Claude-Session: https://claude.ai/code/session_018LRh1S2bHJYhEgrMu3UJx8
2026-09-13 13:09:24 +12:00
Paul O'Reilly
e31d472ff9 fix: migrate Claude model files to current API IDs (opus-5, sonnet-5, haiku-4.5)
Bug 57d8a047-d26d-47ce-ae6f-bc5cb98fef0e: Opus-tier tasks 404'd because
models/claude-opus-4.yaml pinned default_flags.model to "claude-opus-4-5",
a retired ID. models/claude-sonnet-4.yaml was pinned to a dated snapshot
("claude-sonnet-4-20250514") with the same problem.

Slug strategy: the registry slug (filename / RegistryEntry.name) doubles
as the literal --model argument on the workflow-template pass-through path
(task-templates/workflow/*.yaml `model:` field -> compiler WF-COMP-18 ->
payload.runtime.model -> entrypoint/runners/claude.py `--model`), which has
no translation step through this file's default_flags. So rather than
patch default_flags.model in place (leaving the slug stale and the
pass-through bug latent), rename the slug to match the current API ID:

- models/claude-opus-4.yaml, model-registry/claude-opus-4.yaml
  -> claude-opus-5.yaml (name/endpoint/default_flags.model: claude-opus-5)
- models/claude-sonnet-4.yaml, model-registry/claude-sonnet-4.yaml
  -> claude-sonnet-5.yaml (claude-sonnet-5)
- model-registry/claude-haiku-4.yaml -> claude-haiku-4-5.yaml
  (claude-haiku-4-5); added the previously-missing models/claude-haiku-4-5.yaml
  so the claude runner can actually resolve this endpoint
- model-registry/harness-roles.yaml, model-registry/tiers.yaml,
  workflows/smart-agent.yaml, task-templates/workflow/{spec,plan}-review-loop@1.yaml:
  updated every claude-opus-4 / claude-sonnet-4 / claude-haiku-4 reference
  to the new slugs
- models/openrouter-sonnet.yaml: dated snapshot "claude-sonnet-4-20250514"
  -> "claude-sonnet-5" (third-party router proxying the same retired ID)
- refreshed cost_per_1k_tokens on the three renamed registry entries to
  current published pricing

Claude-Session: https://claude.ai/code/session_015nXvGNNNixJPFwZKZHNyha
2026-09-10 12:05:14 +12:00
Paul O'Reilly
30c3a75c20 feat(workflow): bug-ancestor-auto-advance@1 demo template (M43 Task 2) 2026-09-10 09:35:29 +12:00
Paul O'Reilly
3eabc924a2 refactor(python-dev): swap pip -> uv pip for project install
uv is now pre-baked into the base image
(agent-runtimes/images/base/Dockerfile) and is faster than pip with
better retry on transient network failures. Closes the last runtime
hang vector for project-deps install — apt install was removed 2026-09-06
in 0c57972f-pre-bake work but the pip install -e line in init.sh
remained. uv pip install is the equivalent operation with the new
pre-baked tooling.

Refs F-WE-PDIV/RCA-2026-09-04-zombies.
2026-09-09 21:56:48 +12:00
Paul O'Reilly
be57e1e246 fix(bug-verify): fresh UUID Idempotency-Key so re-verification with a different verdict does not 409
Claude-Session: https://claude.ai/code/session_01U3biMxRhFGkwtf4jVTNjcj
2026-09-09 13:57:40 +12:00
Paul O'Reilly
33501ca54e fix(bug-verify-sonnet@1): agent self-transitions flow_state, remove dead verdict-tx node
verdict-tx (kind: script) never worked: script nodes are harness-exempt
(WF-COMP-6/MN-38) and run in their own empty container, so it could
never credentially read /workspace/verdict from the agent's node.

Option 3: give the agent node's own composite (planning-sonnet-repo) a
cp-service-token/v1 layer, and have the agent PATCH its own item's
flow_state (verified|rejected) to the CP directly as its last step,
before task_complete. Removes verdict-tx entirely.

See agent-runtimes work item 88ecd23e and spec/typed-workflows.md
WF-COMP-25 (agent-runtimes commit 8972d266) for the finalize.py
precedence fix this depends on (ambiguous pipe-separated output.state
must never be auto-PATCHed over the agent's own value).

Claude-Session: https://claude.ai/code/session_01U3biMxRhFGkwtf4jVTNjcj
2026-09-09 13:56:34 +12:00
Paul O'Reilly
5a8cd32aec feat(harnesses): add customer-script/v1 composite
Minimal harness for kind: customer_script nodes (agent-runtimes
spec/tenant-namespaces.md SCR-1..SCR-6). No LLM turn - runs via the
"shell" runner, agent-repo/v1 clone access only. Per-script credential
needs are deliberately not baked into this base (SCR-6: narrow,
per-script review) - compose a customer-script-<need>/v1 variant
layering whichever specific credential context a given script actually
needs, rather than widening this shared base.

Without this commit, kind: customer_script was not dispatchable from
any machine other than the one it was authored on - the harness lookup
against a fresh CRS sync would fail.

Claude-Session: https://claude.ai/code/session_012arAwUuBQrpnMzJ36mEVBk
2026-09-08 07:42:48 +12:00
Paul O'Reilly
3a550837aa docs(bug-verify-sonnet): note the scratchpad/verdict follow-up, not yet wired
Attempted to wire verdict-tx to clone the agent's branch and read
scratchpad/verdict (the new cross-node artifact convention,
agent-repo/v1 init.sh) instead of the ephemeral /workspace/verdict.
Reverted: script tasks (dispatcher/task_manager.py::_run_script_task)
have no credentialed way to clone a private repo — the per-task SSH key
is provisioned through the full ESO/account harness resolution
pipeline, which script tasks deliberately bypass entirely. Left the
template on its current (still-broken-for-cross-container-reasons)
/workspace/verdict contract with a note, pending a scoped follow-up on
how script nodes get read access to the branch (new secrets plumbing,
vs. folding the state transition into the agent node's own already-
credentialed CP access).
2026-09-06 23:59:52 +12:00
Paul O'Reilly
4b4d02926d feat(agent-repo): create scratchpad/ at task branch top level
Cross-node artifact passing within a workflow manifest — nodes each run
in their own ephemeral container/pod with no shared filesystem, so an
agent node writing e.g. a verdict to /workspace/verdict is invisible to
a downstream kind: script node in the same manifest (found live
2026-09-06, bug-verify-sonnet's verdict-tx). The git task branch is the
only channel every node in a manifest actually shares: write to
scratchpad/, commit (picked up by finalize.sh's existing git add -A),
next node clones the same branch and reads it back.

scratchpad/ is scratch, never deliverable content, and must never
survive a merge into main — a CI gate in the target repo
(agent-runtimes .gitea/workflows/build-images.yaml,
no-scratchpad-in-main) is the hard backstop.
2026-09-06 23:44:51 +12:00
Paul O'Reilly
a685bf16a6 feat: bug-verify-sonnet@1 template + planning-sonnet-repo runtime
Adds the CRS-side deliverables for agent-runtimes work item f59f0132
(ai-resolve bug-verification stage, M42 concept 7666d278). Mirrors
planning-opus-repo's layer stack with the sonnet model applied at the
node level (model: sonnet), per the established convention that the
composite name is descriptive only — the workflow node's own model:/
tier: field is what actually selects the model.

The template's terminal node runs the (separately-tracked, sibling
task ad975ac6) state-tx-verdict script — this template will not be
runnable end-to-end until that script lands, but the declarative
config itself is independently valid: schema-validates cleanly and
both eligibility scenarios from the task spec pass (verify-pending +
ai-resolve -> ok=True; missing flow_state -> state_mismatch).
2026-09-05 11:34:37 +12:00
Paul O'Reilly
0384e5d453 fix: remove misplaced hatchmate-plan-review-loop@1 (project template referencing hatchmate-crs model slugs; broke CP WorkflowRegistry reload 2026-09-05)
Belongs in hatchmate-crs/task-templates/workflow/plan-review-loop@1.yaml, which already exists.

Claude-Session: https://claude.ai/code/session_01FNHuaZyTjdknKYcQdbRTcp
2026-09-05 10:24:36 +12:00
Paul O'Reilly
b4bac0d2e8 feat: hatchmate-plan-review-loop@1 — project-specific plan review template
Hand-sync of hatchmate-crs's plan-review-loop@1 under a project-prefixed name
so hatchmate's triggers can reference it via the global WorkflowRegistry.

Interim pattern until agent-runtimes ships project-scope template serving
via crs_manager (M42 gap: DispatchService only consults the concepts_syncer
WorkflowRegistry, not crs_manager's repo store). Template is hatchmate-specific
throughout: Fable-low + MiniMax-M3-max + Airouter-Qwen3.8-max reviewers,
hatchmate/hatchmate-agents clone URL, hatchmate-aware prompts and conventions.

Claude-Session: https://claude.ai/code/session_01PdFrhZypEDBTsbAeTJqHq1
2026-09-04 20:49:13 +12:00
Paul O'Reilly
253b147a39 fix(harness): cp-service-token/v1 — restage ESO secret, fix unreadable-by-agent bug
The ESO-mounted secret is root-owned mode 0400 (correct — init.sh runs as
root before the gosu drop to the agent user). The original version of
this context pointed CP_SERVICE_TOKEN_FILE directly at that raw mount,
which the agent process (uid 1000) can never read.

Confirmed live 2026-09-03: a real scope-decompose-sonnet@1 dispatch
against concept 7666d278-ae58-4f12-990d-c4959a3e19a9 hit exactly this —
the agent correctly diagnosed 'cp_cli invocation can't proceed... token
is root-owned mode 0400 so it's not readable by the agent user', wrote
its decompose plan, but could never actually call cp-cli to create the
child tasks. The trigger engine's new side-effect verification (finalize.py,
bug 9dffc5b8) correctly caught this and refused to advance flow_state —
so this was a visible, retriable failure rather than another silent
false-positive.

Fix: init.sh restages the secret to /run/agent/cp-service-token/token,
mode 0600, owned by the agent user — mirrors
anthropic-cloud-paul-oauth/v1/init.sh's existing pattern.
CP_SERVICE_TOKEN_FILE now points at the restaged copy.
2026-09-04 13:03:07 +12:00
Paul O'Reilly
38cd0b040b feat(harness): cp-service-token/v1 context — AU-51/AU-51b credential for decompose
New context mounts the cp-decompose-service-token account (system
provider type, account_id 1d963673-6ac9-4f85-875a-2ce5323e76ad, owner
(cp, cp)) via ESO and exports CP_SERVICE_TOKEN_FILE pointing at the
mounted secret file. Wired into spec-writing-sonnet-repo (backs
scope-decompose-sonnet@1, which calls back POST
/v1/work-items/{id}/decompose — bug b3a96acc / fa41caac / M42 stall).

The mounted value must match the CP's CP_INTERNAL_BEARER_TOKEN
(agent-runtimes deploy repo, overlays/{production,staging}/app-secret.sops.yaml).

No init.sh needed — the mount path is static at harness-authoring time
and entrypoint/actions/decompose_work_items.py (AU-51b, agent-runtimes
commit 0fa8b760) reads CP_SERVICE_TOKEN_FILE directly, so no
transformation/staging step is required.
2026-09-04 05:31:34 +12:00
Paul O'Reilly
2dcb9c7605 fix(minimax-m3-max, fable-low-effort): requires takes harness refs, not capability tags
'requires: [claude-code]' failed composition ('Invalid harness reference
format'). Both contexts need no hard dependency — layer ordering in the
composites already guarantees the auth layer precedes them. Validated
locally with entrypoint.harness compose_harness for all 6 affected
composites this time.

Claude-Session: https://claude.ai/code/session_019tJk7P8tZzJ24PvtgoGhLN
2026-09-03 01:13:34 +12:00
Paul O'Reilly
7244e0ec5f fix(minimax-m3-max, fable-low-effort): H-SECRET-4 rejected MAX_THINKING_TOKENS in env
The validator pattern-matches *TOKEN* as credential-shaped and rejected
both contexts, failing every task on the new harnesses. The env var name
is fixed by Claude Code, so deliver the thinking budget via the
settings.json env map in init.sh instead (jq-merge preserves apiKeyHelper
from the minimax/oauth layer).

Claude-Session: https://claude.ai/code/session_019tJk7P8tZzJ24PvtgoGhLN
2026-09-03 00:39:59 +12:00
Paul O'Reilly
2fa4dc92c2 pipeline model routing: mechanical stages to MiniMax M3, spec stages to Fable low effort
- scaffolding-repo + test-writing-repo: anthropic-cloud-paul-oauth -> minimax + minimax-m3-max
- merge@1: new best-practices-minimax-repo composite (impl-review stays Sonnet)
- spec-draft-opus@1: Opus -> Fable 5 low effort via new fable-low-effort/v1
  env context (ANTHROPIC_MODEL=claude-fable-5, MAX_THINKING_TOKENS=1024) +
  spec-writing-fable-low-repo composite
- review-spec-arch-opus@1: Qwen3.6/airouter -> Fable 5 low effort via
  best-practices-fable-low-repo (arch review was on the cheapest model)

Template names kept (trigger rules reference them). Node model: fields
removed where env pins the model — a --model flag overrides ANTHROPIC_MODEL.

Claude-Session: https://claude.ai/code/session_019tJk7P8tZzJ24PvtgoGhLN
2026-09-02 21:43:23 +12:00
Paul O'Reilly
4201b1ac3a integration-direct: route to MiniMax M3 max-effort instead of Anthropic OAuth
Integration runs were burning the personal Anthropic 5-hour window
(429 storm + window drain, 2026-09-02). New env-only context
minimax-m3-max/v1 pins ANTHROPIC_MODEL=MiniMax-M3[1m], maxes the
thinking budget, and sets the 1M auto-compact window; layered on
minimax/v1 for base URL + apiKeyHelper auth.

Claude-Session: https://claude.ai/code/session_019tJk7P8tZzJ24PvtgoGhLN
2026-09-02 21:33:50 +12:00
Paul O'Reilly
e89208f44b fix(templates): per-item branches for concept-stage nodes (was shared spec/auto-draft)
All 6 concept/idea-stage templates hardcoded the literal shared branch
spec/auto-draft instead of a per-item branch. Concurrent concept items
(now routine via the M41 auto-advance sweep) all pushed to the same
branch — a git collision risk. Switched to spec/${item.uuid}, matching
the established task/${item.uuid} convention used by every task-stage
template (merge@1, scaffold@1, etc — see spec/typed-workflows.md WF-COMP
stable-per-item-branch rationale). spec-review-loop@1's 4 nodes keep the
literal branch shared ACROSS the node set (now per-item, not global) so
loop iterations still accumulate on one branch per item, per spec's
cross-iteration-artifact caveat.

Files: review-spec-arch-opus@1.yaml, spec-draft-opus@1.yaml,
spec-review-loop@1.yaml, review-spec-arch-airouter@1.yaml,
spec-draft-airouter@2.yaml, scope-decompose-sonnet@1.yaml
2026-09-01 02:11:20 +12:00
Paul O'Reilly
e0d3a60279 fix(templates): spec-draft-opus@1 route to Opus, not airouter/Qwen3.6
Was silently dispatching to Qwen3.6 via airouter despite the name;
live runs were timing out (exit_code=124), wedging four M41 auto-advance
concepts. Mirrors agent-runtimes commit acc5cbe5.

Claude-Session: https://claude.ai/code/session_012arAwUuBQrpnMzJ36mEVBk
2026-09-01 00:37:52 +12:00
Paul O'Reilly
fefc8846c3 templates: reference triggers.yaml with WT-ADV safe defaults (M41)
version: 2 + auto_advance default deny — imported projects are inert until
a human applies a grant tag (spec/workflow-triggers.md §3b WT-ADV-8).

Claude-Session: https://claude.ai/code/session_012arAwUuBQrpnMzJ36mEVBk
2026-08-30 02:56:03 +12:00
Paul O'Reilly
73acc6a11d feat(best-practices): pointer CLAUDE.md so agents know the library exists
The 237KB library was mounted at /workspace/best-practices/ in every
consuming ConfigMap but nothing in the prompt mentioned it (directory
targets never enter the context manifest). New ~90-word CLAUDE.md file
target enters the system prompt: points at INDEX.md, instructs reading
only task-relevant topics.

Claude-Session: https://claude.ac/code/session_012arAwUuBQrpnMzJ36mEVBk
2026-08-19 09:34:31 +12:00
Paul O'Reilly
1ce42a9e59 fix(harness): resolve layer contradictions + context-budget caps for airouter TDD
- tdd-gate: pass criterion is the task's TEST_FILES scope (matches
  run-ci-tests.sh M19 P-14), not the full suite — contradicted
  qwen-code-methodology rule 5 in the same system prompt
- tdd-protect: tests/ path described relative to project working dir
  (AGENT_WORKING_DIR is /workspace/project in repo composites)
- qwen-code-methodology: task_complete tool DOES exist — rule 8 said
  the opposite; pytest examples use -q
- airouter-code-tdd template: TT-39 runtime_overrides
  (max_result_bytes 24KB, max_history_turns 16)

Claude-Session: https://claude.ai/code/session_012arAwUuBQrpnMzJ36mEVBk
2026-08-19 09:10:22 +12:00
Paul O'Reilly
76a7277961 fix(decompose-template): replace inline python3 -c paste with cp-cli decompose verb
The python3 -c block imported internal entrypoint code directly and
pasted module paths into agent prompts — a security boundary violation.
Switch to the thin-client verb (added in agent-runtimes a116aedb).

Claude-Session: https://claude.ai/code/session_0124mK2BVfCdkELLXDCr5Zzs
2026-08-17 10:11:22 +12:00