feat(beta-delivery-ux): S2 PARTIAL — T11 ship create-worktree.sh under env+ (stage stays open, 6 forks parked) - #1284
Merged
Conversation
…r env+ profile (A9 part 1) Wiring-only slice of A9 part 1 (kickoff §4 binding — REUSE, do not rebuild). Extends setup.d/10-skills.sh with §1j: gates create-worktree.sh shipping on PROFILE=env|factory OR legacy WITH_AIF_SUITE, mirroring the F7-split pattern at line 95. The script itself is unchanged — copied verbatim via copy_safe to $PROJECT_ROOT/scripts/create-worktree.sh. Closes the S1 inventory gap (kickoff §1 + LAYERS.md:10): create-worktree.sh exists in the framework tree but shipped to NO profile before this commit (verified — zero `create-worktree` references in setup.d/ prior to §1j). This is the FIRST env-specific payload surface — the divergence between --profile env and --profile core begins here. Within-bounds fork resolved (kickoff §8 — YOURS to resolve): extend 10-skills.sh vs introduce a new layer file. Picked extend — minimal footprint, matches the file's existing role as "shipped-to-consumer .claude/ + scripts/ artefacts" (§1 skills + §1b-§1i hooks + this §1j workspace script). The §1j naming parallels §1/§1b-§1i. Smoke GREEN: - bash -n setup.d/10-skills.sh — clean syntax - PROFILE=core dry-run — does NOT ship create-worktree.sh (byte-identical invariant preserved per LAYERS.md:10) - PROFILE=env dry-run — DOES ship: "[dry-run] would: ship scripts/create-worktree.sh (env+ profile payload)" The full A9 (T11 + T12 + T13) waits on T12 resolution — `getff work <name>` has a within-bounds sub-fork (bin/ does not exist; entrypoint shape) plus a CC-detection park (Park-4) gating the CC-deferral branch. T11 ships independently of those — no reason to hold the create-worktree.sh wiring while T12 design is settled. Parks (Park-1 through Park-5) documented locally in .ai-factory/plans/beta-delivery-ux-parked-forks.md (gitignored — .ai-factory/plans/* is per-consumer scaffolding per .gitignore:60). The park register carries T1 pre-flight evidence + candidate statements; maintainer picks A/B/C per park; executor resumes from the pick. Prior-art: F7-split pattern at setup.d/10-skills.sh:95 (the established PROFILE-conditional shipping mechanism; this commit is the same pattern, extended from `factory`-only to `env|factory` for the env+ monotonic-depth surface — setup.d/LAYERS.md:10).
artyhoo
enabled auto-merge (squash)
August 7, 2026 23:01
artyhoo
added a commit
that referenced
this pull request
Aug 8, 2026
…six #1284 parks (re-dispatch rev) (#1295) 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). Co-authored-by: Test <test@example.com>
6 tasks
artyhoo
added a commit
that referenced
this pull request
Aug 8, 2026
…kickoff rev 2 clobbered by #1285 squash-rebuild (#1298) * fix(setup): restore §1j create-worktree env+ shipping clobbered by #1285 squash-rebuild PR #1285 (ab280e1) was squash-rebuilt from a stale base and silently reverted PR #1284 (1812a8c): the §1j block shipping scripts/create-worktree.sh under env|factory profiles. Re-applies the original 36-line insertion onto the current file; #1285's A8 three-arm split is untouched. Prior-art: skipped — restoration of already-merged reviewed content, no new capability * docs(orchestrator): restore pnpm-flake kickoff rev 2 clobbered by #1285 squash-rebuild Byte-exact restore of the rev-2 kickoff (PR #1283, 025aac0 — 3 rounds of Phase -1 cold review, GO) that PR #1285's stale-base squash-rebuild reverted to rev 1. The umbrella is closed; this repairs the historical record its done.md cites. Prior-art: skipped — restoration of already-merged reviewed content, no new capability --------- Co-authored-by: Test <test@example.com>
artyhoo
added a commit
that referenced
this pull request
Aug 8, 2026
…es to outdated base blobs (#1285 class) (#1307) * feat(hooks): pr-stale-revert check pair + tests Deterministic PR-time gate for the stale-base squash-rebuild clobber class (incident PR #1285, repaired by #1298): a PR that sets a tracked file to a blob BYTE-IDENTICAL to an OLDER ancestor version of that file on the base branch is silently discarding merged work. Nobody reproduces an old blob by hand by accident, so the signature is mechanical and needs no judgment. Every existing channel misses the class by construction: GitHub's "require branches to be up to date" is POSITIONAL (the branch WAS up to date — the stale content arrived as the PR's own change), no CI test covered the reverted content (a merge queue shares that blindness), and the 21 reverted lines sat inside a 2498-insertion diff, i.e. bare attention. - pr-stale-revert.ts: pure decision logic (git injected via StaleRevertGit) plus the PR-GLOBAL escape token `STALE-REVERT: intended — <rationale >=20 chars>` for deliberate restorations like #1298. The real provider is parameterised by cwd so tests and the calibration harness exercise the shipped code path. - pr-stale-revert-bin.ts: CI glue reading PR_BODY / BASE_REF / BASE_SHA / HEAD_SHA. Fails CLOSED on its own misconfiguration — an unset env var, an unresolvable SHA, or an unresolvable merge-base all produce an EMPTY file set that is indistinguishable from "clean", so they error instead of passing. - Tests: 38 arms, including two paired-negative arms over the real #1285 archaeology and an end-to-end run of the shipped provider and the bin against a throwaway fixture repository reproducing the incident shape. Declared v1 non-goals (rule §8 + SSOT #241 carry the revisit triggers): renames are not followed, deletions are not flagged, and a stale file the PR ALSO edits yields a novel blob and is undetectable by whole-file equality — in #1285 itself setup.d/10-skills.sh would not flag; only the untouched kickoff.md does. Calibration over the 150 staging squash commits back from 004864d: exactly 2 flags, both true positives (ab280e1 = #1285, 4fe20cc = #1298), zero false positives. Prior-art: prior-art-evaluations.md#241 (BUILD — no upstream detects PR-sets-file-to-outdated-base-blob; 9-phrasing WebSearch + DeepWiki git/danger-js + native-gates check all miss; see entry). * ci(workflows): stale-revert-in-pr-diff gate on staging PRs Wires packages/core/hooks/checks/pr-stale-revert-bin.ts as a PR-time job on base=staging PRs, mirroring pr-body-fidelity.yml (same pinned action SHAs, node 22, npm ci --prefix packages/core, job id == job name so the operator registers the string GitHub actually reports). Two load-bearing details: - The checkout sets BOTH `fetch-depth: 0` AND `ref: head.sha`. Without the explicit ref a `pull_request` checkout lands on the synthetic `refs/pull/N/merge` commit, where git has ALREADY merged the newer base content over the stale file — the signal is erased and the gate fails OPEN in exactly the scenario it exists for. Same trap documented at audit-self.yml's pr-commit-trailers job. - Unfiltered events (the pr-body-prior-art.yml model): a `paths:` filter would un-fail-close exactly the docs/config PRs where this class hides. `edited` is included so adding the STALE-REVERT token re-runs the check. The gate is ADVISORY until the operator registers `stale-revert-in-pr-diff` as a required check in the staging branch-protection set; CI cannot verify that registration (GITHUB_TOKEN cannot read branches/*/protection — the KNOWN LIMITATION recorded in workflow-integrity.yml). Deterministic git plumbing, no LLM. Verified with actionlint and zizmor (no findings). Prior-art: skipped — CI wiring only for the detector shipped in the preceding commit; no new capability, no new dependency, no new module. * docs(rules): git-conflict-merge-forward §8 stale-base rebuild hazard Adds §8 for the sibling failure of the merge-forward class: the branch is NOT behind — its CONTENT is. A squash-rebuilt PR (fresh fork + older tree committed over it) silently reverts every file the base moved in between, which is how #1285 discarded #1283 and #1284 before #1298 repaired it. The section records the incident, the mechanical signature (head blob byte-identical to an OLDER ancestor version on the base branch), the shipped PR-time gate and its escape token, and both v1 non-goals with revisit triggers: (a) renames/deletions, and (b) the edited-stale-file false negative — a stale file the PR also edits yields a novel blob and is invisible to whole-file equality, with setup.d/10-skills.sh in #1285 as the worked example. Also reconciles the header's Class-B claim: «a CI principle test is structurally unreachable» scopes the merge-forward PROCEDURE (a command choice, invisible to repo CI); §8's hazard is PR-diff content lineage, which IS mechanically visible at PR time and now has its own CI channel. The Authoritative-for enumeration gains §8. §1.7: forward — the new channel is a deterministic gate, not «a reviewer will read the diff», per attention-is-not-a-mechanism.md:15, and it fires at the earliest channel where the signature exists at all (a PR diff), with zero LLM per no-paid-llm-in-ci.md; the Class-B ceiling claim it qualifies is at .claude/rules/git-conflict-merge-forward.md:5, and the Authoritative-for enumeration was extended in the same edit per doc-authority-hierarchy.md §2-§3. Backward — sibling surfaces in the «agent-facing git/push gotchas» class are §2's trailer-gate range fix, the CLAUDE.md Harness-gates bullet, and the harvest/egress pre-publish rebase carve-out in §3: §8 extends the file's scope from «un-conflicting a branch» to «the branch looks fine and is silently stale», contradicting none of them; no other rule claims authority over PR-diff content lineage. Prior-art: skipped — rule prose amendment documenting a gate shipped two commits earlier; no new capability, no dependency, no module. --------- Co-authored-by: Test <test@example.com>
artyhoo
added a commit
that referenced
this pull request
Aug 8, 2026
… (aif) + self-gen docs sweep (tab) (#1309) * docs(beta-ai-docs-agnosticism): meta-launch kickoff — stage gates, DECOMPOSE routing, autonomous gate shut Generated by `/pipeline beta-ai-docs-agnosticism`. Plan-currency CURRENT at 6f11473; all three umbrella §0 dispatch gates resolved mechanically (A-S3 #1272 + A-S1 #1173 merged; the three inflight-check signals are two merged umbrella-B branches and this session's own worktree). Live anchor spot-check re-confirms C3's negative-existence claim: principle 21 walks agents/*.md only, so no probe enumerates .claude/skills today. Routing: umbrella DECOMPOSE/Mode-B; S1 PAIR -> S2 || S3 PAIR x2 (Mode-B worktrees) -> S4 SOLO. Autonomous aif dispatch is gated shut — the bridge answers (/runtime-profiles 200) but the Lever-1 container probe returns AGENT_MAX_REVIEW_ITERATIONS=UNSET, which per /pipeline §5 #autonomous-dispatch-without-park is UNVERIFIED, not passing. Maintainer-paste tabs until set. state.md stays gitignored per the /pipeline §10 lifecycle split. * docs(beta-ai-docs-agnosticism): S2 + S3 stage kickoffs — skills probe (aif) + self-gen docs sweep (tab) Stage 2 fan-out dispatch inputs, authored per the meta-launch launch-table (PR #1293). S2 (kickoff-s2.md, branch beta-c-s2-skills-probe) — C3 skills agnosticism probe. Dispatch channel: autonomous aif-handoff — Lever-1 verified live 2026-08-08 (docker exec aif-handoff-agent-1 -> AGENT_MAX_REVIEW_ITERATIONS=1, set via docker-compose.override.yml, operator GO). Carries the verbatim Lever-2 park-don't-guess block (dispatch-gate grep target), a host-verify contract (run green on host: 2/2), single ownership of night-mode/SKILL.md, and the dynamic-enumeration falsifier (T-BADC-S2-A). S3 (kickoff-s3.md, branch beta-c-s3-selfgen-docs) — C5 self-generating docs sweep. Dispatch channel: maintainer-paste tab (operator decision 2026-08-08 — fork-heavy D7 ownership judgments; aif precedent on design-heavy stages: #1300 FIDELITY STOP, #1284 PARTIAL). Corrects the umbrella premise with evidence: the zcode-doctrine §3 hand-sync already landed via #1156 (2026-07-25, post-spec), so the first patch proposal is the D7 generated-section CONVERSION of the doctrine's status columns (00-rule-index.md precedent), not a content re-sync. host-verify run green on host: 3/3. T10 inventory-before-migration is the binding order. Both kickoffs declare the S2||S3 file-ownership split (night-mode + probes vs doc migrations + auditor) against #shared-workdir-parallel. --------- Co-authored-by: Test <test@example.com>
artyhoo
added a commit
that referenced
this pull request
Aug 8, 2026
…GUOUS + host-verify contract (#1310) * 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. --------- Co-authored-by: Test <test@example.com>
artyhoo
added a commit
that referenced
this pull request
Aug 8, 2026
… read (api stamps the task row) (#1313) * docs(beta-ai-docs-agnosticism): meta-launch kickoff — stage gates, DECOMPOSE routing, autonomous gate shut Generated by `/pipeline beta-ai-docs-agnosticism`. Plan-currency CURRENT at 6f11473; all three umbrella §0 dispatch gates resolved mechanically (A-S3 #1272 + A-S1 #1173 merged; the three inflight-check signals are two merged umbrella-B branches and this session's own worktree). Live anchor spot-check re-confirms C3's negative-existence claim: principle 21 walks agents/*.md only, so no probe enumerates .claude/skills today. Routing: umbrella DECOMPOSE/Mode-B; S1 PAIR -> S2 || S3 PAIR x2 (Mode-B worktrees) -> S4 SOLO. Autonomous aif dispatch is gated shut — the bridge answers (/runtime-profiles 200) but the Lever-1 container probe returns AGENT_MAX_REVIEW_ITERATIONS=UNSET, which per /pipeline §5 #autonomous-dispatch-without-park is UNVERIFIED, not passing. Maintainer-paste tabs until set. state.md stays gitignored per the /pipeline §10 lifecycle split. * docs(beta-ai-docs-agnosticism): S2 + S3 stage kickoffs — skills probe (aif) + self-gen docs sweep (tab) Stage 2 fan-out dispatch inputs, authored per the meta-launch launch-table (PR #1293). S2 (kickoff-s2.md, branch beta-c-s2-skills-probe) — C3 skills agnosticism probe. Dispatch channel: autonomous aif-handoff — Lever-1 verified live 2026-08-08 (docker exec aif-handoff-agent-1 -> AGENT_MAX_REVIEW_ITERATIONS=1, set via docker-compose.override.yml, operator GO). Carries the verbatim Lever-2 park-don't-guess block (dispatch-gate grep target), a host-verify contract (run green on host: 2/2), single ownership of night-mode/SKILL.md, and the dynamic-enumeration falsifier (T-BADC-S2-A). S3 (kickoff-s3.md, branch beta-c-s3-selfgen-docs) — C5 self-generating docs sweep. Dispatch channel: maintainer-paste tab (operator decision 2026-08-08 — fork-heavy D7 ownership judgments; aif precedent on design-heavy stages: #1300 FIDELITY STOP, #1284 PARTIAL). Corrects the umbrella premise with evidence: the zcode-doctrine §3 hand-sync already landed via #1156 (2026-07-25, post-spec), so the first patch proposal is the D7 generated-section CONVERSION of the doctrine's status columns (00-rule-index.md precedent), not a content re-sync. host-verify run green on host: 3/3. T10 inventory-before-migration is the binding order. Both kickoffs declare the S2||S3 file-ownership split (night-mode + probes vs doc migrations + auditor) against #shared-workdir-parallel. * docs(beta-ai-docs-agnosticism): Lever-1 = 4, set where it is actually read (api stamps the row) Operator decision: raise the review-iteration ceiling to 4 — a cheap executor seat should keep fixing its own review findings rather than parking them on a human. Corrects a real defect in the prior wiring, measured not assumed. autoReviewHandler.ts:125 reads `refreshedTask.maxReviewIterations ?? env.AGENT_MAX_REVIEW_ITERATIONS` — the TASK ROW wins — and api/schemas.ts:79 stamps that row at creation from the *api* container's env. So the previous agent-only setting was INERT for every API-created task: `GET /tasks` showed the 5 most recent rows all carrying mri=3 while the agent container reported 1. Same failure class as the COORDINATOR_MAX_CONCURRENT_TASKS incident already documented in docker-compose.override.yml ("the line above NEVER took effect"). Now set on BOTH services; verified api=4, agent=4, GET /settings maxReviewIterations=4. Scope honesty recorded in both kickoffs: this is a GLOBAL ceiling, not GLM-only. Nothing pins a task to the GLM seat without a `<!-- bridge-profile: -->` marker (runtime-bridge/src/kickoff.ts:30 -> AifHandoffBackend.ts:221), and Tier-2 kickoffs omit that marker by rule — verified absent in all three umbrella kickoffs by running the extractor's own regex; resolvedDefaultTaskRuntimeProfileId is null. The tier-vs-pinning tension is surfaced as an open maintainer fork, not decided here. meta-launch §4c flipped GATED SHUT -> OPEN accordingly (both legs verified). --------- Co-authored-by: Test <test@example.com>
artyhoo
added a commit
that referenced
this pull request
Aug 8, 2026
… path, bind run-3 blockers (#1319) * 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. --------- Co-authored-by: Test <test@example.com>
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.
beta-delivery-ux S2 — PARTIAL: T11 only (A9 part 1). Ships
scripts/create-worktree.shinto consumer repos under the env+ profile (setup.d/10-skills.sh§1j, profile-gatedenv|factory|WITH_AIF_SUITE,copy_safeverbatim — no script rewrite, §4 REUSE). This PR does NOT close stage S2: A4 (presets), A5 (/pipeline status), A9 parts 2-3 (getff work+ CC-detection) are parked on six maintainer forks — see Parked questions. The stage re-dispatches after the forks are answered.Provenance: aif task
fd1d75e1(re-dispatch of the empty-done2b84effa), harvested via host push after a pre-publish rebase onto current staging (single commitbb89f69a5e→3a3e83d031, content identical — rebase only).Cold fidelity audit (external seat, 2026-08-07): branch clean and honest, verdict REVISE at stage level (1 of 3 deliverables) → harvested per the audit's explicit «safe as partial» ruling with its two conditions applied: (1) this partial marking; (2) the parks surfaced to the maintainer below (the worker's register lived only in a gitignored container file + task record — the task closed
doneinstead ofmanualReviewRequired, so without this PR body the parks were invisible to the queue).Parked questions
Six forks from the worker's park register (
beta-delivery-ux S2 — Parked forks register, taskfd1d75e1), each with full Option-format in the register; condensed here as the durable record:parse-override-flags.shparser / SKILL §2.5 Step 5 predicates / marker emit) — guessed in isolation it breaks the other two.references/dir is all-markdown today; a data format would be the first non-md entry. Spec §11 F-B′ lists three options + a binding criterion.economypreset reviewer-tier semantics: spec calls it «cheap reviewer» — cost/depth tradeoff is a maintainer value call.getff work: A9 must defer to CC-native worktree UX on CC;dual-implementation-discipline.md §4forbids brand-name matching, so the capability-check signal is a genuine fork.economyvsaif(CONDITIONAL): fires only if a live runtime-profile probe shows a name collision; deferred to the marker-emit task (bridge was unreachable in the task context).create-worktree.shalone vs with soft-dep siblings (surfaced by the worker's own T15 backward-sweep, post-commit): T11 shipped alone in this PR; the sibling set is the fork.Known minor (audit): the shipped
setup.d/10-skills.sh§1j comment references the gitignored register path — unresolvable for staging readers; superseded by this PR body as the durable park record.Fidelity verdict
FIDELITY: GO
Basis: .claude/orchestrator-prompts/beta-delivery-ux/kickoff-s2.md
Round: 1
Audited-SHA: 3a3e83d
GO is scoped to the T11 partial this PR actually ships (the stage-level verdict was REVISE — recorded above, stage stays open). Evidence: profile-gated §1j block
setup.d/10-skills.sh:291(branch numbering; gateenv|factory|WITH_AIF_SUITEmatches the F7-split precedent atsetup.d/10-skills.sh:95); zero priorcreate-worktreerefs insetup.d/(audit grep);bash -nsyntax-clean;LAYERS.md:10monotonic-depth claim honoured. Audited-SHA note: the audit ran onbb89f69a5e;3a3e83d031is the same single commit rebased onto current staging with an identical diff (verified content-equal at rebase time).