Commit Graph
513 Commits
Author SHA1 Message Date
Vance IngallsandClaude Opus 5 4f464dc424 feat(cli,studio): telemetry opt-out is canary opt-out
Both reviewers flagged the same gap: seed injection was gated on
telemetryShouldTrack(), but canary EVALUATION was not. An install with
DO_NOT_TRACK=1 was still bucketed and still had real code paths flipped
(e.g. HF_DE_PARALLEL_ROUTER), silently and unmeasurably.

A canary is a measured rollout — we enrol a slice precisely so it can be
compared against everyone else. An install that sends nothing can't be
compared, so enrolling it buys no signal and only changes that user's
code path, on an experimental feature, without their knowledge. That is
the wrong side of an opt-out.

Resolves to a new `telemetry_opt_out` reason BEFORE bucketing, so no
cohort is assigned at all. Distinct from `excluded` because "why is my
canary off" has a very different answer for CI than for opted-out, and
the reason never reaches telemetry by construction.

Covers every opt-out route: persisted preference, the runtime env vars
and dev/telemetry-disabled builds via policy.ts, and Studio's
hyperframes-studio:telemetryDisabled.

An explicit HF_CANARY_* / ?hf_canary_*= override still wins — a
deliberate local choice, not silent enrolment, and the documented way to
exercise a canary with telemetry off.

The CLI check mirrors shouldTrack() rather than importing it: client.ts
already imports canary.ts for canaryEventProperties, so depending on it
would be a cycle. Both read the same two inputs, so they cannot disagree.

Tests: 9 new across CLI and Studio (preference off, each runtime
override, no bucket assigned, override still honoured, flag properties
all-false). Fault injection: removing the CLI gate fails 6, removing the
Studio gate fails 3.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 16:11:34 -07:00
Vance IngallsandClaude Opus 5 9f2b892a71 fix(cli): keep the canary bucket seed inside the config dir
Adopts the #2904 pattern for bucketSeed. The seed rides in
install-state.json, which now lives beside config.json in ~/.hyperframes
rather than in ~/.local/state/hyperframes/.

Review rejected persisting state outside the config dir to defeat a
user's reset, and that objection is sharpest for the seed: it is the one
field that would turn install-state into a persistent pseudonymous
identifier surviving `rm -rf ~/.hyperframes`.

The carryover still earns its place, just against the churn that
actually happens. config.json is rewritten on every command and every
render, and readConfig recovers from any parse/permission/IO failure by
minting a fresh identity — so a re-mint would reshuffle cohorts
mid-rollout. A no-schema file written once at mint is decoupled from
that without leaving the directory. Config re-mint: cohorts hold.
Directory deleted: cohorts go too, deliberately.

A pre-move seed is adopted by the same migration, so installs already
carrying one do not have a live cohort reshuffled under them.

Tests: seed survives a re-mint, does NOT survive deleting the config
dir, and migrates from the pre-move path. Prose in config.ts, canary.ts
and canary-rollouts.mdx corrected — it still claimed cohorts survive a
wipe. Docs gain a removal-path section.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:21:46 -07:00
Vance IngallsandClaude Opus 5 8dd20ac2e8 feat(cli): bucket canaries on a machine-lineage seed, not the telemetry id
Cohort membership now survives a config wipe. Canaries bucket on a
dedicated bucketSeed (fresh random UUID, distinct from anonymousId by
design) that is mirrored write-once into the install-state file and
inherited at mint: a wipe re-rolls the telemetry id but never the canary
assignment. This removes cumulative-exposure drift for the recoverable
churn bucket entirely — the residual drift comes only from fresh
machines, containers, and genuinely new users — and keeps before/after
comparisons valid across a reinstall.

The seed is never emitted in telemetry (only the resulting true/false
assignments are), so it does not link the old id to the new one
server-side. The residual linker is the flag vector itself (k bits for k
live canaries), documented as such. An explicit reset still works by
deleting the state file, and the no-identity test now also asserts the
seed differs from the anonymousId.

Cross-surface coherence: the CLI's studio server injects the seed as
window.__HF_CLI_BUCKET_SEED (same telemetry gate and script-escaping as
the distinct id, and on the /api/telemetry-identity fallback), and the
Studio binding buckets on it when present — without this the CLI would
bucket on the seed while Studio bucketed on the distinct id, splitting
one machine across cohorts (calibration check 4 would catch exactly
this). Standalone Studio still buckets on its localStorage id: the
browser has no second storage location, so that id doubles as the seed.

Legacy configs are backfilled once (lineage seed if the state file has
one, else minted) and persisted immediately — an unpersisted seed would
re-roll cohorts every process. Safe to ship in the same release as the
first canaries: no prior release emitted canary properties, so the
bucketing-unit change is unobservable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:16:16 -07:00
Vance IngallsandClaude Opus 5 0d98de023f docs(canary): calibration check 2 reflects the breaker rollover
The "what cannot be fixed" framing predated the state-file rollover: the
drift still exists, but a re-rolled install no longer re-enters a failed
path, and install_predecessor_found splits the drift into recoverable vs
unrecoverable. Window-length policy comes from the residual, not raw
turnover.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:15:37 -07:00
Vance IngallsandClaude Opus 5 18d6dd2d7f docs(canary): keep contributor docs vendor- and access-neutral
Contributors in the wild have no access to the project's analytics backend,
so the contributing doc must not point them at it: drop the internal
dashboard link, the backend-specific SQL blocks, and the vendor naming.
The calibration check definitions stay (public, fixed terms of the
experiment); the queries live with the dashboard tiles that run them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:15:00 -07:00
Vance IngallsandClaude Opus 5 10536e8473 docs(canary): note override contamination as check 3's innocent explanation
Telemetry carries the assignment but not the decision reason, so a manual
HF_CANARY_* toggle mid-window reads as a cohort flip. Rule it out before
treating a small-nonzero stability read as a mechanism bug; a reason
property is deliberately deferred until the check actually comes back dirty.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:14:59 -07:00
Vance IngallsandClaude Opus 5 c43b4e2d95 docs(canary): make calibration check 4 compare per-surface values
As written, check 4's condition (dual-surface AND value flipped anywhere)
was a strict subset of check 3's (value flipped) — if check 3 read zero,
check 4 was vacuously zero and added no independent signal. Compare the
value each surface actually reported instead, and state plainly that any
disagreement is also a check-3 flip: this check's job is attributing such
a flip to binding divergence. Matching fix applied to the live PostHog
tile (insight jQi7QdW1, dashboard 1918875).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:14:59 -07:00
Vance IngallsandClaude Opus 5 00b5762974 docs(canary): link the calibration dashboard from the checks section
The four pre-registered checks now exist as PostHog tiles. Without the link
the doc describes queries someone has to re-type; with it the doc and the
dashboard are one artifact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:14:59 -07:00
Vance IngallsandClaude Opus 5 a7bb061afe feat(core): inert calibration canaries to validate the mechanism in the wild
Registers two canaries that gate nothing — `calibration-10` (10%) and
`calibration-50` (50%) — so the rollout mechanism can be proven against real
traffic before any real feature depends on it. Zero behavioural risk: they are
read by nothing.

They answer what the unit tests structurally cannot. The tests bucket
generated UUIDs and weight every install equally; real render volume is
heavily skewed toward a few heavy installs, and real install ids churn (~25x
more distinct ids over 30 days than in any single day on the desktop render
population).

Four checks, pre-registered in the docs so the read is not post-hoc:

1. ACCURACY — does 10% land at 10%, install-weighted AND event-weighted?
2. DRIFT — how fast does CUMULATIVE exposure climb above target as ids churn?
   The instantaneous share is flat by construction; the set of installs
   enrolled at some point is not.
3. STABILITY — does any install ever change cohort? Must be zero. Percentages
   are held FIXED for the window precisely so a flip is unambiguously a bug;
   during a real ramp a false->true flip would be correct instead.
4. CROSS-SURFACE — do the CLI and Studio bindings agree for the same install?
   A CLI-launched Studio adopts the CLI id, and 16,961 installs currently
   share an id across both surfaces, so this is measurable.

