Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions HANDOFF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Run the reviewed local collaboration example

A developer can use FeatureClipStudio to turn a recorded two-client interaction into a movie and GIF. Start with the preserved LiveSync example: it shows an added card, a fixed-text agent response and the same selected result in both clients. Its title identifies local, in-memory behavior. This example does not establish a cloud service, model response or durable collaboration.

**Re your request:** make the current tool usable for developer handoff with actual exported proof — the commands below reproduce the scoped example from this checkout. The [evidence index](promotion/evidence/local-livesync-handoff-20260907/README.md) separates the original failures, corrected capture behavior and accepted encoded output.

## First render

The observed lane used Windows, Node 22.22.2, the locked Remotion 4.0.474 and Playwright 1.60.0. Use a short checkout path on Windows. Have ffmpeg and ffprobe on PATH; Python 3 is needed only for the evidence verifier. Other host/version combinations were not certified by this run.

Run from the repository root, choosing fresh output names:

```sh
npm ci
npm run check
node run-remotion.mjs browser ensure
node run-remotion.mjs render src/index.js WTC-LiveSync out/local-livesync.mp4 --concurrency=2
ffmpeg -v error -i out/local-livesync.mp4 -vf "fps=15,scale=720:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=128:stats_mode=diff[p];[s1][p]paletteuse=dither=bayer:bayer_scale=3:diff_mode=rectangle" -loop 0 out/local-livesync.gif
ffprobe -v error -show_streams -show_format -of json out/local-livesync.mp4
```

This uses 54 checked-in captures and authored presentation metadata; it performs no new browser interaction. The [accepted movie](promotion/evidence/local-livesync-handoff-20260907/after-output/readable-livesync.mp4) has 588 video frames, 1920×1080 at 30 fps and 19.600 seconds of video. Its container is 19.648 seconds because of the AAC stream. The [actual GIF](promotion/evidence/local-livesync-handoff-20260907/after-output/readable-livesync.gif) has 294 frames, 720×405 at nominal 15 fps. Both fully decoded without errors. Encoded bytes can differ across environments; the supplied files have exact hashes in the packet.

The normal source check passed 39 JavaScript parses, 36 tour anchors and 34 prose citations on the reviewed behavior source. This handoff and its evidence index were added afterward; they do not imply another runtime run or shared CI result.

## Optional: capture the local interaction again

Recapture deliberately replaces the selected LiveSync frame directory and generated data module. Keep a baseline or backup first. Install the capture browser once:

```sh
node node_modules/playwright/cli.js install chromium
```

Keep the local demo running in a separate terminal:

```sh
node examples/collab-demo/server.mjs
```

The demo listens on port 8930 by default and does not enforce a loopback-only bind. It uses fixed text and in-memory state. In Bash, capture only this example:

```sh
COLLAB_ONLY=LiveSync node walkthrough.collab.mjs
```

In PowerShell, scope that selection to the command and restore the previous value:

```powershell
$previousCollabOnly = [Environment]::GetEnvironmentVariable('COLLAB_ONLY', 'Process')
try {
$env:COLLAB_ONLY = 'LiveSync'
node walkthrough.collab.mjs
if ($LASTEXITCODE -ne 0) { throw "LiveSync capture failed with exit $LASTEXITCODE" }
} finally {
[Environment]::SetEnvironmentVariable('COLLAB_ONLY', $previousCollabOnly, 'Process')
}
```

Then render and export with fresh output names. Stop the demo you started when finished. No provider key, voice pipeline or external product target is required for these commands.

## Failure and recovery

Unknown or mixed-unknown selections, whitespace-only values and comma-created empty entries fail before browser/output work. An absent variable or explicit empty string follows the existing refusal to capture all specs without a deliberate broad selection. These two meanings of “empty” are distinct.

An unavailable demo or exhausted action failure now exits nonzero, preserves diagnostic output and leaves the generated data module unchanged. Attempted selected frame directories can be incomplete, including earlier specs in a multi-spec run; they are not rolled back. Restore the demo/control and explicitly recapture the selected example successfully before rendering it. Existing swallowed `waitText` timeouts remain a limitation, so exit success alone does not prove every desired text assertion.

## What the evidence supports

The accepted framing makes the selected control/result and both client labels readable in the actual movie and GIF. The longest card has a tight lower margin. The previous card is partly cropped, and early camera travel does not show every complete stream state. These are disclosed presentation limits, not synchronization latency measurements. Audio was not listened to; no full continuous-motion or human-comprehension grade was granted.

