Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b696196
feat: checkpoint creator workspace and governed media pipeline
HomenShum Jul 21, 2026
e521c94
feat: adopt NodeKit Caseflow for creator campaigns
HomenShum Jul 21, 2026
7f1f1c0
feat: adopt NodeKit Caseflow in creator workflow
HomenShum Jul 21, 2026
9a18c99
fix: align NodeKit manifest with registered contracts
HomenShum Jul 21, 2026
175c4e2
test: bind production Caseflow and router proof
HomenShum Jul 21, 2026
80d6170
test: gate Caseflow proof on explicit backend
HomenShum Jul 22, 2026
825de13
fix: allow durable creator synchronization in production
HomenShum Jul 22, 2026
0050178
test: isolate generated conformance caches
HomenShum Jul 22, 2026
d6af6fc
fix: normalize typed free-router responses
HomenShum Jul 22, 2026
13a9a91
test: validate creator CSP deployment contract
HomenShum Jul 22, 2026
fd9de2c
test: assert durable free-router model receipt
HomenShum Jul 22, 2026
b98ab11
feat: require structured free-router plans
HomenShum Jul 22, 2026
6db95bb
fix: recover typed plans from reasoning envelopes
HomenShum Jul 22, 2026
bce407b
docs: record production Caseflow and free-router proof
HomenShum Jul 22, 2026
64419bc
ci: bind creator proof to Convex endpoint
HomenShum Jul 22, 2026
a240f64
feat: rebuild creator as artifact workspace
HomenShum Jul 22, 2026
ed2da53
fix: retry invalid free router plans
HomenShum Jul 22, 2026
95ada31
test: harden production creator proof
HomenShum Jul 22, 2026
45bcab2
fix: add free model failover routing
HomenShum Jul 22, 2026
40e3af5
fix: bound OpenRouter fallback list
HomenShum Jul 22, 2026
4a34d08
fix: repair free planner output through allowlist
HomenShum Jul 22, 2026
9f6ab86
feat: add local smart reframe creator workflow
HomenShum Jul 22, 2026
bb6cf26
fix: preserve artifact dominance at tablet widths
HomenShum Jul 22, 2026
0c7ee32
feat: add scalable tracking artifact atlas
HomenShum Jul 22, 2026
d216e9a
test: verify atlas media delivery contract
HomenShum Jul 22, 2026
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
2 changes: 2 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ jobs:
timeout-minutes: 20
env:
CI: 'true'
VITE_CONVEX_URL: ${{ vars.NODEVIDEO_CONVEX_URL }}
NODEVIDEO_CONVEX_URL: ${{ vars.NODEVIDEO_CONVEX_URL }}
steps:
- name: Check out repository
uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ test-results/

