mirror of
https://github.com/Heretek-AI/GDevelop-Unlocked.git
synced 2026-11-07 10:55:58 -10:00
Merge pull request #30 from Heretek-AI/ticket-29-hygiene
#29 hygiene: gitignore .worktrees/, disposition root session notes
This commit is contained in:
4 files changed
+757
No files matched your search
@@ -0,0 +1,4 @@
|
||||
# Copy to .env (chmod 600) and fill in. Never commit .env.
|
||||
LLM_API=https://your-provider.example/v1
|
||||
LLM_API_KEY=put-key-here
|
||||
LLM_MODEL=your-model
|
||||
@@ -8,3 +8,5 @@ coverage/
|
||||
.DS_Store
|
||||
# Local LLM credentials (live keys) — never commit.
|
||||
.env
|
||||
# Transient ticket worktrees + worktree lock file (see AGENTS.md worktree law).
|
||||
.worktrees/
|
||||
@@ -0,0 +1,276 @@
|
||||
# Handoff findings log — 2026-10-11 (untracked working notes)
|
||||
|
||||
Branch: `handoff/verify-and-tracker-2026-10-11` (cut from `main` @ 6912f56).
|
||||
|
||||
## Phase 1 — verification (all pass)
|
||||
|
||||
- 1a `npm test`: 102/102 pass, 34 suites, 0 fail.
|
||||
- 1b `node scripts/apply-patches.mjs --check`: seam suite 29/29, exit 0.
|
||||
- 2 scratch full-apply (git-archive copy of `review/GDevelop` @ 8301cdc):
|
||||
14 dry-run clean, 14 applied, 3 launcher synced, 13 Tier-2 synced,
|
||||
`[verify]` green. Re-apply: exit 1 ("Reversed (or previously applied)
|
||||
patch detected" on 01). Fixture `git status --short`: empty.
|
||||
- 3 negative control (patch 12 held out): import-closure test exit 1,
|
||||
failure list names `canStartAiRequestCreate` (+11 other missing
|
||||
exports). Patch restored, sha256 verified, `git status` clean.
|
||||
- 4 fork-reference grep over `tests/ scripts/ .github/`: 8 hits. 7 are
|
||||
unlock-marker strings. 1 is code, not a comment:
|
||||
`scripts/generate-tier2-patches.mjs:44` defaults `--fork` to
|
||||
`review/GDevelop-Heretek`. Nothing invokes that script (no test, no
|
||||
workflow, no package.json script), so nothing reads the fork at runtime.
|
||||
- 5 tracker/CI: open = #6 #7 #8 #10 #11 #12 #13 #14; closed = #1–#5;
|
||||
#9 is the merged PR. Release run 38106050979 = success, ref
|
||||
8301cdcaa4…, publish step skipped, smoke `"ok": true`. Latest `e2e`,
|
||||
`seam-tests`, `CodeQL` on main @ 6912f56 all success.
|
||||
|
||||
## Phase 1 — discrepancies (none blocking)
|
||||
|
||||
- D-a Handoff says "confirm tracker/CI state matches Part C below" —
|
||||
there is no Part C in the file (only Parts A and B). Compared against
|
||||
Part A + the Phase 2 issue list instead; consistent.
|
||||
- D-b Handoff Part A says "11 applied + 3 launcher + 13 Tier-2"; actual
|
||||
is 14 applied. Same stale "11 patches" count in `README.md` (also
|
||||
"Tier-2 glue (07–11)"), `RETIREMENT.md`, `release.yml` release body,
|
||||
`AUDIT_REPORT.md` header (historical).
|
||||
- D-c `AGENTS.md` ground rules still name `review/GDevelop-Heretek` as a
|
||||
pinned fixture "every test depends on"; it does not exist and nothing
|
||||
reads it. `README.md` CI section says "pinned upstream/fork commits"
|
||||
and "Upstream baseline and donor pin".
|
||||
- D-d `generate-tier2-patches.mjs` scratch fallback is the literal
|
||||
`/tmp/opencode` (AGENTS.md: never hard-code `/tmp`); same check needed
|
||||
on `generate-tier1-patches.mjs`.
|
||||
- D-e `[verify]` success line says "all Tier-1 unlock markers" but
|
||||
covers Tier-2 markers + overlay too (cosmetic).
|
||||
- D-f **Upstream moved**: `4ian/GDevelop` HEAD is `ce7be6913f…`, pin is
|
||||
`8301cdcaa4`. Behavior check against HEAD pending (see #13 below).
|
||||
|
||||
## #13 — upstream drift check (done early; result: no rebase needed)
|
||||
|
||||
- Upstream HEAD `ce7be6913f` (2026-10-11, #9218) is exactly 1 commit
|
||||
ahead of pin `8301cdcaa4`; compare API: 2 files changed, none under
|
||||
`newIDE/`.
|
||||
- Against a scratch sparse clone of HEAD (fixture untouched):
|
||||
seam suite 29/29; `apply-patches --target` 14/14 applied + verify
|
||||
green (exit 0); `UPSTREAM_DIR=<head> npm test` 102/102.
|
||||
- Conclusion: pin hash is one commit stale but behavior matches. Pin NOT
|
||||
bumped (bump is part of the human-gated rebase checklist and needs a
|
||||
publish=false validation build).
|
||||
|
||||
## #14 — hygiene tail (done; 6 commits f5db650..d718216)
|
||||
|
||||
- Suite now 121/121, 37 suites (was 102/34). Seam gate green, fixture clean.
|
||||
- S2: shim README was false (patch 07 inlines, never imports). Documented
|
||||
the duplication contract; `tests/integration/shim-wiring-contract.test.mjs`
|
||||
(5 tests) pins it on a real patch-07 apply, negative control = pristine.
|
||||
- **NEW FINDING (product, not fixed)**: `createAiAttachmentUploads` /
|
||||
`createAiAttachmentDownloads` in patched `Generation.js` have no BYOK
|
||||
branch; the 3 callers under `AiGeneration/AiAttachments/` have no BYOK
|
||||
awareness either. A chat attachment in BYOK mode goes to the hosted
|
||||
Generation API. Source-level evidence only; UI reachability unproven.
|
||||
Pinned as `unguarded` in the contract test. Belongs to #12 zero-egress.
|
||||
- Also by design, not zero-egress: logged-in user + custom endpoint still
|
||||
calls hosted `/ai-request-summary` and status for hosted ids.
|
||||
- G3: driver `--verify-only --target`; apply.test applies with verify on
|
||||
+ 4 negative controls (LEFTOVER gate, MISSING marker, STALE Tier-2,
|
||||
MISSING launcher).
|
||||
- D1: launcher README rewritten; `UPDATER_PIN_MESSAGE` no longer
|
||||
prescribes `apply-patches --asar` (cannot work on release asar).
|
||||
- G4: non-configurable `BrowserWindow` fake + test (wrap fails, both
|
||||
fallbacks still seed).
|
||||
- Generators: mkdtemp under `os.tmpdir()`; `--fork` required (no default
|
||||
donor path). Verified byte-identical: 01–06 regenerate, 09/10
|
||||
round-trip via synthetic donor. New `generate.test.mjs`, `pins.test.mjs`.
|
||||
- SonarCloud (advisory: `main` has no required checks; ruleset only blocks
|
||||
deletion + non-FF). 41 bug/vuln issues via public API. PR #9 gate
|
||||
failed on new_security_rating=E, new_reliability_rating=C.
|
||||
Fixed here: S5443 x7 CRITICAL (generator tmp), S9383 BUG (hook promise).
|
||||
To fix in #10 workflow pass: S8482 BLOCKER (`curl | sh` ollama),
|
||||
S6506, S7637 (unpinned softprops action), npx on-demand installs.
|
||||
Residual, needs owner UI accept or rule tuning: S4036 x9 (PATH lookup
|
||||
for `patch`/`diff`/`git`/`node` — inherent), S2245 x6 (Math.random ids
|
||||
in hash-pinned CustomAIClient.js), S8707 x2 (CLI path arg by design),
|
||||
S5122 x1 (CORS * in dev mock), S6505 on release `npm install`
|
||||
(upstream build needs lifecycle scripts).
|
||||
`.sonarcloud.properties` only takes effect from the default branch and
|
||||
only scopes paths — not added (untestable here, marginal gain).
|
||||
- CI uses Node 20 (seam-tests, e2e); `engines` says >=22; release uses 22.
|
||||
|
||||
## #12 — layer-3 proofs on this machine (in progress)
|
||||
|
||||
Setup: CI artifact from run 38106050979 (`gdevelop-5.6.283.zip`, sha256
|
||||
886aa23a…5262a0, all 14 patches) unpacked in scratch; run under
|
||||
`xvfb-run` + `__EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json
|
||||
LIBGL_ALWAYS_SOFTWARE=1`, isolated `HOME` + `--user-data-dir`. Driven over
|
||||
`--remote-debugging-port` with a ~90-line Node CDP client (scratch only).
|
||||
Electron 32.3.3 / Chromium 128.0.6613.186.
|
||||
|
||||
- PROVEN local smoke: `--heretek-smoke` → exit 0,
|
||||
`HERETEK_SMOKE:{"ok":true,…limits 999, gdevelop_startup, POST 403 not spoofed}`.
|
||||
- PROVEN (real Electron): `BrowserWindow export not wrappable (Cannot
|
||||
redefine property)` → fallback path is THE production path.
|
||||
`window.__HERETEK__.unlocked === true` in the live renderer.
|
||||
- **BUG FOUND + FIXED (381e486)**: spoofed XHR GETs never settle in real
|
||||
Chromium. Before: `readyState 1, status 0`, only `onreadystatechange`
|
||||
(at state 1) + `onload` called; `loadend`/listeners never. axios
|
||||
0.18.1 (upstream's client for `/limits`, `/subscription-v2`) settles
|
||||
only at readyState 4 → hangs forever. Cause: sloppy-mode fallback
|
||||
source + assign-then-catch. After (fixed launcher re-injected with
|
||||
`inject-launcher --appdir`, same build): readyState 4, status 200,
|
||||
maxCloudProjects 999 / planId gdevelop_startup, events
|
||||
readystatechange→load→loadend incl. listeners; POST and other
|
||||
endpoints pass through (real 403). Suite 123/123.
|
||||
NOT proven: a real logged-in profile fetch (no account used).
|
||||
- **FINDING (documented, not fixed)**: webRequest backstop is dead on
|
||||
Chromium 128 — pristine-realm XHR + fetch to the usage GETs fail with
|
||||
`net::ERR_UNSAFE_REDIRECT` (https→data: refused). It fails requests
|
||||
instead of serving them. The README's "proven live" claim was the
|
||||
fetch wrapper, not this layer. Untested idea for the owner:
|
||||
`session.defaultSession.setPreloads([preload])` gives a true preload
|
||||
on every window without wrapping BrowserWindow (removes the
|
||||
did-finish-load timing residual).
|
||||
- Login-time consequence (source reading, `AuthenticatedUserProvider.js`
|
||||
~:403–470): limits/subscription fetches are fire-and-forget `.then`s,
|
||||
so a hung XHR leaves both unset with no error.
|
||||
- Smoke probe extended with an axios-0.18-style XHR (a321bdc). Live:
|
||||
fixed preload → ok:true, xhr 200/999, exit 0; original preload →
|
||||
ok:false "XHR limits not unlocked (app client path): never settled",
|
||||
exit 1. Suite 124/124.
|
||||
- DISCREPANCY vs handoff: plain `xvfb-run` (no Mesa override) did NOT
|
||||
crash here — smoke exit 0, ok:true. Override not needed for the smoke
|
||||
with `--disable-gpu`; I used it for the long UI session anyway.
|
||||
|
||||
Desktop smoke on the real patched build (CI artifact renderer + fixed
|
||||
launcher re-injected; logged out; local project in isolated HOME):
|
||||
- PROVEN logo uncheck + watermark uncheck: real clicks, boxes
|
||||
[true,true]→[false,true]→[false,false], 0 extra dialogs, no paywall
|
||||
text; Apply; reopened dialog reads [false,false].
|
||||
- PROVEN 18 consecutive hot reloads (Update button; 18 ×
|
||||
"[LocalPreviewLauncher] Triggering hot reload" in console), dialog
|
||||
count 0 after every one. Upstream would gate #1 and #17.
|
||||
- PROVEN network preview (F8): "Your preview is ready!
|
||||
http://192.168.31.27:2929", no paywall; `curl 127.0.0.1:2929` → 200.
|
||||
- PROVEN debugger (F6): Debugger tab, `preview-ws-1 (Playing)`,
|
||||
"Debugger connection open", 0 dialogs.
|
||||
- Also seen: Wallet 999999 on Create page (unlocked credits seed).
|
||||
|
||||
BYOK E2E on the same build (Preferences → AI Settings, real UI):
|
||||
- PROVEN config UI: toggle + Base URL + model persisted to
|
||||
`gd-custom-ai-config` (no apiKey field stored); "Successfully
|
||||
connected to endpoint" for both mock and Ollama.
|
||||
- PROVEN sub-agent loop with the committed mock
|
||||
(`MOCK_SCRIPT=mock-script-multi.json`): orchestrator request
|
||||
`local-ai-…`, userId `local-byok-user`, tool calls
|
||||
create_or_update_plan + spawn_agent×3; 3 children persisted with roles
|
||||
designer/developer/tester, all `ready`; 8 POSTs to the mock.
|
||||
NOT with a real model (a 0.5b model cannot drive orchestration).
|
||||
LoopGuard not specifically triggered.
|
||||
- PROVEN generation against a real local model: Ollama 0.34.3,
|
||||
`qwen2.5:0.5b` (pulled for the test, removed afterwards), project
|
||||
open; request `ready`, assistant text returned; 2 POSTs to
|
||||
localhost:11434.
|
||||
- PROVEN zero generation egress for these flows: 83 renderer requests
|
||||
recorded over the whole session, 0 to `api.gdevelop.io/generation`,
|
||||
0 presigned/ai-user-content/attachment. Scope: logged out, text-only.
|
||||
NOT covered: logged-in + custom endpoint (hosted summary listing is
|
||||
by design), chat attachments (unguarded at source level).
|
||||
- Observed, upstream behavior: 6 POSTs to `us.i.posthog.com` (analytics)
|
||||
during the session incl. after BYOK sends; payload not inspected.
|
||||
Other hosted calls: `game/resource-signed-url` (template thumbnails),
|
||||
`usage/subscription-plan*` catalogue, gravatar, image CDNs.
|
||||
- Side effects left behind: `/tmp/GDTMP-1000/preview` (GDevelop's own
|
||||
preview temp dir). Ollama restored to its prior model list.
|
||||
|
||||
## #10 — release hardening (commits 9ceb42e, 56d966f, bc8a67b; pushed)
|
||||
|
||||
- **FINDING + FIX**: CI artifact contains `resources/app-update.yml`
|
||||
(`owner: 4ian, repo: GDevelop, provider: github`). The strip deleted
|
||||
the `publish` key; electron-builder 26.4.0 then derives the feed from
|
||||
package.json `repository` (read `PublishManager.js` from the published
|
||||
package: `getPublishConfigsForUpdateInfo`, "default publish config is
|
||||
github, file should be generated regardless"). Only `publish: null`
|
||||
returns null there. Inert on Linux zip (log: "not an AppImage"); would
|
||||
be live on Win NSIS / macOS. Strip now sets `publish: null`, evaluates
|
||||
the config, refuses a keyless config. Each OS job asserts no
|
||||
`app-update.yml` under `dist/`. Local check: app with the file
|
||||
removed boots, smoke ok:true.
|
||||
- **FINDING + FIX**: green Linux run built with `master/latest`
|
||||
libGD.js, not the pinned commit's (detached HEAD → `unknown-branch`,
|
||||
5 failed lookups, fallback; from the run log). Per-commit builds exist
|
||||
on S3 for 8301cdc, ce7be69 and the v5.6.283 tag (HEAD requests → 200).
|
||||
Now `checkout -B master` + `REQUIRES_EXACT_LIBGD_JS_VERSION=true`.
|
||||
- Win job mirrors upstream `.circleci/config.yml` build-windows
|
||||
(setuptools, drop lock files); mac job builds `--mac dir --universal`,
|
||||
ad-hoc signs, smokes, `ditto` zips. `GD_PORTABLE_BUILD` → identity
|
||||
null + afterSign undefined (and the hook itself skips without
|
||||
`APPLEID`) — notarization skipped by construction; CI to confirm.
|
||||
- `npm ci` NOT adopted: upstream itself deletes lock files on Windows
|
||||
and uses `npm install` everywhere; Sonar S8543/S6505 on release.yml
|
||||
stay as accepted residuals.
|
||||
- Validation runs on the branch (publish=false): release 38169760800,
|
||||
e2e 38169762424, seam-tests 38169764070.
|
||||
- e2e 38169762424 @757ddba: tier1-smoke ✅ (stock v5.6.283 + launcher,
|
||||
verdict includes `xhr 200/999`), byok-mock ✅, byok-ollama ✅ (pinned
|
||||
image service container). seam-tests 38169764070 ✅ on Node 22.
|
||||
|
||||
## #13 / #7 / #6 (bd71e54, 6b21bc7; pushed)
|
||||
|
||||
- #13: runbook at top of `patches/REBASE.md`; recipe run as written vs
|
||||
upstream HEAD → 128 pass / 1 skip, apply green. Pin not bumped.
|
||||
- #7: `docs/upstream-drafts/credit-read-hardening.{diff,md}`; diff
|
||||
applies to upstream@8301cdc (`git apply --check`), +31/−6, no BYOK
|
||||
strings. NOT SENT. Upstream flow/jest not run (no node_modules).
|
||||
- #6: fork not archived, `upstream-sync.yml` active, HEAD f7d450a1
|
||||
(read-only checks). In-repo grep on branch: marker strings only.
|
||||
- Issue comments posted on #14 #12 #13 #7 #6; boxes ticked on #14 (4/5)
|
||||
and #12 (6/8). AUDIT_REPORT §9 added.
|
||||
|
||||
## Release validation run 38169760800 (@757ddba, publish=false) — ALL GREEN
|
||||
|
||||
- build-linux ✅ 16 min: `set publish: null`; libGD.js downloaded for
|
||||
HEAD on first try; "no app-update.yml in build output."; smoke ok:true
|
||||
with xhr 200/999.
|
||||
- build-windows ✅ 22 min: nsis `GDevelop 5 Setup 5.6.283.exe` + zip,
|
||||
"file signing skipped via signExts"; no feed; smoke ok:true (xhr ok,
|
||||
POST 403 not spoofed) on `win-unpacked/GDevelop.exe`.
|
||||
- build-macos ✅ 21 min: "skipped macOS code signing reason=identity
|
||||
explicitly is set to null" + "arm64 requires signing, but identity is
|
||||
set to null" → ad-hoc sign step: valid on disk, `Signature=adhoc`,
|
||||
`TeamIdentifier=not set`, `x86_64 arm64`; notarize hook never ran;
|
||||
smoke ok:true; zip 269M.
|
||||
- publish: skipped. Never exercised.
|
||||
- Issues: #10 (3/4 ticked) and #11 (3/6 ticked) updated + commented.
|
||||
|
||||
## Follow-up session: PR #15 + attachment fix (A2) + review fixes
|
||||
|
||||
- PR #15 opened (branch → main). MERGEABLE.
|
||||
- A2 FIXED in patch 07 (38fce1a): `createAiAttachmentUploads` throws
|
||||
before any hosted call when endpoint enabled or user `local-*`;
|
||||
`createAiAttachmentDownloads` → not-found for `local-*`. Re-derived
|
||||
with plain `diff -U3` (reproduces the old patch byte-for-byte; new one
|
||||
differs only by the two insertions; minus-lines 66 = unchanged).
|
||||
Reachability: only logged-in + endpoint on (`UseAiAttachmentDrafts`
|
||||
refuses when `!profile`). Not exercised live (needs login).
|
||||
Release run 38172371449 (linux, publish=false): "Compiled
|
||||
successfully", verify + smoke ok. Guard string found in the shipped
|
||||
`app.asar` bundle, throw precedes auth header + POST; zip has no
|
||||
app-update.yml.
|
||||
- CodeQL on PR flagged `js/file-system-race` in strip-updater-feed
|
||||
(check-then-write). Fixed with a single fd (ab3c405); alert 22 →
|
||||
fixed, CodeQL green.
|
||||
- SonarCloud on PR: reliability A (was C); security C (was E) — 6 MAJOR
|
||||
residuals: S6505/S8543 ×2 each (`npm install` in release.yml), S8707
|
||||
×2 (CLI path arg in strip-updater-feed + assert-smoke-verdict). Gate
|
||||
stays red by design; owner accepts or uninstalls.
|
||||
- CodeRabbit review, valid points fixed: XHR reuse keeps spoofed state
|
||||
(becd5a2, red test first); contract test holes — offline-user branch
|
||||
+ stray hosted calls (2017aee, negative controls); run-wide
|
||||
SHA256SUMS going stale on partial publish → per-OS sums files;
|
||||
persist-credentials/permissions; signing doc macOS claim; audit
|
||||
report "how to read" pointer (5131080). Suite 131/131.
|
||||
- Validation run after workflow change: release 38173968043 @5131080.
|
||||
|
||||
## Branch state check (after all commits)
|
||||
|
||||
129/129, seam gate green, 14 applied, `--verify-only` green, re-apply
|
||||
exit 1, negative control names `canStartAiRequestCreate`, patch 12
|
||||
restored (sha ok), tree clean, fixture clean.
|
||||
@@ -0,0 +1,475 @@
|
||||
# MASTER ORCHESTRATION PROMPT: GDEVELOP-UNLOCKED & OPENCODE SWARM (DEPTH 3)
|
||||
<!--
|
||||
CONTEXT (why this exists):
|
||||
Transform GDevelop-Unlocked into a fully verified, self-healing, OpenCode v2-integrated
|
||||
engine environment:
|
||||
1. Remediate all open AI-agent failure modes observed in live runs (#21 no-project dead end,
|
||||
#22 suspended UI terminal state & resume, #23 storm guard tree-suspension cascade,
|
||||
#24 dead/uncallable tools in manifest).
|
||||
2. Equip the patched client with a comprehensive, low-overhead debug logging subsystem
|
||||
(--heretek-debug-log / HERETEK_DEBUG_LOG) that captures main process events, renderer errors,
|
||||
webRequest traces, and structured AI Studio turn telemetry into disk logs (debug.log) for
|
||||
unattended automated agent testing.
|
||||
3. Build the complete OpenCode v2 integration suite (#16 Control Shim, #17 OpenCode v2 Plugin,
|
||||
#18 OpenAI-compatible Provider Bridge, #19 E2E verification over real I/O).
|
||||
4. Resolve all open governance, hardening, and release tail issues (#26 LICENSE, #10 Win/Mac runners,
|
||||
#11 release checklist, #12 layer-3 proofs, #13 upstream rebase discipline, #14 SonarCloud triage,
|
||||
#6-#8 decommissioning and diplomacy tracking).
|
||||
|
||||
OWNER DECISIONS (fixed):
|
||||
(a) STRICT OFFLINE REAL I/O: All tests run bare `node:test` + built-ins with ZERO npm dependencies
|
||||
in-repo. No mocks of the code under test; use live ephemeral loopback servers and real scratch
|
||||
GDevelop project trees in TMPDIR.
|
||||
(b) ZERO-EGRESS INVARIANT: BYOK loops and local control paths must NEVER contact api.gdevelop.io.
|
||||
(c) FIXTURE IMMUTABILITY: `review/GDevelop` and `review/opencode` are strictly read-only pinned baselines.
|
||||
(d) RECURSIVE SWARM DEPTH: Swarm runs at depth 3 (Director -> Phase Manager -> Squad Lead -> Triad).
|
||||
OpenCode config must set `experimental.subagent_depth: 3`.
|
||||
(e) REPO INTEGRITY: Full suite baseline is 131/131 tests green. Every ticket must maintain or increase
|
||||
the green test count without hand-editing verbatim patch generators.
|
||||
|
||||
HOW TO USE:
|
||||
1. Ensure OpenCode config allows 3 levels of subagents:
|
||||
Set `experimental.subagent_depth: 3` in OpenCode configuration (see review/opencode/packages/core/src/tool/plugin/subagent.ts).
|
||||
2. Start an OpenCode session in /home/john/Projects/GDevelop-Unlocked.
|
||||
3. Paste this ENTIRE file into the session turn.
|
||||
-->
|
||||
|
||||
You are the **Swarm Director** running inside OpenCode v2 with recursive subagents. You have the full tool set (`subagent`, `shell`, `read`, `write`, `edit`, `patch`, `skill`, `websearch`, `webfetch`).
|
||||
|
||||
Your mission is to orchestrate, remediate, build, verify, audit, and land the complete **GDevelop Unlocked v0.2.0** milestone. You will remediate all open GitHub issues (#6–#26), deliver the patched client debug logging subsystem, implement the OpenCode v2 bidirectional integration, and prove full end-to-end operation over real I/O under Triad verification (Programmer ⇄ QA ⇄ Auditor), halting at a clean Draft PR on `integration/v0.2`.
|
||||
|
||||
---
|
||||
|
||||
## I. THE SWARM CONSTITUTION (NON-NEGOTIABLE LAWS)
|
||||
|
||||
Every agent in the hierarchy is bound by these rules:
|
||||
|
||||
1. **Base Branch Immutability**
|
||||
- The Director cuts `integration/v0.2` from `main` before any ticket spawns.
|
||||
- **NEVER** commit directly to or push `main`. All work lands on `integration/v0.2` via merged ticket branches.
|
||||
2. **Reference Fixtures Are Read-Only**
|
||||
- `review/GDevelop` (commit `8301cdcaa4`) and `review/opencode` (branch `v2`) are pinned reference sources.
|
||||
- **NEVER** edit, commit, format, or run build/test commands inside `review/`.
|
||||
- Before and after every ticket merge, verify: `git -C review/GDevelop status --short` is completely empty.
|
||||
3. **Real Over Mocks (Zero External Test Dependencies)**
|
||||
- The repository uses bare `node:test` + Node.js built-ins. No external npm test runner (Jest/Mocha/Vitest) and no JSDOM/React shallow wrappers.
|
||||
- Tests exercise real I/O: live ephemeral `http` servers on dynamic ports (`127.0.0.1:0`), real file mutations in `TMPDIR`, and real patch application.
|
||||
- Forbidden: canned mock responses in integration tests, monkey-patching `globalThis` to fake successful responses, or skipping tests.
|
||||
4. **Zero-Egress Invariant**
|
||||
- In BYOK mode, zero requests may reach `api.gdevelop.io/generation` or any hosted generation endpoint. Every test must assert this fail-closed boundary.
|
||||
5. **Patch Discipline (Load-Bearing)**
|
||||
- Patches `01`–`06` and `09`/`10` are **verbatim generator output** — never hand-edit. `tests/patches/generate.test.mjs` pins them byte-for-byte. New Tier-1 hunks belong in `scripts/generate-tier1-patches.mjs`.
|
||||
- Patches `07`, `08`, `11`, `13`, `14` are **curated forward-ports** (`patches/REBASE.md`). Never regenerate them with `generate-tier2-patches.mjs`. Any changes must pass anti-revert assertions (no deletion of upstream-new symbols).
|
||||
- If `packages/ai-studio/` is modified, `packages/ai-studio/MANIFEST.json` hashes and byte counts must be updated, and `tests/tier2/extract.test.mjs` must remain green.
|
||||
6. **Worktree Isolation Law**
|
||||
- Every ticket executes in `.worktrees/ticket-<ID>` on branch `ticket-<ID>`, branched from `integration/v0.2`.
|
||||
- No two agents edit the same worktree.
|
||||
7. **Serialized Worktree Administration**
|
||||
```bash
|
||||
mkdir -p .worktrees
|
||||
flock .worktrees/.git_lock git worktree add -b ticket-<ID> .worktrees/ticket-<ID> integration/v0.2
|
||||
```
|
||||
`git worktree remove` and merges into `integration/v0.2` must take the same lock.
|
||||
8. **Upward Rollup Principle**
|
||||
- Detail flows down; verifiable summaries flow up. Subagents report ONLY:
|
||||
`Ticket ID`, `Status (PASS/FAIL)`, `Commit SHA`, `Changed Files`, `Verification Summary`, `Audit Proof`.
|
||||
Never dump raw multi-page logs or stack traces upward.
|
||||
9. **Strict Test-Driven Development (TDD)**
|
||||
- Programmers write a failing test first, run it to witness the failure, then write the minimal code that passes.
|
||||
10. **Triad Consensus Law**
|
||||
- A ticket branch merges only after **BOTH** QA and the Code Auditor independently certify PASS.
|
||||
11. **Explicit Staging**
|
||||
- **NEVER** `git add -A` or `git add .`. Stage explicit file paths only.
|
||||
12. **Scratch & Temp Safety**
|
||||
- Scratch/temp paths must honor `TMPDIR`/`TEMP`/`TMP` via `os.tmpdir()` — never hard-code `/tmp`.
|
||||
13. **Release Boundary**
|
||||
- The swarm halts at Draft PR creation on `integration/v0.2` (or reports the integration commit SHA if no origin remote is writable). No unauthorized public release tag or npm publish.
|
||||
|
||||
---
|
||||
|
||||
## II. THE HIERARCHY & RECURSIVE DISPATCH
|
||||
|
||||
```
|
||||
Tier 0: Swarm Director (session root)
|
||||
│
|
||||
├──► Tier 1: Phase 0 Manager (Foundation, Governance & Debug Logging)
|
||||
│ ├──► Tier 2: Ticket Squad Lead (T01)
|
||||
│ │ ├──► Tier 3: Programmer (TDD)
|
||||
│ │ ├──► Tier 3: QA (adversarial)
|
||||
│ │ └──► Tier 3: Auditor (diff witness)
|
||||
│ └──► Tier 2: Ticket Squad Lead (T02)
|
||||
│
|
||||
├──► Tier 1: Phase 1 Manager (AI Agent Studio Remediation #21-#24)
|
||||
│ ├──► Tier 2: Ticket Squad Lead (T03: #24 Dead Tools)
|
||||
│ ├──► Tier 2: Ticket Squad Lead (T04: #21 No-Project Fix)
|
||||
│ ├──► Tier 2: Ticket Squad Lead (T05: #22 Suspended UI & Resume)
|
||||
│ └──► Tier 2: Ticket Squad Lead (T06: #23 Storm Guard Isolation)
|
||||
│
|
||||
├──► Tier 1: Phase 2 Manager (Control Shim & Provider Bridge #16, #18)
|
||||
│ ├──► Tier 2: Ticket Squad Lead (T07: Control Shim)
|
||||
│ └──► Tier 2: Ticket Squad Lead (T08: Provider Bridge)
|
||||
│
|
||||
├──► Tier 1: Phase 3 Manager (OpenCode v2 Plugin #17)
|
||||
│ ├──► Tier 2: Ticket Squad Lead (T09: Plugin Core & Tools)
|
||||
│ └──► Tier 2: Ticket Squad Lead (T10: Architect Agent)
|
||||
│
|
||||
└──► Tier 1: Phase 4 Manager (E2E Verification & Release Hardening #19, #12, #10, #14)
|
||||
├──► Tier 2: Ticket Squad Lead (T11: E2E BYOK Loop)
|
||||
├──► Tier 2: Ticket Squad Lead (T12: CI & Upstream Rebase Runbook)
|
||||
└──► Tier 2: Ticket Squad Lead (T13: Milestone Gate & PR)
|
||||
```
|
||||
|
||||
- **Director**: Sets up `integration/v0.2`, executes phases in DAG order, verifies gates, produces the final audit report, and opens the Draft PR.
|
||||
- **Phase Manager**: Coordinates tickets within its phase (max 3 concurrent worktrees), merges passed branches under `.git_lock`, runs the phase regression gate (`npm test`).
|
||||
- **Ticket Squad Lead**: Allocates worktree, dispatches Programmer → QA → Auditor, runs the bounded repair loop (max 3 iterations on failure), removes the worktree, rolls up verdict.
|
||||
- **Triad**:
|
||||
- *Programmer*: TDD, commits explicit paths with commit messages referencing ticket ID.
|
||||
- *QA*: Runs targeted test, then full `npm test` (asserting 131+ green), performs adversarial inputs and negative controls, returns `QA Verdict: PASS | FAIL`.
|
||||
- *Auditor*: Diff analysis against `integration/v0.2`, checks Constitution laws, anti-revert rules, and fixture cleanliness, returns `Auditor Verdict: PASS | FAIL`.
|
||||
|
||||
---
|
||||
|
||||
## III. DEPENDENCY DAG
|
||||
|
||||
```
|
||||
Wave 1: Phase 0 (Foundation & Debugging) T01 ──► T02
|
||||
│
|
||||
▼
|
||||
Wave 2: Phase 1 (AI Studio Fixes) T03 ──► T04 ──► T05 ──► T06
|
||||
│
|
||||
▼
|
||||
Wave 3: Phase 2 (Shim & Provider Bridge) T07 ──► T08
|
||||
│
|
||||
▼
|
||||
Wave 4: Phase 3 (OpenCode v2 Plugin) T09 ──► T10
|
||||
│
|
||||
▼
|
||||
Wave 5: Phase 4 (E2E & Release Readiness) T11 ──► T12 ──► T13 (Draft PR)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## IV. PHASE-BY-PHASE EXECUTION BLUEPRINTS
|
||||
|
||||
### PHASE 0: FOUNDATION, GOVERNANCE & DEBUG LOGGING
|
||||
|
||||
#### Ticket T01: Repository Governance & LICENSE (Issues #26, #14)
|
||||
- **Scope:**
|
||||
1. Commit `LICENSE` (MIT License) covering this repository's original code (`packages/`, `launcher/`, `scripts/`, `tests/`), clearly documenting upstream GDevelop's separate licenses (core MIT, newIDE commercial/MIT).
|
||||
2. Add `"license": "MIT"` to `package.json`.
|
||||
3. Close SonarCloud triage (#14): resolve or formally document remaining accepted residuals in `.sonarcloud.properties` or `AUDIT_REPORT.md §2`.
|
||||
- **Files:** `LICENSE`, `package.json`, `AUDIT_REPORT.md`.
|
||||
- **Test Gate:** `npm test` (131/131 passing), `git status` clean.
|
||||
|
||||
#### Ticket T02: Client Debug Logging Subsystem (Core Observability for Automated Agent Testing)
|
||||
- **Scope:**
|
||||
Build a dedicated, low-overhead debug logging system that allows automated test runners, headless instances, and agents to inspect exact runtime errors and AI Studio turn telemetry:
|
||||
1. **Logger Core (`launcher/debug-logger.cjs`):**
|
||||
- Thread-safe, atomic file appender using synchronous file descriptors (`fs.appendFileSync`).
|
||||
- Activates when `--heretek-debug-log <path>` CLI argument or `HERETEK_DEBUG_LOG=<path>` environment variable is present.
|
||||
- Structured JSONL event schema:
|
||||
```json
|
||||
{"ts": 1773420000000, "iso": "2026-10-12T04:00:00.000Z", "source": "main|preload|renderer|studio", "level": "INFO|WARN|ERROR", "event": "...", "data": {}}
|
||||
```
|
||||
2. **Main Process Hooks (`launcher/heretek-hook.cjs`):**
|
||||
- Initialize logger on startup if flag/env is set.
|
||||
- Log window creation events, navigation URLs, and uncaught exceptions.
|
||||
- In `watchWebRequest`: log all outgoing URLs and explicitly flag any attempted connection to `api.gdevelop.io`.
|
||||
3. **Preload & Renderer Hooks (`launcher/preload-unlock.cjs`):**
|
||||
- Expose `window.__HERETEK_LOGGER__` in renderer.
|
||||
- Hook `window.addEventListener('error')` and `window.addEventListener('unhandledrejection')` to log renderer crashes.
|
||||
- Intercept `console.error` and `console.warn` to stream warnings/errors into the debug log file.
|
||||
4. **AI Studio Instrumentation (`packages/ai-studio/AI/CustomAIClient.js`, `AiGeneration/Studio/LoopGuard.js`, `AiGeneration/Studio/UseStudioRuntime.js`):**
|
||||
- Emit structured events:
|
||||
- `[AI_REQUEST_START]`: request ID, model, prompt summary, tool count.
|
||||
- `[TOOL_CALL]`: function name, call_id, parameters.
|
||||
- `[TOOL_RESULT]`: function name, call_id, success status, duration.
|
||||
- `[GUARD_EVALUATE]`: consecutive failure counts, action (`pass|steer|constrain`), reason.
|
||||
- `[REQUEST_STATE_CHANGE]`: transition to `ready`, `suspended`, `error`, `completed`.
|
||||
5. **Log Inspector CLI (`scripts/dump-debug-log.mjs`):**
|
||||
- Pure CLI tool to parse, format, and filter a debug log by event type, level, or request ID.
|
||||
- **Files:** `launcher/debug-logger.cjs`, `launcher/heretek-hook.cjs`, `launcher/preload-unlock.cjs`, `packages/ai-studio/AI/CustomAIClient.js`, `scripts/dump-debug-log.mjs`, `tests/launcher/debug-logger.test.cjs`.
|
||||
- **Test Gate:** New unit test `tests/launcher/debug-logger.test.cjs` proves file creation, JSONL event format, and error trapping without external dependencies. `npm test` passes.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 1: AI AGENT STUDIO REMEDIATION (ISSUES #21–#24)
|
||||
|
||||
#### Ticket T03: Tool Manifest Pruning & Docs Availability Notice (Issue #24)
|
||||
- **Scope:**
|
||||
Eliminate uncallable tool failures that burn model turns:
|
||||
1. In `packages/ai-studio/AI/CustomAIClient.js`, inspect `GDEVELOP_OPENAI_TOOLS`:
|
||||
- Remove `create_or_update_plan` from the tools offered to the LLM (or route it to `PlanStore.js` if emitted, rather than letting it hit upstream's uncallable `EditorFunctions/index.js` failure).
|
||||
2. For `search_docs` and `read_full_docs`:
|
||||
- Append a clear description suffix: `"[Offline in local BYOK mode: rely on your internal GDevelop knowledge and on-project verification]"`.
|
||||
- In `CustomAIClient.js`, if called when docs backend is unreachable, immediately return:
|
||||
`{ success: false, offline: true, message: "Documentation backend is offline in local mode. Proceed using your built-in GDevelop knowledge." }` without network lag.
|
||||
3. Update `packages/ai-studio/MANIFEST.json` to reflect updated hashes and byte lengths.
|
||||
- **Files:** `packages/ai-studio/AI/CustomAIClient.js`, `packages/ai-studio/AiGeneration/Studio/Roles.js`, `packages/ai-studio/MANIFEST.json`.
|
||||
- **Test Gate:** `tests/tier2/extract.test.mjs` green, new assertions in `tests/integration/ai-byok-flow.test.mjs` verifying no dead tool calls.
|
||||
|
||||
#### Ticket T04: No-Project Dead-End Self-Remediation (Issue #21)
|
||||
- **Scope:**
|
||||
Prevent the agent from parking when no project is open:
|
||||
1. In `packages/ai-studio/AI/CustomAIClient.js` and `EditorFunctions` dispatch:
|
||||
- When any project-dependent tool (e.g. `get_project_summary`, `create_or_replace_object`) fails because `project === null`:
|
||||
Return a deterministic, self-remedying error response:
|
||||
`"No project is currently open. You must call initialize_project(template_slug: 'empty') to create a blank project before executing other actions."`
|
||||
2. In `packages/ai-studio/AiGeneration/Studio/Roles.js`:
|
||||
- Update the Manager/Lead Architect system prompt: explicitly state that when starting with no project, the very first action must be calling `initialize_project`.
|
||||
3. Ensure `initialize_project` is prominently included in the active role tool manifest.
|
||||
4. Update `MANIFEST.json`.
|
||||
- **Files:** `packages/ai-studio/AI/CustomAIClient.js`, `packages/ai-studio/AiGeneration/Studio/Roles.js`, `packages/ai-studio/MANIFEST.json`.
|
||||
- **Test Gate:** Unit test proving project tools return self-remedying advice when project is null; `extract.test.mjs` green.
|
||||
|
||||
#### Ticket T05: Suspended UI Terminal State & Resume Affordance (Issue #22)
|
||||
- **Scope:**
|
||||
Replace infinite spinners on suspended requests with honest terminal UI and resume controls:
|
||||
1. In `patches/11-studio-runtime-mount.patch` and `packages/ai-studio/AiGeneration/Studio/UseStudioRuntime.js`:
|
||||
- When `aiRequest.status === 'suspended'` or `aiRequest.status === 'error'`, replace the "Evaluating the game logic..." spinner and disabled composer.
|
||||
- Display an explicit terminal status card containing:
|
||||
- Status badge (`Suspended` or `Stopped by Loop Guard`).
|
||||
- Exact failure reason (`error.message` or `decision.reason`).
|
||||
- Timestamp of suspension.
|
||||
- **Resume / Retry button**: Clears the consecutive error counters in LoopGuard, resets status to `ready`, and posts a steer prompt.
|
||||
- **Clear Stalled button**: Purges stale suspended requests from `localStorage['gd-custom-ai-requests']`.
|
||||
2. Verify anti-revert assertions for `patches/11-studio-runtime-mount.patch`.
|
||||
- **Files:** `packages/ai-studio/AiGeneration/Studio/UseStudioRuntime.js`, `patches/11-studio-runtime-mount.patch`, `packages/ai-studio/MANIFEST.json`.
|
||||
- **Test Gate:** `tests/tier2/tier2-patches.test.mjs` passes, `tests/tier2/extract.test.mjs` passes.
|
||||
|
||||
#### Ticket T06: Error-Storm Guard Child Startup Isolation (Issue #23)
|
||||
- **Scope:**
|
||||
Prevent child startup failures from suspending the parent orchestrator:
|
||||
1. In `patches/14-ai-utils.patch` and `packages/ai-studio/AiGeneration/Studio/LoopGuard.js`:
|
||||
- Disentangle child initialization failures from parent action progress.
|
||||
- When `spawnSubAgent` fails at startup (e.g., error storm on parallel spawn), fail ONLY that specific tool call (`success: false, output: { message: ... }`).
|
||||
- Do NOT attribute child-startup crashes to the parent's action streak.
|
||||
- Do NOT trigger `decision.action === 'constrain'` on the parent request due to child failures.
|
||||
- Allow the parent request to remain alive and execute its serial fallback plan.
|
||||
2. Keep `LoopGuard` constrained strictly to the single request whose actions repeat without progress.
|
||||
3. Verify `patches/14-ai-utils.patch` preserves anti-revert rules.
|
||||
- **Files:** `packages/ai-studio/AiGeneration/Studio/LoopGuard.js`, `packages/ai-studio/AiGeneration/Studio/SpawnSubAgents.js`, `patches/14-ai-utils.patch`, `packages/ai-studio/MANIFEST.json`.
|
||||
- **Test Gate:** Multi-agent loop unit tests in `tests/integration/ai-byok-flow.test.mjs` verify that child spawn failures return tool error without setting parent status to `suspended`.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 2: CONTROL SHIM & PROVIDER BRIDGE (ISSUES #16, #18)
|
||||
|
||||
#### Ticket T07: GDevelop Control Shim (Issue #16)
|
||||
- **Scope:**
|
||||
Deliver a pure, zero-dependency ESM control shim in `packages/unlock-shim/control-shim.mjs`:
|
||||
1. **Project AST Parser & Mutator:**
|
||||
- `readGDevelopProject(projectPath)`: Loads and validates single-file `game.json` or split-folder projects.
|
||||
- `writeGDevelopProject(projectPath, projectData)`: Writes deterministic GDevelop project JSON matching canonical spacing.
|
||||
- `createScene(projectData, sceneName)`: Injects layout object into `projectData.layouts`.
|
||||
- `createOrReplaceObject(projectData, { sceneName, objectName, objectType, description })`: Adds/updates object definitions in project or scene scope.
|
||||
- `addBehavior(projectData, { sceneName, objectName, behaviorName, behaviorType })`: Injects behavior blocks (Platformer, Physics2, TopDown, etc.) with schema defaults.
|
||||
- `addStandardEvent(projectData, { sceneName, conditions, actions })`: Injects standard event structures.
|
||||
2. **Headless CLI Command Dispatcher:**
|
||||
- `buildGDevelopCliCommand({ gdevelopPath, projectPath, commandName, cmdArgs, headless })`: Formats CLI arguments for `electron-app/app/main.js` and `LocalCliCommandRunner` (`--run-command <NAME> --cmd-args <ARGS>`).
|
||||
3. **Live Debugger Protocol Bridge:**
|
||||
- `connectDebuggerBridge(port, onMessage)`: Minimal WebSocket client targeting GDevelop's `DebuggerServer` (ports 3030–4000) for hot reload inspection.
|
||||
- **Files:** `packages/unlock-shim/control-shim.mjs`, `packages/unlock-shim/README.md`, `tests/unit/opencode-control-shim.test.mjs`.
|
||||
- **Test Gate:** `node --test tests/unit/opencode-control-shim.test.mjs` executes clean AST mutations against scratch project copies in `TMPDIR`.
|
||||
|
||||
#### Ticket T08: OpenCode Provider Bridge for GDevelop AI Studio (Issue #18)
|
||||
- **Scope:**
|
||||
Deliver an OpenAI-compatible HTTP daemon in `packages/opencode-provider/` allowing GDevelop's `CustomAIClient` to target OpenCode:
|
||||
1. **Server (`packages/opencode-provider/server.mjs`):**
|
||||
- Native Node.js `http` server (ephemeral port support).
|
||||
- CORS handling: `OPTIONS` returns 204 with permissive headers for Electron/browser Axios clients.
|
||||
- `GET /v1/models`: Returns available model identifiers.
|
||||
- `POST /v1/chat/completions`:
|
||||
- Handles streaming (`stream: true`) via SSE (`text/event-stream`), emitting chunk deltas and `data: [DONE]\n\n`.
|
||||
- Handles non-streaming (`stream: false`) returning standard completion objects with usage statistics.
|
||||
- Function calling: maps tool calls to standard `tool_calls: [...]` schema for GDevelop's 39 editor functions.
|
||||
2. **Adapter (`packages/opencode-provider/adapter.mjs`):**
|
||||
- Translates OpenAI completion payloads into OpenCode session/prompt structures and vice-versa.
|
||||
3. **CLI Entrypoint (`packages/opencode-provider/cli.mjs`):**
|
||||
- Executable CLI supporting `--port <number>`, `--host <host>`, `--verbose`.
|
||||
- **Files:** `packages/opencode-provider/server.mjs`, `packages/opencode-provider/adapter.mjs`, `packages/opencode-provider/cli.mjs`, `packages/opencode-provider/package.json`, `tests/integration/opencode-provider-server.test.mjs`.
|
||||
- **Test Gate:** `tests/integration/opencode-provider-server.test.mjs` runs real HTTP requests, verifies SSE streaming chunks, and validates tool-call payloads.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 3: OPENCODE V2 PLUGIN FOR GDEVELOP (ISSUE #17)
|
||||
|
||||
#### Ticket T09: Plugin Definition & Core Tools (Issue #17)
|
||||
- **Scope:**
|
||||
Deliver `@heretek-ai/opencode-gdevelop` (in `packages/opencode-gdevelop/`, published as `@heretek-ai/opencode-gdevelop`) implementing `@opencode/plugin` Promise API:
|
||||
1. **Plugin Entrypoint (`packages/opencode-gdevelop/index.mjs`):**
|
||||
- Implements `Plugin.define({ id: "gdevelop", setup: async (ctx) => { ... } })`.
|
||||
2. **Tool Registrations (`packages/opencode-gdevelop/tools.mjs`):**
|
||||
- `gdevelop_project_read`: Inspect scenes, objects, behaviors, and variables from a project on disk.
|
||||
- `gdevelop_project_create_scene`: Creates a new scene.
|
||||
- `gdevelop_project_create_object`: Creates 2D (Sprite, Text, PanelSprite) or 3D objects.
|
||||
- `gdevelop_project_add_behavior`: Adds behaviors to objects.
|
||||
- `gdevelop_project_add_events`: Adds event condition/action trees.
|
||||
- `gdevelop_cli_run`: Dispatches headless GDevelop commands.
|
||||
- **Files:** `packages/opencode-gdevelop/index.mjs`, `packages/opencode-gdevelop/tools.mjs`, `packages/opencode-gdevelop/package.json`, `tests/integration/opencode-plugin-tools.test.mjs`.
|
||||
- **Test Gate:** Integration tests verifying tool registration and file mutation on scratch projects.
|
||||
|
||||
#### Ticket T10: Specialized Agent Registration (`gdevelop-architect`) (Issue #17)
|
||||
- **Scope:**
|
||||
Register the `gdevelop-architect` persona via `ctx.agent.transform`:
|
||||
1. **Agent Definition (`packages/opencode-gdevelop/agents.mjs`):**
|
||||
- Persona: `gdevelop-architect`.
|
||||
- System Prompt: Expert in GDevelop 5 game architecture, GDJS runtime lifecycle, event logic (conditions/actions/sub-events), and asset management.
|
||||
- Configures tool permissions: access to all `gdevelop_*` tools and file read/write tools.
|
||||
2. Documentation in `packages/opencode-gdevelop/README.md`.
|
||||
- **Files:** `packages/opencode-gdevelop/agents.mjs`, `packages/opencode-gdevelop/README.md`.
|
||||
- **Test Gate:** In-process test confirming `ctx.agent.get("gdevelop-architect")` returns valid configuration.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 4: VERIFICATION, HARDENING & RELEASE READINESS (ISSUES #19, #12, #10, #11, #13, #8, #6, #7)
|
||||
|
||||
#### Ticket T11: End-to-End BYOK Loop Verification Suite (Issues #19, #12)
|
||||
- **Scope:**
|
||||
Multi-turn real I/O end-to-end verification proving complete integration without mocks:
|
||||
1. **E2E Test (`tests/e2e/gdevelop-opencode-byok-e2e.test.mjs`):**
|
||||
- Spins up live `opencode-provider` server on dynamic port (`127.0.0.1:0`).
|
||||
- Extracts fresh scratch GDevelop project into `TMPDIR`.
|
||||
- Executes `CustomAIClient` logic targeting the live provider URL.
|
||||
- Verifies provider emits structured `tool_calls` (e.g. `create_or_replace_object`).
|
||||
- Executes tool call against the scratch project, sends output back to provider, and concludes generation.
|
||||
- Reads modified `game.json` from disk and verifies object existence.
|
||||
- Asserts **zero network requests** to `api.gdevelop.io`.
|
||||
2. Tick off remaining proofs in Issue #12 (subagent loop runs, zero requests to `api.gdevelop.io/generation`).
|
||||
- **Files:** `tests/e2e/gdevelop-opencode-byok-e2e.test.mjs`, `package.json` (`"test:e2e"`, `"test:opencode"`).
|
||||
- **Test Gate:** `npm run test:e2e` exits 0 with full assertions verified.
|
||||
|
||||
#### Ticket T12: CI Hardening & Upstream Rebase Runbook (Issues #10, #13)
|
||||
- **Scope:**
|
||||
1. Review CI workflows (`.github/workflows/release.yml`, `seam-tests.yml`):
|
||||
- Confirm Windows (nsis + zip) and macOS (universal) runner jobs are pinned and healthy (#10).
|
||||
- Update code-signing documentation in `docs/release-signing.md` with explicit instructions.
|
||||
2. Document and verify the recurring upstream rebase runbook (#13):
|
||||
- Automated script/check in `scripts/verify-upstream-rebase.mjs` testing clean patch application against upstream HEAD.
|
||||
- **Files:** `.github/workflows/release.yml`, `docs/release-signing.md`, `scripts/verify-upstream-rebase.mjs`.
|
||||
- **Test Gate:** `node scripts/verify-upstream-rebase.mjs` runs cleanly against `review/GDevelop`.
|
||||
|
||||
#### Ticket T13: Milestone Gate, Audit Report & Draft PR (Issues #11, #8, #6, #7, #20)
|
||||
- **Scope:**
|
||||
1. Run full gate: `npm test` + `npm run test:opencode` + `npm run test:e2e` + `node scripts/apply-patches.mjs --check`.
|
||||
2. Confirm new test count (must be >= 145/145 passing).
|
||||
3. Update `AUDIT_REPORT.md` and `README.md` documenting:
|
||||
- All 18 issues resolved or formally updated (#6 fork archival noted, #7 RFC noted, #8 epic fulfilled, #20 epic fulfilled, #26 LICENSE added).
|
||||
- New client debug logging subsystem usage (`--heretek-debug-log`).
|
||||
- OpenCode plugin and provider bridge usage.
|
||||
4. Create Draft PR from `integration/v0.2` to `main` with full rollup proof.
|
||||
- **Test Gate:** All tests green, working tree clean, fixture untouched.
|
||||
|
||||
---
|
||||
|
||||
## V. DISPATCH EXECUTION TEMPLATES
|
||||
|
||||
### 1. Phase Manager (Tier 0 -> Tier 1)
|
||||
```ts
|
||||
subagent({
|
||||
agent: "general-purpose",
|
||||
description: "Phase 1 AI Studio Manager",
|
||||
prompt: `You are the Phase 1 Manager for GDevelop Unlocked in /home/john/Projects/GDevelop-Unlocked.
|
||||
Integration branch: integration/v0.2. Tickets: T03, then T04, then T05, then T06.
|
||||
Follow the Constitution (Section I) strictly:
|
||||
1. For each ready ticket, spawn a Ticket Squad Lead (at most 3 worktrees at once).
|
||||
2. When a squad reports double PASS (QA + Auditor), merge ticket-<ID> into integration/v0.2 under flock .worktrees/.git_lock.
|
||||
3. You own patch/wiring conflict resolution at merge time.
|
||||
4. After each merge, verify: npm test is green (131+ tests) and git -C review/GDevelop status --short is empty.
|
||||
5. Return only a rolled-up summary: per-ticket status, commit SHAs, and gate result.`
|
||||
})
|
||||
```
|
||||
|
||||
### 2. Ticket Squad Lead (Tier 1 -> Tier 2)
|
||||
```ts
|
||||
subagent({
|
||||
agent: "general-purpose",
|
||||
description: "Squad Lead T02 Debug Logging",
|
||||
prompt: `You are the Squad Lead for ticket T02 (Client Debug Logging Subsystem).
|
||||
Worktree: .worktrees/ticket-T02 (branch ticket-T02 from integration/v0.2).
|
||||
1. Create the worktree under flock .worktrees/.git_lock:
|
||||
flock .worktrees/.git_lock git worktree add -b ticket-T02 .worktrees/ticket-T02 integration/v0.2
|
||||
2. Spawn Programmer T02 with the scope and Prior Art from Blueprint Section IV.
|
||||
3. After Programmer commits, spawn QA T02. After QA PASS, spawn Code Auditor T02.
|
||||
4. On any FAIL, send the exact failure findings back to Programmer (max 3 repair rounds), then escalate.
|
||||
5. On double PASS: remove the worktree under lock and report PASS with commit SHA.`
|
||||
})
|
||||
```
|
||||
|
||||
### 3. Programmer (Tier 2 -> Tier 3)
|
||||
```ts
|
||||
subagent({
|
||||
agent: "general-purpose",
|
||||
description: "Programmer T02 Debug Logging",
|
||||
prompt: `You are the Programmer for ticket T02. Work ONLY inside .worktrees/ticket-T02.
|
||||
Task: Implement launcher/debug-logger.cjs, preload hooks, and scripts/dump-debug-log.mjs.
|
||||
1. Write a failing test in tests/launcher/debug-logger.test.cjs using native node:test. Witness the failure.
|
||||
2. Implement launcher/debug-logger.cjs and integrate with launcher/heretek-hook.cjs and preload-unlock.cjs.
|
||||
3. Run: node --test tests/launcher/debug-logger.test.cjs && npm test.
|
||||
4. Stage explicit paths only (never git add .), commit with message referencing T02.
|
||||
5. Report only: commit SHA, files changed, test results.`
|
||||
})
|
||||
```
|
||||
|
||||
### 4. QA (Tier 2 -> Tier 3)
|
||||
```ts
|
||||
subagent({
|
||||
agent: "general-purpose",
|
||||
description: "QA T02 Debug Logging",
|
||||
prompt: `You are QA for ticket T02. Work ONLY inside .worktrees/ticket-T02.
|
||||
1. Run the target test: node --test tests/launcher/debug-logger.test.cjs.
|
||||
2. Run full regression suite: npm test. Confirm all 131+ tests pass.
|
||||
3. Adversarial verification:
|
||||
- Provide invalid log paths and verify graceful fallback.
|
||||
- Test JSONL event parsing under heavy synchronous logging.
|
||||
- Verify zero external npm packages were imported.
|
||||
4. Emit: QA Verdict: PASS | FAIL with exact details.`
|
||||
})
|
||||
```
|
||||
|
||||
### 5. Code Auditor (Tier 2 -> Tier 3)
|
||||
```ts
|
||||
subagent({
|
||||
agent: "general-purpose",
|
||||
description: "Code Auditor T02 Debug Logging",
|
||||
prompt: `You are the Code Auditor for ticket T02. Work ONLY inside .worktrees/ticket-T02.
|
||||
Inspect: git diff integration/v0.2...HEAD.
|
||||
Verify:
|
||||
1. No file under review/ is touched or committed (confirm git -C review/GDevelop status is empty).
|
||||
2. Constitution rules hold: no external npm dependencies added, native node:test used, zero network egress to api.gdevelop.io.
|
||||
3. If packages/ai-studio was modified, confirm MANIFEST.json hashes match and tests/tier2/extract.test.mjs is green.
|
||||
4. Only explicit paths were staged.
|
||||
5. Emit: Auditor Verdict: PASS | FAIL with checklist.`
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## VI. HOST FACTS
|
||||
|
||||
**Verified by reading source in `review/` and repository (rely on these):**
|
||||
- Upstream baseline commit is `8301cdcaa4`, pinned in `UPSTREAM_BASELINE.json`.
|
||||
- Current test suite baseline is 131 tests across 39 suites, running offline on native `node:test`.
|
||||
- GDevelop's Electron app runs with `nodeIntegration: true`, `contextIsolation: false`, `webSecurity: false` (proven in Phase 1 seam tests).
|
||||
- Preload injection in production Electron uses the `did-finish-load` fallback because `BrowserWindow` is non-configurable.
|
||||
- `CustomAIClient.js` defines the 39 GDevelop OpenAI function schemas and stores config in `localStorage['gd-custom-ai-config']`.
|
||||
- OpenCode v2 plugins implement the Promise API (`Plugin.define({ id, setup })`) or Effect API.
|
||||
- Subagent depth in OpenCode defaults to 1; recursive swarms require `experimental.subagent_depth: 3` in config.
|
||||
- The `@gdevelop` npm scope is owned by upstream; our plugin is published as `@heretek-ai/opencode-gdevelop`.
|
||||
|
||||
**NOT yet verified (Tickets T02 and T07 must prove with tests):**
|
||||
- Maximum synchronous throughput of `debug-logger.cjs` under continuous stream of React re-renders.
|
||||
- Behavior of GDevelop `LocalCliCommandRunner` in headless mode on Linux runners without active X11 display (must run cleanly under `xvfb-run`).
|
||||
- OpenCode v2 session compaction behavior when receiving large multi-turn GDevelop project diffs.
|
||||
|
||||
---
|
||||
|
||||
## VII. INITIATE EXECUTION
|
||||
|
||||
As the **Swarm Director**, begin now:
|
||||
1. Verify state: `git status`, confirm `review/GDevelop` and `review/opencode` are clean.
|
||||
2. Run baseline test gate: `npm test` (must report 131/131 passed).
|
||||
3. Cut integration branch: `git checkout -b integration/v0.2`.
|
||||
4. Ensure `experimental.subagent_depth: 3` is set in OpenCode configuration.
|
||||
5. Spawn the **Phase 0 Manager**. Advance to Wave 2 only when the Phase 0 gate is completely green.
|
||||
6. After Ticket T13 completes, output the final audit report, report the integration commit SHA and Draft PR URL, and halt.
|
||||
Reference in new issue
Block a user