Commit Graph

26 Commits

Author SHA1 Message Date
BenStullsBets bf1013be74 feat(content): per-clip right-brain feelings drawn from each clip's footage
Affect was authored per SCALE — every clip in an altitude shared the same 4
emotion words. Now every clip carries its OWN feelings, read from that specific
footage (mood, motion, light), so e.g. the violent Tarantula nebula evokes "a
violent ferment" while the dying-star Southern Ring evokes "a star's slow dying /
a luminous farewell," and a drowsing seal haul-out evokes "a sun-warmed drowse."

Adds AFFECT_CLIP (per-clip override; falls back to the scale register) covering
all 41 clips — 41 distinct feeling-sets, one per clip. Keeps each scale's
emotional family as a base and swaps in 1-2 footage-specific feelings, reusing the
existing feel.* palette where it fits and adding 19 new nuance keys (sublime,
tenderness, turbulence, radiance, mortality, poignancy, eeriness, purity,
solitude, verdancy, freshness, repose, hush, poise, flow, intricacy, spectral,
alienness, strangeness) with full es/fr/ja. 42 distinct feeling keys now in use.

Drafted by viewing each clip's footage (per-scale passes); first-pass reads that
want operator by-eye review. Data-only (build_pool_manifest.py + manifest + i18n
catalogs). Verified: 34/34 catalog+i18n+build pytest, 16/16 node unit, 4-language
parity for every clip, live render shows distinct feelings per clip (incl. new
keys) with Think/Feel overlap still 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:33:21 -07:00
BenStullsBets 8cfceffb76 feat(content): enrich left (Think) labels to >=3/clip + motion-track abyss creatures
Every clip now carries at least 3 factual LEFT annotations to match the 4 RIGHT
(Feel) affect words — fixes the "many clips missing Think labels" asymmetry
(right read "everywhere", left felt sparse). Adds one researched factual label to
each of the 23 thin clips (orbit_bluemarble had only 1; 22 had 2), with full
es/fr/ja parity via the catalogs, and converts the 4 still-static abyss creature
subjects (octopus, bigfin squid, dandelion siphonophore, sea pig) from fixed
boxes to 3-keyframe motion-tracked labels (tracked clips 7 -> 11).

Boxes/tracks are a first pass sampled by eye from base footage (t=0.05/0.5/0.95);
they want operator by-eye review in author mode to fine-tune positions. Remaining
static clips are landscapes (correctly static) plus 2 diffuse fish schools and 2
surface-animal scenes, available for author-mode tracking if wanted.

Data-only change (build_pool_manifest.py LABELS + manifest + i18n catalogs); no
app/engine code touched. Verified: 43/43 manifest+catalog+i18n pytest, 16/16 node
unit, live render shows 3 chips/clip in all 4 languages with no JS errors. (The 3
failing pytest are pre-existing cv2/ffmpeg-absent env limits, unrelated.)

Note: the reported "audio not playing" was a false alarm — exhaustive repro
(Chromium+WebKit, strict autoplay, both servers, RMS-verified non-silent files)
found the audio engine correct; the operator's Safari output was muted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 08:36:05 -07:00
BenStullsBets 7995ba4069 feat(content): left-brain factual labels for the 28 pool clips that lacked them
Every rotating-pool clip shipped with right-brain `affect` (auto-generated per
scale by _affect_for_clip) but only 13 carried LEFT-brain factual `LABELS`. The
other 28 rendered with no detected.*/measure.* labels at any Left knob level.