The default `npm run render:example` still renders historical WT-NodeRoom inputs and retains a separate output-quality hold. LiveSync acceptance does not certify other examples, responsive browser behavior, physical devices, provider behavior or production. The recorded install reported 12 dependency advisories (2 low, 10 high), which remain unresolved. Full criterion and overall grades remain null.

Verify the packet and its selected current source bindings from the repository root:

```sh
python promotion/evidence/local-livesync-handoff-20260907/verify.py
python promotion/evidence/local-livesync-handoff-20260907/verify.py --source-root .
```

The first command checks exact packet bytes. The optional source check accepts only each row's demonstrated Git checkout newline transformation; it does not rerun capture/render or certify the whole repository. The evidence index records raw versus minimized receipts and which historical artifacts remain operator-local.
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ Not a single final‑state "hero shot" — the viewer follows the *whole flow*.

---

For the reviewed local example, use the [current developer handoff](HANDOFF.md): locked setup, explicit capture, accepted exports and known limits.

## Local collaboration presentation

The two-client `LiveSync` example uses `layout: "stacked"` and the existing per-step zoom metadata to keep the acted control or relevant result visible in both labelled clients. Its persistent title identifies fixed text and in-memory state. The other examples keep their existing framing.

The checked-in LiveSync presentation metadata was projected onto the same 54 captured images; it does not record another action, measure synchronization latency, or establish durable state. A future explicit LiveSync capture obtains zoom points from the spec's selectors. Output readability must be judged from the actual MP4 and 720-pixel GIF, including the complete final result, rather than from readable native screenshots. The inherited `waitText` limitation and the capture failure/recovery behavior below remain unchanged.

## Storyboard first

The default quality bar is not "nice zooms." A walkthrough should have a clear
Expand Down Expand Up @@ -1248,13 +1256,26 @@ Ships with a **worked example** (the live-collab counterpart to the single-pane
`useMutation().withOptimisticUpdate`, `ctx.scheduler` + `internalMutation` for the
streamed agent) — the production reference, mapped 1:1 to the local demo.

Reproduce it:
After `npm ci` and `npx playwright install chromium`, keep the demo server running
in one terminal and run the selected capture in another:
```bash
node examples/collab-demo/server.mjs # local demo on :8930 (no install, no login)
node walkthrough.collab.mjs # multi-pane capture: Client A + Client B
node examples/collab-demo/server.mjs # terminal 1: local demo on :8930
COLLAB_ONLY=LiveSync node walkthrough.collab.mjs # terminal 2 (Bash): Client A + Client B
node run-remotion.mjs render src/index.js WTC-LiveSync out/collab.mp4
# then the same two-pass ffmpeg palette → assets/feature-collab.gif
```
In PowerShell, set `$env:COLLAB_ONLY = "LiveSync"` before `node walkthrough.collab.mjs`.
The demo uses local, in-memory state and fixed text; it does not call a model or
prove durable Convex behavior. Its listener is not restricted to loopback by the server.

Every selected ID must exist. Unknown or empty selector entries fail before the
browser starts or capture files change. An exhausted navigation/action failure
keeps the diagnostic PNGs, exits nonzero and does not write generated data or print
the completion marker. Selected frame directories can contain partial output;
this is not automatic rollback. Preserve the failed evidence and re-capture the
selected walkthrough successfully before rendering it. Configured retry counts
are unchanged; a successful command still needs its actual captured states checked.

Panes + steps live in `walkthrough.collab.specs.mjs`; the 2-up renderer is
`src/Walkthrough2up.jsx`. See **[`STACK_GUIDELINES.md`](STACK_GUIDELINES.md)** for why
Convex + React demos need this and Streamlit doesn't.
Expand Down Expand Up @@ -1355,8 +1376,9 @@ against a real, deployed app (not just a demo harness).

</details>

Specs: `walkthrough.noderoom.specs.mjs`. Capture: `node walkthrough.collab.mjs` (the NodeRoom
specs are imported into the collab specs). Render: `node run-remotion.mjs render src/index.js WTC-NRsolo`
Historical examples use `walkthrough.noderoom.specs.mjs`, imported into the collab specs.
Re-capturing requires an explicitly selected current spec ID in `COLLAB_ONLY` and
its intended application running; a bare capture command is refused. Render: `node run-remotion.mjs render src/index.js WTC-NRsolo`
/ `WTC-NRsync` / `WTC-NRfresh` / `WTC-NRdeepDive`.

