• buildStage2Prompt() renders MVCP M.15's confirmed one-step six-section
    template and enforces the two dynamic risks M.15.1 flagged: caps
    appearanceDescriptor/garmentDescriptor at ~40 words each, and
    truncates motionDescriptor if it alone would push detailed_description
    past H6's 500-word cap (the only placeholder that lands in that
    section).
    
    Also fixes the footwear-drift the S1 spike found (model self-selected
    shoes when the prompt didn't constrain them) — pins footwear to
    <Picture 1> in both subject_definitions and retention_analysis, and
    says <Picture 2> doesn't affect it. Propagated the same fix into the
    M.15 template in the MVCP doc so the doc and the code don't drift.
    
    Tests check the mechanical M.15.1 items that are checkable from the
    rendered string (H1/H5/H6/H9) plus the truncation behavior and the
    footwear fix. H13 (reference counts) is a submission-payload concern,
    covered by T8's tests instead.
    yibo authored
     
    Browse Code »
  • Table + inline edit + add-form pages matching admin.html's existing
    conventions, wired to the T3-T5 CRUD API and T2's upload endpoints.
    Cross-linked with admin.html and each other in the topbar.
    
    No browser tooling available in this environment to render/click
    through these, so admin-pages-flow.test.js exercises the exact API
    call sequence each page's JS performs (login -> upload a real file ->
    create with the returned URL -> list -> confirm the shape the table
    renders), which is where a field-name mismatch would surface.
    yibo authored
     
    Browse Code »
  • POST /api/admin/upload-video: mp4 magic-byte sniff (checks the ftyp
    box, not offset-0 like images), 50MB cap, no re-encode needed (unlike
    images, no EXIF/GPS concern for video). Reuses the multipart parser
    and uploads/ layout from T2's image path via a shared placeInUploads
    helper.
    yibo authored
     
    Browse Code »
  • mountCrud() is a small generic GET-list/POST-create/PATCH/DELETE
    router shared across the three entities (same shape, see MVCP
    M.3/M.4/M.5) instead of copy-pasting the boilerplate three times.
    Each entity fills in its own admin_seed-appropriate defaults on
    create. characters additionally enforces the single-default-character
    invariant (2 节) across create/update.
    
    HTML admin pages for these come next.
    yibo authored
     
    Browse Code »
  • Single shared password (.env ADMIN_PASSWORD) + in-memory HttpOnly
    session cookie, no accounts/roles — MVCP M.1/M.10's real account
    system supersedes this in period 3. Covers the existing
    /api/admin/library/* routes (previously unauthenticated, see
    architecture.md 1.2's tech-debt note) plus the new upload endpoint.
    
    admin.html gets a fetch() interceptor that redirects to the new
    admin-login.html on any 401 from /api/admin/*, rather than patching
    every call site.
    yibo authored
     
    Browse Code »
  • POST /api/admin/upload: hand-rolled multipart parser (no deps installed
    in this project), real magic-byte sniffing (rejects extension-spoofed
    files), 8MB cap, and EXIF/GPS stripping via a sips bmp round-trip
    (macOS-native, no dependency — sips's direct jpeg->jpeg re-encode alone
    does NOT strip EXIF, only the bmp intermediate does). GET /uploads/*
    serves the result with a path-traversal guard.
    
    forwardToH3Assets() is the T7/T8 hook for pushing a saved upload to H3
    Console's own POST /v1/assets (found in the S1-S4 spike) — not covered
    by the automated suite since it needs a live network call, same
    treatment as the spike scripts.
    yibo authored
     
    Browse Code »
  • S1: person+garment images directly into ref2va with attribute_transfer
    produce correct face/outfit/motion in one call — no separate compose
    step needed. S2: reference_video_urls has a real, strong effect on
    output motion (A/B tested). S4: H3 Console's own POST /v1/assets
    endpoint (undocumented until now) solves asset reachability without
    exposing our own uploads/ publicly.
    
    Evidence and scripts in spike/s1-s2-s4-2026-09-02/. Propagated the
    one-step design into the requirements doc, MVCP design doc, the
    architecture doc, and H3-CONSOLE.md; dev-plan.md's spike section
    marked done and its task table updated accordingly.
    yibo authored
     
    Browse Code »
  • Generic createStore(filePath) shared by characters.json/garments.json/
    dance-refs.json, same full-read/full-write pattern as library.json.
    Not yet wired into server.js routes — that's T3-T5.
    yibo authored
     
    Browse Code »

  • Duration: fixed 10s (within H3's 4-15s hard constraint), frames=240 @ 24fps.
    
    Prompt: follows the internal H3 prompt-writing methodology already sitting
    in the repo (docs/h3skill.md, from a parallel session) — the "all-purpose
    reference mode" six-section structure. Character appearance details are
    auto-captioned from the Stage1 composed image (new composed_images.
    appearanceDescriptor field); dance motion phrasing is admin-authored once
    per reference video (new dance_refs.motionDescriptor field), since the
    format requires concrete descriptors and forbids "as shown in the picture."
    
    Flagged as needing a pass through h3skill.md's own 22-item mechanical
    acceptance checklist before production use, not claimed as fully compliant.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01SdtXTsDRz5QWMjvt1HBXLz
    yibo authored
     
    Browse Code »
  • H3_GEN_PARAMS.frames 120 -> 240 (at 24fps, 5s -> 10s), still within H3's
    4-15s range (H2 in docs/h3skill.md). Updated the prompt-optimization system
    prompt's duration reference and widened its word budget (40-70 -> 60-100)
    to match — still one continuous shot, just more room to let the camera move
    and the action unfold. Verified against the real GLM endpoint.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • Previously left as inline "勘误" patch notes; now the baseline doc
    (docs/done) states the current 480x832 default outright, and the
    dance-room docs describe live.html/dance.html as two independently
    configured H3_GEN_PARAMS that happen to agree, rather than flagging an
    erratum.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01SdtXTsDRz5QWMjvt1HBXLz
    yibo authored
     
    Browse Code »
  • Data model, front/back-end view inventory, button-level control design, and
    per-user-type process flows for the not-yet-built feature. Also corrects the
    requirements doc's stale "live.html stays landscape" claim now that
    H3_GEN_PARAMS was changed to portrait there too (commit 1dc7084).
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01SdtXTsDRz5QWMjvt1HBXLz
    yibo authored
     
    Browse Code »
  • The previous system prompt asked GLM for a free-form "shot-by-shot" expansion,
    which reliably produced 4-5 fake cuts with timestamps running out to 8-10s —
    impossible for a clip fixed at ~5s (H3_GEN_PARAMS.frames / FPS). Rewrote it
    against docs/h3skill.md (MiniMax's own H3 prompt-writing methodology, added
    alongside this commit): every chat prompt has no reference images, so it's
    always T2VA mode, and at ~5s it's one continuous shot, never a montage.
    
    The new prompt asks for H3's actual three-field T2VA structure
    (integrated_multimodal_description / overall_soundscape / non_diegetic_music,
    fixed order and labels), a single dominant camera movement from the official
    vocabulary (type + amplitude + speed), concrete lighting (no hollow buzzwords
    like "8K"/"cinematic" alone), and — previously missing entirely — explicit
    sound design. Verified against the real GLM endpoint on several sample
    prompts: single continuous shot throughout, correct field structure, no more
    impossible multi-shot timestamps.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • Documents the new outfit-swap dance live room (dance.html) requirements
    alongside the existing text-prompt live channel baseline, plus the
    combined system architecture covering both.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01SdtXTsDRz5QWMjvt1HBXLz
    yibo authored
     
    Browse Code »
  • Adds a prompt-optimization step ahead of H3 generation: a viewer's short
    chat line ("一只猫跳舞") gets expanded into a detailed shot-by-shot English
    prompt (camera work, lighting, action, setting) via one GLM Coding Plan call
    (glm-5.3-flash, /api/coding/ endpoint — the coding-plan-specific path, not
    the pay-per-token one) before being handed to H3. The expanded prompt becomes
    the clip's fullPrompt; the original short text stays as the display prompt.
    Persisted on the queue entry so a restart mid-generation doesn't re-call GLM.
    Best-effort throughout — no API key, a timeout, or any GLM error just falls
    back to using the original text unchanged, never blocking generation.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • Swaps the H3_GEN_PARAMS default so future chat-triggered generations come out
    mobile-friendly (9:16) instead of 832x480 landscape. Existing library clips
    keep whatever aspect ratio they were generated at — the player already uses
    object-fit: contain, so mixed aspect ratios render fine either way.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • Adds playCount to each library clip, incremented every time it airs
    (markPlayed). The idle-filler pick in pickNextClip now randomizes only among
    the least-played clips in the eligible pool — everyone at 0 plays first, then
    everyone tied at 1, and so on — instead of picking uniformly at random across
    the whole library, which let some clips rack up far more airtime than others
    by chance alone.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • The video autoplays muted underneath a full-screen splash — logo, play icon,
    slogan and a credit line, matching infiniteslop.ai's own splash. Clicking it
    is the user gesture that lets the browser allow unmuted playback, so desktop
    viewers land with sound instead of the silent-until-you-find-the-mute-button
    experience from the previous change. Mobile stays muted after entry, same as
    infiniteslop.ai, since unmuted autoplay-adjacent playback is unreliable there.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • Drops the muted attribute and tries an unmuted autoplay first; if the browser
    blocks unmuted autoplay (no prior user gesture on the page), falls back to
    muted playback and syncs the mute button label to match. Once a viewer
    unmutes once, later clip switches keep playing with sound.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • Reworks live.css/live.html to match infiniteslop.ai's visual language: Tahoma
    bold type, pure-black canvas, hot-pink accent, and hand-drawn white cards with
    a thick black border + hard offset shadow for every button/bubble/prompt card.
    Left queue now groups into 接下来播放/生成中/排队中 sections, the center gets a
    white "now playing" card (time + requester + prompt) plus a pulsing LIVE pill,
    chat bubbles are colored per-nickname via a pastel hash, and the top bar gained
    a chat-close toggle alongside mute and the watching count.
    
    Adds real upvoting to go with the new queue UI: POST /api/queue/vote/:id
    toggles a per-viewer (cookie uid) vote on a queued prompt, and pickNextClip
    now schedules the highest-voted matched/ready entry first instead of strict
    FIFO — lets chat bump a favorite prompt to the front of the line.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
    yibo authored
     
    Browse Code »
  • - "昵称 X ✎" button (next to the "聊天" title) replaced with a row directly
      above the chat input: hidden until a nickname is set, then shows
      "<nickname>  change name" — matches infiniteslop.ai's own placement/label
    - Nickname prompt now triggers on focusing the chat input itself, not just
      on hitting send — so a first-time visitor sees it the moment they click in
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • Previously the nickname modal only appeared implicitly on first chat send,
    with no way to see or change it afterward. Adds an always-visible "昵称 X ✎"
    button next to the chat panel title — same modal, pre-filled with the
    current nickname, keeps the existing uid when editing.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • - Cookie-based viewer identity: first chat attempt prompts for a nickname
      (inline modal, not a blocking native prompt()), generates a client-side
      uid, both persisted in cookies for 1 year
    - Right panel is now a live chat feed (username + message + status) with
      an input row below it, replacing the old bare prompt textarea
    - New POST /api/chat: runs a moderation check (banned-word blocklist —
      ponytail: starter list, not a real content policy, swap in the real one)
      before a message is allowed into the existing prompt-matching/generation
      pipeline; rejected messages still show in the chat log, just flagged
    - New GET /api/chat: recent chat history (capped at 300), polled every 3s
    - Left queue simplified to prompt + submitter name only — dropped the
      resolution/duration/date metadata that was there before
    - schedule/promptQueue now carry `requestedBy`/`nickname` through to
      /api/live/state so the left queue and "now playing" bar can show who
      asked for what
    - /api/prompt kept working (now a thin wrapper over the same
      submitPromptToQueue() the chat endpoint uses) for direct API testing
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • Inspected infiniteslop.ai's computed styles directly (fonts, colors, button
    shapes) rather than guessing from memory:
    - Pure black background, Tahoma body font (matches their retro-web feel)
    - Shrikhand display font for the logo mark, pink drop-shadow for pop
      (their black stroke doesn't read on a black background, so swapped)
    - Hot-pink accent (#ff90e8, their exact "Say" button color) for active
      tabs, the primary CTA button, and active-row/tab indicators
    - White pill buttons with bold black text for secondary controls (tabs,
      mute toggle) — matches their unmute/chat button treatment
    
    Layout structure (queue-left/player-center/input-right, mobile sub-tabs,
    no native video controls) is unchanged — this is a re-skin, not a layout
    clone, since that structure was built to this project's own requirements.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • - library.json: all 303 real entries now have casual zh/en names (prompt/promptEn)
    - ingest.js: fixed a data-loss bug where the H3 console fetch was hardcoded
      to limit=200, silently dropping older jobs (and their edited names) as new
      content pushed them out of the window; sync is now a non-destructive
      merge with a much higher fetch limit
    - ingest.js: replaced the prefix-only test-job regex with a length-gated
      word-boundary check after 5 infra smoke-test clips slipped past it
      ("test verify", "cancel test - ...", "final flip test") — no false
      positives against the 303 real entries
    - deleted the 5 stray test clips (also removed on the H3 console side)
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »
  • Static video-gen testing tool (MiniMax native API, then fal.ai) that grew
    into an AI drama live channel backed by an internal H3 Console GPU cluster:
    shared virtual-playhead live playback, prompt submit/match/generate queue,
    admin CRUD for the video library, and bilingual (zh/en) semantic clip names.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Code »