@event4u/agent-config 2.23.0 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent-src/commands/create-pr/description-only.md +39 -11
- package/.agent-src/commands/create-pr.md +59 -5
- package/.agent-src/commands/video/from-script.md +123 -0
- package/.agent-src/commands/video/scene.md +92 -0
- package/.agent-src/commands/video/stitch.md +83 -0
- package/.agent-src/commands/video/storyboard.md +95 -0
- package/.agent-src/commands/video.md +59 -0
- package/.agent-src/contexts/execution/roadmap-process-loop.md +69 -14
- package/.agent-src/personas/README.md +5 -1
- package/.agent-src/personas/ai-video-technical-director.md +81 -0
- package/.agent-src/personas/hollywood-director.md +99 -0
- package/.agent-src/profiles/content_creator.yml +5 -0
- package/.agent-src/rules/media-governance-routing.md +82 -0
- package/.agent-src/rules/persona-governance.md +90 -0
- package/.agent-src/rules/post-push-rewrite-discipline.md +70 -0
- package/.agent-src/rules/provider-lifecycle-discipline.md +75 -0
- package/.agent-src/rules/roadmap-ci-steps-policy.md +145 -0
- package/.agent-src/rules/roadmap-progress-sync.md +11 -5
- package/.agent-src/skills/character-consistency/SKILL.md +131 -0
- package/.agent-src/skills/git-workflow/SKILL.md +133 -0
- package/.agent-src/skills/motion-choreographer/SKILL.md +161 -0
- package/.agent-src/skills/pixar-storyteller/SKILL.md +120 -0
- package/.agent-src/skills/roadmap-writing/SKILL.md +10 -0
- package/.agent-src/skills/scene-expander/SKILL.md +137 -0
- package/.agent-src/skills/scene-expander/scene-blueprint.schema.yaml +108 -0
- package/.agent-src/skills/subagent-orchestration/SKILL.md +17 -15
- package/.agent-src/skills/video-director/SKILL.md +126 -0
- package/.agent-src/templates/agent-settings.md +19 -0
- package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/.agent-src/templates/roadmaps.md +16 -0
- package/.claude-plugin/marketplace.json +11 -1
- package/CHANGELOG.md +65 -0
- package/README.md +7 -5
- package/config/agent-settings.template.yml +54 -0
- package/docs/adrs/caveman/0001-default-off-until-bench.md +2 -2
- package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +2 -2
- package/docs/architecture.md +3 -3
- package/docs/catalog.md +18 -5
- package/docs/contracts/command-clusters.md +1 -0
- package/docs/contracts/compression-default-kill-criterion.md +1 -1
- package/docs/contracts/file-ownership-matrix.json +405 -0
- package/docs/contracts/provider-lifecycle.md +122 -0
- package/docs/decisions/ADR-011-domain-pack-readiness.md +213 -0
- package/docs/decisions/INDEX.md +1 -0
- package/docs/getting-started-by-role.md +10 -0
- package/docs/getting-started.md +2 -2
- package/docs/parity/ruflo.md +3 -3
- package/docs/personas.md +73 -26
- package/docs/profiles.md +9 -4
- package/package.json +1 -1
- package/scripts/_tmp_scan_framework_leakage.py +119 -0
- package/scripts/ai-video/adapters/gemini-veo.sh +62 -0
- package/scripts/ai-video/adapters/higgsfield.sh +88 -0
- package/scripts/ai-video/adapters/kling.sh +59 -0
- package/scripts/ai-video/adapters/openai-images.sh +57 -0
- package/scripts/ai-video/adapters/sora.sh +60 -0
- package/scripts/ai-video/lib/adapter-common.sh +116 -0
- package/scripts/ai-video/lib/adapter-contract.md +163 -0
- package/scripts/ai-video/lib/fixtures/gemini-veo/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/gemini-veo/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/fixtures/higgsfield/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/higgsfield/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/fixtures/kling/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/kling/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/fixtures/openai-images/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/openai-images/scene-0001.png +3 -0
- package/scripts/ai-video/lib/fixtures/sora/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/sora/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/load-config.sh +140 -0
- package/scripts/ai-video/lib/operator-pick.sh +119 -0
- package/scripts/ai-video/lib/parse-blueprint.sh +122 -0
- package/scripts/ai-video/lib/redact.sh +85 -0
- package/scripts/ai-video/lib/validate-deps.sh +132 -0
- package/scripts/ai-video/stitch.sh +154 -0
- package/scripts/ai-video/test-pipeline.sh +169 -0
- package/scripts/check_portability.py +6 -0
- package/scripts/lint_media_policy_linkage.py +140 -0
- package/scripts/lint_persona_governance.py +164 -0
- package/scripts/lint_roadmap_ci_steps.py +182 -0
- package/scripts/schemas/command.schema.json +8 -0
- package/scripts/smoke/schema.sh +1 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "auto"
|
|
3
|
+
tier: "2a"
|
|
4
|
+
description: "When authoring or executing roadmaps — forbid task ci / make test / npm run check steps when quality.local_auto_run is false; skip inline at execution"
|
|
5
|
+
source: package
|
|
6
|
+
triggers:
|
|
7
|
+
- path_prefix: "agents/roadmaps/"
|
|
8
|
+
- path_prefix: "app/Modules/"
|
|
9
|
+
- keyword: "task ci"
|
|
10
|
+
- keyword: "make test"
|
|
11
|
+
- keyword: "npm run check"
|
|
12
|
+
- keyword: "pnpm run check"
|
|
13
|
+
- keyword: "yarn check"
|
|
14
|
+
- keyword: "composer test"
|
|
15
|
+
- phrase: "run the quality pipeline"
|
|
16
|
+
- phrase: "run task ci"
|
|
17
|
+
- phrase: "run the full ci"
|
|
18
|
+
applies_to_user_types:
|
|
19
|
+
- "maintainer"
|
|
20
|
+
- "developer"
|
|
21
|
+
validator_ignore:
|
|
22
|
+
- type: "substring"
|
|
23
|
+
pattern: "agents/roadmaps/"
|
|
24
|
+
reason: "Rule's subject is roadmap files under agents/roadmaps/; every body link points there by design."
|
|
25
|
+
- type: "substring"
|
|
26
|
+
pattern: ".agent-settings.yml"
|
|
27
|
+
reason: "Rule reads quality.local_auto_run from .agent-settings.yml; naming the file is the contract."
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# Roadmap CI-Steps Policy
|
|
31
|
+
|
|
32
|
+
## Iron Law
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
WHEN quality.local_auto_run IS FALSE,
|
|
36
|
+
ROADMAPS MUST NOT SCHEDULE FULL-PIPELINE CI STEPS,
|
|
37
|
+
AND EXECUTION MUST SKIP THEM INLINE WITH [-] AND A REASON.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
When `quality.local_auto_run: false` in `.agent-settings.yml`, every
|
|
41
|
+
full-pipeline gate run during roadmap work is wasted wall-clock and
|
|
42
|
+
tokens — remote CI on the PR is the authoritative gate. Roadmaps
|
|
43
|
+
must neither schedule nor execute them locally. New CI gates and
|
|
44
|
+
smoke/test files added by the roadmap itself are exempt — they must
|
|
45
|
+
run once locally to count as verified evidence per
|
|
46
|
+
[`verify-before-complete`](verify-before-complete.md).
|
|
47
|
+
|
|
48
|
+
## Forbidden step patterns (authoring + execution)
|
|
49
|
+
|
|
50
|
+
A step is **CI-shaped** when its text matches any pattern below.
|
|
51
|
+
Case-insensitive. Line-bounded — literal must appear inside the
|
|
52
|
+
step's `- [ ]` line or its immediate inline `<!-- … -->` / `(…)` note.
|
|
53
|
+
|
|
54
|
+
| Pattern | Example |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `task ci` | `Run task ci before the boundary` |
|
|
57
|
+
| `task ci-strict` | `task ci-strict release gate` |
|
|
58
|
+
| `task ci-fast` | `task ci-fast smoke` |
|
|
59
|
+
| `make test` | `Run make test on phase boundary` |
|
|
60
|
+
| `make ci` | `make ci pre-merge` |
|
|
61
|
+
| `npm run check` / `pnpm run check` / `yarn check` | `npm run check before commit` |
|
|
62
|
+
| `composer test` | `composer test on every phase` |
|
|
63
|
+
| `vendor/bin/phpunit` (whole-suite, no path arg) | `vendor/bin/phpunit` |
|
|
64
|
+
| `php artisan test` (no `--filter`) | `php artisan test` |
|
|
65
|
+
|
|
66
|
+
Targeted commands (`vendor/bin/phpstan analyse app/Modules/X`,
|
|
67
|
+
`php artisan test --filter=…`, `npm run lint -- --fix path/`) are
|
|
68
|
+
**not** CI-shaped — narrow verifications, allowed regardless of the
|
|
69
|
+
setting.
|
|
70
|
+
|
|
71
|
+
## Carve-outs — when CI-shaped steps are still allowed
|
|
72
|
+
|
|
73
|
+
1. **New CI gate / smoke test / test file landed by this roadmap.**
|
|
74
|
+
Once-locally execution is mandatory under
|
|
75
|
+
[`verify-before-complete`](verify-before-complete.md) carve-out
|
|
76
|
+
(see `templates/agent-settings.md` § `quality.local_auto_run`).
|
|
77
|
+
Mark the step with `<!-- carve-out: new-gate-verification -->`
|
|
78
|
+
on the same line; linter and execution loop honour it and let the
|
|
79
|
+
step run.
|
|
80
|
+
2. **`quality.local_auto_run: true`.** Opt-in restores pre-policy
|
|
81
|
+
behaviour — linter no-ops, execution loop runs CI steps unmodified.
|
|
82
|
+
3. **Acceptance-criteria block at end of roadmap.** Final-gate prose
|
|
83
|
+
like "All quality gates pass (`task ci`)" inside an
|
|
84
|
+
`## Acceptance criteria` section is documentation, not an
|
|
85
|
+
executable step (no `- [ ]` checkbox in front). Linter ignores;
|
|
86
|
+
execution loop never reaches it as a step.
|
|
87
|
+
|
|
88
|
+
## Authoring — linter blocks at write-time
|
|
89
|
+
|
|
90
|
+
`task lint-roadmap-ci-steps` (wired into `task ci-fast` /
|
|
91
|
+
`lint-roadmap-complexity` cadence) scans `agents/roadmaps/*.md` and
|
|
92
|
+
`app/Modules/*/agents/roadmaps/*.md`. Exit code:
|
|
93
|
+
|
|
94
|
+
- `0` — no CI-shaped steps, or setting is `true`, or every match is
|
|
95
|
+
carve-out-marked.
|
|
96
|
+
- `1` — at least one CI-shaped step in an active (non-archived,
|
|
97
|
+
non-skipped) roadmap with `quality.local_auto_run: false` and no
|
|
98
|
+
carve-out marker. Linter prints file, line, matched literal, and
|
|
99
|
+
suggested rewording.
|
|
100
|
+
|
|
101
|
+
Archive (`agents/roadmaps/archive/`) and skipped
|
|
102
|
+
(`agents/roadmaps/skipped/`) are out of scope — they record history,
|
|
103
|
+
not future work.
|
|
104
|
+
|
|
105
|
+
## Execution — process-loop skips inline
|
|
106
|
+
|
|
107
|
+
Wrappers `/roadmap:process-step|phase|full` honour the policy at the
|
|
108
|
+
top of [`roadmap-process-loop § 5`](../contexts/execution/roadmap-process-loop.md#5-step-loop):
|
|
109
|
+
|
|
110
|
+
1. Before running a step, match its text against the patterns above.
|
|
111
|
+
2. CI-shaped **and** `quality.local_auto_run: false` **and** no
|
|
112
|
+
carve-out marker → flip checkbox to `[-]` (cancelled), append a
|
|
113
|
+
one-line reason as inline note, regenerate the dashboard, continue
|
|
114
|
+
to next step. **Never** run the gate.
|
|
115
|
+
3. CI-shaped **and** `quality.local_auto_run: true` → run normally.
|
|
116
|
+
4. Carve-out-marked → run regardless of the setting.
|
|
117
|
+
|
|
118
|
+
The `[-]` reason format is fixed:
|
|
119
|
+
`<!-- skipped: quality.local_auto_run=false → remote CI is the gate -->`.
|
|
120
|
+
Per [`roadmap-progress-sync`](roadmap-progress-sync.md) the flip and
|
|
121
|
+
dashboard regen happen in the **same reply** that decides to skip;
|
|
122
|
+
saving skips for the archive commit is a rule violation.
|
|
123
|
+
|
|
124
|
+
## Failure modes
|
|
125
|
+
|
|
126
|
+
- Authoring `- [ ] Run task ci` while `local_auto_run: false` — linter
|
|
127
|
+
fails the PR.
|
|
128
|
+
- Executing a CI-shaped step without inline-skip flip — Iron Law
|
|
129
|
+
violation; loop never reaches the gate.
|
|
130
|
+
- Carve-out marker on an *existing* pipeline run — abuse; the marker
|
|
131
|
+
is reserved for **new** gates introduced by the same roadmap.
|
|
132
|
+
- Hiding the literal inside a fenced bash block to dodge the linter —
|
|
133
|
+
linter matches inside fenced blocks too (see
|
|
134
|
+
`scripts/lint_roadmap_ci_steps.py`).
|
|
135
|
+
|
|
136
|
+
## See also
|
|
137
|
+
|
|
138
|
+
- [`verify-before-complete`](verify-before-complete.md) — Iron Law
|
|
139
|
+
this rule narrows; carve-out cites it.
|
|
140
|
+
- [`roadmap-progress-sync`](roadmap-progress-sync.md) — inline flip +
|
|
141
|
+
dashboard regen contract.
|
|
142
|
+
- `templates/agent-settings.md` § `quality.local_auto_run` — source
|
|
143
|
+
of the toggle and its carve-out wording.
|
|
144
|
+
- [`contexts/execution/roadmap-process-loop`](../contexts/execution/roadmap-process-loop.md)
|
|
145
|
+
— § 5 owns the inline-skip mechanics.
|
|
@@ -25,16 +25,17 @@ Roadmap touch = create / rename / delete / move file, add/rename/remove a phase,
|
|
|
25
25
|
```
|
|
26
26
|
EVERY DONE STEP FLIPS [ ] → [x] IN THE SAME REPLY THAT LANDS THE WORK.
|
|
27
27
|
NO "I UPDATE THE ROADMAP AT THE END OF THE PHASE."
|
|
28
|
-
NO "FOUR STEPS DONE, ONE COMMIT, ONE REGEN."
|
|
29
28
|
A REPLY THAT LANDS A VERIFIED STEP WITHOUT FLIPPING ITS CHECKBOX
|
|
30
29
|
IS A RULE VIOLATION, NOT AN OVERSIGHT.
|
|
31
30
|
```
|
|
32
31
|
|
|
33
|
-
`/roadmap:process-step`, `/roadmap:process-phase`, `/roadmap:process-full`, and any other multi-step autonomous run flip the box for step N **before** moving on to step N+1. The
|
|
32
|
+
`/roadmap:process-step`, `/roadmap:process-phase`, `/roadmap:process-full`, and any other multi-step autonomous run flip the box for step N **before** moving on to step N+1. The checkbox itself is the real-time monitor — the markdown file is the source of truth, the dashboard is a derived view.
|
|
34
33
|
|
|
35
34
|
**Step counts as done** when its code/doc change is written and saved AND the verification cited in the step has passed (fresh output in this reply or an earlier one).
|
|
36
35
|
|
|
37
|
-
**In-progress marker.** When a step takes more than one reply, mark it `[~]` the moment work starts
|
|
36
|
+
**In-progress marker.** When a step takes more than one reply, mark it `[~]` the moment work starts — the user sees one row move `[ ] → [~] → [x]` instead of silent rows. `[~]` stays open for `count_open` but advances the phase percentage.
|
|
37
|
+
|
|
38
|
+
**Dashboard regen cadence — opt-in batching.** The checkbox flip is non-batchable. The **subprocess regen** (`./agent-config roadmap:progress`) is batchable per `roadmap.dashboard_regen_cadence` in `.agent-settings.yml` (`per_step` default · `every_5_steps` · `phase_boundary`). Run end, phase boundary, and any file-shape touch (rename / phase add / archive — Iron Law 1) always force an immediate regen regardless of cadence.
|
|
38
39
|
|
|
39
40
|
## Pre-send self-check — MANDATORY
|
|
40
41
|
|
|
@@ -42,10 +43,15 @@ Before sending any reply that landed roadmap work:
|
|
|
42
43
|
|
|
43
44
|
1. Did this reply land a step (code/doc saved + verification passed)?
|
|
44
45
|
2. Is its checkbox flipped to `[x]` / `[~]` / `[-]` in `agents/roadmaps/<file>.md`? If no → flip, then continue.
|
|
45
|
-
3.
|
|
46
|
+
3. Is regen due now per `roadmap.dashboard_regen_cadence`?
|
|
47
|
+
- `per_step` → yes, always.
|
|
48
|
+
- `every_5_steps` → yes when this is the 5th, 10th, … closed step in the run, or the last step of the reply.
|
|
49
|
+
- `phase_boundary` → only when this reply closes the phase or run.
|
|
50
|
+
- Any file-shape touch (rename / phase add / archive) → yes, regardless of cadence.
|
|
51
|
+
If yes and not run yet → run `./agent-config roadmap:progress`, then continue.
|
|
46
52
|
4. Did `count_open` reach 0? If yes → `git mv` to `archive/` and regen again — same reply.
|
|
47
53
|
|
|
48
|
-
Any "no" at step 2
|
|
54
|
+
Any "no" at step 2 → reply is incomplete. Do not send. A skipped step 3 regen is fine when cadence permits — checkbox truth lives in the markdown file.
|
|
49
55
|
|
|
50
56
|
Long-form mechanics (failure-mode catalog, Copilot fallback, `[~]` vs `[ ]` semantics, hook + CI defence-in-depth) live in `guideline:agent-infra/roadmap-progress-mechanics`.
|
|
51
57
|
Trigger-set above activates this routing under the `balanced` and `full` profiles.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: character-consistency
|
|
3
|
+
description: "Use when a character must stay visually identical across AI video scenes — locks identity tokens (silhouette, palette, wardrobe, prop) in JSON. Triggers 'character lock', 'same character'."
|
|
4
|
+
personas:
|
|
5
|
+
- hollywood-director
|
|
6
|
+
source: package
|
|
7
|
+
domain: product
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# character-consistency
|
|
11
|
+
|
|
12
|
+
> Lock a character's visual identity into
|
|
13
|
+
> `agents/ai-video/<project>/characters/<id>.json` so every scene
|
|
14
|
+
> reuses the **exact same tokens** verbatim. Downstream skills
|
|
15
|
+
> ([`video-director`](../video-director/SKILL.md),
|
|
16
|
+
> [`pixar-storyteller`](../pixar-storyteller/SKILL.md),
|
|
17
|
+
> [`motion-choreographer`](../motion-choreographer/SKILL.md)) read
|
|
18
|
+
> this file and never paraphrase. Verified by visual regression
|
|
19
|
+
> (pixel similarity ≥ 95%, Phase 6 Step 3).
|
|
20
|
+
|
|
21
|
+
## When to use
|
|
22
|
+
|
|
23
|
+
- A multi-scene run names the same character on screen more than
|
|
24
|
+
once — Character Lock is mandatory before the second scene drafts.
|
|
25
|
+
- A character drift bug landed (face / outfit / prop changed between
|
|
26
|
+
scenes) — re-lock and rerun the affected scenes.
|
|
27
|
+
- A series, episode, or recurring ad uses the same on-screen identity.
|
|
28
|
+
|
|
29
|
+
Do NOT use when:
|
|
30
|
+
|
|
31
|
+
- One-shot scene with no recurring character — overhead is wasted.
|
|
32
|
+
- The "character" is an object or environment, not a person /
|
|
33
|
+
creature — use a `style.json` lock pattern in the project's notes
|
|
34
|
+
instead.
|
|
35
|
+
|
|
36
|
+
## Procedure
|
|
37
|
+
|
|
38
|
+
### Step 0: Inspect
|
|
39
|
+
|
|
40
|
+
1. Check `agents/ai-video/<project>/characters/` — if a lock already
|
|
41
|
+
exists for this id, **read it, do not redraft**. Edits require an
|
|
42
|
+
explicit revision note (Phase 6 visual regression must rerun).
|
|
43
|
+
2. Confirm the character will appear in ≥ 2 scenes; one-shot → skip.
|
|
44
|
+
|
|
45
|
+
### Step 1: Draft identity tokens
|
|
46
|
+
|
|
47
|
+
Emit a JSON file at
|
|
48
|
+
`agents/ai-video/<project>/characters/<character-id>.json` with the
|
|
49
|
+
following fields. Every field is mandatory; missing field → fail
|
|
50
|
+
the lock.
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"id": "kebab-case-id",
|
|
55
|
+
"name": "Display Name",
|
|
56
|
+
"silhouette": "one-line read of the body shape from 30m",
|
|
57
|
+
"palette": ["#hex1", "#hex2", "#hex3"],
|
|
58
|
+
"wardrobe": "garment list, materials, era",
|
|
59
|
+
"signature_prop": "the one object that travels with them",
|
|
60
|
+
"posture_default": "how they stand when not acting",
|
|
61
|
+
"eye_behavior": "blink rhythm, glance habit",
|
|
62
|
+
"face": "age band, skin tone, hair (length / color / texture), distinguishing marks",
|
|
63
|
+
"voice_note": "timbre + cadence for native-audio adapters; null if N/A",
|
|
64
|
+
"reference_frame": "scenes/<id>/frames/<n>.png or null",
|
|
65
|
+
"version": 1
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Step 2: Reference frame
|
|
70
|
+
|
|
71
|
+
1. After the first scene renders, copy the highest-quality frame
|
|
72
|
+
showing the character full-face and full-body to
|
|
73
|
+
`agents/ai-video/<project>/characters/<id>.ref.png`.
|
|
74
|
+
2. Update `reference_frame` in the JSON to point at it.
|
|
75
|
+
3. Phase 6 visual regression compares every subsequent scene's
|
|
76
|
+
character frame against this reference (ImageMagick `compare`
|
|
77
|
+
≥ 95% similarity).
|
|
78
|
+
|
|
79
|
+
### Step 3: Validate
|
|
80
|
+
|
|
81
|
+
1. JSON parses (`jq . characters/<id>.json` exits 0).
|
|
82
|
+
2. All mandatory fields present and non-empty.
|
|
83
|
+
3. Palette has ≥ 2 and ≤ 5 hex values.
|
|
84
|
+
4. Downstream skills cite this file by path, never paraphrase its
|
|
85
|
+
contents.
|
|
86
|
+
|
|
87
|
+
## Output format
|
|
88
|
+
|
|
89
|
+
1. **`agents/ai-video/<project>/characters/<id>.json`** — locked
|
|
90
|
+
identity tokens, schema above.
|
|
91
|
+
2. **`agents/ai-video/<project>/characters/<id>.ref.png`** —
|
|
92
|
+
reference frame (added after first render).
|
|
93
|
+
3. **`agents/ai-video/<project>/characters/CHANGELOG.md`** — one
|
|
94
|
+
line per revision: `v<n> · YYYY-MM-DD · reason · scenes-to-rerun`.
|
|
95
|
+
|
|
96
|
+
## Gotcha
|
|
97
|
+
|
|
98
|
+
- The model wants to "improve" identity tokens on each scene —
|
|
99
|
+
this is the silent drift failure. Tokens are immutable until a
|
|
100
|
+
revision note bumps `version`.
|
|
101
|
+
- Palette without a count fails downstream — adapters need a small
|
|
102
|
+
closed set (2–5 hex).
|
|
103
|
+
- `voice_note: null` is explicit; missing the key entirely breaks
|
|
104
|
+
the schema validator.
|
|
105
|
+
- Reference frame is captured *after* the first successful render,
|
|
106
|
+
not before — bootstrap scenes have no reference and only the
|
|
107
|
+
JSON locks them.
|
|
108
|
+
- A revision (`version` bumped) requires Phase 6 visual regression
|
|
109
|
+
to rerun against every prior scene that used the old version.
|
|
110
|
+
|
|
111
|
+
## Do NOT
|
|
112
|
+
|
|
113
|
+
- Do NOT paraphrase identity tokens when drafting scene prompts —
|
|
114
|
+
copy verbatim or break the lock.
|
|
115
|
+
- Do NOT edit a locked JSON in place without bumping `version` and
|
|
116
|
+
adding a CHANGELOG line.
|
|
117
|
+
- Do NOT skip the reference frame after the first render — visual
|
|
118
|
+
regression has nothing to compare against.
|
|
119
|
+
- Do NOT lock a character that appears in only one scene.
|
|
120
|
+
|
|
121
|
+
## Policies
|
|
122
|
+
|
|
123
|
+
When a character lock would identify or render a real person, consult before emitting the JSON:
|
|
124
|
+
|
|
125
|
+
- [`agents/policies/media/likeness.md`](../../../agents/policies/media/likeness.md) — real-person identity tokens require a cited likeness release.
|
|
126
|
+
- [`agents/policies/media/public-figures.md`](../../../agents/policies/media/public-figures.md) — recognised public figures carry the harder gate (publicity rights + transformative-intent).
|
|
127
|
+
- [`agents/policies/media/voice-cloning.md`](../../../agents/policies/media/voice-cloning.md) — when `voice_note` references a real person's voice.
|
|
128
|
+
- [`agents/policies/media/disclosure.md`](../../../agents/policies/media/disclosure.md) — outputs carrying a real-person lock require the non-removable AI-generation disclosure downstream.
|
|
129
|
+
|
|
130
|
+
Refuse-and-surface the file path; do not silently sanitise the prompt.
|
|
131
|
+
|
|
@@ -77,6 +77,139 @@ The project uses `.github/pull_request_template.md`:
|
|
|
77
77
|
- `main` is default/production branch.
|
|
78
78
|
- Merge strategy: merge commits (not squash).
|
|
79
79
|
|
|
80
|
+
## Procedure: Safe squash-after-push
|
|
81
|
+
|
|
82
|
+
Use ONLY when the user explicitly authorized a squash on a branch that
|
|
83
|
+
is already on origin. The whole sequence runs in **one turn** — never
|
|
84
|
+
end the session between rewrite and push.
|
|
85
|
+
|
|
86
|
+
Trigger context: `post-push-rewrite-discipline` rule routed here.
|
|
87
|
+
|
|
88
|
+
### 1. Snapshot before touching anything
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
BRANCH=$(git branch --show-current)
|
|
92
|
+
DATE=$(date +%F)
|
|
93
|
+
git fetch origin
|
|
94
|
+
git tag "safe-squash-pre/${BRANCH}/${DATE}" HEAD
|
|
95
|
+
git tag "safe-squash-origin/${BRANCH}/${DATE}" "@{u}"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Two tags = two recoveries (local tip + origin tip). Do not skip the
|
|
99
|
+
tags — `git reflog` is TTL-bounded and unreliable across sessions.
|
|
100
|
+
|
|
101
|
+
### 2. Verify aligned starting state
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
git rev-list --left-right --count HEAD...@{u}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- `0 0` → aligned, proceed.
|
|
108
|
+
- `N 0` (local ahead) → unpushed work, proceed.
|
|
109
|
+
- `0 N` (origin ahead) → `git pull --ff-only` first, then re-check.
|
|
110
|
+
- `M N` (both non-zero) → **divergent**. Abandon the squash and run
|
|
111
|
+
§ Divergent-State Recovery below.
|
|
112
|
+
|
|
113
|
+
### 3. Perform the squash
|
|
114
|
+
|
|
115
|
+
Default — soft-reset path (single token-cheap rewrite):
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
git reset --soft "$(git merge-base HEAD <base>)"
|
|
119
|
+
git commit -m "<conventional commit message>"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Interactive rebase only when the user wants per-commit control — it
|
|
123
|
+
replays derived files (`.compression-hashes.json`, router projections)
|
|
124
|
+
per commit and conflicts on every replay.
|
|
125
|
+
|
|
126
|
+
### 4. Re-push in the SAME turn
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
FETCHED_SHA=$(git rev-parse "@{u}")
|
|
130
|
+
git push --force-with-lease="${BRANCH}:${FETCHED_SHA}" origin "${BRANCH}"
|
|
131
|
+
git fetch origin
|
|
132
|
+
[ "$(git rev-parse HEAD)" = "$(git rev-parse @{u})" ] \
|
|
133
|
+
&& echo "OK: origin matches HEAD" \
|
|
134
|
+
|| echo "MISMATCH — do not end session"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
If the push fails (pre-push hook, network, token budget):
|
|
138
|
+
- Fix the underlying cause **now**.
|
|
139
|
+
- Re-push immediately.
|
|
140
|
+
- Do not commit new work on top of the squashed-but-unpushed tip.
|
|
141
|
+
- Do not end the session until `HEAD == @{u}`.
|
|
142
|
+
|
|
143
|
+
### 5. Hand off only with verified parity
|
|
144
|
+
|
|
145
|
+
Report exactly:
|
|
146
|
+
- pre-squash tip SHA (from step 1)
|
|
147
|
+
- pre-squash tag name (for recovery)
|
|
148
|
+
- post-squash tip SHA == origin SHA (verified in step 4)
|
|
149
|
+
- PR number, if any, and confirm it picked up the new tip
|
|
150
|
+
|
|
151
|
+
## Procedure: Divergent-State Recovery
|
|
152
|
+
|
|
153
|
+
Fires when `git rev-list --left-right --count HEAD...@{u}` shows
|
|
154
|
+
**both** sides non-zero on the current branch.
|
|
155
|
+
|
|
156
|
+
### 1. Stop. Do not pull.
|
|
157
|
+
|
|
158
|
+
A blind `git pull --rebase` here replays remote commits on top of a
|
|
159
|
+
local history that may already represent the same work in a different
|
|
160
|
+
shape — guaranteed conflict storm in derived files, possible
|
|
161
|
+
double-application of the same change. This is the documented failure
|
|
162
|
+
mode behind `post-push-rewrite-discipline`.
|
|
163
|
+
|
|
164
|
+
### 2. Tag both sides immediately
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
TS=$(date +%FT%H%M)
|
|
168
|
+
git tag "diverged-local/${TS}" HEAD
|
|
169
|
+
git tag "diverged-origin/${TS}" "@{u}"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 3. Diagnose: which side is the correct future?
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
git log --oneline @{u}..HEAD # local-only commits
|
|
176
|
+
git log --oneline HEAD..@{u} # origin-only commits
|
|
177
|
+
git diff @{u}..HEAD --stat # shape of local-ahead work
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Decision matrix:
|
|
181
|
+
|
|
182
|
+
| Pattern | Future | Action |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| Local has the same logical work as origin, just reshaped (squash/rebase) | **Local** | After PR-review check (step 4), `git push --force-with-lease=<branch>:<origin-sha>` |
|
|
185
|
+
| Origin has commits local does not reflect (another contributor pushed) | **Origin** | Tag any local-ahead work for cherry-pick, then `git reset --hard @{u}` |
|
|
186
|
+
| Both sides have genuine independent work | **ask user** | Never decide silently — surface the two commit lists and let the user pick |
|
|
187
|
+
|
|
188
|
+
### 4. PR review-comment check (mandatory before any force-push)
|
|
189
|
+
|
|
190
|
+
If a PR is open on this branch:
|
|
191
|
+
```bash
|
|
192
|
+
gh pr view --json reviews,comments
|
|
193
|
+
# or via GitHub API: /repos/<owner>/<repo>/pulls/<num>/{reviews,comments}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
If review comments are anchored to commits that the force-push will
|
|
197
|
+
erase → STOP, ask the user how to preserve them. A force-push that
|
|
198
|
+
destroys live review feedback is unrecoverable from the agent side.
|
|
199
|
+
|
|
200
|
+
### 5. Recover or proceed
|
|
201
|
+
|
|
202
|
+
Use the tags from step 2 to restore either side if step 4 surfaces a
|
|
203
|
+
problem. After resolution, verify `HEAD == @{u}` and report both
|
|
204
|
+
SHAs plus the tags created.
|
|
205
|
+
|
|
206
|
+
## Hard prohibitions on a pushed branch
|
|
207
|
+
|
|
208
|
+
- No `git pull --rebase` after detecting divergent state.
|
|
209
|
+
- No `git push --force` without `--force-with-lease=<branch>:<sha>`.
|
|
210
|
+
- No squash-then-end-session — the push must complete in the same turn.
|
|
211
|
+
- No reflog-only recovery — always tag the state explicitly first.
|
|
212
|
+
|
|
80
213
|
## Output format
|
|
81
214
|
|
|
82
215
|
1. Commits following conventional commit format
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: motion-choreographer
|
|
3
|
+
description: "Use when turning a locked still + blueprint into a provider-tuned motion prompt — camera, primary + secondary motion, physics, native-audio sync. Triggers 'motion prompt for Veo/Kling/Sora'."
|
|
4
|
+
personas:
|
|
5
|
+
- ai-video-technical-director
|
|
6
|
+
source: package
|
|
7
|
+
domain: product
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# motion-choreographer
|
|
11
|
+
|
|
12
|
+
> Turn an approved still + the 12-block scene blueprint into a
|
|
13
|
+
> provider-tuned **motion prompt** that the target video adapter
|
|
14
|
+
> consumes. Camera choreography, primary subject motion, secondary
|
|
15
|
+
> environment motion, physics constraints, and — when the adapter
|
|
16
|
+
> declares `audio: native` — a synchronized audio direction block.
|
|
17
|
+
> Reads adapter capabilities from
|
|
18
|
+
> [`adapter-contract.md`](../../../scripts/ai-video/lib/adapter-contract.md);
|
|
19
|
+
> never speaks to a network API.
|
|
20
|
+
|
|
21
|
+
## When to use
|
|
22
|
+
|
|
23
|
+
- An image is locked (operator picked one candidate via
|
|
24
|
+
`operator-pick.sh`) and the next step is motion + audio direction
|
|
25
|
+
for the video adapter.
|
|
26
|
+
- The blueprint exists in `scenes/<id>/blueprint.json` but the
|
|
27
|
+
motion prompt has not been emitted yet.
|
|
28
|
+
- A provider switch (Veo → Kling, Sora → Higgsfield) requires the
|
|
29
|
+
same scene retuned for the new adapter's capability profile.
|
|
30
|
+
|
|
31
|
+
Do NOT use when:
|
|
32
|
+
|
|
33
|
+
- The blueprint is still prose only — run
|
|
34
|
+
[`scene-expander`](../scene-expander/SKILL.md) → `parse-blueprint.sh`
|
|
35
|
+
first.
|
|
36
|
+
- No still has been locked — the operator-selection checkpoint
|
|
37
|
+
must complete first.
|
|
38
|
+
- The output is a still graphic — `canvas-design`.
|
|
39
|
+
|
|
40
|
+
## Procedure
|
|
41
|
+
|
|
42
|
+
### Step 0: Inspect
|
|
43
|
+
|
|
44
|
+
1. Read `scenes/<id>/blueprint.json` — fail loud if missing.
|
|
45
|
+
2. Read `scenes/<id>/selection.json` — fail loud if missing; the
|
|
46
|
+
locked image path is required as the motion anchor.
|
|
47
|
+
3. Read the target adapter's capability via
|
|
48
|
+
`scripts/ai-video/adapters/<id>.sh capability`. Cache `audio=*`
|
|
49
|
+
for Step 3.
|
|
50
|
+
4. If a `character.json` lock exists, load it verbatim — identity
|
|
51
|
+
tokens are immutable.
|
|
52
|
+
|
|
53
|
+
### Step 1: Camera choreography
|
|
54
|
+
|
|
55
|
+
Emit a `CAMERA MOTION` block with the move type, distance, speed
|
|
56
|
+
in seconds, and start-end framing.
|
|
57
|
+
|
|
58
|
+
- Move types: lock-off, pan, tilt, dolly-in, dolly-out, truck,
|
|
59
|
+
pedestal, push, pull, handheld, gimbal-glide, crane, whip.
|
|
60
|
+
- Speed in seconds per beat (`0.4s push, hold 1.6s, 0.4s pull`).
|
|
61
|
+
- Start and end framing named (`MS → CU`, `WS → MS`).
|
|
62
|
+
|
|
63
|
+
Adapter quirks:
|
|
64
|
+
|
|
65
|
+
- **Veo** — accepts named moves; prefers ≤ 8s clips.
|
|
66
|
+
- **Kling** — motion intensity 0–1 token; map our speed to that.
|
|
67
|
+
- **Sora** — natural-language move + duration; no token.
|
|
68
|
+
- **Higgsfield** — preset-driven; pick the preset that matches the
|
|
69
|
+
move; record the preset id in the motion prompt.
|
|
70
|
+
|
|
71
|
+
### Step 2: Primary + secondary motion
|
|
72
|
+
|
|
73
|
+
Two blocks:
|
|
74
|
+
|
|
75
|
+
1. **PRIMARY MOTION** — what the subject does, beat-counted, with
|
|
76
|
+
physics anchors (mass, contact points, momentum). Reuse `ACTION`
|
|
77
|
+
from the blueprint; refine for the adapter's preferred verb
|
|
78
|
+
density.
|
|
79
|
+
2. **SECONDARY MOTION** — what the world does (hair, fabric,
|
|
80
|
+
foliage, water, dust, particles, breath). One layer per line.
|
|
81
|
+
|
|
82
|
+
### Step 3: Audio direction (conditional)
|
|
83
|
+
|
|
84
|
+
If adapter capability is `audio: native` AND the blueprint's
|
|
85
|
+
`audio.enable_native_audio` is `true`:
|
|
86
|
+
|
|
87
|
+
Emit an `AUDIO DIRECTION` block with:
|
|
88
|
+
|
|
89
|
+
- `DIALOGUE TIMING` — `speaker @ 0.4s: "line"` per dialogue entry.
|
|
90
|
+
- `AMBIENT LAYERS` — copy from blueprint; one layer per line.
|
|
91
|
+
- `SYNC CUES` — which action beat maps to which audio cue
|
|
92
|
+
(`footstep @ 1.2s`, `door close @ 2.1s`).
|
|
93
|
+
|
|
94
|
+
If adapter capability is `audio: none`:
|
|
95
|
+
|
|
96
|
+
- Emit a `# AUDIO: ffmpeg-mux fallback` comment with the
|
|
97
|
+
blueprint's audio paths queued for stitch-time mux.
|
|
98
|
+
- Set `enable_native_audio: false` in the motion-prompt JSON.
|
|
99
|
+
|
|
100
|
+
### Step 4: Physics constraints
|
|
101
|
+
|
|
102
|
+
Emit `PHYSICS` — a short list of what the model must respect:
|
|
103
|
+
gravity direction, contact friction, fluid behavior, hair / cloth
|
|
104
|
+
inertia, lens parallax. Single line per constraint.
|
|
105
|
+
|
|
106
|
+
### Step 5: Emit motion-prompt JSON
|
|
107
|
+
|
|
108
|
+
Write `scenes/<id>/motion-prompt.json` with the adapter-contract
|
|
109
|
+
stdin shape. The orchestrator pipes this into the video adapter's
|
|
110
|
+
`submit` subcommand.
|
|
111
|
+
|
|
112
|
+
### Step 6: Validate
|
|
113
|
+
|
|
114
|
+
1. JSON parses (`jq .`).
|
|
115
|
+
2. `requires.audio_native` is consistent with the chosen adapter's
|
|
116
|
+
capability.
|
|
117
|
+
3. Duration in the motion prompt matches blueprint duration ±0.
|
|
118
|
+
4. Identity tokens (if `character.json` exists) are verbatim.
|
|
119
|
+
|
|
120
|
+
## Output format
|
|
121
|
+
|
|
122
|
+
1. **`scenes/<id>/motion-prompt.json`** — adapter-contract stdin.
|
|
123
|
+
2. **`scenes/<id>/motion-prompt.txt`** — labeled prose blocks
|
|
124
|
+
(CAMERA MOTION · PRIMARY MOTION · SECONDARY MOTION · AUDIO
|
|
125
|
+
DIRECTION · PHYSICS) for operator review.
|
|
126
|
+
3. **`scenes/<id>/adapter-notes.md`** — which adapter, which
|
|
127
|
+
capability, which preset / model, with rationale.
|
|
128
|
+
|
|
129
|
+
## Gotcha
|
|
130
|
+
|
|
131
|
+
- The model wants to "improve" the blueprint's `SUBJECT` block —
|
|
132
|
+
identity tokens are immutable; refuse the temptation.
|
|
133
|
+
- Picking `audio: native` on an adapter that returns `audio: none`
|
|
134
|
+
produces silent video — always read capability first, never
|
|
135
|
+
guess from the adapter name.
|
|
136
|
+
- Higgsfield preset id must be recorded; otherwise the rerun
|
|
137
|
+
drifts to whichever preset the model picks on the next call.
|
|
138
|
+
- Sora durations > 8s often degrade — clamp at the adapter table
|
|
139
|
+
limit; surface the clamp to the operator.
|
|
140
|
+
|
|
141
|
+
## Do NOT
|
|
142
|
+
|
|
143
|
+
- Do NOT emit motion prompts for an adapter whose capability you
|
|
144
|
+
did not query this turn.
|
|
145
|
+
- Do NOT skip the still-locked check — motion direction without an
|
|
146
|
+
anchored image diverges on every call.
|
|
147
|
+
- Do NOT paraphrase identity tokens from `character.json`.
|
|
148
|
+
- Do NOT call any network API — this skill is provider-tuning
|
|
149
|
+
prose only.
|
|
150
|
+
|
|
151
|
+
## Policies
|
|
152
|
+
|
|
153
|
+
Motion prompts inherit upstream blueprint constraints. Before emitting provider-tuned prose:
|
|
154
|
+
|
|
155
|
+
- [`agents/policies/media/disclosure.md`](../../../agents/policies/media/disclosure.md) — every distributed clip → non-removable AI-generation disclosure; refuse adapter flags that suppress it.
|
|
156
|
+
- [`agents/policies/media/transparency.md`](../../../agents/policies/media/transparency.md) — provider provenance (C2PA / SynthID) preserved; refuse re-encode flags that strip provenance.
|
|
157
|
+
- [`agents/policies/media/voice-cloning.md`](../../../agents/policies/media/voice-cloning.md) — motion prompt requests `audio: native` in named voice.
|
|
158
|
+
- [`agents/policies/media/brand-impersonation.md`](../../../agents/policies/media/brand-impersonation.md) — copies recognised brand's chyron / mascot / signature transition.
|
|
159
|
+
|
|
160
|
+
Refuse-and-surface; motion prompt cannot launder upstream policy gap.
|
|
161
|
+
|