## Designing for specific stacks
Expand Down
11 changes: 8 additions & 3 deletions docs/START_HERE.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,14 @@ hand.` and the run prints `WALKTHROUGH_CAPTURE_DONE`.
**Output** — `src/walkthrough.data.js`, overwritten whole. Its sibling generated files
follow the same rule: `src/walkthrough.collab.data.js` (from `walkthrough.collab.mjs`),
`src/walkthrough.roomos.data.js`, `src/walkthrough.visual.data.js`.
**Failure behavior** — the file is written even if some specs failed all their
retries; a failed spec contributes an empty `steps` array rather than aborting the
others. Check the console for `attempt N/M err:` lines before trusting a render.
**Failure behavior** — the single-pane writer described here can write the file
even if a spec exhausted its retries. Check its `attempt N/M err:` lines before
trusting a render. The collaboration driver has a stricter command boundary:
every selected ID must exist, and an exhausted navigation/action failure exits
nonzero before the generated module is written or its completion marker printed.
Partial/failed PNGs remain for diagnosis; the previously generated module is not
rewritten, but earlier selected frames are not automatically restored. Re-capture
that selection successfully before rendering it.
**One more writer, and it is worth knowing about:** `clip.mjs:31` (`writeFileSync("src/walkthrough.data.js"`) **rewrites this same
file in place**, changing each step's `hold` so the picture lasts exactly as long as
its spoken narration. That is the only other thing that edits generated data.
Expand Down
13 changes: 9 additions & 4 deletions docs/codebase/INTEGRATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ on different dev servers because the url is per-spec.
Streamlit accommodation, and the fallback exists because scoping to a selector that
does not exist made every step fail while the run still reported success.

**Failure mode:** the app is not running → `page.goto` throws a connection error and
the spec's attempt fails into the forensics path (`zz-fail.png`). The app is running
but slow → the `ready` proof string times out after 30 s. Neither can produce a
green run with empty frames; that is the whole point of the `ready` field.
**Failure mode:** the single-pane driver uses its `ready` proof string to check
that the intended app is present. In the collaboration driver, navigation and
thrown action errors enter the per-pane forensics path (`zz-fail-p<N>.png`). An
exhausted attempt closes its contexts/browser and exits nonzero before writing
generated data or printing completion. Unknown selection entries are rejected
before browser launch or output changes. This does not make every semantic check
strict: the existing collaboration `waitText` helper still swallows its timeout,
so final captured state needs independent observation. Partial selected PNGs are
diagnostics, not a rollback or a verified render input.

**Setup:** `npx playwright install chromium`. `npm ci` alone is not enough.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* -text
52 changes: 52 additions & 0 deletions promotion/evidence/local-livesync-handoff-20260907/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Reviewed LiveSync example and capture-status evidence

Start with the [developer handoff](../../../HANDOFF.md). A developer can render the preserved two-client example, or deliberately recapture the local demo and recover from a failed capture. This packet supports those scoped jobs; it is not a whole-product readiness certificate.

The [movie](after-output/readable-livesync.mp4) and [actual palette GIF](after-output/readable-livesync.gif) are the accepted encoded files. Their [independent final review](judgments/E6o_FEATURECLIPSTUDIO_READABILITY_FINAL_JUDGE.md.txt) covers selected controls/results, both clients and the persistent local/fixed-text/in-memory disclosure. Both files fully decoded. Audio listening, every motion frame and human comprehension remain unverified.

## Read the evidence by claim

| Claim | Physical payload |
|---|---|
| Normal locked setup and current source check | [Install output](setup/normal-ci.stdout.txt), [Node version](setup/node-version.stdout.txt), [normal check](checks/normal-check.stdout.txt). The install recorded 12 advisories; they remain unresolved. |
| Original false success | [Unknown selector exit](before-status/unknown-selector-command.json), [unavailable demo exit](before-status/unavailable-demo-command.json), [original completion output](before-status/unavailable-demo.stdout.txt). These are historical failures, not passing examples. |
| Corrected selection boundary | [Six selector cases](after-status/02-selection-negatives/selection-semantics.json), including absent/explicit empty versus whitespace/comma semantics. |
| Failed work exits with its cause; explicit recovery succeeds | [Unavailable demo](after-status/04-unavailable/unavailable-command.json), [missing control](after-status/05-missing-control/missing-control-command.json), [successful recapture](after-status/06-recovery/selected-livesync-command.json), [native observation](after-status/native-observation.json), [54 native-buffer/generated/disk bindings](after-status/06-recovery/native-generated-disk-bijection.json). |
| Same native captures, changed presentation | [Labelled prior boundary](scope/change-boundary.png), [state contract](scope/change-boundary.md.txt), [eight selected legacy comparisons](checks/legacy-parity.json). |
| Actual encoded outputs | [Render command](encoding/render-readable-command.json), [documented GIF command](encoding/documented-gif-command.json), [movie probe](encoding/readable-ffprobe.stdout.txt), [GIF probe](encoding/gif-probe.stdout.txt), [movie decode](encoding/readable-decode-command.json), [GIF decode](encoding/gif-decode-command.json). |
| Final source/process closure | [Stage04 summary](encoding/stage04-receipt.json), [stage05 receipt](encoding/stage05-receipt.json), [stage05 closing guard](encoding/stage05-closed.json). Command success itself does not grant visual acceptance. |

The 54 native PNGs are already part of the repository's `public/wt-collab/LiveSync` cohort. They are not recopied here. The first render reuses those inputs; it is not another native interaction, a synchronization-latency measurement or a durable-state result.

## Actual before and after pixels

These pairs use the same output frame and preserved input sequence:

| Frame | Before | After |
|---|---|---|
| MP4 0 | [Before](before-output/repaired-frame-0.png) | [After](after-output/movie-0.png) |
| MP4 147 | [Before](before-output/repaired-frame-147.png) | [After](after-output/movie-147.png) |
| MP4 294 | [Before](before-output/repaired-frame-294.png) | [After](after-output/movie-294.png) |
| MP4 587 | [Before](before-output/repaired-frame-587.png) | [After](after-output/movie-587.png) |
| Actual GIF 293 | [Before](before-output/gif-frame-293.png) | [After](after-output/gif-293.png) |

All eight settled steps have MP4/GIF samples: [1](after-output/movie-26.png), [2](after-output/movie-96.png), [3](after-output/movie-156.png), [4](after-output/movie-210.png), [5](after-output/movie-294.png), [6](after-output/movie-372.png), [7](after-output/movie-432.png), [8](after-output/movie-518.png). Their GIF files use the corresponding nominal half-frame numbers. [GIF216](after-output/gif-216.png) retains the longest card's lower border with tight clearance. [Early402](after-output/movie-402.png), [408](after-output/movie-408.png) and [420](after-output/movie-420.png) preserve the disclosed camera travel: not every early stream state is fully visible. The previous card is partly cropped in result focus. Fixed output dimensions do not prove responsive browser behavior.

The [historical assessment](judgments/E6o_FEATURECLIPSTUDIO_CRITERION_ASSESSMENT.json) stays a distinct prior observation. The [scoped successor](judgments/E6o_FEATURECLIPSTUDIO_READABILITY_CRITERION_ASSESSMENT.json) updates evidence supported by LiveSync's output, retaining 21 partial observations, 23 not run and all full scores null. Its [precise field correction](judgments/final-judge-field-correction.json) explains the final judgment's inherited nested pending-review label; the top-level approval is unchanged. The [reviewer's resolved reading concern](judgments/reviewer-reading-correction.json) is also preserved.

The default WT-NodeRoom example, recorded dependency advisories, inherited swallowed `waitText` timeout, provider/model paths and production remain held. This scoped approval does not certify those surfaces.

## Portability and verification

From the repository root:

```sh
python promotion/evidence/local-livesync-handoff-20260907/verify.py
python promotion/evidence/local-livesync-handoff-20260907/verify.py --source-root .
```

[The manifest](manifest.json) checks strict packet bytes, including logs and inert historical text. [The copy map](copy-map.json) distinguishes exact raw copies from explicit derivatives and binds each to its original hash. Derivatives remove named operator/home path prefixes or redundant recorder fields; they are never labelled exact raw copies. The narrow `.gitattributes` preserves raw packet bytes under Git.

[Selected source bindings](source-bindings.json) separately record raw working SHA-256/Git blob and the actual Git-filtered canonical identities. Optional source verification permits CRLF→LF only for rows where the native Git filter demonstrated that equivalence; binary and other exact rows stay strict. This is a selected-source check, not a full repository or installed-dependency inventory. The current behavior proof precedes this documentation-only addition; it does not assert a new shared CI run.

[Omissions](omissions.json) identify hash-bound operator-local groups. Unselected pictures, full DOM/session state, old movies, controller histories, private path/environment inventories, databases and caches are not portable. Hashes do not reconstruct them. Inert historical reports may reference those local originals; use the copy map to find the files actually supplied. The correct historical generated-custody origin is plan01, as recorded in omissions, rather than the missing relative plan03 link.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "absent",
"argv": [
"C:/nvm4w/nodejs/node.exe",
"walkthrough.collab.mjs"
],
"seconds": 0.343,
"timeoutSeconds": 45,
"timedout": false,
"exitCode": 1,
"expectedExitCodes": [
1
]
}
Loading
Loading