HANDOFF: vv webcam plan locked; drop the unverified vertical-preview landmine
Planning-only session: no code, no build, no test run. The creator's vv (9:16) webcam feature is now specified, and HANDOFF carries the locked rules plus the code facts needed to build it without re-hunting: - vv Live: small tile, circle OR rect (creator's choice), snapped to one of six spots (top/bottom x L/C/R). vv Chat: rect only, plus enlarge to fill one 607x540 area (exactly 50% of the frame), top or bottom. 16:9 and Starting/BRB/Ending unchanged. - Placement by tap/click-drag with snap, like the socials, plus manual entry in properties. vv keeps its own camera layout per scene, so the 16:9 layout survives switching modes (creator-confirmed). - Geometry only: preview and compositor both read the element's own X/Y/W/H + ClipShape, so the two-tile look falls out of the camera covering half the band - no capture, chat-box or blit-path change. The existing per-scene clamp already permits 607x540. Withdraws the HANDOFF landmine "vertical-format regression ... no longer shrinks the capture border in the preview": never verified, and wrong as stated - the creator confirms vv dims the two bands astride the centre band. It cost this session a pointless question. MyMistakes.md records the session-history search recipe (the creator's turns live in session_message, NOT part - a hit in part can be my own text echoing the phrase) and the ask-don't-check lesson plus the creator's standing reply-format directives.
This commit is contained in:
+85
-54
@@ -1,53 +1,84 @@
|
|||||||
# HANDOFF — 2026-10-16 (work committed locally; NOT pushed — push at the next milestone)
|
# HANDOFF — 2026-10-17 (PLANNING ONLY session; nothing pushed — push at the next milestone)
|
||||||
|
|
||||||
## At a glance
|
## At a glance
|
||||||
- **Branch** main, tracking `origin/main`. **origin/main = `931ab46`; HEAD = the tip commit
|
- **Branch** main, tracking `origin/main`. **origin/main = `931ab46`; HEAD = the tip commit
|
||||||
"Read the first instrumented take: the judder did not reproduce, no element is slow"** —
|
"HANDOFF: vv webcam plan, and drop the stale vertical-preview landmine"** — **5 ahead, 0 behind**
|
||||||
**4 ahead, 0 behind** (nothing pushed this session; per the commit/push policy, push only when the
|
(nothing pushed; per the commit/push policy, push only when the creator says so). This file cannot
|
||||||
creator says so). This file cannot record its own commit's hash — amending a commit changes that
|
record its own commit's hash, so the tip is named by subject.
|
||||||
hash — so the tip is named by subject.
|
- The five local-only commits: `3cb29ea` (previous session's HANDOFF refresh), `a3a4681`
|
||||||
- The four local-only commits: `3cb29ea` (**previous session's HANDOFF refresh — the old handoff
|
(per-element composite timing + scene dump), `84cbec2` (FramePumpTests thread-safe log sink),
|
||||||
claimed it was pushed; it never was**), `a3a4681` (per-element composite timing + scene dump),
|
`cdf82f6` (read the first instrumented take), the tip. Always check
|
||||||
`84cbec2` (FramePumpTests thread-safe log sink), the tip. Always check
|
`git log origin/main..HEAD` — never trust a handoff's own "0 ahead" claim.
|
||||||
`git log origin/main..HEAD` — never a handoff's own "0 ahead" claim.
|
|
||||||
- Working tree clean after the tip commit.
|
- Working tree clean after the tip commit.
|
||||||
- **The creator's first take of the instrumented build happened today** (18:40–18:44, Release
|
- **This session produced NO code, NO build, NO test run.** It specified the creator's **vv
|
||||||
recording). **The judder did NOT reproduce and no element is slow** — full reading in `ai.md` →
|
(vertical 9:16) webcam feature** end to end; implementation has not started. The locked rules are
|
||||||
"✅ What the first instrumented take said". Nothing is queued to fix from it.
|
below — they are the deliverable, and they must land in `TASKS.md` when work is queued.
|
||||||
|
|
||||||
## This session (2 commits — both unpushed)
|
## vv webcam feature — locked rules (creator, 2026-10-17)
|
||||||
1. **`84cbec2` — FramePumpTests race fix (own commit, creator-approved).** A full-suite failure
|
| mode | shape | size | position |
|
||||||
(`Stats_ReportRealRendersAndDistinctWebcamFrames…`, "Collection was modified") was a **test-side
|
|---|---|---|---|
|
||||||
data race**: a plain `List<string>` enumerated by the test while the pump logged from its own
|
| 16:9 | as today | as today | as today |
|
||||||
thread. Fixed with `ConcurrentBag<string>`. **Proof: full suite 428/428 passed, 0 warnings.**
|
| **vv · Live** | **circle OR rect, creator's choice** | small tile | one of six spots: top/bottom × L/C/R |
|
||||||
Lesson recorded in `MyMistakes.md` → "known failure label" (2nd instance).
|
| **vv · Chat** | **rect only — no circle option** | normal, or enlarged to fill one area (607×540) | enlarged → top or bottom |
|
||||||
2. **The reading (this is the tip commit).** Take `ty-20261016-1841-559-0002.mp4` (174.5s, Release
|
| Starting / BRB / Ending | unchanged | unchanged | unchanged |
|
||||||
`e95154d9`, 1920×1080 1:1, recording): **60 composites/s, avg render 1.0–1.1ms, biggest element =
|
|
||||||
webcam 0.4ms**, backdrop 0.2ms, other four under the 0.1ms floor, `cache 151R/150H`, webcam 30.0/s
|
- **Placement is set by tap/click-drag with snap, exactly like the socials today**, plus manual entry
|
||||||
at the resolver (longest gap 50ms), and the FILE holds **29.6 distinct webcam images/s with 82% of
|
in properties. Creator's explicit precedent, not an inferred one.
|
||||||
images held exactly 2 frames**. No culprit element exists in this take.
|
- **vv keeps its own camera position, size and shape per scene** — creator-confirmed: switching back
|
||||||
- **The historic slow numbers are different configurations:** Oct 9 19:48 (still on disk) was the
|
to 16:9 restores the desktop layout exactly as it was.
|
||||||
**vertical** tier (`comp=608x1080`, 45ms, 92 renders/5s); Oct 5 12:01's geometry was never logged
|
- **No explicit borderless/no-background mode is needed**: round + border/bg options already let the
|
||||||
(the `scene=/comp=` suffix didn't exist) so the map's 21:9 story stays a hypothesis. Every slow
|
creator strip both (creator's ruling — this deletes that item from the original request).
|
||||||
window shows `cache xR/0H`; one Oct 5 take latches fast→slow (1.5ms → 45ms) within 15s.
|
- Creator's "square" means the rectangular view (the camera's own aspect), not a literal 1:1 box.
|
||||||
- **Corrected in the map (not appended):** "it was never Debug-vs-Release" is withdrawn (same
|
|
||||||
1920×1080 tier: Oct 9 = 10.4ms vs today's Release 1.0ms, and `Build <hash>` records no
|
## What the code already gives us (established this session — do not re-hunt)
|
||||||
configuration), and the "same scene shape" 10:01/12:01 comparison is superseded.
|
- **vv = the active tier's centred band crop.** 1080p60-vertical: master band **x 656.25–1263.75
|
||||||
- **Same commit ships the probe + its recipe.** `scripts/webcam-cadence.py` (new tool): the
|
(607.5 wide), full height**, upscaled to 1080×1920 (`MainViewModel.Streaming.cs` `ApplyStreamQuality`
|
||||||
ground-truth check for what the FILE holds. Its three traps (H.264 re-encoding defeats
|
→ `OutputRect*`). The band splits into **two 607×540 areas** (top/bottom) — the creator's "two mini
|
||||||
exact-pixel comparison; a round-clip crop's corners leak 60fps background; a fixed crop across a
|
16:9 views", each exactly 50% of the frame.
|
||||||
scene switch reads background) cost three wrong readings — all in `MyMistakes.md`, with an
|
- **The Live webcam sits at x≈1425 → entirely outside the band.** That is the whole motivation: in vv
|
||||||
ffmpeg-native cross-check (`tblend=difference` + `signalstats.YAVG`) that agreed (52.2%
|
the camera is not misplaced, it is invisible.
|
||||||
duplicates / 28.6 distinct/s).
|
- **Geometry only — no render-path change.** Preview (`Controls/PreviewPane.xaml` 144–230) and
|
||||||
|
compositor (`Services/Compositor/SceneCompositor.cs` 389–397, `DrawBorder`) both read the element's
|
||||||
|
own `X/Y/W/H` + `ClipShape`, so parking the camera needs no compositor or preview work. The
|
||||||
|
two-tile look *falls out of* the camera covering half the band — the capture element, chat box and
|
||||||
|
blit path stay untouched.
|
||||||
|
- **Round / border / background are independent**: `ClipShape.Round`; `HasBorder` = width > 0 AND a
|
||||||
|
valid 6-hex colour; `BackgroundEffect` = None/Remove/Blur.
|
||||||
|
- **Per-scene camera size policy already exists**: `MaxWebcamWidthFor/HeightFor` (Chat 1358×764,
|
||||||
|
others 960×540) + `ClampWebcamToBounds`. **A 607×540 tile sits inside both → the clamp needs no
|
||||||
|
change.**
|
||||||
|
- **Storage**: `WebcamSceneConfig` table; new columns go in `MigrateWebcamConfigTable()` as idempotent
|
||||||
|
`ALTER TABLE … ADD COLUMN` guarded on `PRAGMA table_info` — the established "additive, no version
|
||||||
|
bump" idiom (`RectWidth/RectHeight`, TASK 51's `BackgroundEffect` landed this way) — plus
|
||||||
|
`LayoutStore.Save.cs` INSERT and `LayoutStore.Load.cs` SELECT.
|
||||||
|
- **Existing per-element precedent for remembered geometry**: `RectWidth/RectHeight` +
|
||||||
|
`ToggleClipShape` (`Models/SceneElement.cs` 124–152) — the pattern for keeping the 16:9 layout
|
||||||
|
while vv owns its own.
|
||||||
|
|
||||||
|
## Units (each: ONE Good Dog integration test, own commit, memory in the same commit)
|
||||||
|
1. **vv camera layout** — stored separately per scene, resolved when the tier changes. Live: small
|
||||||
|
tile (circle or rect) snapped to one of six spots; drag like the socials + properties entry.
|
||||||
|
*Test:* with the vertical tier active, dragging the Live camera to top-right places it top-right
|
||||||
|
inside the band; switching back to 16:9 restores the original layout.
|
||||||
|
2. **vv · Chat** — rect enforced with the circle option unavailable, plus enlarge-to-one-area
|
||||||
|
(607×540) snapping top or bottom.
|
||||||
|
*Test:* in Chat under the vertical tier, enlarge sets the full top area and the circle option is
|
||||||
|
not offered.
|
||||||
|
|
||||||
|
## Corrections made this session
|
||||||
|
- **Withdrawn landmine (creator-confirmed):** the old line "Vertical-format regression (STALE, not
|
||||||
|
fixed): 1080p60-vertical selection no longer shrinks the capture border in the preview" was **never
|
||||||
|
verified**, and it cost this session a pointless question. The creator confirms vv *does* dim the two
|
||||||
|
bands astride the centre band and that this is expected/best practice. If the original symptom was
|
||||||
|
something else (the capture element's own border?), it is **unexplained, not known-broken** — do not
|
||||||
|
re-raise it as a dependency.
|
||||||
|
- The prev-session content (first instrumented take: judder did not reproduce, no element slow; probe
|
||||||
|
+ recipe; the four local commits) is unchanged and lives in `ai.md` →
|
||||||
|
"✅ What the first instrumented take said".
|
||||||
|
|
||||||
## Next step
|
## Next step
|
||||||
- **Creator take in the FAILING geometry — the vertical 1080p60 tier first** (creator's pick from the
|
- **Implement Unit 1 on the creator's go-ahead.** Nothing is queued in `TASKS.md` — the creator queues
|
||||||
two options offered). Then, if the creator is willing, the 21:9 display config.
|
work, and this plan lives here until then. Queue it in `TASKS.md` as part of the first Unit 1 commit.
|
||||||
- Read three lines in `%APPDATA%\ytLlive\startup.log`: `FramePump parts (N renders/5s): …` (which
|
|
||||||
stage/element eats the budget), the `FramePump scene dump:` block (the shape), and `cache NR/NH`
|
|
||||||
(0 hits = the slow state's signature). **No fix until that take names the stage** — the latch
|
|
||||||
hypothesis (a composite pushed past the camera period can never reuse the whole-frame cache again)
|
|
||||||
is unproven and the `parts` line is what decides it.
|
|
||||||
|
|
||||||
## Open (operational)
|
## Open (operational)
|
||||||
- **verify.sh's known-failure whitelist is too loose (confirmed twice on 2026-10-16):** it passes when
|
- **verify.sh's known-failure whitelist is too loose (confirmed twice on 2026-10-16):** it passes when
|
||||||
@@ -55,22 +86,18 @@
|
|||||||
known flake (`LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder`, which
|
known flake (`LayerReorderPersistenceTests.RealMouseDrag_OnTheLayerList_PersistsTheReorder`, which
|
||||||
passes in isolation) it reports "NOT the known pre-existing pair". **Follow-up: require EVERY
|
passes in isolation) it reports "NOT the known pre-existing pair". **Follow-up: require EVERY
|
||||||
failure line to be whitelisted**, and add `MasterLimiter_CapsTheLiveMix_OnThePipe` +
|
failure line to be whitelisted**, and add `MasterLimiter_CapsTheLiveMix_OnThePipe` +
|
||||||
`RealMouseDrag_OnTheLayerList_PersistsTheReorder` to the list. Not fixed here — `scripts/verify.sh`
|
`RealMouseDrag_OnTheLayerList_PersistsTheReorder` to the list.
|
||||||
was never in a declared file list.
|
- **A pre-existing stash is still sitting there:** `stash@{0}` = "WIP on main: 0464593 Compositor:
|
||||||
- **A pre-existing stash from older work is still sitting there:** `stash@{0}` = "WIP on main:
|
fast-path opaque 1:1 when source fills canvas" (NOT this session's; do not drop it blindly).
|
||||||
0464593 Compositor: fast-path opaque 1:1 when source fills canvas" (NOT this session's; do not drop
|
- The judder reproduction take in the FAILING geometry (vertical 1080p60 first) is still outstanding —
|
||||||
it blindly).
|
**no fix until a take names the stage** (see `ai.md`; the `parts` line decides the latch hypothesis).
|
||||||
- **Vertical-format regression (STALE, not fixed):** 1080p60-vertical selection no longer shrinks the
|
|
||||||
capture border in the preview (`Controls/PreviewPane.xaml:319-322` + `MainViewModel.Streaming.cs`
|
|
||||||
`ApplyStreamQuality`). Root cause unknown — paused. Note the vertical tier is ALSO the only slow
|
|
||||||
take still on disk, so if the next take reproduces the 45ms there, this area gets touched twice.
|
|
||||||
- ⛔ Sudo password rotation pending (user; then update both `CREDENTIALS.md` password lines).
|
- ⛔ Sudo password rotation pending (user; then update both `CREDENTIALS.md` password lines).
|
||||||
- TASK 56 secret scan before `gramps/LlamaCasty` goes public.
|
- TASK 56 secret scan before `gramps/LlamaCasty` goes public.
|
||||||
- TASK 55 disk hygiene (`startup.log` uncapped — 23MB and the new lines add to it every 5s).
|
- TASK 55 disk hygiene (`startup.log` uncapped — 23MB and the new lines add to it every 5s).
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
- Full suite **428/428 passed, 0 warnings** (2026-10-16, the gate run for `84cbec2`) — a completely
|
- Last full run: **428/428 passed, 0 warnings** (2026-10-16, the gate run for `84cbec2`). **No run this
|
||||||
clean run, including the audio tests that usually flake.
|
session (planning only).**
|
||||||
- Known flaky-by-environment (all pass in isolation): `AudioPipelineTests.Mix_HonorsProviderGains…`,
|
- Known flaky-by-environment (all pass in isolation): `AudioPipelineTests.Mix_HonorsProviderGains…`,
|
||||||
`MasterLimiter_CapsTheLiveMix_OnThePipe`, `LayerReorderPersistenceTests.RealMouseDrag…`,
|
`MasterLimiter_CapsTheLiveMix_OnThePipe`, `LayerReorderPersistenceTests.RealMouseDrag…`,
|
||||||
`Round_Clip_Corner…`. **Read verify.sh's output — it can pass with an unlisted failure present, or
|
`Round_Clip_Corner…`. **Read verify.sh's output — it can pass with an unlisted failure present, or
|
||||||
@@ -81,6 +108,10 @@
|
|||||||
`%APPDATA%\ytLlive\ytLlive.auth` (DPAPI). Startup log: `%APPDATA%\ytLlive\startup.log` (23MB).
|
`%APPDATA%\ytLlive\ytLlive.auth` (DPAPI). Startup log: `%APPDATA%\ytLlive\startup.log` (23MB).
|
||||||
- Recordings land in `C:\Users\gramp\Downloads\recordings\` (`ty-<date>-<time>-<ms>-<seq>.mp4`; a
|
- Recordings land in `C:\Users\gramp\Downloads\recordings\` (`ty-<date>-<time>-<ms>-<seq>.mp4`; a
|
||||||
duplicate name gets a `-2` suffix — the log's path and the file on disk can differ that way).
|
duplicate name gets a `-2` suffix — the log's path and the file on disk can differ that way).
|
||||||
|
- **Conversation history (how to recover what was actually said):**
|
||||||
|
`~/.local/share/opencode/opencode.db`, table **`session_message`** (`type='user'`, text in
|
||||||
|
`data.text`). The `part` table holds only assistant-authored text — searching it for a creator
|
||||||
|
message returns nothing. Recipe + command in `MyMistakes.md`.
|
||||||
- LAN credentials: `CREDENTIALS.md` (gitignored). Google Cloud OAuth project number `198374416003`,
|
- LAN credentials: `CREDENTIALS.md` (gitignored). Google Cloud OAuth project number `198374416003`,
|
||||||
owned by `llamachile.shop@gmail.com` — verify at
|
owned by `llamachile.shop@gmail.com` — verify at
|
||||||
`https://console.cloud.google.com/apis/credentials?project=198374416003`.
|
`https://console.cloud.google.com/apis/credentials?project=198374416003`.
|
||||||
|
|||||||
@@ -1645,3 +1645,57 @@ semantics* — anchored-capture vs follow-the-box — before building any "zoom"
|
|||||||
captures ALL layers with an extra layer in the fixture and assert it appears; (3) "draw above
|
captures ALL layers with an extra layer in the fixture and assert it appears; (3) "draw above
|
||||||
everything" is a compositor ordering property (skip in the layer loops + blit last), not a z-index
|
everything" is a compositor ordering property (skip in the layer loops + blit last), not a z-index
|
||||||
of the element among the others.
|
of the element among the others.
|
||||||
|
|
||||||
|
## 2026-10-17 — Your own conversation history is in `session_message`, NOT `part`
|
||||||
|
|
||||||
|
I was asked to repeat the creator's original query verbatim. After a compaction I had only the summary,
|
||||||
|
so I searched the session store and landed on the wrong table twice. In `part` my search for the
|
||||||
|
creator's phrases returned hits — but they were **my own reasoning text quoting the phrase back**, which
|
||||||
|
looks exactly like a real hit and sent me chasing roles (`message.data` role), then
|
||||||
|
`instruction_entry`/`instruction_blob` (which do **not** hold prompts at all).
|
||||||
|
|
||||||
|
The creator's turns live in **`session_message`**, one row per turn: `type='user'`, the text inside the
|
||||||
|
JSON `data.text`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# find the session by any distinctive phrase the creator used
|
||||||
|
sqlite3 ~/.local/share/opencode/opencode.db \
|
||||||
|
"SELECT DISTINCT session_id FROM session_message WHERE data LIKE '%<phrase>%';"
|
||||||
|
# then dump that session's turns in order
|
||||||
|
sqlite3 ~/.local/share/opencode/opencode.db \
|
||||||
|
"SELECT seq, json_extract(data,'\$.text') FROM session_message \
|
||||||
|
WHERE session_id='ses_…' AND type='user' ORDER BY seq;"
|
||||||
|
```
|
||||||
|
|
||||||
|
Lessons: (1) when compacted and unsure *what was asked*, query the store — never reconstruct the
|
||||||
|
creator's words from a summary; (2) a phrase hit in `part` may be my own echo of it, so check the
|
||||||
|
table's `type` before trusting a match; (3) this is the fix for "I can't search my own history" — it is
|
||||||
|
one query away, and the creator found their own query manually while I guessed.
|
||||||
|
|
||||||
|
## 2026-10-17 — I asked the creator to verify a preview visual I could have looked at
|
||||||
|
|
||||||
|
Planning the vv webcam feature, I asked: "when you select the vertical tier, does the preview actually
|
||||||
|
dim outside the band?" The answer was, in effect, *of course — that's the standard*. Two failures
|
||||||
|
stacked:
|
||||||
|
|
||||||
|
1. **I propagated an unverified claim.** My only reason to doubt it was a `HANDOFF.md` landmine
|
||||||
|
("vertical-format regression … no longer shrinks the capture border", marked STALE/root-cause-
|
||||||
|
unknown). It had never been verified, and it was **wrong** as stated. A stale, unverified handoff
|
||||||
|
line is a question-generator, not a fact — check it against the code or the app before letting it
|
||||||
|
shape what I ask.
|
||||||
|
2. **It was checkable without the creator.** The crop rectangle and the dimming are wired in code
|
||||||
|
(`PreviewPane.xaml:319-322` + `DimRects`/`ApplyStreamQuality`), and the creator can see the result in
|
||||||
|
one glance. I spent the creator's scarcest resource on something one look would have settled.
|
||||||
|
|
||||||
|
Created 2026-10-17 and standing (the creator stated these explicitly, after being left unable to tell
|
||||||
|
my reasoning from my replies):
|
||||||
|
|
||||||
|
- **Every reply begins with the reply marker on its own line.** The creator will not read an unmarked
|
||||||
|
reply — reasoning and reply are indistinguishable in their UI. Do not drop it; do not rely on a
|
||||||
|
leading blank line instead (the renderer trims it).
|
||||||
|
- **One explanation and one question per reply.** No question batteries, no "three things I need"
|
||||||
|
lists, no blue-sky option menus (A-vs-B, clamp behaviour) — those read as derailing.
|
||||||
|
- **State the decision I would make, in one line, and let the creator veto** — rather than presenting a
|
||||||
|
menu of choices for them to sort out.
|
||||||
|
- **Ask the creator only what only they can decide** (product intent). Anything the code, the app, or a
|
||||||
|
single look can answer, I answer myself.
|
||||||
|
|||||||
Reference in New Issue
Block a user