Spaces:
Running on Zero
Running on Zero
docs: hand off Phase 01 at the deploy gate
Browse filesRecord where the work stands, why 42 commits are unpushed on purpose, and the
traps that cost real time this session so none of them get re-derived: the two
Gradio 6.22.0 API defects, the ASR q8/WASM incompatibility, and the two spec
corrections that supersede the research doc.
HANDOFF.json is the machine-readable half that resume-work reads first. Its
absence after the earlier crash is what made recovering this plan expensive.
- .planning/HANDOFF.json +44 -0
- RESUME.md +121 -0
.planning/HANDOFF.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"created": "2026-08-27",
|
| 3 |
+
"created_by": "session handoff — user stepping away from the machine",
|
| 4 |
+
"status": "blocked_on_user",
|
| 5 |
+
"phase": "01-voice-avatar-loop-skeleton",
|
| 6 |
+
"plan": "01-05",
|
| 7 |
+
"task": 1,
|
| 8 |
+
"total_tasks": 3,
|
| 9 |
+
"next_action": "Decide whether to run plan 01-05, the user-gated deploy. It is the only thing blocking the rest of Phase 01. Run `/gsd:execute-phase 01` to resume; the orchestrator will pick up at 01-05.",
|
| 10 |
+
"blockers": [
|
| 11 |
+
"01-05 Task 1 pushes to the `space` remote, which PUBLISHES the app publicly on the WolfDavid Hugging Face profile. This was deliberately not done autonomously.",
|
| 12 |
+
"Every remaining plan depends on it: 01-08 depends_on [01-05, 01-06, 01-07]; 01-09 depends_on [01-08]; 01-10 depends_on [01-09]. Nothing else in the phase can proceed.",
|
| 13 |
+
"The Space's README front-matter (which lives only on the HF side — there is NO README.md in this repo) was auto-generated wrong at Space creation: sdk_version 6.26.0 must become 6.22.0 to match requirements.txt, and python_version '3.12' must become 3.12.12. Plan 01-05 owns writing the corrected README. Pushing BEFORE 01-05 writes it would trigger a public build on the wrong Gradio version."
|
| 14 |
+
],
|
| 15 |
+
"human_actions_pending": [
|
| 16 |
+
"Approve (or decline) the public deploy in plan 01-05.",
|
| 17 |
+
"Plan 01-05 Task 3 is a blocking human-verify gate: judge the spike verdict — confirm the inline gr.HTML transport, or take the AVATAR_TRANSPORT=iframe fallback.",
|
| 18 |
+
"Plan 01-10 re-raises the VRM sourcing gate: keep VRM1_Constraint_Twist_Sample as a permanent asset, or author a bespoke VRoid Studio character. It is currently a TEMPORARY dev asset."
|
| 19 |
+
],
|
| 20 |
+
"completed_tasks": [
|
| 21 |
+
{ "plan": "01-01", "status": "complete", "note": "hosting + VRM gates; both human checkpoints closed" },
|
| 22 |
+
{ "plan": "01-02", "status": "complete", "note": "toolchain, LFS, package skeleton, test scaffolding" },
|
| 23 |
+
{ "plan": "01-03", "status": "complete", "note": "avatar stage + transport seam; resumed from a crash at Task 3 this session" },
|
| 24 |
+
{ "plan": "01-04", "status": "complete", "note": "VOICEVOX TTS, requirements.txt, ground-truth fixtures" },
|
| 25 |
+
{ "plan": "01-06", "status": "complete", "note": "mora-to-viseme timeline builder" },
|
| 26 |
+
{ "plan": "01-07", "status": "complete", "note": "push-to-talk mic gate + tiered browser ASR" },
|
| 27 |
+
{ "plan": "01-05", "status": "not_started", "note": "BLOCKED — user-gated public deploy" },
|
| 28 |
+
{ "plan": "01-08", "status": "not_started", "note": "blocked behind 01-05" },
|
| 29 |
+
{ "plan": "01-09", "status": "not_started", "note": "blocked behind 01-08" },
|
| 30 |
+
{ "plan": "01-10", "status": "not_started", "note": "blocked behind 01-09; user-gated" }
|
| 31 |
+
],
|
| 32 |
+
"uncommitted_files": [],
|
| 33 |
+
"unpushed_commits": 42,
|
| 34 |
+
"push_state": "NOTHING PUSHED. The only remote is `space` (the public HF Space) and pushing it IS the gated deploy. Branch `master` has no upstream. There is no GitHub remote for this repo.",
|
| 35 |
+
"context_notes": [
|
| 36 |
+
"Working tree is clean. All work is committed locally. 42 commits are unpushed by design, not by omission.",
|
| 37 |
+
"Verified green at handoff: 82 quick-loop tests in ~12.8s, 15 e2e browser tests, ruff check + format --check clean.",
|
| 38 |
+
"RUN `pytest tests/e2e/` AS A WHOLE before trusting a green phase. Per-file runs hid two real defects this session — each plan's own verification passed while the full suite failed.",
|
| 39 |
+
"Gradio 6.22.0 traps found the hard way — copy from src/japanese_avatar/ui/avatar_component.py, NOT from 01-RESEARCH.md: (1) js_on_load cannot use top-level await, it compiles to a non-async Function; use an async IIFE. (2) Custom props are **kwargs, not props={...}.",
|
| 40 |
+
"ASR traps: dtype 'q8' cannot create an ONNX session on the WASM backend at all — q4 is the only quantisation working on both tiers. A failed WebGPU init poisons the ONNX backend registry for the page, so asr.js probes requestAdapter() first rather than relying on the prescribed fallback.",
|
| 41 |
+
"Plan frontmatter over-claims shared requirements. AVTR-01, AVTR-02, VOIC-02/03/04/05, DPLY-01 and DPLY-04 appear in plans that do not satisfy them. Never blind-run `requirements mark-complete` — verify the acceptance test actually ran.",
|
| 42 |
+
"01-VALIDATION.md and plan 01-06 assert the slow timeline is exactly 1/0.75x longer within 2 frames. It measures 1.3410852713178294x, which is 4 frames out. The plan's stated truth was written from a wrong assumption; the measured ratio is correct and corroborates a 01-04 finding. Update 01-VALIDATION.md when 01-10 touches it so the verifier does not read this as an unmet must-have."
|
| 43 |
+
]
|
| 44 |
+
}
|
RESUME.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Resume here — Japanese Learning Avatar
|
| 2 |
+
|
| 3 |
+
**Written 2026-08-27, stepping away from the machine.**
|
| 4 |
+
Working tree is clean. Everything is committed. Nothing is pushed, deliberately — see below.
|
| 5 |
+
|
| 6 |
+
To pick back up, run `/gsd:resume-work` in this directory. It reads `.planning/HANDOFF.json`
|
| 7 |
+
first, which carries the same state in machine-readable form.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## One-line status
|
| 12 |
+
|
| 13 |
+
Phase 01 is **6 of 10 plans complete and hard-blocked on a decision only you can make**:
|
| 14 |
+
whether to publicly deploy the Hugging Face Space.
|
| 15 |
+
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
## Why nothing was pushed
|
| 19 |
+
|
| 20 |
+
This repo's **only** git remote is `space` — the public Hugging Face Space at
|
| 21 |
+
`WolfDavid/japanese-learning-avatar`. There is no GitHub remote. Branch `master` has no upstream.
|
| 22 |
+
|
| 23 |
+
So `git push` here does not mean "back up my work." It means **publish the app publicly and
|
| 24 |
+
trigger a Space rebuild** — which is precisely plan 01-05 Task 1, the gate that is waiting on you.
|
| 25 |
+
|
| 26 |
+
Pushing right now would also produce a **broken** public build. There is no `README.md` in this
|
| 27 |
+
repo; the Space's front-matter lives only on the HF side and was auto-generated wrong when the
|
| 28 |
+
Space was created:
|
| 29 |
+
|
| 30 |
+
| Front-matter key | Currently on HF | Must become | Why |
|
| 31 |
+
|---|---|---|---|
|
| 32 |
+
| `sdk_version` | `6.26.0` | `6.22.0` | must match `gradio==6.22.0` in `requirements.txt` |
|
| 33 |
+
| `python_version` | `'3.12'` | `3.12.12` | ZeroGPU provides only 3.10.13 and 3.12.12 |
|
| 34 |
+
|
| 35 |
+
Writing that corrected README is part of plan 01-05. Push after 01-05 runs, not before.
|
| 36 |
+
|
| 37 |
+
**42 commits are unpushed by design, not by omission.**
|
| 38 |
+
|
| 39 |
+
If what you actually want is an off-machine backup, that is a *different* action from deploying:
|
| 40 |
+
add a private GitHub remote and push there. That was not done unprompted because the standing
|
| 41 |
+
rule for this account is to ask before pushing nested repos.
|
| 42 |
+
|
| 43 |
+
---
|
| 44 |
+
|
| 45 |
+
## Where the work stands
|
| 46 |
+
|
| 47 |
+
| Plan | What it is | State |
|
| 48 |
+
|---|---|---|
|
| 49 |
+
| 01-01 | Hosting decision + Space creation + VRM sourcing | Complete |
|
| 50 |
+
| 01-02 | Toolchain, Git LFS, package skeleton, test scaffolding | Complete |
|
| 51 |
+
| 01-03 | Avatar stage, shared facade + turn loop, both transports | Complete (resumed from the crash) |
|
| 52 |
+
| 01-04 | VOICEVOX TTS, `requirements.txt`, ground-truth fixtures | Complete |
|
| 53 |
+
| 01-06 | Mora-to-viseme timeline builder | Complete |
|
| 54 |
+
| 01-07 | Push-to-talk mic gate + tiered browser ASR | Complete |
|
| 55 |
+
| **01-05** | **Space manifest, deploy the spike, verdict** | **BLOCKED — your call** |
|
| 56 |
+
| 01-08 | Turn-loop wiring — closes the round trip | Blocked behind 01-05 |
|
| 57 |
+
| 01-09 | Full deployed E2E suite + `LICENSES.md` | Blocked behind 01-08 |
|
| 58 |
+
| 01-10 | Vendor modules, latency harness (user-gated) | Blocked behind 01-09 |
|
| 59 |
+
|
| 60 |
+
The dependency chain is real, not a preference: `01-08 depends_on [01-05, 01-06, 01-07]`,
|
| 61 |
+
`01-09 depends_on [01-08]`, `01-10 depends_on [01-09]`. Nothing proceeds until 01-05 does.
|
| 62 |
+
|
| 63 |
+
### Verified green at handoff
|
| 64 |
+
|
| 65 |
+
- 82 quick-loop tests in ~12.8 s
|
| 66 |
+
- 15 end-to-end browser tests
|
| 67 |
+
- `ruff check .` and `ruff format --check .` both clean
|
| 68 |
+
|
| 69 |
+
**Run `pytest tests/e2e/` as a whole before trusting a green phase.** Per-file runs hid two real
|
| 70 |
+
defects this session — each plan's own verification passed while the full suite failed.
|
| 71 |
+
|
| 72 |
+
---
|
| 73 |
+
|
| 74 |
+
## What deploying would actually test
|
| 75 |
+
|
| 76 |
+
The risky part is already retired. three.js + `@pixiv/three-vrm` render inside a real
|
| 77 |
+
Gradio 6.22.0 `gr.HTML` component locally, with `threeInstanceCount === 1` and
|
| 78 |
+
`mountCount === 1`, and the iframe fallback boots identically under `AVATAR_TRANSPORT=iframe`.
|
| 79 |
+
|
| 80 |
+
What remains genuinely deployment-specific: CDN reach from `*.hf.space`, `set_static_paths`
|
| 81 |
+
behind the Space proxy, cold-start behaviour, and mobile.
|
| 82 |
+
|
| 83 |
+
Also note: **1 of 2 free ZeroGPU slots is already consumed** by this Space. The remaining slot is
|
| 84 |
+
the last free Gradio Space this account can create without PRO — budget it against the other
|
| 85 |
+
HF-profile projects. `cpu-basic` is not a fallback; it returns HTTP 402 for Gradio Spaces.
|
| 86 |
+
|
| 87 |
+
---
|
| 88 |
+
|
| 89 |
+
## Traps found the hard way — do not re-derive these
|
| 90 |
+
|
| 91 |
+
`01-RESEARCH.md` is **wrong** on these points. Copy from
|
| 92 |
+
`src/japanese_avatar/ui/avatar_component.py` and `avatar/asr.js` instead.
|
| 93 |
+
|
| 94 |
+
1. **`js_on_load` cannot use top-level `await`.** Gradio 6.22.0 compiles it into a plain
|
| 95 |
+
non-async `Function`, so the documented snippet throws `SyntaxError` and `window.Avatar`
|
| 96 |
+
never exists. Use an async IIFE with its own `.catch`.
|
| 97 |
+
2. **Custom props are `**kwargs`, not `props={...}`.** The dict form creates one prop literally
|
| 98 |
+
named `props`, so `props.vrmUrl` comes back `undefined`.
|
| 99 |
+
3. **ASR `dtype:'q8'` cannot create an ONNX session on the WASM backend at all** — for every
|
| 100 |
+
Whisper size tested. It works on WebGPU, so the prescribed default would ship green on a dev
|
| 101 |
+
machine and dead on exactly the browsers the WASM tier exists to serve. **`q4` is the only
|
| 102 |
+
quantisation working on both tiers.**
|
| 103 |
+
4. **The prescribed WebGPU→WASM fallback does not fall back.** A failed WebGPU init poisons the
|
| 104 |
+
ONNX Runtime Web backend registry for the whole page. `avatar/asr.js` probes
|
| 105 |
+
`requestAdapter()` first so the doomed call is never issued.
|
| 106 |
+
|
| 107 |
+
## Two spec corrections carried forward
|
| 108 |
+
|
| 109 |
+
- **Frame quantisation:** the correct form is `round(round(sec * 93.75) / speed)`, **not**
|
| 110 |
+
`round(sec / speed * 93.75)`. Measured 24/24 correct vs 8/24. Already shipped in `visemes.py`.
|
| 111 |
+
- **The slow/long duration ratio is 1.3410852713178294, not exactly 1/0.75** — 4 frames out from
|
| 112 |
+
what `01-VALIDATION.md` and plan 01-06 assert. The plan's stated truth was written from a wrong
|
| 113 |
+
assumption. **Update `01-VALIDATION.md` when 01-10 touches it**, so the phase verifier does not
|
| 114 |
+
read this as an unmet must-have.
|
| 115 |
+
|
| 116 |
+
## Standing warning about requirements
|
| 117 |
+
|
| 118 |
+
Phase 1 plan frontmatter **over-claims shared requirements**. AVTR-01, AVTR-02, VOIC-02/03/04/05,
|
| 119 |
+
DPLY-01 and DPLY-04 all appear in the `requirements:` field of plans that do not actually satisfy
|
| 120 |
+
them. Never blind-run `requirements mark-complete` — verify the acceptance test has really run.
|
| 121 |
+
Three executors this session correctly declined to mark requirements complete for this reason.
|