Authors static tiered labels (general → specific → scientific → +fact) for all
28 — 5 cosmos, 4 orbit, 8 sky, 5 coast, 2 reef, 4 abyss — in build_pool_manifest.py
following the existing static_label pattern, plus their es/fr/ja translations in
tools/i18n/catalogs (binomials/measurements kept verbatim; units localized per
each catalog's convention). Rebuilds the manifest and merges all four languages.

Result: 41/41 clips now have left+right annotations with full en/es/fr/ja parity.

Labels are static (footage not eyeballed); the abyss/reef creature clips could
later be upgraded to tracked labels via author mode.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 06:44:36 -07:00
BenStullsBets 8df7859c5a feat(i18n): author es/fr/ja annotation translations + merge into manifest
41 clips, 753 string-variants per language, structure-validated (key-sets
and tier-counts identical to en). Escalation semantics preserved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 18:54:37 -07:00
BenStullsBets dcdc3d62f7 feat(i18n): manifest translation extract/merge tool + en catalog
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 18:49:52 -07:00
BenStullsBets 39fb9108db feat(audio): ffmpeg production pass — loop/loudnorm builders, runner, build script
Pure arg builders (audio_ops) + thin runner (audio_run) + build_audio_media.py.
Produces the 5 normalized soundtrack loops + a synthesized pink-noise bed under
the gitignored sample_media/audio tree. 6 tests pass (white-noise integration
runs against bundled imageio_ffmpeg).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 07:41:34 -07:00
BenStullsBets 70fd367c70 tools(pipeline): hybrid track.py + simulator label author mode
Content-pipeline Increment 2, part 2 (the tooling). Implements design §11.5
(docs/superpowers/specs/2026-06-24-content-pipeline-design.md):

- tools/pipeline/track.py — the stage-5 geometry pass. Classical path: a
  hand-seeded normalized box propagated by OpenCV Lucas-Kanade optical flow
  (CSRT used instead when a contrib build provides it), sampled to a SPARSE
  loop-normalized keyframed track + an appear/disappear window. Optional ML
  detect+track path lazy-imports ultralytics (clear ImportError if absent;
  base install needs only cv2). Pure helpers (normalize/denormalize, loop_t,
  infer_window, sample_track, track_to_annotation) are unit-tested; the cv2
  propagation is an opt-in integration test on real abyss_wow footage.
  Semantics are never produced here — geometry only.

- Author mode — /author.html + author.js/.css reuse the preview stage: pick a
  pool clip, scrub, drag a seed box, Run tracker (or Add as static box), author
  the LEFT detail tiers (general -> scientific+fact) + salience, shift-click to
  place affect anchors with RIGHT emotion tiers, and Save to manifest. Backend:
  POST /api/author/track (runs track_seed on the clip's base) + POST
  /api/author/clip (idempotent upsert via tools.pipeline.manifest — keeps media
  + provenance, replaces only authored content, reloads in place). The tracker
  propagates box geometry; all strings/scientific names/facts are hand-typed.

- Repointed the pipeline integration test off the retired forest base to the
  cosmos pool primary. USER_GUIDE simulator section brought current (pools,
  coast, 3-knob Mood, real-time dream, progressive tiers, author mode).

267 passed / 2 skipped (+ track pure + opt-in real-footage + author endpoint
tests). Author UI by-eye review deferred to the operator (no Chrome on this box).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:14:32 -07:00
BenStullsBets 02c762fd45 fix(pipeline): probe duration via cv2 (no ffprobe dep); wire MASTER_MAX_W; fps-sync note
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:09:01 -07:00
BenStullsBets f1c83c1a9a feat(pipeline): resolve bundled ffmpeg fallback; integration test runs on real forest base
- run.py: add resolve_ffmpeg() mirroring setup_scales_media.py; change
  process_clip ff param to None and resolve at call time
- test_pipeline_integration.py: gate on resolve_ffmpeg() not PATH ffmpeg;
  verify proxy dims with cv2 instead of ffprobe
- ffmpeg_ops.py: add fps= to trim segments in crossfade_loop_args so xfade
  receives CFR input (xfade rejects 1/0 rate from raw trim output)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:05:11 -07:00
BenStullsBets 38a1046433 feat(pipeline): runner + opt-in integration test on real forest base (content pipeline §3)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:01:25 -07:00
BenStullsBets dc122fa0bf feat(pipeline): manifest assembly — upsert clip + ring scale/edges (content pipeline §3.6) 2026-06-24 07:57:38 -07:00
BenStullsBets 0fd8b1203d feat(pipeline): strict-PD provenance record (content pipeline §3.1) 2026-06-24 07:57:07 -07:00
BenStullsBets 4b5fd20374 feat(pipeline): master/proxy transcode arg builder (content pipeline §3.4/§6) 2026-06-24 07:54:36 -07:00
BenStullsBets 7217daeb44 feat(pipeline): crossfade seamless-loop arg builder (content pipeline §3.3) 2026-06-24 07:54:01 -07:00
BenStullsBets 642451925f feat(pipeline): frame stage ffmpeg arg builder (content pipeline §3.2) 2026-06-24 07:53:28 -07:00
Ben Stull 376edd7819 feat: interactive review CLI
Per sub-project-2 plan Task 12 / spec §8.2. Walks proposed records (fields +
coords + rationale + best-effort ffmpeg preview), prompts accept/edit/skip/quit,
and persists each approval via save_catalog rewrite. I/O seams (input_fn/now_fn/
out) and --no-preview make the walk testable hermetically; decision logic lives
in the tested review core.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:34:34 -07:00
Ben Stull 3e07e86187 feat: review transition core (proposed -> approved)
Per sub-project-2 plan Task 11 / spec §8.1. proposed_records filter and approve()
return an approved copy via dataclasses.replace (no in-place mutation), with
optional coordinate/rationale override and an injected reviewed_at timestamp.
Pure, no I/O, no clock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:33:27 -07:00
Ben Stull 1d7f821ab8 feat: ingest CLI entry point
Per sub-project-2 plan Task 10. argparse entry wiring named fetcher +
HeuristicProposer into ingest_search/ingest_candidate; --query/--resolve,
--limit, --catalog, --media-root (env HEF_MEDIA_ROOT), --dominant-color.
Unknown archive -> exit 2, deferred archive -> exit 3. Secrets env-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:33:01 -07:00
Ben Stull cecc5a0f61 feat: LibriVox/NASA/Internet Archive fetchers (+ deferred stubs)
Per sub-project-2 plan Task 9 / spec §6.4. Three keyless first-ship fetchers
parse documented JSON APIs via an injected HttpClient; license/attribution go
through tools.licensing; NASA third-party + IA no-license cases are flagged in
notes for review. musopen/fma/freesound are explicit deferred stubs raising
NotImplementedError; freesound documents FREESOUND_API_TOKEN (secret, env-only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:32:18 -07:00
Ben Stull 2db2b7ac16 feat: ingest pipeline (Candidate/Fetcher/ingest_candidate)
Per sub-project-2 plan Task 8 / spec §6. ingest_candidate dedupes, downloads,
mechanically tags, drafts coordinates, builds a proposed Record and appends it;
ingest_search loops over fetcher hits. All boundaries (download/prober/color_fn)
injectable, so the pipeline is fully hermetic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:29:09 -07:00
Ben Stull 3d5c34491c feat: heuristic coordinate proposer (drafting)
Per sub-project-2 plan Task 7 / spec §7. HeuristicProposer seeds the brain plane
from archive priors and the mood plane from title/description keyword nudges,
clamps to 0..4, and emits a one-line rationale. Deterministic, no I/O, no ML
(honors design §11) — only a DRAFT a human reviews.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:27:37 -07:00
Ben Stull 222421e773 feat: per-archive license normalization
Per sub-project-2 plan Task 6 / spec §5.3. normalize_license maps CC URLs /
identifiers and public-domain markers to the LICENSES vocab, builds non-empty
attribution for cc_by/cc_by_nc, and rejects unmappable licenses at ingest.
librivox_license() helper returns public_domain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:26:21 -07:00
Ben Stull d2a97823f5 feat: ffmpeg frame extraction + optional dominant_color
Per sub-project-2 plan Task 5 / spec §5.2. ffmpeg-only dominant color (no image
library), opt-in by design; extract_frame for review previews. Runners injectable
so the unit suite never shells out.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:25:11 -07:00
Ben Stull 542b5a5641 feat: mechanical mode/duration/resolution tagging
Per sub-project-2 plan Task 4 / spec §5.1. derive_tags(Probe) -> Tags with the
attached_pic cover-art guard so an art-bearing audio file stays mode=audio.
Duration falls back to the longest stream when format.duration is absent, and
rounds half-up so 12.5s -> 13s (Python's round() would give 12 via banker's
rounding) to match the spec's stated behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:24:33 -07:00
Ben Stull 19104f94cd feat: ffprobe wrapper (tools.probe)
Per sub-project-2 plan Task 3 / spec §5.1. Parses ffprobe JSON into a Probe
(streams + format); subprocess runner injectable so tests never shell out.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:23:24 -07:00
Ben Stull db4f036729 chore: scaffold tools/ package + stdlib http client
Per sub-project-2 plan Task 1. Adds tools/ to setuptools packages,
gitignores media/, and a minimal injectable urllib HTTP client.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 06:22:30 -07:00