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
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,53 @@

### Added

- Independent `brand.titleCard` and `brand.endCard` overrides. The existing
`brand.cards` switch remains the default for both, so current configs render
unchanged while artifact-first pieces can omit only the opening card.
- A production pack for Factory AI at Work Gate 1: one pinned landscape master,
three 9:16 cuts, a real-capture contract, publishing copy, contract tests, and
an operator runbook. Its reviewed-pack promoter now binds an exact,
single-filesystem renderer topology before sealing, writes locale-independent
manifests, requires exact relative concat selections, and probes those same
archived segments against the reported shot timeline. Privileged,
environment-scrubbed receipt validation rejects placeholder review evidence;
phase-aware cleanup restores an interrupted writable attempt or reports the
retained sealed path, and a failed post-commit status write cannot misreport
an already verified promotion as a retryable failure. Production receipts
bind one clean source-build attestation and archived claim ledger. The pack
deliberately leaves served-state observation and the three-episode promotion
counter to the ratified channel operator authority. Captured and rendered
media remain ignored.
- Full SHA-256 render provenance for the resolved config, narration script, and
ordered prebaked clip bytes. Clips are rechecked after capture and before
rendering; the existing short config and script hashes remain for
compatibility. The committed source-snapshot launcher additionally binds a
local render to a private detached worktree of the tracked runner, commit,
scoped Git tree, package manifest, and dependency lock before application
modules load. The streamed launcher rejects caller startup files, functions,
command paths, working-directory config, Git environment, global or system
Git config, repository hooks and filesystem monitors, and implicit Node or
package-manager selection. Frozen dependency installation runs without
Doppler secrets, lifecycle scripts, pnpm hook files, or caller npm/pnpm
configuration. A module-local capability prevents another pipeline graph
from reusing the admitted session, and source drift during rendering blocks
the receipt. Direct mutable-checkout use of `--attest-source-build` is
refused, and an otherwise successful render fails if its detached snapshot
cannot be removed.
- A per-run `--out <new-directory>` override for immutable production attempts.
The target is claimed exclusively and an existing path is refused before
inputs are read or artifacts are changed. On a Linux filesystem under Linux
or WSL, subsequent writes stay bound to a private staging-directory handle.
Publication moves the authenticated claim into the output as
`.agent-demo-video-output-claim` and uses a no-clobber rename without
pathname-based cleanup. The guarantee covers existing targets and
accidental or cooperating collisions, not a malicious same-UID process.
`--clips-dir` and `--script` can select attempt-owned prebaked and narration
inputs without editing a config; configs without the flags retain their
reusable behavior.
- Full-bleed source geometry gates in both preflight and rendering. A finished
composition whose display aspect differs from its output canvas now fails
instead of being silently padded into a valid-size letterboxed file.
- `platform` distribution preset. `"shorts"` renders a 9:16 `1080x1920` canvas for
Shorts/TikTok/Reels cuts while still capturing web apps at a 16:9 desktop viewport;
the framed scene keeps the capture's aspect for the floating window, so nothing is
Expand Down Expand Up @@ -102,6 +149,12 @@

### Fixed

- CLI parsing now rejects unknown options, surplus config paths, duplicate
singleton flags, and pipeline-only flags on `login`, so a mistyped production
`--out` cannot silently fall back to a reusable configured output.
- Source-attested production renders now fail if their required
`render-report.json` cannot be built or written. Ordinary renders retain the
historical best-effort provenance behavior.
- Every config schema object now rejects unrecognised keys, so a typo in a
setting fails loudly instead of silently applying the default it was written
to override.
Expand Down
59 changes: 54 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,46 @@ shots it could not adjudicate, so a finished video says for itself how it was ch
The gate is fail-closed. Set `preflight: false` in the config, or pass `--no-preflight`
for a single run, to decline it; a declined run says so in its output.

For a production attempt, pass `--out <new-directory>`. This per-run override
atomically reserves the fresh output name and refuses an existing path before
reading the script or changing an artifact. On a Linux filesystem under Linux
or WSL (not a mounted Windows/DrvFs path), later writes stay bound to a new
private staging-directory handle while the requested name remains occupied.
A changed claim fails the run without deleting the replacement; success parks
and retains the authenticated claim as `.agent-demo-video-output-claim` inside
the output, then publishes the staged directory with a no-clobber rename. This
protects against existing targets and accidental or cooperating concurrent
reuse. It is not an isolation boundary against a malicious process running as
the same Unix user, which can manipulate that user's pathnames and `/proc`
handles.
Omitting the flag preserves the legacy reusable `config.out` behavior. Use
distinct fresh directories for rehearsal and real narration.
`--clips-dir <absolute-directory>` can pin a run to attempt-owned copies of
prebaked inputs without changing the config file. `--script <absolute-file>`
does the same for a copied narration manifest. Both overrides require absolute
paths so their meaning never changes with the launch or config directory.

