Skip to content

feat(beta-delivery-ux): S4 run 3 — GLM one-button per kickoff §7b/§7c (A2) [FIDELITY STOP — base for run 4] - #1322

Closed
artyhoo wants to merge 1 commit into
stagingfrom
feature/beta-delivery-ux-e65989
Closed

feat(beta-delivery-ux): S4 run 3 — GLM one-button per kickoff §7b/§7c (A2) [FIDELITY STOP — base for run 4]#1322
artyhoo wants to merge 1 commit into
stagingfrom
feature/beta-delivery-ux-e65989

Conversation

@artyhoo

@artyhoo artyhoo commented Aug 9, 2026

Copy link
Copy Markdown
Owner

What

Harvest of aif task e65989fa-6a0e-448f-9ea3-eab7da315f2abeta-delivery-ux S4 run 3 (GLM one-button + aif companion install, spec A2). One commit 53fce45f51, 4 files, +690/−10.

This PR is NOT ready to merge. The round-3 cold fidelity audit returned STOP. It is opened so the work leaves the container and becomes reviewable — it had been sitting at status=done since 2026-08-08T14:51Z with no branch on origin and no PR (#autonomous-done-no-harvest, the same failure that produced #1300).

What stands in this run (do not re-do it): run 3 delivered every §7c correction that #1300/run 2 missed. scripts/getff-glm-onebutton.sh is 361 lines here vs 212 on feature/beta-delivery-ux-92bf00; the profile-routed path replaced run 2's PATCH /project (aifHttp.ts:96 says the only write path is PUT /projects/:id) and its vendor-direct ping. Round-3's STOP is for the §7e.2–§7e.6 items below, not for the §7c work.

Supersession chain: #1300 (run 2) → this PR (run 3) → run 4, which per kickoff §7e.0 bases on this branch. Expect both #1300 and this PR to close as superseded when run 4's PR lands.

Fidelity verdict

FIDELITY: STOP
Basis: .claude/orchestrator-prompts/beta-delivery-ux/kickoff-s4.md
Round: 3
Audited-SHA: 53fce45
Evidence: scripts/getff-glm-onebutton.sh:222-226 — the POST /runtime-profiles create body omits runtimeId and providerId, both of which the live API declares required (ZodError, "expected string, received undefined"), so step 5 can never succeed against a real aif.

Findings (kickoff §7e.2–§7e.6; §7e is the round-3 audit distilled into the brief)

BLOCKER-1 — the create body is missing two required fields, so the flow's core step is dead on arrival.
scripts/getff-glm-onebutton.sh:222-226 sends {name, defaultModel, baseUrl, apiKeyEnvVar, enabled}. The live API rejects it: POST /runtime-profiles with a body lacking runtimeId/providerId returns 400 ZodError naming both paths. Kickoff §7e.2. Consequence: :228-233 always takes the objective-3 MISS branch.

BLOCKER-2 — the ping route does not exist. Measured, not inferred.
scripts/getff-glm-onebutton.sh:53 resolves AIF_PROFILE_CHAT_PATH to /runtime-profiles/%p/v1/messages. Probed live from aif-handoff-agent-1 on 2026-08-09: GET http://api:3009/runtime-profiles200, and POST http://api:3009/runtime-profiles/<real-profile-id>/v1/messages404. There is no such route. Kickoff §7e.3 additionally establishes that the two candidate substitutes do not close the gap either: POST /runtime-profiles/validate returns ok:true after checking only that apiKey/baseUrl are non-empty — no network call (aif-handoff packages/runtime/src/adapters/claude/index.ts:468-479) — and POST /runtime-profiles/models returned a static Claude catalogue for a Qwen profile. §7a #3's "real model call via the created profile" therefore needs the two-half split §7e.3 specifies.

BLOCKER-3 — §7b #1 is undelivered: the helper can only ever instruct, never wire.
scripts/getff-glm-onebutton.sh:189-198 prints wiring instructions for glm.env and exit 1s; :204-215 then verifies reachability. Nothing in the helper makes the key reachable, so a first run on a clean host always terminates in an objective-3 MISS. A helper whose only mechanism is a printed instruction is the #warning-nobody-reads shape — attention-is-not-a-mechanism.md §1. Kickoff §7e.4 names hasApiKey in the /validate response as the exact verifier once wiring exists.

MAJOR-4 — the test suite green-lights routes that do not exist.
tests/install-sh/glm-onebutton.test.sh:74-97 (and the :188-210 twin) install a curl() stub that returns 200/201 by path glob, regardless of body. So the suite passes over BLOCKER-1 and BLOCKER-2: "green" means "the mock agrees with the helper", which is why a helper posting to a 404 route and an invalid create body ships with a passing suite. Kickoff §7e.6 binds the fix: an explicit path allowlist (each entry dated to its probe), rejection of a create body missing a required field with the same 400 the live API returns, and a paired-negative proving the stub fails on this run's helper. This is the MAJOR the run-4 brief is built around.

MAJOR-5 — the companion install is prose in a field the engine never reads.
setup.d/companions.manifest:33 now carries (bridge: git clone https://github.com/lee-to/aif-handoff.git && cd aif-handoff && docker compose up -d) in install_cmd. The clone URL is the §7d.2 correction and is right. But setup.d/engine.sh:18 early-returns past that field for kind=external-service, and setup.d/bridge-guided.sh:11-29 only prints hints — so there is no consent surface, and §4 item 4's "decline → env degradation" has nothing to decline. The manifest comment at :26-32 states this honestly ("engine.sh IGNORES install_cmd for kind=external-service"), which makes it a documented non-delivery rather than a hidden one — but §4 item 4 is still MISSED. Kickoff §7e.5: deliver a real consent+install path for this kind, or PARK with engine.sh:18 quoted.

Scope: CLEAN. The diff touches exactly INSTALL-FOR-AI.md, scripts/getff-glm-onebutton.sh, setup.d/companions.manifest, tests/install-sh/glm-onebutton.test.sh. setup.d/10-skills.sh (S5's sole editor), .zcode/**, and packages/runtime-bridge/** are absent — the S4/S5 boundary held.

Watch-list (carried into run 4)

id criterion defect site reintroduction tell
W-1 §7e.2 — the create body carries every schema-required field scripts/getff-glm-onebutton.sh:222 a POST /runtime-profiles body without runtimeId + providerId
W-2 §7e.3 — the model proof uses the baseUrl read back from /validate, never a hardcoded $GLM_BASE_URL scripts/getff-glm-onebutton.sh:53 any ping target that is neither a probed-live aif route nor a baseUrl echoed by /validate
W-3 §7e.4 — the helper wires the key, then verifies, then pings scripts/getff-glm-onebutton.sh:189-198 an exit 1 whose only preceding action is printf of instructions
W-4 §7e.6 — the curl() stub is fail-closed and has a paired-negative tests/install-sh/glm-onebutton.test.sh:74-97 a stub branch returning 2xx without inspecting the request body
W-5 §7e.5 — no objective is reported met via a field the engine does not read setup.d/companions.manifest:33 install_cmd prose on a kind=external-service row presented as delivery
W-6 §1/§5 — S4 never edits setup.d/10-skills.sh none — preventive that path in the branch's git diff --name-only

Round 3: W-1 REINTRODUCED · W-2 REINTRODUCED · W-3 REINTRODUCED · W-4 REINTRODUCED · W-5 REINTRODUCED · W-6 CLEAN

§1.7 Forward-check applied

Disciplines checked against this diff, by the harvesting session, with evidence:

  • attention-is-not-a-mechanism.md §1 — BLOCKER-3 and MAJOR-5 are both instances of #warning-nobody-reads: scripts/getff-glm-onebutton.sh:191-198 prints wiring instructions as the delivery mechanism, and setup.d/companions.manifest:33 puts an install command in a field setup.d/engine.sh:18 never reads. Neither is a mechanism; both are recorded as MISSES above rather than as delivered objectives.
  • no-paid-llm-in-ci.md — the diff adds no workflow and no CI-side model call; the only model call it contemplates is consumer-side at install time (scripts/getff-glm-onebutton.sh:53). CLEAN.
  • Build-vs-reuse / capability-commit gate (CLAUDE.md) — NOT a capability commit: no package.json dependency added, and the two new files (scripts/getff-glm-onebutton.sh:1, tests/install-sh/glm-onebutton.test.sh:1) sit outside packages/, so neither LOC trigger applies. No Prior-art: trailer required.
  • Key-handling invariant (kickoff §4 item 2) — HELD. The create body passes only the env-var NAME (scripts/getff-glm-onebutton.sh:225), and the reachability probe at :206 is exit-code-only via printenv, never echoing the value. This is the one binding invariant run 3 satisfies outright.

§1.7 Backward-check applied

Sibling surfaces the diff did NOT touch, swept by the harvesting session (T21 — surfaces enumerated from the class, not from the diff's own file list):

  • setup.d/engine.shGAP-FOUND. :18 early-returns past install_cmd for kind=external-service, which is precisely why MAJOR-5 exists. Action: run 4 must either give the field a reader or PARK with this line quoted (kickoff §7e.5). Not fixed here.
  • setup.d/bridge-guided.shGAP-FOUND. :11-29 prints hints only; it is the surface that would have to host the consent flow. Same action as above.
  • setup.d/10-skills.shSWEPT-CLEAN. Absent from git diff --name-only origin/staging...HEAD (4 files listed above). S5 owns this file; the S4/S5 collision the kickoff §5 warns about did not occur.
  • packages/runtime-bridge/**SWEPT-CLEAN. Untouched. Its aifHttp.ts:96 remains the in-repo oracle for the PUT /projects/:id shape, and scripts/getff-glm-onebutton.sh:285 now agrees with it.
  • .zcode/skills/** and the plugin channel — SWEPT-CLEAN. No glm-handoff skill shipping in this diff; that half of A2 is not attempted here.
  • packages/core/templates/**SWEPT-CLEAN. No template rendering depends on the manifest row's install_cmd; the row's detect_cmd is unchanged in shape.
  • .github/workflows/audit-self.ymlGAP-FOUND. tests/install-sh/glm-onebutton.test.sh is not wired into any CI shard by this diff, so MAJOR-4's stub defect is invisible to CI as well as to the suite. Run 2's branch had wired it (feature/beta-delivery-ux-995e9c); run 4 should carry the wiring forward after the stub is made fail-closed — wiring a permissive stub into CI makes the theatre load-bearing.

Provenance

Stage PR. Kickoff .claude/orchestrator-prompts/beta-delivery-ux/kickoff-s4.md (§7d PR #1318 + §7e PR #1319) · base SHA 9344f6b1b9 · substrate: aif task e65989fa-6a0e-448f-9ea3-eab7da315f2a (autonomous) · fidelity Round 3 · harvested by /dispatcher 2026-08-09, --no-auto-merge (a STOP verdict must not arm auto-merge).

… (A2)

Run 3 of stage S4, dispatched after kickoff-s4.md gained §7b (key-acquisition
channel), §7c (run-2 binding corrections) and §4.1 (host-verify contract), merged
to staging as PR #1310.

Committed by the dispatcher at harvest time: the aif task reached status=done with
the work uncommitted (D12 class — the review gate passes done on a dirty worktree),
so the tree is committed here to give the pre-egress fidelity audit a stable SHA
that harvest.ts can push as-is.

Prior-art: skipped — stage implementation under an existing umbrella kickoff; no new
dependency and no new module under packages/, so no capability-commit trigger fires.
artyhoo added a commit that referenced this pull request Aug 9, 2026
…harvested, 995e9c dead-end) (#1324)

§7e was written before two things happened: run 3 got harvested to origin, and a
duplicate dispatch (995e9c) landed a dead-end branch in the container. §7f records
both so run 4 cannot repeat the base-selection mistake that produced the duplicate.

- §7f.0 — run 3 is now PR #1322 on origin (`feature/beta-delivery-ux-e65989`,
  `53fce45f51`); its body carries the round-3 watch-list W-1..W-6.
- §7f.1 — `feature/beta-delivery-ux-995e9c` is a dead end: do not base on it, do not
  delete it (T18). Its one salvageable item is the audit-self shard-A wiring, and only
  after the §7e.6 stub fix lands.
- §7f.2 — measured from `aif-handoff-agent-1`: `POST /runtime-profiles/:id/v1/messages`
  → 404, the exact path `scripts/getff-glm-onebutton.sh:53` targets. §7e.3's two-half
  split is the only reachable form of §7a #3, not a preference.
- §7f.3 — the §2.4 2-consecutive-REVISE cap counts unchanged scope; §7d/§7e are each a
  scope change, so run 4 is legitimate.

Prior-art: skipped — kickoff dispatch-facts addendum, markdown only, no new capability

Co-authored-by: Test <test@example.com>
@artyhoo artyhoo changed the title beta-delivery-ux feat(beta-delivery-ux): S4 run 3 — GLM one-button per kickoff §7b/§7c (A2) [FIDELITY STOP — base for run 4] Aug 9, 2026
artyhoo added a commit that referenced this pull request Aug 9, 2026
…d when it cannot (#1330)

The §2.0 pre-dispatch guard listed three signals — `git branch -a`, `gh pr list`,
`done.md` — and all three are origin/host-scoped. A branch that exists only inside
the aif container is invisible to every one of them, so a finished-but-unharvested
run reads as "nothing here". That is not hypothetical: `feature/beta-delivery-ux-995e9c`
was dispatched 2026-08-08T21:22Z by a session whose probe checked origin + `gh pr list`
only, roughly an hour after run 3 had finished in the container. One wasted run.

Adding a fourth command to the prose would not fix it — prose is executed by attention,
and attention is not a detection layer (attention-is-not-a-mechanism.md §1). So the
guard becomes a script the skill invokes:

  SLUG=<umbrella> bash .claude/skills/dispatcher/helpers/probe-inflight.sh

Five signals, one VERDICT line. Signal 4 asks the container directly; signal 5 joins
the aif task list against the PR list to surface finished work carrying no PR (the
`#autonomous-done-no-harvest` shape). Verdict precedence is led by PROBE-INCOMPLETE:
if a probe could not be *asked*, the guard says so rather than reporting a clean state,
because converting ignorance into permission is the defect itself, not an edge of it.
DONE-UNHARVESTED outranks ALREADY-DONE — a loose end is loose even under a closed
umbrella.

Verified against the live umbrella it was written for: the probe names both
`feature/beta-delivery-ux-995e9c` (the duplicate) and `feature/beta-delivery-ux-a83379`
(an un-harvested S2 rework nobody had noticed), and correctly omits run 3, now that
PR #1322 carries it.

Two defects were found and fixed in the helper by running it rather than reading it:
`printf '%s'` silently dropped the last detail line while still counting it (5 counted,
4 shown), and the `printf '%s\n'` + `while read` repair aborted the script mid-probe
under `set -e` on the trailing blank line. Both display paths are now `grep . | sed`
pipelines, which have neither failure mode. The count-equals-shown invariant is a test.

Two external precedents surfaced by the consult, both REFERENCE (neither adoptable —
wrong substrate), recorded because they name the shape rather than merely rhyme with it:
`gsd-build/gsd-2` issue #5559 is the same defect in a different medium — orphan branches
"present in `git branch`, absent from `git worktree list`" are invisible because the probe
queries a narrower surface than the one holding the state. And the fail-closed precedence
rule has published form: arxiv 2606.20520 rejects a request when its revocation service is
unreachable, while arxiv 2601.17744 names the opposite failure — "defaulting to continuation
rather than denial — fail-open behavior", which is precisely what the old guard did.

- .claude/skills/dispatcher/helpers/probe-inflight.sh — the guard, every collector
  overridable via PROBE_* for fixture-driven tests (the TASK_JSON pattern from
  monitor-classify.sh). shellcheck clean.
- packages/core/skills/dispatcher/probe-inflight.test.ts — 16 tests. The load-bearing
  one is the fail-closed pair: two runs differing ONLY in whether the container
  answered must not produce the same verdict.
- .claude/skills/dispatcher/SKILL.md §2.0 — invokes the helper, documents all five
  verdicts and the scope of each signal.
- CLAUDE.md `Pre-dispatch in-flight probe` — carried the same origin-only doctrine in
  items (a)-(c); container branches + un-harvested tasks added as (d).

Prior-art: prior-art-evaluations.md#111 (/dispatcher operator-side execution loop, verdict BUILD) — this guard IS §2.0 of that already-registered capability, not a new capability area. T16 re-verified against the gap rather than assumed: DeepWiki on `lee-to/aif-handoff` (2026-08-09) states it "does not explicitly detect or report tasks marked done whose work was never pushed to a remote or opened as a pull request", and its dedup is `projectId`+`normalizedTitle`+`roadmapAlias` at roadmap import plus a CAS on `backlog→planning` — all INSIDE the state machine, never against git or PR state. Signal 5 is exactly that unserved join.
Prior-art: prior-art-evaluations.md#232 (builderz-labs/mission-control, verdict WATCHLIST) — the named successor candidate for the whole #111 class. Its F1 probe (does it push a branch out of a container, open a PR, gate a next stage on merge state?) is still unrun, so this change does not settle it; if F1 lands ADOPT, this helper retires with the rest of the loop rather than being defended.

Co-authored-by: Test <test@example.com>
artyhoo added a commit that referenced this pull request Aug 9, 2026
…cted, model proof measured (#1340)

The Round-4 fidelity audit emitted KICKOFF-AMBIGUOUS on §7e.3 and a DECISION-NEEDED fork
(weaken §7a #3's completion proof, or weaken §2 constraint 1's key-handling invariant). Both
options were unnecessary: the fork rested on §7f.2's claim that every aif-side completion route
is closed, and that claim came from a single probe.

Corrected here, each against a measurement rather than a re-reading:

- §7f.0 — «base on run 3» pointed at PR #1322, which is still OPEN and red. The S4 work is on
  `staging` as `6ea6011560` (PR #1323); `git merge-base --is-ancestor 6ea6011 49eaafe`
  → YES, so a staging-based run 4 satisfies §7e.0 with a superset, not a regression.
- §7f.1 — `…-995e9c` was labelled a dead end. The BRANCH is; its CONTENT was repaired
  dispatcher-side, pushed as `harvest/s4-995e9c` and merged as #1323, shard-A wiring included.
- §7f.2 — `POST /runtime-profiles/<id>/v1/messages` → 404 was measured and stands, but the
  conclusion drawn from it («the only reachable form of §7a #3») generalised one probe into a
  negative-existence claim, missing project invariant #3. `POST /chat/sessions` → 400: the route
  exists. `chat.ts:923-937` project-scope-validates `runtimeProfileId`; `chat.ts:1275` is the
  completion endpoint; §7e.4 already established the key is read off aif's own `process.env`, so
  aif makes the call and the helper never handles the value. Both constraints hold.

Proven end-to-end with one operator-approved billed call: `assistantMessage` returned,
`costUsd:0.117219`, `runtime.profileId:53eca24c-…`, and that profile's `lastUsageAt` moved
`09:15:11.263Z` → `09:51:42.017Z`. Cost is recorded as ~$0.12/run, not token-scale, because aif
injects project context — the suite must stub it and only host-verify may fire it live.

What is still unproven is stated as run 5's task rather than implied closed: the probe used an
already-created profile on a warm aif, not a cold install immediately after the helper's own
`POST /runtime-profiles`.

The file lands at exactly 600 lines. `.husky/pre-commit` carries no kickoff exemption (only
`md-line-gate.sh` does, and its glob is `kickoff.md`, which never matches `kickoff-s4.md`), so
the next correction to this file needs a split, not a trim.

Prior-art: skipped — documentation only; corrects three falsified facts in an existing kickoff
section and adds no capability, no dependency, and no new module.

Co-authored-by: Test <test@example.com>
@artyhoo

artyhoo commented Aug 9, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #1341 (merged). This PR's body was the source of the W-1..W-6 watch-list, which was carried and re-verified in rounds 4, 5, 6 and 7 — the final state is recorded in #1341's Review findings section. The branch itself was never based on; #1341 builds on staging (which carries #1323). Closing rather than leaving a red STOP open indefinitely.

@artyhoo artyhoo closed this Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant