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
59 changes: 59 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Changelog

All notable **user-visible** changes to H3 Prompt Studio are documented here.
Engineering-only changes (refactors, tests, internal hardening, deployment
posture) are tracked in the dated reports under [`docs/reports/`](docs/reports/).

This project adheres to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
and uses [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Added

- **H3 camera-movement preset chips** in the generation composer — Pan left,
Pan right, Push in, Pull out, Tracking shot, and Static shot. Each chip
inserts its cue at the prompt cursor (replacing a selection, or appending at
the end before the cursor is placed) without disturbing surrounding text,
then the cue-augmented prompt is still validated through the H3 policy
(character limit, duration, ratio, media rules) before submission. Chips are
keyboard-reachable with visible focus and are disabled until every variable is
resolved. (`389ce61`, 2026-07-31)

## [1.0.0] - 2026-07-31

Initial release of H3 Prompt Studio — a self-hostable, single-user workspace
combining a versioned MiniMax H3 video-prompt library with asynchronous H3
generation jobs. Runs end-to-end with no MiniMax key in deterministic mock mode
and switches to the real server-side API when a key is configured.
(`f41af8c`, 2026-07-31)

### Added

- **Versioned prompt library** — title, description, tags, and lifecycle status;
immutable prompt versions; restore-as-new-head; duplicate; archive (never
hard-delete); full-text + tag/status search and filtering.
- **Template engine** — `{{variable}}` placeholders auto-detected into editable
forms, live render preview, and validation of missing variables and render
errors before submission.
- **H3 generation composer** — durations 4–15s, explicit non-adaptive aspect
ratios, `2K`-only resolution, and optional first-frame / last-frame /
reference-image / reference-video / reference-audio URL inputs.
- **Async, idempotent generation jobs** — requests return immediately with a
local job id; `queued → running → succeeded` (or `failed`/`expired`) states
with automatic status refresh; submissions de-duplicated by an idempotency key
(same key + different payload is a conflict).
- **Provider error translation** — provider failures mapped to useful messages
(authentication, balance, moderation, rate-limit, provider) while retaining
the request id; failed/expired jobs retryable as new jobs.
- **Auditable generation history** — each job records the immutable prompt
version, rendered prompt, parameters, provider task id, timestamps, and
outcome.
- **Two providers** — a deterministic mock (seeded sample prompts; success,
failure, expired, provider-error, and slow scenarios) and the real MiniMax H3
V2 adapter; selected by configuration with no silent fallback to mock.
- **Health endpoint** distinguishing application health from provider
configuration (a missing paid key is reported as `degraded`, not an outage).
- **Production deployment artifacts** — multi-stage Docker image, Docker
Compose, and Kubernetes manifests for namespace `jcode` with persistent
SQLite storage, probes, and non-root hardening.
201 changes: 201 additions & 0 deletions docs/reports/2026-07-31.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Release report — 2026-07-31

| Field | Value |
| ---------------- | --------------------------------------------------------------------- |
| Reporting window | 2026-07-24 → 2026-07-31 (UTC), the previous 7 days |
| Generated | 2026-07-31 (UTC) |
| Base branch | `main` |
| Window head | `389ce61` `feat: add H3 camera movement presets` |
| Scope | Default-branch commits and merged changes within the window |
| Pull requests | 2 (Ready, squash-merged): [#8](https://github.com/cnjack/minimax-video-prompt-library/pull/8), [#11](https://github.com/cnjack/minimax-video-prompt-library/pull/11) |
Comment on lines +5 to +10

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git show -s --format='%H %aI %cI %s' 7843444 f41af8c 389ce61

echo "Window ending at 2026-07-31T00:00:00Z:"
git log --since='2026-07-24T00:00:00Z' --until='2026-07-31T00:00:00Z' \
  --format='%h %cI %s' main

echo "Seven calendar dates including July 31:"
git log --since='2026-07-25T00:00:00Z' --until='2026-08-01T00:00:00Z' \
  --format='%h %cI %s' main

Repository: cnjack/minimax-video-prompt-library

Length of output: 843


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Report header and relevant sections:"
sed -n '1,25p;185,205p' docs/reports/2026-07-31.md

echo
echo "Repository refs / relevant tags or commits:"
git show-ref | rg 'HEAD|heads/main|tags/|389ce61|2026-07-31|7843444|f41af8c' || true

echo
echo "Files mentioning 2026-07-31 or window head:"
rg -n "2026-07-31|window head|389ce61|ready|squash-merged|pull/8|pull/11" .

Repository: cnjack/minimax-video-prompt-library

Length of output: 9176


Define the reporting window with the intended timestamps.

Line 5 says 2026-07-24 → 2026-07-31, but an ending timestamp of 2026-07-31T00:00:00Z would exclude the same-day committed and squash-merged changes documented on July 31. Use exact timestamps, such as 2026-07-24T00:00:00Z → 2026-07-31T23:59:59Z, or adjust the label to match the intended seven-day scope.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/reports/2026-07-31.md` around lines 5 - 10, Update the Reporting window
entry in the report to use explicit UTC timestamps that include July 31 changes,
such as a start at 2026-07-24T00:00:00Z and an end at 2026-07-31T23:59:59Z; keep
the documented seven-day scope consistent with the timestamp range.


> This is a documentation-only steward's report. It summarizes what changed and
> does not alter application behavior, dependencies, generated artifacts, or
> deployment settings. It is idempotent for the stated window: regenerating it
> against the same commits reproduces this content.

## Summary

This window contains the **initial product release** of H3 Prompt Studio plus one
follow-on feature commit. Three commits landed on `main`, all within the same
~6-hour span on 2026-07-31 (UTC):

1. The repository brief/PRD and agent profiles were seeded (`7843444`).
2. The complete H3 Prompt Studio vertical slice shipped (`f41af8c`) — the
versioned prompt library, async generation lifecycle, mock + real MiniMax
providers, tests, and production deployment artifacts.
3. The H3 camera-movement preset workflow shipped (`389ce61`), bundled with
prompt/value consistency hardening reviewed adversarially.

Delivery was mixed. The seed commit (`7843444`) was a **direct commit** to
`main`. The other two changes were delivered as **Ready pull requests** (not
draft) that were **squash-merged** to `main`: H3 Prompt Studio via
[PR #8](https://github.com/cnjack/minimax-video-prompt-library/pull/8) (→ squash
`f41af8c`, merged 2026-07-31T22:41:18Z) and the camera-movement presets via
[PR #11](https://github.com/cnjack/minimax-video-prompt-library/pull/11) (→ squash
`389ce61`, merged 2026-07-31T23:50:19Z). These PR associations come from
**GitHub**, not from commit history: squash-merge commits do not carry PR numbers
in the ordinary `git log`, so commit history alone is not an adequate SCM source
for this window.

## User-visible changes

### H3 Prompt Studio — initial release (`f41af8c`)

- **Versioned prompt library** — create prompts with title, description, tags,
and lifecycle status; immutable versions; restore-as-new-head; duplicate;
archive (never hard-delete); full-text + tag/status search and filtering.
- **Template engine** — `{{variable}}` placeholders with auto-detected,
editable variable forms, live render preview, and validation of missing
variables, blank/unresolved names, and render errors before submission.
- **H3 generation composer** — durations 4–15s, explicit **non-adaptive** aspect
ratios, `2K`-only resolution, and optional first-frame / last-frame /
reference-image / reference-video / reference-audio URL inputs.
- **Async, idempotent generation jobs** — requests return immediately with a
local job id; jobs progress through `queued → running → succeeded` (or
`failed`/`expired`) with automatic status refresh and a visible last-updated
time; submissions are de-duplicated by an idempotency key.
- **Resilient provider error handling** — provider failures are translated into
useful messages (auth, balance, moderation, rate-limit, provider) while
retaining the request id; failed/expired jobs can be retried as new jobs.
- **Auditable history** — each job records the immutable prompt version, the
rendered prompt, parameters, provider task id, timestamps, and outcome.
- **Two providers, one interface** — a deterministic mock (with seeded sample
prompts and success/failure/expired/provider-error/slow scenarios) for
key-less evaluation, and the real MiniMax H3 V2 adapter when a key is
configured (never a silent fallback).
- **Operator surface** — a health endpoint that distinguishes application health
from provider configuration (a missing paid key is `degraded`, not an outage).

### Camera-movement preset chips (`389ce61`)

- **One-click H3 camera-motion chips** in the generation composer — **Pan left,
Pan right, Push in, Pull out, Tracking shot, Static shot** — insert their cue
at the prompt cursor (replacing a selection, or appending at the end before
the cursor is placed) without disturbing surrounding text.
- Chips are **keyboard-reachable buttons** with visible focus rings and
accessible motion descriptions; they are **disabled until every variable is
resolved** (a cue in an unresolved prompt would freeze it to only the token).
- The edited prompt mirrors the live render until first touched, then becomes
the source of truth; **Reset to rendered** re-syncs it from the variables.
- The cue-augmented prompt is still validated through the existing H3 request
policy (7000-character limit, duration, ratio, media rules) before submission.

## Engineering changes

### Architecture & build (`f41af8c`)

- pnpm workspace with `shared` / `server` / `client` packages, strict TypeScript
throughout, feature-first modules, and zod runtime schemas as the contract.
- SQLite source of truth with identity (`prompts`) separated from immutable
`prompt_versions` and `generation_jobs`; migrations run on startup and via
`pnpm migrate`.
- **Provider seam** (`VideoProvider` `create`/`query`) isolating MiniMax: the
real H3 V2 adapter (multimodal `content[]`, server-side `Authorization`,
task-state and HTTP-error mapping) and the deterministic mock, tested through
a fake HTTP transport with no paid calls.
- **In-process poller** advances only non-terminal jobs with bounded
retry/backoff; the browser polls the server, never the provider.
- **Concurrency-safe idempotency** — a SQLite unique-key race resolves into
reuse or a 409, never a generic 500; the client keeps its key across transient
failures so a retry cannot create a paid duplicate.
- **Startup orphan recovery** — queued/running jobs with no recorded provider
task are moved to a recoverable `failed` state instead of spinning forever.
- **Security posture** — credentials read server-side only; no logging of
authorization headers or media payloads; inbound request-ids validated against
a bounded safe character set; external URLs validated as `http(s)`.
- **Production artifacts** — multi-stage Docker image (non-root `h3` UID/GID
`10001`), `docker-compose.yml`, and Kubernetes manifests for namespace
`jcode` (Namespace/ConfigMap/PVC/Deployment/Service, probes, `Recreate`
strategy, referenced-but-never-embedded secrets).
- Test suite covering template engine, validation, MiniMax mapping, mock
transitions, repositories, generation service/poller, the core API path, and
high-risk UI states. Verified count: **301 passing** — 84 shared, 43 client,
174 server (see the validation section below).

### Camera presets & consistency hardening (`389ce61`)

- New pure, dependency-free `packages/shared/src/cameraPresets.ts` (labels +
inserted tokens + cursor-aware `insertTokenAtSelection`), exported from the
shared contract and unit-tested.
- `CreateGenerationRequest` gained an optional `prompt` override (trimmed, capped
at `H3_MAX_PROMPT_CHARS`); the generation service **always renders/validates
the immutable version with `values` first**, then uses a non-blank override
verbatim as the final prompt text item — so unresolved variables still fail
before any job or provider call.
- Payload hash and retry now include the `prompt` override, so override-bearing
submissions de-duplicate/retry correctly.
- Composer gains a prompt/value staleness guard: once the prompt is touched, a
later variable edit is flagged and submission is blocked until **Reset to
rendered** re-syncs, preventing recorded `values` from diverging from the
generated text.

## Risks

- **Exactly-once boundary (documented, pre-existing)** — the single-instance PoC
stores a job row before submitting to the provider; if interrupted after the
provider accepted but before the task id persisted, the provider may have
started a generation the local row does not know about. Startup recovery
mitigates, but does not eliminate, this gap.
- **New prompt-override surface (`389ce61`)** — a client-authored `prompt`
override is now the generated text. Correctness depends on the new
server-side guard (always render/validate the immutable version with `values`
first, then cap the override). This is brand-new code this week and its risk
is concentrated in `generationService.ts` and the create-generation schema.
- **Single-instance polling** — no durable queue, horizontal multi-instance
polling, or webhooks; acceptable for the PoC, not for prod scale.
- **SSRF / media safety** — external media URLs are validated as `http(s)` only;
URL allowlists and server-side media ingestion are a documented extension
point, not yet implemented.
- **Mutable image tag** — the committed `:latest` Docker tag is a local
convenience; production should pin an immutable tag or digest.

## Follow-ups

- Close the exactly-once gap with a **durable outbox plus provider-side
idempotency** (the documented extension point).
- Replace the in-process poller with a **distributed queue** and add
**webhooks**; support **horizontal multi-instance** polling.
- Implement **SSRF allowlists / media scanning** before provider fetches.
- Pin a **digest/tag** for the Kubernetes Deployment instead of `:latest`.
- Revisit the **camera-preset list** if MiniMax guidance expands beyond the
current six motions, keeping the single shared module as the source of truth.
- Consider a version bump (e.g. `1.1.0`) to formally release the camera-preset
feature currently captured under `[Unreleased]` in `CHANGELOG.md`.

## Validation

This report is documentation-only; the repository's documented delivery gate was
nonetheless re-run on the window head (`389ce61`) to confirm the documented
quality bar still holds. Exact outcomes:

| Step | Command | Result |
| ----------- | ---------------------- | ------- |
| Install | `pnpm install` | ✅ ok (372 packages) |
| Lint | `pnpm lint` | ✅ pass — no warnings/errors (exit 0) |
| Type check | `pnpm typecheck` | ✅ pass — shared, server, client strict (exit 0) |
| Tests | `pnpm -r run test` | ✅ **301 passing** (shared 84, client 43, server 174), 0 failing (exit 0) |
| Prod build | `pnpm -r run build` | ✅ pass — shared + server + client (`vite build`, exit 0) |

No application behavior, dependencies, generated artifacts, or deployment
settings were changed by this report. The working-tree diff is limited to
`CHANGELOG.md` and `docs/reports/2026-07-31.md`; `dist/` and `node_modules`
remain gitignored and are not part of the diff.

## Source references

The window has **two Ready pull requests**, both squash-merged to `main`, plus
one direct seed commit. Pull-request numbers are **sourced from GitHub**, not
inferred from `git log` (squash merges do not put PR numbers in ordinary commit
history, so commit history alone is not an adequate SCM source). All three rows
are `main`-branch commits; there are no separate merge commits.

| Short | Full SHA | Author date (UTC) | Subject | Primary classification | Delivered via |
| --------- | --------------------------------------- | ------------------------ | ---------------------------------------- | ---------------------- | ------------- |
| `7843444` | `78434445211333fd593578f67775331ce5ab037e` | 2026-07-31 17:57:23 | `chore: seed Cloud dogfood product brief` | Repo scaffolding / docs | Direct commit to `main` |
| `f41af8c` | `f41af8c65b4d1662527e5ad9fab8509e28b31808` | 2026-07-31 22:41:18 | `feat: ship H3 Prompt Studio` | Initial release | Ready [PR #8](https://github.com/cnjack/minimax-video-prompt-library/pull/8), squash-merged 2026-07-31T22:41:18Z |
| `389ce61` | `389ce6115c3418458e91eb63b6ba7a9d274d39f7` | 2026-07-31 23:50:19 | `feat: add H3 camera movement presets` | Feature + hardening | Ready [PR #11](https://github.com/cnjack/minimax-video-prompt-library/pull/11), squash-merged 2026-07-31T23:50:19Z |

Author dates above are normalized to UTC from the commit's `+0800` timezone.
Report produced by the repository's release-steward process; delivery of the
branch and any pull request is owned by Cloud.