Commit Graph

26 Commits

Author SHA1 Message Date
BenStullsBets 1c7f2b7785 feat(credits): public CC-BY/BY-SA attribution colophon + CC BY-SA work license
CC BY / CC BY-SA footage needs its author + license shown to the viewer, and the
installation alters every frame (a derivative). Per-clip license/source already
shipped in clips.json but only surfaced in the dev panel and internal review
pages — the public experience showed nothing, so the static benstull.art site
was not attribution-compliant.

Option A — add a manifest-driven credits/colophon (credits.html + credits.js):
the page fetches the same clips the experience uses (baked clips.json in static,
the live API otherwise) and renders one attribution block per clip (title,
license, source), HTML-escaped, sorted, never silently dropping a clip. An
"ⓘ Credits & licenses" link in the header (localised en/es/fr/ja) makes it
reachable from the work — what CC's "reasonable to the medium" calls for. Audio
is all PD/CC0, credited as a courtesy block.

Option D1 — the colophon declares the altered work itself is offered under
CC BY-SA 4.0 and states the footage is modified, satisfying the ShareAlike +
"indicate changes" obligations for the BY-SA sources. Non-commercial.

Ships in the static build (added to PUBLIC_ASSETS). Verified: 41/41 clips
credited incl. all 7 CC-BY/BY-SA clips, 0 missing a license. Tests: node units
for creditEntries/creditsListHtml + escaping + page structure/declaration;
pytest build-output assertion; Playwright e2e (page lists attributions, header
links through).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 08:39:26 -07:00
BenStullsBets 77cb04bb8c feat(static): build script — dist/<app>/ + manifest-only media tree, baked API JSON, _redirects
Run via 'python -m tools.build_static' (avoids tools/http.py shadowing stdlib http).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 07:43:49 -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