Plus an independence check: overlap between the two calibration canaries
should be ~p1*p2 (~5%), not ~min(p1,p2) (~10%, which would mean every canary
lands on the same unlucky cohort).

The docs also record what calibration CANNOT fix: per-install cohorts never
flip, but a person who wipes their config gets a new id and a fresh roll.
Preventing that needs stable identity across resets, and both candidates were
rejected — hardware fingerprinting correlates the cohort with hardware (fatal
for a rendering experiment, and it survives uninstall) and account identity
covers only ~3.6% of local rendering installs. The drift is therefore a
measured, accepted limit, and the point of calibrating is to size it and pick
canary window lengths accordingly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:14:59 -07:00
Vance IngallsandClaude Opus 5 a1682e1228 feat(core): emit canary assignments as PostHog flag properties
Replaces the single `canaries: "a,b"` telemetry property with PostHog's own
flag shape, one property per registered canary:

    $feature/canary-de-parallel-router: "true" | "false"

PostHog treats `$feature/<key>` as a first-class flag property, so breakdowns,
funnels split by cohort and the experiment surfaces work on a canary with
nothing configured server-side. The decision still happens locally: the render
path forbids render-time network calls, behaviour must not depend on analytics
being reachable, and neither the CLI nor Studio ships posthog-js (both
hand-roll a batch POST, so there is no SDK to evaluate a real flag with).
Decide locally, analyse natively.

Two decisions worth recording:

- BOTH ARMS ARE EMITTED. A non-enrolled install reports "false" rather than
  omitting the property. Absent means "this build predates the canary", which
  is a different fact from "this install is control" — collapsing them makes a
  ramp unreadable, because you cannot separate a control group from an old
  version.

- KEYS ARE NAMESPACED with a `canary-` infix. A real PostHog flag namespace
  already exists in this project, owned by the web app (`enable-chat-tab`, set
  by posthog-js from `$lib=web` events). Namespacing guarantees a canary key
  can never alias a real flag key and have the two fight over one property.

Values are the strings "true"/"false" to match how PostHog records boolean
flag values, so the property is directly comparable to a real flag.

98 core / 1437, 166 cli / 2194, 269 studio / 2982 green; tsc clean across all
three packages.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:14:58 -07:00
Vance IngallsandClaude Opus 5 df1521a0b6 feat(cli): attach canary cohort to telemetry, harden canary tests, document
Follow-up to the canary primitive.

Telemetry: every event now carries a `canaries` property listing the cohorts
the install is enrolled in, attached in `trackEvent` so it lands on ALL
events rather than renders only — a staged rollout is only as useful as the
ability to split any metric by cohort. Resolved after the shouldTrack guard,
so opted-out installs never pay for it, and omitted entirely (not null or "")
when the install is in no canary, since PostHog treats those as real values.

Test hardening, after validating the shipped code against 60k synthetic and
101 real fleet install ids:

- Pin FNV-1a against canonical vectors, AND assert the shipped canaryBucket
  actually uses that hash. Without the second assertion the first is
  tautological — it would only prove the test's own copy is correct while
  canary.ts drifted to a different hash, silently reshuffling every live
  cohort. Fault-injection confirms only this assertion catches a hash change;
  the distribution tests stay green because a perturbed hash is still
  well-distributed.
- Tighten the share test from a 0.6x-1.4x band to +/-1 percentage point.
  Measured error was 0.16pp at n=60k, so the old band would have passed a
  badly skewed hash.
- Add chi-square uniformity across all 100 buckets (chi2 89.0 vs 148.2
  critical at p=0.001). A lumpy hash yields roughly the right total share
  while overloading some buckets, so the share test alone cannot catch it.
- Assert N concurrent canaries enrol binomially rather than in lockstep:
  8 canaries at 10% put ~43% of installs in none and zero in all eight,
  matching binomial(8, 0.1). Correlated slices would put ~10% in all eight.

Also verified 88,443 of 88,448 fleet install ids are well-formed UUIDs; the
5 that are not fail closed, which is the intended direction.