Every successful `render-report.json` keeps the existing short config and
script hashes and also records full SHA-256 values for the resolved config,
script, and each ordered prebaked clip. Before narration spend, the pipeline
copies each source clip into a private read-only render binding. The renderer
and report consume only those bound bytes, so an ordinary later export to the
operator source path cannot change the artifact or its digest.

For a local source-run production render, `--attest-source-build` is reserved
for the committed snapshot launcher. The launcher bytes are streamed from one
fixed commit, create a private detached worktree, verify and freeze every
scoped repository byte before application modules load, and then invoke that
snapshot's `src/cli.ts`. Direct mutable-checkout use is refused. The report
records snapshot execution, the commit, scoped Git tree, package manifest, and
dependency-lock hashes, and the pipeline blocks the receipt if that state
changes during rendering. Installed dependency and system-tool bytes remain
reported toolchain inputs, not part of the repository source claim. The frozen
dependency install receives no render secrets and ignores caller npm/pnpm
configuration, lifecycle scripts, and pnpm hook files. Snapshot attestation is
intentionally incompatible with `--render-host` until remote bundles have their
own content-addressed attestation.

## Authenticated SaaS capture (`target: live`)

`target: live` drives an authenticated SaaS app (Slack, Notion, Linear, Stripe, any
Expand Down Expand Up @@ -255,9 +295,9 @@ Key fields in `demo.config.json` (full schema in `src/types.ts`):

| Field | Default | Notes |
|---|---|---|
| `script` | — | Path to DEMO_SCRIPT.md |
| `script` | — | Path to DEMO_SCRIPT.md. `--script <absolute-file>` overrides it for one run |
| `dashboardBaseUrl` | — | Base URL of the running app (e.g. `http://localhost:3000`) |
| `out` | `"out"` | Output directory |
| `out` | `"out"` | Output directory. On a Linux filesystem under Linux or WSL, `--out <new-directory>` overrides it for one run, reserves a nonexistent target, renders through a private directory handle, retains the authenticated claim marker, and publishes with a no-clobber rename. This is a cooperative-process guarantee, not hostile same-UID isolation |
| `platform` | `"landscape"` | Distribution preset. `"shorts"` renders a 9:16 `1080x1920` canvas for Shorts/TikTok/Reels while still capturing at a 16:9 desktop viewport; the framed scene floats the capture as a window on the tall canvas. Explicit `resolution` / `capture.viewport` override the preset |
| `resolution` | preset (`1920×1080` landscape) | Output canvas of the finished video |
| `capture.viewport` | preset (follows canvas on landscape; `1920×1080` on shorts) | Browser capture geometry, decoupled from the canvas |
Expand All @@ -274,14 +314,19 @@ Key fields in `demo.config.json` (full schema in `src/types.ts`):
| `theme.frame.enabled` | `true` | Scene framing: the capture floats as a rounded, shadowed window on a gradient backdrop |
| `audio.soundDesign` | `true` | Synthesized ambient bed ducked under narration, click ticks, segment sweeps |
| `motion.livingCamera` | `true` | Continuous camera path with drift; `motion.zoomOnAction: false` disables all camera motion |
| `brand` | (off) | `{ title, subtitle, url, accent, cards }` adds branded title and end cards |
| `clipsDir` | `"clips/prebaked"` | Where a **bare** prebaked clip filename resolves. Resolved against the config file's directory unless absolute |
| `brand` | (off) | `{ title, subtitle, url, accent, cards }` adds branded title and end cards. `titleCard` / `endCard` may override either side independently while `cards` remains the shared default |
| `clipsDir` | `"clips/prebaked"` | Where a **bare** prebaked clip filename resolves. Resolved against the config file's directory unless absolute; `--clips-dir <absolute-directory>` overrides it for one run |
| `preflight` | `true` | Fail-closed pre-flight selector gate; see [Pre-flight selector gate](#pre-flight-selector-gate). `false` (or `--no-preflight`) declines it |
| `maxDurationSec` | `300` | Hard ceiling for the finished video. The render fails if the result exceeds it. Set it to the length limit you are shipping against. |
| `capture.settleMs` | `500` | Budget for the post-navigation readiness wait (fonts ready, visible images decoded). `0` disables the probe. Exceeding the budget warns and records anyway. Under the default `screencast` engine the wait happens BEFORE recording starts, so unsettled frames are excluded; the legacy `recordvideo` engine binds capture at context creation, so there the wait shifts those frames later rather than excluding them. |

Sample: `demo.config.sample.json`.

An executable real-production example lives at
[`demos/factory-ai-at-work/gate-01/`](demos/factory-ai-at-work/gate-01/README.md):
one landscape master and three portrait cuts, all pinned and fail-closed on
operator-supplied captures.

## Third-party tabs

For surfaces you cannot or should not drive live (SaaS login walls, desktop apps, external products), pre-capture a clip once and reference it:
Expand Down Expand Up @@ -310,7 +355,11 @@ Add `- fullBleed: true` to a shot whose clip is ALREADY a finished composition,
motion-graphic title card rendered by another tool. The pipeline then skips the window framing and
the segment fade-in for that shot, because the clip carries its own framing and its own motion.
Without it a full-bleed card is shrunk to `theme.frame.scale` inside a shadowed window it was never
designed for.
designed for. A finished composition must match the output canvas aspect. Preflight probes existing
full-bleed clips before TTS, and the renderer checks again before normalization; a mismatch is
rejected instead of silently padded with bars. Finished compositions must use square sample pixels
(`1:1` SAR). The guard rejects anamorphic input because the current render filters operate on coded
geometry, and normalization pins the same `v:0` stream that the geometry probe validates.

```markdown
### SHOT title
Expand Down
84 changes: 84 additions & 0 deletions demos/factory-ai-at-work/gate-01/CAPTURE_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Gate 1 Capture Plan

All footage is captured from real runs owned by the operator. Nothing in this
plan authorizes connecting sensitive folders, exposing credentials, or
publishing an artifact.

## Common clip contract

- Master clips are finished 1920x1080 compositions at 30 fps.
- Cut clips are finished 1080x1920 compositions at 30 fps.
- Encode H.264 with yuv420p pixel format, square sample pixels (`1:1` SAR), and
no embedded narration.
- Keep captions out of the source clip. The pipeline burns the pinned captions.
- Blur credentials, account identifiers, notifications, and unrelated files.
- Use only footage captured for this episode or other rights-clean operator
footage.
- Every clip is declared `fullBleed: true`; it already owns its framing,
reframing, labels, motion, and brand cards.
- Match the real file count, prompt, elapsed time, formula cells, notifications,
and session state shown in the capture. If the run differs, update narration
and the run receipt before render.
- Do not use generated product screens or staged timestamps.

Place clips in these ignored directories relative to this pack.
The rehearsal reads these working files. Before real narration, the runbook
copies the exact twelve files into the fresh attempt's `evidence/clips/` tree;
production preflight and render read only those owned copies.

## Master clips

| File | Evidence job |
|---|---|
| `clips/master/01-cold-open.mp4` | Finished organized folder and formula-backed spreadsheet, then the same real folder before organization and the Windows Claude entry point. |
| `clips/master/02-roadmap.mp4` | Four-step strip plus honest Windows 11 and local-versus-cloud setup. |
| `clips/master/03-setup.mp4` | Paid-plan, Windows-version, and admin-rights checklist with no credential or account detail. |
| `clips/master/04-install-it-right.mp4` | Real download, UAC approval, Start-menu sign-in boundary, Virtual Machine Platform setting, restart, and the Cowork selector payoff. |
| `clips/master/05-first-real-task.mp4` | Real staged folder, exact typed prompt, plan, any permission request that actually occurred, folder changes, spreadsheet, and formula spot check. |
| `clips/master/06-where-it-runs.mp4` | Remote-session receipt, lid-close continuation, local-file gate, Hyper-V diagram, safety guidance, and second-device progress with real timestamps. |
| `clips/master/07-anywhere-on-a-schedule.mp4` | Same session on web and phone, a real notification, local-file boundary, scheduled task, on-demand run, and the resulting digest. |
| `clips/master/08-recap.mp4` | Four real payoff shots replayed in order. |
| `clips/master/09-next.mp4` | Channel close with one subscribe action and the next episode topic. |

The pipeline generates the final 15-second disclosure card. Do not prepend a
title card: the first frame must be the finished artifact.

## Portrait cut clips

| File | Evidence job |
|---|---|
| `clips/cut-a/cut-a-install.mp4` | Portrait reframe of the real UAC, Virtual Machine Platform, restart, and Cowork-selector sequence. |
| `clips/cut-b/cut-b-real-job.mp4` | Portrait reframe of the real folder, exact prompt, work progression, folder result, and formula spot check. |
| `clips/cut-c/cut-c-remote.mp4` | Portrait composition of the remote-session receipt, lid-close continuation, desktop-file gate, and safety boundary. |

## Run-dependent receipts

Before a production render, record these in the attempt's copied
`PRODUCTION_RECEIPT.md`:

1. Exact source folder file count and a content inventory showing it contains no
sensitive documents.
2. Exact Cowork prompt used in the run.
3. Whether Cowork showed a permission prompt. If it did not, no permission
prompt may appear in footage.
4. Real elapsed timestamps for task progress and lid-close continuation.
5. Desktop, web, and phone proof for any narration that says the session is on
every device.
6. The spreadsheet formula cells spot checked and their expected totals.
7. The source URLs and access date for every vendor claim shown as a receipt.

## Mechanical checks

For every clip:

```bash
ffprobe -v error \
-select_streams v:0 \
-show_entries stream=width,height,pix_fmt,r_frame_rate,sample_aspect_ratio \
-of default=noprint_wrappers=1 <clip.mp4>
```

Expected master geometry is `1920x1080`; expected cut geometry is `1080x1920`;
pixel format is `yuv420p`; frame rate is `30/1`; sample aspect ratio is `1:1`.
The renderer and preflight both inspect `v:0`, and normalization pins that same
stream.
Loading