# QA evidence stays local unless an explicitly authorized case publishes selected sanitized derivatives.
.qa/cache/
.qa/creator-build/
.qa/evidence/
.qa/media/
.qa/models/
.qa/showcase/
.qa/*.log

.vercel
4 changes: 4 additions & 0 deletions .qa/memory/findings.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@
{"severity":"P2","area":"coach contract accuracy","symptom":"Contract listed suggestion buttons unconditionally (gone after first message) and claimed segment button always streams a proposal","fix":"Added present-only-before-first-message state to the 3 suggestions; amended segment meaning to note the no-window/no-verdict text-only paths; documented disabled-input + stop-control and error event","evidence":"Contract verifier green across 4 surfaces. PR #21","status":"fixed","ts":"2026-07-18T10:21:40.661Z","fp":"57d51affe689"}
{"area":"e2e-axe","symptom":"CI-only Axe contrast failure surviving retry: audit ran mid CSS color-transition after a click on slow ubuntu runner, computing blended transient colors (#6a6d62 on #7e912e)","cause":"spec mutates UI state then audits immediately; button color transitions still in flight on slow runners while fast local machines finish first","fix":"global prefers-reduced-motion rule in src/styles.css collapsing transition/animation durations + contextOptions.reducedMotion reduce in playwright.config.ts (Playwright 1.61: reducedMotion lives under contextOptions, not top-level use)","severity":"P1","ts":"2026-07-19T21:30:01.962Z","fp":"1e5412e68702","status":"open"}
{"severity":"P1","area":"collab export background-tab honesty","symptom":"Collab canvas compositor and WebM export were requestAnimationFrame-driven, allowing black or stale output when the page compositor stalled.","cause":"Recording had no independent frame pump and no visibility or incomplete-recording fail-closed boundary.","fix":"Added a 30fps timer safety pump, explicit hidden-tab/dual-pump cancellation, completion authorization, partial/empty output discard, delayed object-URL revocation, locked recording controls, and visible cancel/status states.","evidence":"Focused collab Playwright spec passes all five viewport projects, including forced rAF stall, user cancellation, hidden-tab cancellation, cleanup reuse, and one authorized completed download.","status":"fixed","ts":"2026-07-20T04:02:00.000Z","fp":"c1e1ed7cd218"}
{"sev":"P1","area":"creator-form-accessibility","symptom":"workflow-select-and-textareas-lacked-accessible-names","rootCause":"labels-not-associated-to-control-ids","evidence":"axe-initial-fail-then-desktop-mobile-pass","fix":"added-ids-htmlFor-and-named-trigger","status":"fixed","ts":"2026-07-21T22:13:23.331Z","fp":"9fa28c330851"}
{"id":"nodevideo-ui-topology-20260721","rootCause":"onboarding-operation-provider-proof-export-composed-as-one-card-dashboard","sev":"P0","symptom":"proof-dashboard-as-primary-product-instead-of-artifact-workspace","status":"fixed","area":"creator-product-topology","evidence":"harness/references/anti-references/nodevideo-proof-dashboard-as-product","fix":"guided-start+artifact-workspace+run-inspector+mobile-modes+topology-gate","ts":"2026-07-22T01:14:09.081Z","fp":"95a1b08805f3"}
{"id":"NV-SR-001","sev":"P1","area":"creator responsive topology","symptom":"Artifact stage falls below majority width at tablet and xl boundary viewports","rootCause":"Three-column workspace stayed active below the width where both side rails could coexist with an artifact-dominant canvas","evidence":"GitHub Actions run 29885587329 and focused xl-boundary/tablet Playwright rerun","fix":"Switch tablet to mode-based surfaces at 1023px and compact rails from 1024px through 1350px","status":"fixed","ts":"2026-07-22T02:30:07.066Z","fp":"09e51987fd46"}
{"id":"NV-ATLAS-001","sev":"P1","area":"tracking-atlas-responsive-topology","symptom":"The 834px tablet viewport retained the desktop navigation rail and overflowed horizontally","rootCause":"The Atlas single-column breakpoint was set to 820px, below the tested tablet width","evidence":".qa/runs/2026-07-21-tracking-atlas/pixels/tablet-dark.png and tablet-light.png before/after pixel rerun","fix":"Move the deliberate single-column navigation transition to 900px and assert document scrollWidth against innerWidth","status":"fixed","ts":"2026-07-22T03:24:00.000Z","fp":"nv-atlas-tablet-900"}
6 changes: 6 additions & 0 deletions .qa/memory/runs.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@
{"executor":"Codex GPT-5","deployment":"https://nodevideo-pi.vercel.app","convex":"https://spotted-cat-868.convex.site","eve":"https://nodevideo-eve-agent.vercel.app","final":true,"journeys":{"A0":"PASS","A1":"PASS exact source-only five assets","A2":"PASS live Eve read_job tool","A3":"PASS fifteen durable stages and artifact lineage","A4":"PASS strict-passing technical edit; taste not evaluated","A5":"PASS frame inspector one-frame controls","A6":"PASS five responsive projects and live 390 browser","A7":"PASS retry and recovery","A8":"PASS hidden evaluator isolation"},"bar":{"B1":2,"B2":2,"B3":2,"B4":2,"B5":2,"B6":2,"B7":1,"B8":2,"B9":2,"B10":2,"B11":2,"total":"21/22"},"gates":{"unit":"twenty files and 129 tests PASS","focusedE2E":"five of five PASS across desktop xl tablet 390 and 320","uiPolicy":"twenty-five generated shadcn files verified; zero exceptions; authored UI 896 of 900; CSS 95 of 120","productionBrowser":"390 px no overflow and no console warnings or errors; strict inspector seven of seven verified","workflow":"production job fifteen of fifteen stages and thirteen artifacts and forty-eight events; retry recorded","evaluator":"six of six strict boundaries within two frames","eve":"authenticated production session called read_job and returned completed fifteen of fifteen and thirteen artifacts and evaluator completed"},"evidenceDir":".qa/evidence/private/live-product-proof","ts":"2026-07-16T11:23:23.164Z"}
{"executor":"Codex GPT-5","deployment":"local source audit; no deployment","journeys":{"A0":"PASS extension first-run","A1":"SKIPPED primitive-audit scope","A2":"SKIPPED primitive-audit scope","A3":"SKIPPED primitive-audit scope","A4":"SKIPPED primitive-audit scope","A5":"PASS five responsive viewports plus Axe and overflow","A6":"PASS raw-control and direct-Radix adversarial scan","A7":"SKIPPED primitive-audit scope"},"bar":{"B8":2,"B9":"DEFERRED(no new pixel review)"},"gates":{"uiPolicy":"PASS 27 generated files zero exceptions authored UI 900/900 CSS 95/120","directScan":"PASS no raw generic controls direct Radix imports or custom max breakpoints","typecheck":"PASS","unit":"161/161 PASS","e2e":"10/10 PASS across five viewport projects","lint":"251 files PASS","extensionBuild":"PASS"},"evidenceDir":"docs/ui-primitive-audit.md","ts":"2026-07-17T00:03:07.736Z"}
{"executor":"claude-opus-4-8","journeys":{"A0":"PASS","A1":"SKIPPED(needs owner key + local worker)","A2":"SKIPPED(no local sidecar in pass)","A3":"PASS(inspector badges + hash verification)","A5":"PASS","A6":"PARTIAL(collapsed-disclosure + theme toggle exercised)"},"bar":{"B1":2,"B2":2,"B3":2,"B4":2,"B5":2,"B6":2,"B7":1,"B8":2,"B9":2,"B10":2,"B11":1},"gates":"npm run check green after biome fix; lint 255 clean; Playwright 10/10 five-viewport","evidenceDir":"scratchpad/qa-shots + prod screenshots","ts":"2026-07-17T20:29:20.421Z"}
{"id":"creator-pipeline-2026-07-21","timestamp":"2026-07-21T00:46:00-07:00","mode":"SANDBOX DOGFOOD","executor":"codex","journeys":{"A0":"PASS","A1":"PASS","A2":"SKIPPED(no live model; deterministic orchestration proof)","A3":"PASS","A4":"PASS","A5":"PASS(desktop+mobile dark; overflow checked)","A6":"PASS(contract adversarial prompts)","A7":"N/A"},"bar":{"B1":2,"B2":2,"B3":2,"B4":1,"B5":2,"B6":1,"B7":1,"B8":2,"B9":2,"B10":1,"B11":1},"gates":["lint","typecheck","195 unit tests","capability validation","UI policy and budget","creator desktop/mobile E2E","real H.264 export","production bundle"],"evidenceDir":".qa/evidence/creator-pipeline","notes":"Generalized creator route: upload, shared MediaIndex, recipe routing, variants, approval, EditPlan v2, receipt, and local MP4 export. Standard dist build was locked by pre-existing preview servers; identical Vite production build passed under .qa/cache/creator-build.","ts":"2026-07-21T07:47:07.742Z"}
{"executor":"Codex","journeys":{"A0":"PASS","A1":"PASS","A2":"BLOCKED_HIGGSFIELD_SIGNIN","A3":"PASS","A4":"PASS","A5":"PASS","A6":"PASS","A7":"PARTIAL_PROVIDER_BLOCKED"},"bar":{"B1":2,"B2":2,"B3":2,"B4":2,"B5":2,"B6":1,"B7":1,"B8":2,"B9":2,"B10":2,"B11":2},"gates":{"typecheck":"PASS","unit":"206_PASS","creatorBrowser":"5_PASS_1_EXPECTED_SKIP","axe":"PASS_DESKTOP_MOBILE","build":"PASS","uiBudget":"PASS_900_OF_900"},"evidenceDir":".qa/evidence/creator-pipeline","ts":"2026-07-21T22:13:23.436Z"}
{"executor":"Codex","journeys":["A0","A1","A3","A4","A5","A6"],"bar":{"B1":2,"B2":2,"B3":2,"B4":2,"B5":2,"B6":2,"B7":2,"B8":2,"B9":2,"B10":2,"B11":1},"gates":{"typecheck":"pass","unit":"212-pass","build":"pass","browser":"10-pass-4-skip","twoSession":"pass","exportReopen":"pass","paidExecutorSubmitted":false,"deploymentRevisionBound":false},"evidenceDir":".qa/evidence/creator-pipeline","notes":"local-proof-53.188s-submission-blocked","ts":"2026-07-21T23:39:07.536Z"}
{"evidenceDir":".qa/evidence/creator-topology","executor":"codex","gates":{"fullCheck":"pass","topology":"pass","creatorDesktopMobile":"12-pass-4-intentional-skip","build":"pass","typecheck":"pass"},"bar":{"durability":5,"functional":5,"responsive":5,"visual":4,"safety":5,"accessibility":5},"journeys":["guided-first-arrival","artifact-workspace","proposal-review","paid-executor-gate","durable-two-session","export-reopen","mobile-surface-modes"],"ts":"2026-07-22T01:13:56.489Z"}
{"executor":"Codex","journeys":["Smart Reframe local journey"],"bar":{"functional":4,"coherence":4,"responsive":4,"accessibility":4,"proof":4},"gates":{"check":"pass","creatorProof":"pass"},"evidenceDir":".qa/evidence/smart-reframe","ts":"2026-07-22T02:19:26.333Z"}
{"executor":"Codex","mode":"AUTHORIZED PRODUCTION","journeys":{"A0":"PASS","A1":"PASS(local catalog)","A2":"N/A(no external model; local guide)","A3":"PASS(hash-bound receipts)","A4":"PASS(downloadable 42.6s compilation)","A5":"PASS(desktop/tablet/mobile light+dark)","A6":"PASS(fail-closed license/hash validators)","A7":"N/A"},"bar":{"B1":2,"B2":2,"B3":2,"B4":2,"B5":2,"B6":2,"B7":1,"B8":2,"B9":2,"B10":2,"B11":2},"gates":{"atlasVerify":"8-pass","atlasE2E":"4-pass","typecheck":"pass","build":"pass","pixels":"6-pass-no-overflow"},"evidenceDir":".qa/runs/2026-07-21-tracking-atlas","notes":"Eight CC Attribution fixtures; six automatic YOLO11n routes and two explicit first-frame seed plus OpenCV routes. Fixture-bound proof only.","ts":"2026-07-22T03:24:00.000Z"}
22 changes: 22 additions & 0 deletions .qa/requests/higgsfield/nodevideo-platform-hero.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"jobType": "seedance_2_0",
"prompt": "A clean cinematic macro shot of a luminous modular video-editing timeline assembling itself from source clips into three aspect-ratio variants, dark studio background, chartreuse interface accents, no people, no logos, no text, smooth controlled camera move",
"parameters": {
"aspect-ratio": "16:9",
"bitrate-mode": "standard",
"duration": 5,
"generate-audio": false,
"genre": "auto",
"mode": "fast",
"resolution": "480p"
},
"recipeId": "recipe.nodevideo-platform-hero.v1",
"referenceAssetIds": [],
"intendedUses": ["private-interface-evaluation"],
"rights": {
"sourceAssetsOwned": true,
"mediaEgressApproved": true,
"syntheticPeopleOnly": true,
"providerTermsSnapshot": "higgsfield-cli-1.1.19-2026-07-21"
}
}
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Changelog

## Unreleased — NodeKit Caseflow consumer

### Components

- Reframed the creator experience around one founder-launch journey with a case rail, durable video
artifact stage, NodeAgent right rail, and bottom activity strip.
- Added inline proposal review plus governed specialist-executor cards.

### Server

- Added a schema-validated OpenRouter Free planning endpoint with deterministic fallback.
- Added exact-digest proposal, approval, receipt, and executor mutations.

### Database

- Added Convex cases, runs, threads, messages, artifact versions, approvals, exceptions, executor
jobs, receipts, and timeline events.
- Added idempotent campaign creation, exactly-once approval, and stale-write rejection.

### Integration

- Added the shared NodeKit Caseflow contract test and git-pinned dependency.
- Added Higgsfield capability discovery, quote/egress proposals, approval invalidation, decline, and
local alternative decisions without automatic spending.
- Added desktop/mobile, two-session, export/reopen, and accessibility proof.
95 changes: 95 additions & 0 deletions NODEVIDEO_CREATOR_PRODUCT_CONTRACT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# NodeVideo Creator Product Contract

## Product job

NodeVideo turns source media, creative intent, and references into reviewable video variants. The agent coordinates the work; deterministic tools and specialized executors perform it; the creator remains authoritative over consequential edits, media egress, paid execution, and the canonical export.

The normal journey is:

```text
Describe the outcome → add media and references → review a creative direction
→ inspect video, timeline, and variants → review exact changes → approve
→ execute locally or through an approved provider → export and retain proof
```

## Two product modes

### Guided creation

The first arrival contains one outcome composer, source/reference inputs, output targets, and one Start action. It must explain the product in under ten seconds. It must not expose an execution graph, provider configuration, receipt controls, raw executor identifiers, or every later workflow stage.

### Creator workspace

After creation begins, the product becomes an artifact workspace:

- Desktop: project/progress rail (220–260px), dominant video canvas and timeline, persistent NodeAgent/review rail (360–420px), stage header, and compact run-status strip.
- Mobile: explicit Canvas, Agent, Review, and Sources modes. Only one major surface is visible at a time; the current action and sticky action/composer remain reachable above the fold.

## Core hierarchy

1. Primary: current video artifact, selected variant, and timeline.
2. Adjacent: agent conversation, tool activity, proposals, and decisions.
3. Supporting: sources, project stages, versions, and render state.
4. Secondary disclosure: raw traces, hashes, executor IDs, full receipts, model detail, provider setup, worker status, and BYOK routing.

The primary artifact must occupy at least 55% of the desktop working area after planning. The selected variant and canonical version must always be identifiable.

## Shared NodeKit concepts

`CaseHeader`, `StageProgress`, `CurrentAction`, `ArtifactWorkspaceShell`, `AgentReviewRail`, `AgentThread`, `ToolActivity`, `ProposalReview`, `EvidenceRail`, `ExceptionState`, `ReceiptInspector`, `VersionHistory`, `RunStatusBar`, `EgressApproval`, and `CostApproval`.

## NodeVideo-specific concepts

`VideoCanvas`, `SourceVault`, `Timeline`, `ClipInspector`, `VariantSwitcher`, `VariantCompare`, `EditPlanInspector`, `RenderQueue`, `MediaExecutorProposal`, and `VideoExport`.

## Durable Caseflow mapping

| Product concept | Durable object |
| --- | --- |
| Project/campaign | Case |
| Creative objective | Case objective |
| Agent conversation | Thread + messages |
| Editing attempt | Run |
| Tool activity | Run events |
| Proposed edit | Version-pinned proposal |
| Approval/rejection | Decision |
| Accepted video | Canonical artifact version |
| Provider execution | Exact executor proposal + approval |
| Proof/export | Receipt + artifact reference |

The agent rail carries the case, run, selected artifact, selected variant, durable thread, inline tools, proposals, approvals, and execution state. Selecting a clip or variant updates agent context. Accepted proposals apply exactly once; stale approvals fail; a second session observes updates reactively.

## Proposal contract

Every edit proposal must show:

- selected variant scope;
- base/canonical version;
- exact timeline operations and timestamps;
- source lineage;
- meaning-sensitive changes;
- validation state;
- before/after comparison;
- primary approve/reject actions.

Export remains unavailable until the proposal is approved and applied.

## Provider and payment contract

Provider execution is optional. The creator sees provider detail only when it changes a decision. A paid or egressing job requires a fresh exact proposal containing provider, job, inputs, egress disclosure, quoted cost, balance, quote expiry/price invalidation, and local/decline alternatives. Approval authorizes only that immutable proposal.

## Run Inspector

`/creator/runs/:runId/proof` is the technical Run Inspector. It owns compiled graphs, raw executor IDs, hashes, model/tool versions, detailed lineage, full receipts, and diagnostic state. This information must not dominate `/creator`.

## Acceptance invariants

- First arrival has one clear job and primary action, without backstage machinery.
- Active desktop workspace is artifact-dominant and keeps the agent rail visible.
- Mobile uses surface modes, never a page-length stack of desktop columns.
- Tool actions and proposals remain associated with the conversation.
- Conversations and proposals survive reload.
- Canonicalization is exactly once, stale approval is rejected, and a second browser is reactive.
- Export reopens and matches the accepted artifact.
- The application uses the phrase **agent-workspace composition**, not “platform parity.”

Loading
Loading