Docs: docs/contributing/canary-rollouts.mdx, registered in docs.json (an
unregistered page is invisible in the nav).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:14:35 -07:00
Santhi Prakash a52dd9c308 docs(studio): document monorepo dev server port (#2902)
- Problem: @hyperframes/studio package docs showed bun run dev without the
  localhost URL contributors need after #2901 fixed contributing.mdx only.
- Fix: note that the studio dev server listens on localhost:5190 per
  packages/studio/vite.config.ts server.port.
- Verification: preflight_ship.py + read vite.config.ts; bun run format:check.
2026-07-30 21:14:42 +02:00
Santhi Prakash ffe5e12cf8 docs(contributing): fix studio dev server port in setup guide (#2901)
- Problem: setup guide pointed contributors to localhost:3000 after bun run dev.
- Fix: use localhost:5190 to match packages/studio/vite.config.ts server.port.
- Verification: preflight_ship.py + read vite.config.ts server.port (5190).
2026-07-30 21:09:59 +02:00
Vance Ingalls 12ee861123 chore: release v0.7.85 2026-07-30 10:38:10 -07:00
WaterrrForever 2efbfd4758 docs(prompting): document the intent interview and align pages with skill contracts (#2872)
* docs(prompting): correct workflow one-liners against skill contracts

general-video leads with its positive identity and companion mode;
faceless-explainer keys on invented visuals instead of TTS;
talking-head-recut uses the 'graphic overlays' trigger term;
motion-graphics gains its input side and overlay output;
music-to-video stops implying images are required.

* docs(prompting): make vocabulary video grids readable

Replace the 4-5 column table hack with a 3-column CSS grid,
switch demo clips to autoplay muted loops (no black poster frame,
no player chrome over tiny videos), and align cells at 16:9.

* docs(prompting): document the opening interview and run-shape questions

The guide taught prompt shapes but never prepared readers for the
conversation that follows: the intent interview, the two run-shape
questions (storyboard, automation vs companion), the just-build-it
skip, and BRIEF.md as the resumable artifact. Add that section to the
overview, a disambiguation note on the storyboards page, and free up
'companion' as a reserved term in media-and-audio.

* docs(guides): make BRIEF.md the pipeline's Step 3 artifact

Step 3 (Strategy & Messaging) listed no output while describing
exactly what BRIEF.md now captures. Name the artifact in the step
table, project tree, step body, gate, and iterating list, and fix
SCRIPT.md's step label in the tree (Step 4, not 3).

* docs(quickstart): realign the setup surface with the skills catalog

The quickstart drifted from docs/guides/skills.mdx, CLAUDE.md, and the
prompting overview — it had never been updated when those surfaces were:

- `--full-depth` on both install commands, with the reason inline. Without
  it `skills add` fetches the skills.sh registry blob, which lags `main` by
  hours, so a reader following the quickstart installs stale skills.
- `check` in the `/hyperframes-cli` row, and a validate step in the manual
  dev loop, which went preview → render with no gate at all. The prompting
  overview calls `check` "the step people skip and regret" and states both
  `lint` and `check` must pass before rendering.
- `/hyperframes-keyframes` in the core-skills table (8 rows → 9).
- `/figma` in the optional-workflow list (10 → 11).


* docs(skills): close the catalog drift class and complete the music-to-video input

Follow-up on the two review nits from #2872.

`/music-to-video`'s SKILL.md names three inputs — an audio file, a video to
pull audio from, or a track generated from a mood brief. Every compressed copy
of that description carried only the first two, and the third is the one that
makes "a complete video needs zero assets" true. Fixed on all eight surfaces
that state it, so no surface is now more correct than its siblings: the
prompting overview and quickstart setup tables, docs/guides/skills.mdx, the
README catalog, root CLAUDE.md + AGENTS.md, both CLI project templates, and the
router's own routes/music-to-video.md Input line (whose Interview must-haves
already listed all three).

The drift was structural, not accidental: the sync set declared in
docs/guides/skills.mdx and in CLAUDE.md's "Skill catalog maintenance" named
four surfaces and never the two setup tables, so those two were free to rot
while the declared four stayed correct. Both declarations now name them, and
both say the set applies to a *changed contract* — a reworded description —
not only to an added or renamed skill.

skills-manifest.json regenerated for the touched route file.

* docs(claude): point the routing-surface rule at routes/, not the moved stubs

Item 3 of "Skill catalog maintenance" still sent readers to
`references/workflow-catalog.md` for a workflow's input/output/trigger
contract and `references/route-briefs.md` for its interview entry. Both are
now "moved" stubs — the contract and the interview entry live together in
`references/routes/<workflow>.md`, one read per candidate route.

Same failure class the previous commit fixed at item 1: a maintenance rule
outliving the layout it describes. Swept the tree for other pointers at the
two stubs; there are none, so this closes it rather than fixing one instance.
2026-07-31 01:17:11 +08:00
Vance Ingalls 2e4c2c4407 Merge pull request #2109 from heygen-com/fix/prompt-guide-validation-bugs
docs: Prompt Guide as a novice-to-capstone arc + text corrections from validation
2026-07-30 05:09:56 -07:00
Vance Ingalls fdf3ad8fdd docs: address remaining prompt guide feedback 2026-07-30 05:01:12 -07:00
Vance Ingalls 73ebc7c621 docs: address prompt guide review findings 2026-07-30 04:54:27 -07:00
Vance IngallsandClaude Opus 5 8fb1482e7f docs(prompting): rebuild rule 2 as cross-fade vs camera move
The old demo argued that a locked frame crops the story. The sharper claim is
what a cut throws away: a move carries the spatial relationship between two
shots, a cross-fade carries none.

Five stages each get their own colour and the halves diverge on how the next
colour arrives -- in place, or by travelling to it. 30-47% of pixels differ,
against 3% for every version where the WITHOUT half moved the content.

That 3% is the trap now documented in the rule: translating the scene and
translating the camera are the same transform, so sliding content past a fixed
frame is not a static comparison, it is the same shot rendered twice.

Embed is cache-busted to -v2; docs images carry immutable year-long cache, so
reusing the filename would serve returning visitors the old render.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 02:51:13 -07:00
Vance Ingalls 065293ecf3 chore: release v0.7.84 2026-07-30 01:39:54 -07:00
Vance IngallsandClaude Opus 5 cdac57c075 docs(prompting): rebuild rule 1-3 demos around motivated subjects
Live telemetry panel, an isometric deploy pipeline wider than the frame, and
a progressive edge rollout across twelve regions. In each, the rule follows
from the content rather than being applied to it.

Rule 2's demo carries the strongest evidence in the chapter: deleting the
three stages the locked frame never shows and re-rendering leaves that half
identical on all 180 frames.

Rule 3 gains a rule-level distinction the rebuild surfaced — stagger what is
happening, not what is merely present.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 22:12:00 -07:00
Vance IngallsandClaude Opus 5 dd4fd9cefa docs(prompting): rebuild rule 4-6 demos around motivated subjects
Replaces the generic card/chip/disc subjects with ones where the rule is
unavoidable given the content: a payment sheet over a receipt, a split-flap
departure board, and a render-farm corridor.

Rules 5 and 6 in the grammar list were one-liners that under-said what their
demos prove. Rule 5 now carries the mass claim, the follow-through lag, and
the transforms-only caveat (a counter that overshoots renders a false value).
Rule 6 credits occlusion over blur and prefers one foreground element.

Section intro no longer endorses over-cranking; every movement in an applied
half has to finish "this moves because...".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 22:12:00 -07:00
Vance Ingalls a17755d2ef docs(prompting): rebuild rule 1 demo around a motivated idle 2026-07-29 21:11:09 -07:00
Vance Ingalls 6f29f1454e docs(prompting): lead the motion chapter with meaning, not amplitude 2026-07-29 20:56:19 -07:00
Vance Ingalls cebf66e6e8 docs(prompting): rule demos gain before/after prompts and exaggerated applied sides 2026-07-29 20:07:53 -07:00
Vance Ingalls 75dac808a9 docs(prompting): fix MDX parse error from an orphaned Warning close tag 2026-07-29 19:34:48 -07:00
Vance Ingalls d4bd2917b5 docs(prompting): add per-rule A/B demos and the worker-boundary determinism caveat 2026-07-29 19:22:07 -07:00
Vance Ingalls 1f4d00e15e docs(prompting): add the motion-purpose filter, offset ratio, and property coherence 2026-07-29 18:50:22 -07:00
Vance Ingalls 4260f12b01 docs(prompting): frame.md is the design spec, drop design.md references 2026-07-29 18:45:30 -07:00
Vance Ingalls 5a05182226 docs(prompting): rebuild beat-synced slideshow — generated brutalist plates, no stock 2026-07-29 18:38:32 -07:00
Vance Ingalls 5244dde5f1 chore: release v0.7.83 2026-07-29 18:37:58 -07:00
Vance Ingalls 770e79dc69 docs(prompting): refresh example gallery with motion grammar and named spectacle beats 2026-07-29 16:48:03 -07:00
Vance Ingalls fda3d9a65a docs(prompting): add fromTo back-render and round-linecap dot traps to the appendix 2026-07-29 16:00:15 -07:00
Vance Ingalls 4d89bd4261 docs(prompting): document layout waivers and the contrast-gate side effect 2026-07-29 15:55:53 -07:00
Vance Ingalls 8468771dc6 docs(prompting): six more validated renders, tighten the prompts their builds exposed 2026-07-29 15:10:08 -07:00
Vance Ingalls 87843f2910 docs(prompting): validated chart example, add duration-with-no-tail rewrite 2026-07-29 14:47:34 -07:00
Vance Ingalls a3e8806692 docs(prompting): warn on webgpu-only glass block, strengthen chart prompt, embed validated renders 2026-07-29 14:35:32 -07:00
Vance Ingalls d888be198d docs(prompting): validated showreel + handmade prompts, fix spec defects they exposed 2026-07-29 14:30:08 -07:00
Vance Ingalls 44f9db4259 docs(prompting): audit fixes — validation gate, framework vocabulary, thread consistency 2026-07-29 14:08:44 -07:00
Miguel Ángel fdc5932897 fix(cli): honor check navigation timeout (#2860)
* fix(cli): honor check navigation timeout

* test(cli): clarify diagnostic timeout precedence
2026-07-29 20:50:20 +02:00
Miguel Ángel b904343949 chore: release v0.7.82 2026-07-29 11:25:04 +00:00
James 0d42d65525 chore: release v0.7.81 2026-07-29 06:11:11 +00:00
Miguel Ángel 5829515932 chore: release v0.7.80 2026-07-29 02:22:54 +00:00
Miguel Ángel a68729bcf1 chore: release v0.7.79 2026-07-28 23:06:45 +00:00
Vance Ingalls 9cbab0c78a Merge remote-tracking branch 'origin/main' into fix/prompt-guide-validation-bugs
# Conflicts:
#	skills-manifest.json
2026-07-28 16:00:07 -07:00
Vance Ingalls bde474dab3 Merge remote-tracking branch 'origin/main' into fix/prompt-guide-validation-bugs
# Conflicts:
#	docs/guides/prompting.mdx
#	skills-manifest.json
#	skills/hyperframes-core/SKILL.md
2026-07-28 15:57:37 -07:00
Xuanru LiandCursor 3a7950fd63 feat(check): add data-layout-allow-caption-zone waiver (#2853)
* feat(check): add data-layout-allow-caption-zone waiver

Opt intentional lower-third copy out of caption_zone_collision.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(check): address caption-zone waiver review nits

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(skills): document caption-zone waiver on CLI agent path

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(cli): document caption-zone waiver under check, not inspect

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-28 15:56:43 -07:00
Vance Ingalls 90a281b7f8 docs(prompting): frame slideshow fix as two properties, camera as one method of many 2026-07-28 15:50:14 -07:00
Vance Ingalls 4f6fb8fc16 docs(prompting): add "Avoiding the slideshow" — continuity contract + dwell-and-sweep 2026-07-28 15:27:45 -07:00
Vance Ingalls c691869e22 chore: release v0.7.78 2026-07-28 05:27:29 -07:00