docs(beta-delivery-ux): S4 kickoff §7d — retract the unreachable host path, bind run-3 blockers - #1319
Merged
Merged
Conversation
added 5 commits
August 8, 2026 11:39
…six #1284 parks (re-dispatch rev) Records the operator's 2026-08-08 batch: Park-1 schema = flat Candidate A + description field; Park-2 format = JSON (F-B' shell-sourced rejection recorded with the WHY); Park-3 economy review = whole line on executor tier, aif cap 1 iteration, external cold fidelity mandatory; Park-4 CC detection = CLAUDE_CODE_SESSION_ID env-presence capability check; Park-5 conditional park did not fire (live runtime-profiles probe, no substring collision); Park-6 ship the full functional set (create-worktree.sh + worktree-node-modules.sh + link-coordination.sh) under the same $1j gate, fresh-consumer smoke AC added. Unblocks the S2 re-dispatch (A4 presets + A5 status + A9 parts 2-3).
…ry-ux-pipeline-ac40e1
…GUOUS + host-verify contract Run 2 (aif task 92bf0019) returned FIDELITY STOP with KICKOFF-AMBIGUOUS (PR #1300). The kickoff's §7a never states how the aif runtime acquires the key VALUE: #1 stores only the env-var NAME in the profile, #4(ii) writes the value to ~/.config/getff/glm.env, and #3 requires the validation ping to run through the created profile. Verified against source: aif resolves the key from its own runtime process.env by that name (aif-handoff packages/runtime/src/resolution.ts:217-219, :247), and that env comes from the compose env-file (docker-compose.yml:15,59,94) — so glm.env is a dead end as written and #3 is unreachable without dereferencing the value, which #1 forbids. §7b closes it by binding the OUTCOME (value reachable in the aif runtime process env under the §7a #1 name, verified before the ping, honest objective-3 MISS on failure) while leaving the wiring mechanism to the worker as a §7 technical fork. It is marked as a dispatcher-authored completion, not an operator decision — the operator can override it. §7c carries run 2's settled corrections: PUT /projects/:id with a full body (aifHttp.ts:96) instead of the invented PATCH /project, no GET /projects/:id (:90), both defaults halves, ping through the profile, 10-skills.sh untouched. §4.1 adds the missing host-verify contract — the stage ships a shell helper, an install-time gate and a tests/install-sh suite, i.e. exactly the container-vs-host surface destination-environment-verification.md §1 exists for; the umbrella had no contract on any of its six kickoffs (exit 2). Prior-art: skipped — dispatch-input documentation only, no new capability; resolves an ambiguity in an existing stage kickoff against in-repo source citations.
… path, bind run-3 blockers §7d.0 retracts the §1 + §7a #1 instruction to re-read `~/code/aif-handoff/packages/api/src/routes/runtimeProfiles.ts` at stage entry. That path is host-only: the agent container mounts `$PROJECTS_DIR` (= `$PROJECTS_HOST_ROOT/projects`), so the repo root holding `packages/api/` sits one level above the mount. The instruction was unexecutable and run 3 guessed instead of parking — same class as state.md §2 decision 14. Replacement is an oracle the container can actually reach: the live aif API. §7d.1 pins two probes (required-field discovery + route-existence discovery) with the dispatcher's own 2026-08-09 outputs recorded for reproduction, not for trust. Run-3 blockers bound as corrections: §7d.2 `runtimeId`+`providerId` required in the create body; §7d.3 the ping route is `POST /runtime-profiles/validate` (the guessed `/<id>/v1/messages` → 404); §7d.4 §7b #1 still undelivered (the helper verifies reachability but never establishes it); §7d.5 companion install is prose in a field `engine.sh:18` early-returns past; §7d.6 (MAJOR) the suite mocks the non-existent endpoint and a body-blind 201, so §4.1 passed over §7d.2/§7d.3 — the stub becomes fail-closed with a paired-negative that fails on the run-3 helper, and `it.fails()`-as-delivery is banned. Adds T-BDU-D: unreachable instructed source → probe, else PARK; never substitute a plausible shape. Prior-art: skipped — kickoff prose revision only, no new capability; markdown is exempt from the capability-commit LOC triggers per CLAUDE.md.
…ry-ux-pipeline-ac40e1 # Conflicts: # .claude/orchestrator-prompts/beta-delivery-ux/kickoff-s4.md
added 3 commits
August 9, 2026 00:25
…, and the container trap under it Own cold-QA of #1319 caught two defects in §7d.1. (1) It invented `$AIF`; the helper actually resolves `AIF_URL="${RUNTIME_BRIDGE_AIF_URL:-http://localhost:3009}"` (scripts/getff-glm-onebutton.sh:94), so the probe block now uses that name. (2) The more load-bearing half: that shipped default is unreachable from the agent container. Measured 2026-08-09 from aif-handoff-agent-1 — `http://localhost:3009/runtime-profiles` → curl exit 7 (000), `http://api:3009/runtime-profiles` → 200. `RUNTIME_BRIDGE_AIF_URL` is unset in the container, so an in-container run of the run-3 helper could not have reached aif at all, which is consistent with the suite mocking every call (§7d.6). §7d.1 now instructs the export for probing, explicitly forbids changing the shipped consumer default, and §4 item 1 must quote the base URL alongside any live end-to-end transcript. Prior-art: skipped — kickoff prose correction only, no new capability; markdown is exempt from the capability-commit LOC triggers per CLAUDE.md.
…r; the ping is two halves §7d.3 as first written told the worker to route §7a #3's «one real minimal model call» through `POST /runtime-profiles/validate` and left a falsifier for the case where that endpoint is only a reachability check. The dispatcher fired that falsifier itself rather than shipping the trap: - for `transport: "api"`, `validateClaudeConnection` returns ok after checking only that `apiKey` and `baseUrl` are non-empty — no network call (aif-handoff packages/runtime/src/adapters/claude/index.ts:468-479). Live 2026-08-09: `/validate` against the Qwen3.8-Max-Preview profile returned ok:true sub-second. - `POST /runtime-profiles/models` is not a substitute — it returned a static Claude catalogue (Sonnet 4.6, Opus 4.6) for a Qwen profile, so it is not querying the provider. So §7a #3 and §7c #3 cannot both be satisfied by one aif REST call. §7d.3 now binds both halves — `/validate` for the route proof, plus one 1-token-scale completion against the `baseUrl` READ BACK from that response (not a hardcoded `$GLM_BASE_URL`, which was run 2's W-3 defect). Provenance is stated as dispatcher-authored and operator-overridable, matching §7b. §7d.4 gains an exact, value-free verifier for §7b #3: `hasApiKey` is `Boolean(resolved.apiKey)` and `resolved.apiKey` is `normalizeString(env[envVarName])` off the aif runtime's own process.env (packages/runtime/src/resolution.ts:426, :217-219), so `hasApiKey:true` in the §7d.3(1) response IS proof that §7b #1's outcome was achieved — without dereferencing the key, without argv exposure. Prior-art: skipped — kickoff prose correction only, no new capability; markdown is exempt from the capability-commit LOC triggers per CLAUDE.md.
#1318 landed a §7d on the same file while this branch was in flight, so the block authored here is renumbered §7d → §7e and rebuilt on top of #1318 rather than over it. #1318's content is kept intact. Two corrections to §7d, both evidence-backed: §7e.0 — §7d step 1 orders `git merge feature/beta-delivery-ux-92bf00`, which is run 2 (task 92bf0019, 2026-08-08T01:04Z). Run 3 (task e65989fa, commit 53fce45, 14:51Z) is newer and already carries every §7c correction. Measured: getff-glm-onebutton.sh is 212 lines on 92bf00, still holding `PATCH "$AIF_URL/project"` (:135) and the vendor-direct ping (:171), versus 361 lines at 53fce45 with the profile-routed path in place. Basing on 92bf00 re-does ~150 accepted lines and re-opens two closed defects. §7e.3 — §7d.1 states `POST /runtime-profiles/validate` «exercises the route the flow just built» and is «exactly what §7a #3 / §7c #3 ask for». For `transport: "api"` it makes no network call at all — it checks only that apiKey and baseUrl are non-empty (aif-handoff packages/runtime/src/adapters/claude/index.ts:468-479); live, `/validate` against the Qwen3.8-Max-Preview profile returned ok:true sub-second, and /runtime-profiles/models returned a static Claude catalogue for that same Qwen profile. The ping is therefore split in two: /validate for the route proof, plus one 1-token-scale completion against the baseUrl read back from that response. Carried over unchanged in substance: §7e.1 (host-path retraction + the container base-URL trap — localhost:3009 → 000, api:3009 → 200), §7e.2 (runtimeId/providerId required), §7e.4 (§7b #1 undelivered; hasApiKey as its exact value-free verifier), §7e.5 (companion install in a dead field), §7e.6 (fail-closed mock, it.fails-as-delivery banned). §6 gains T-BDU-D and T-BDU-E. Prior-art: skipped — kickoff prose revision only, no new capability; markdown is exempt from the capability-commit LOC triggers per CLAUDE.md.
This was referenced Aug 9, 2026
artyhoo
added a commit
that referenced
this pull request
Aug 9, 2026
…, name frozen against the live registry (#1336) * docs(beta-delivery-ux): S2 kickoff §8a — operator resolutions of the six #1284 parks (re-dispatch rev) Records the operator's 2026-08-08 batch: Park-1 schema = flat Candidate A + description field; Park-2 format = JSON (F-B' shell-sourced rejection recorded with the WHY); Park-3 economy review = whole line on executor tier, aif cap 1 iteration, external cold fidelity mandatory; Park-4 CC detection = CLAUDE_CODE_SESSION_ID env-presence capability check; Park-5 conditional park did not fire (live runtime-profiles probe, no substring collision); Park-6 ship the full functional set (create-worktree.sh + worktree-node-modules.sh + link-coordination.sh) under the same $1j gate, fresh-consumer smoke AC added. Unblocks the S2 re-dispatch (A4 presets + A5 status + A9 parts 2-3). * docs(beta-delivery-ux): S4 kickoff §7b/§7c — close run-2 KICKOFF-AMBIGUOUS + host-verify contract Run 2 (aif task 92bf0019) returned FIDELITY STOP with KICKOFF-AMBIGUOUS (PR #1300). The kickoff's §7a never states how the aif runtime acquires the key VALUE: #1 stores only the env-var NAME in the profile, #4(ii) writes the value to ~/.config/getff/glm.env, and #3 requires the validation ping to run through the created profile. Verified against source: aif resolves the key from its own runtime process.env by that name (aif-handoff packages/runtime/src/resolution.ts:217-219, :247), and that env comes from the compose env-file (docker-compose.yml:15,59,94) — so glm.env is a dead end as written and #3 is unreachable without dereferencing the value, which #1 forbids. §7b closes it by binding the OUTCOME (value reachable in the aif runtime process env under the §7a #1 name, verified before the ping, honest objective-3 MISS on failure) while leaving the wiring mechanism to the worker as a §7 technical fork. It is marked as a dispatcher-authored completion, not an operator decision — the operator can override it. §7c carries run 2's settled corrections: PUT /projects/:id with a full body (aifHttp.ts:96) instead of the invented PATCH /project, no GET /projects/:id (:90), both defaults halves, ping through the profile, 10-skills.sh untouched. §4.1 adds the missing host-verify contract — the stage ships a shell helper, an install-time gate and a tests/install-sh suite, i.e. exactly the container-vs-host surface destination-environment-verification.md §1 exists for; the umbrella had no contract on any of its six kickoffs (exit 2). Prior-art: skipped — dispatch-input documentation only, no new capability; resolves an ambiguity in an existing stage kickoff against in-repo source citations. * docs(beta-delivery-ux): S4 kickoff §7d — retract the unreachable host path, bind run-3 blockers §7d.0 retracts the §1 + §7a #1 instruction to re-read `~/code/aif-handoff/packages/api/src/routes/runtimeProfiles.ts` at stage entry. That path is host-only: the agent container mounts `$PROJECTS_DIR` (= `$PROJECTS_HOST_ROOT/projects`), so the repo root holding `packages/api/` sits one level above the mount. The instruction was unexecutable and run 3 guessed instead of parking — same class as state.md §2 decision 14. Replacement is an oracle the container can actually reach: the live aif API. §7d.1 pins two probes (required-field discovery + route-existence discovery) with the dispatcher's own 2026-08-09 outputs recorded for reproduction, not for trust. Run-3 blockers bound as corrections: §7d.2 `runtimeId`+`providerId` required in the create body; §7d.3 the ping route is `POST /runtime-profiles/validate` (the guessed `/<id>/v1/messages` → 404); §7d.4 §7b #1 still undelivered (the helper verifies reachability but never establishes it); §7d.5 companion install is prose in a field `engine.sh:18` early-returns past; §7d.6 (MAJOR) the suite mocks the non-existent endpoint and a body-blind 201, so §4.1 passed over §7d.2/§7d.3 — the stub becomes fail-closed with a paired-negative that fails on the run-3 helper, and `it.fails()`-as-delivery is banned. Adds T-BDU-D: unreachable instructed source → probe, else PARK; never substitute a plausible shape. Prior-art: skipped — kickoff prose revision only, no new capability; markdown is exempt from the capability-commit LOC triggers per CLAUDE.md. * docs(beta-delivery-ux): S4 kickoff §7d.1 — name the real base-URL var, and the container trap under it Own cold-QA of #1319 caught two defects in §7d.1. (1) It invented `$AIF`; the helper actually resolves `AIF_URL="${RUNTIME_BRIDGE_AIF_URL:-http://localhost:3009}"` (scripts/getff-glm-onebutton.sh:94), so the probe block now uses that name. (2) The more load-bearing half: that shipped default is unreachable from the agent container. Measured 2026-08-09 from aif-handoff-agent-1 — `http://localhost:3009/runtime-profiles` → curl exit 7 (000), `http://api:3009/runtime-profiles` → 200. `RUNTIME_BRIDGE_AIF_URL` is unset in the container, so an in-container run of the run-3 helper could not have reached aif at all, which is consistent with the suite mocking every call (§7d.6). §7d.1 now instructs the export for probing, explicitly forbids changing the shipped consumer default, and §4 item 1 must quote the base URL alongside any live end-to-end transcript. Prior-art: skipped — kickoff prose correction only, no new capability; markdown is exempt from the capability-commit LOC triggers per CLAUDE.md. * docs(beta-delivery-ux): S4 kickoff §7d.3/§7d.4 — fire my own falsifier; the ping is two halves §7d.3 as first written told the worker to route §7a #3's «one real minimal model call» through `POST /runtime-profiles/validate` and left a falsifier for the case where that endpoint is only a reachability check. The dispatcher fired that falsifier itself rather than shipping the trap: - for `transport: "api"`, `validateClaudeConnection` returns ok after checking only that `apiKey` and `baseUrl` are non-empty — no network call (aif-handoff packages/runtime/src/adapters/claude/index.ts:468-479). Live 2026-08-09: `/validate` against the Qwen3.8-Max-Preview profile returned ok:true sub-second. - `POST /runtime-profiles/models` is not a substitute — it returned a static Claude catalogue (Sonnet 4.6, Opus 4.6) for a Qwen profile, so it is not querying the provider. So §7a #3 and §7c #3 cannot both be satisfied by one aif REST call. §7d.3 now binds both halves — `/validate` for the route proof, plus one 1-token-scale completion against the `baseUrl` READ BACK from that response (not a hardcoded `$GLM_BASE_URL`, which was run 2's W-3 defect). Provenance is stated as dispatcher-authored and operator-overridable, matching §7b. §7d.4 gains an exact, value-free verifier for §7b #3: `hasApiKey` is `Boolean(resolved.apiKey)` and `resolved.apiKey` is `normalizeString(env[envVarName])` off the aif runtime's own process.env (packages/runtime/src/resolution.ts:426, :217-219), so `hasApiKey:true` in the §7d.3(1) response IS proof that §7b #1's outcome was achieved — without dereferencing the key, without argv exposure. Prior-art: skipped — kickoff prose correction only, no new capability; markdown is exempt from the capability-commit LOC triggers per CLAUDE.md. * docs(beta-delivery-ux): R1 stage kickoff — npm release mechanics (A6) R1 is the last unstarted stage of the umbrella (S1-S5 all merged). This is its dispatch input, scoped from the spec (§4 A6 `:278-284`, §11 F-C' `:467-468`) and the binding input `launch-preannounce-track/s6-u10-handoff.md`. Three things the kickoff decides, because a worker cannot: 1. Dispatchability (§0.1) — R1 IS aif-dispatchable. `private: true` STAYS on `packages/core/package.json` for the whole stage; npm refuses to publish a private package, so the publish guard is mechanical rather than a reminder (attention-is-not-a-mechanism §1). Verified `npm pack --dry-run` works on a private package, so the tarball loop runs with the guard armed. 2. Name architecture (§0.2) — probed the live registry, not the spec's prose: unscoped `getff` ALREADY EXISTS at 0.0.1, published 2026-06-23 by the maintainer as a reservation stub. So the registry-side freeze is done, 0.0.1 is spent as a version, and `@getff` SCOPE ownership stays unproven (a 404 on `@getff/core` proves the package is free, not the scope) — that is an entry probe with a STOP attached. 3. Scope boundary (§0.3) — R1 does NOT execute the `@rules-as-tests/*` rename. Measured blast radius 33 tracked files / 55 occurrences; umbrella §3 puts the rename in U9 (post-announce), and the acceptance gate is name-independent because `npm i <tarball>` installs by path. Also recorded: two gates of the binding input's §0 are SUPERSEDED by the 2026-07-23 amendment (U9 no longer the rename window; the private-drop ordering), and the honest gap R1 does not close — U10's `npx getff init` gate needs a package with `bin: getff`, which does not exist in this repo and which A6 does not ask R1 to build. Host-verification contract declared (no opt-out): the new tarball cell plus the existing pnpm start cell, which is the file-copy fallback the §4 rollback doctrine requires to keep working. `scripts/host-verify.sh --list` parses both, exit 0. Prior-art: skipped — dispatch-input authoring only; a markdown kickoff adds no capability, no dependency, and no code module (CLAUDE.md doc-file carve-out). --------- Co-authored-by: Test <test@example.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Unblocks the S4 re-dispatch after run 3 (aif task
e65989fa, Audited-SHA53fce45f51) returnedFIDELITY: STOPwith four standing blockers and noKICKOFF-AMBIGUOUS. Every §7c correction from #1310 landed (W-2..W-5 CLEAN), so the kickoff's decisions held; what failed was one of its path citations — and that one is mine.§7d.0 — the dispatcher's defect, stated plainly. §1 and §7a #1 both ordered the worker to «re-read
~/code/aif-handoff/packages/api/src/routes/runtimeProfiles.tsat stage entry». That is a host path handed to a container worker. Measured 2026-08-09 fromaif-handoff-agent-1:PROJECTS_HOST_ROOT=/Users/art/code/aif-handoffandPROJECTS_DIR=$PROJECTS_HOST_ROOT/projects— onlyprojects/is mounted at/home/www, so the repo root holdingpackages/api/sits one level above the mount and is unreachable by any path. The instruction was unexecutable, and run 3 filled the gap by guessing. This is the same class as state.md §2 decision 14 in this very umbrella (an empirical sweep ordered over branches the worker could not see) — second occurrence, same file. Both instructions are retracted here rather than re-worded, because a rework brief that repeats «re-read the schema at entry» fails identically.The replacement is an oracle the container can actually reach. The live aif API answers the same questions the source file would, and it is reachable in-container (
curl -s -o /dev/null -w '%{http_code}' "$AIF/runtime-profiles"→200). §7d.1 pins two probes — required-field discovery and route-existence discovery — with the dispatcher's own 2026-08-09 outputs recorded for reproduction, not for trust, and the worker is told to re-run them. Generalised as binding: when a fact about aif is needed, probe the API; if neither source nor probe is available, that is a §7 park.Blockers bound as corrections (settled by probe, so not re-parked):
runtimeIdandproviderIdare required in the create body (getff-glm-onebutton.sh:222-226omits both → 400, step 5 could never run live). Probe (a) returns400ZodErrornamingpath: ["runtimeId"]andpath: ["providerId"], both"expected string, received undefined"— the API names its own required fields, so the minimal set of §7a feat: audit fixes Phase 1+2+3 (R2/R11 drift, manifest SSOT, depcruise integration) #1 is established by output rather than by reading a file.POST /runtime-profiles/validate(probe →400, i.e. exists and rejects an empty body); the guessed/runtime-profiles/<id>/v1/messages→404. Falsifier recorded: if/validateturns out to be a reachability check rather than a real model call it does not satisfy §7a chore(meta-factory): Phase 3 Step 0 retrofit + 3 MAJOR fixes #3 — park with the probe quoted, never substitute/health.getff-glm-onebutton.sh:204-216correctly verifies reachability (§7b chore(meta-factory): Phase 3 Step 0 retrofit + 3 MAJOR fixes #3), then:191-198prints wiring instructions andexit 1. Nothing makes the key reachable, so a first run always ends in a MISS. A helper that can only ever instruct is the#warning-nobody-readsshapeattention-is-not-a-mechanism.md §1rejects.companions.manifest:33puts clone+compose ininstall_cmd, whichsetup.d/engine.sh:18early-returns past forkind=external-service, andbridge-guided.sh:11-29only prints hints. No consent surface exists, so §4 item 4's «decline →envdegradation» has nothing to decline. Deliver it or park withengine.sh:18quoted — but do not leave prose in a dead field and report the objective met.tests/install-sh/glm-onebutton.test.sh:78-86mocks the guessed ping path →200andPOST /runtime-profiles→201regardless of body, so §4.1'shost-verifycommand passed over §7d.2 and §7d.3: «green» meant «the mock agrees with the helper». The fix is structural, not a reminder — thecurl()stub is fail-closed (allowlisted paths only, each carrying its probe date; required-field rejection mirroring the live400), plus a paired-negative proving the stub fails on the run-3 helper. A stub that cannot fail on known-bad input is not evidence.it.fails()-as-delivery is banned outright, closing the round-2 S2 shape where a known defect shipped as a passing suite plus an operator TODO.§4.1 keeps its contract but loses its false confidence — a note now states that a green run of
bash tests/install-sh/glm-onebutton.test.shis evidence only once §7d.6 is delivered.T-BDU-D added to §6: «the kickoff told me to read a file I cannot reach, so I filled the gap from plausibility». Run 3's sin was the guess, not the unreachability — the tell is any endpoint, field, or status code in the diff that no command output in the PR body establishes.
A fourth dispatch is legitimate on the §2.4 cap arithmetic: the cap counts consecutive REVISE on unchanged scope, and §7d is a scope change carrying five new obligations.
Fidelity verdict
FIDELITY: skipped — dispatch-input kickoff revision (docs-only, no Provenance section); every §7d claim is backed by a quoted probe output or an in-repo
file:line, and §7d.0 attributes the retracted instruction to the dispatcher rather than to the worker