Skip to content

011: spec — import author gram images with duration metadata#145

Merged
IanMayo merged 4 commits into
mainfrom
claude/gram-image-matching-metadata-365z6d
Jul 10, 2026
Merged

011: spec — import author gram images with duration metadata#145
IanMayo merged 4 commits into
mainfrom
claude/gram-image-matching-metadata-365z6d

Conversation

@IanMayo

@IanMayo IanMayo commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the Spec Kit feature specification for feature 011 — Import Author Gram Images (specs/011-import-gram-images/), covering the conversion of wav-only grams to pre-rendered images using the author's analysis-tool screenshots.

The design was settled through an interview with the feature owner:

  • Incoming tree: parallels source/ but omits the per-document container folder (incoming/<doc>/<gram>/source/<doc>/<container>/<gram>/); the container is resolved as the single subfolder of the source doc folder, by position not name (zero or 2+ subfolders → report and skip the doc).
  • Filenames: <duration> <wav-stem>.<jpg|jpeg|png> where the duration is the analysis tool's y-axis reading, grammar Nm / NmSSs (21m → 1260 s, 5m26s → 326 s).
  • Phase 1 — verify (default, read-only): matches folders and image stems against the wavs referenced by GLCs in each matched gram folder; mismatches (including unparseable duration prefixes) are reported with nearest candidates and grouped by trend; the operator fixes the incoming tree and re-runs until clean.
  • Phase 2 — apply (explicit flag): copies each matched image beside its GLC renamed to the wav's stem, repoints the GLC <filename>, and inserts <bitmap_crop_values><bottom_crop>N</bottom_crop></bitmap_crop_values> so a fresh extract picks the duration up as time_end.
  • The wav stays in place (deliberate divergence from relink_glc_to_image.py's .wav.bak rename): future users may want the audio, and the generator only copies what the GLC references. Idempotency rides on the "GLC already references an image" skip rule.
  • Ambiguities warn-and-skip, never guess; pure pre-CSV prep with no CSV reconciliation; new canonical script + root wrapper alongside (not replacing) the existing relink flow.

Changes

  • specs/011-import-gram-images/spec.md — feature specification (3 prioritized user stories, 16 functional requirements, edge cases, success criteria, assumptions)
  • specs/011-import-gram-images/checklists/requirements.md — spec quality checklist (all items pass; no [NEEDS CLARIFICATION] markers)
  • .specify/feature.json — points downstream Spec Kit commands at the new feature directory

Next steps

/speckit-plan/speckit-tasks → implementation on this branch.

🤖 Generated with Claude Code

https://claude.ai/code/session_01H5E6YjrQ6V7d2t1otjFYiN


Generated by Claude Code

Feature 011 converts wav-only grams to pre-rendered images using the
author's analysis-tool screenshots, delivered in a parallel incoming
tree named "<duration> <wav-stem>.<ext>". Two phases: a read-only
verify pass reports folder/stem/duration mismatches (grouped by trend,
operator fixes the incoming tree); an explicit apply pass copies each
matched image beside its GLC under the wav's stem, repoints the GLC,
and records the duration as bottom_crop seconds. Wavs are deliberately
left in place, diverging from relink_glc_to_image.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H5E6YjrQ6V7d2t1otjFYiN
@github-actions

Copy link
Copy Markdown
Contributor

📄 HTML preview for this PR is live:

Rebuilt on every push to this PR; removed when the PR closes. (May take a minute for GitHub Pages to refresh.)

github-actions Bot added a commit that referenced this pull request Jul 10, 2026
Plan for the ingest stage (scripts/ingest_gram_images.py + ingest.py
wrapper): stdlib-only verify/apply tool. Research pins the duration
grammar regex, exact-match-with-report matching tiers (incl. the
already-converted class that keeps post-apply verifies clean), difflib
nearest-candidates with deterministic trend grouping, plain-text
ingest_report.txt, targeted single-write GLC edits reusing the relink
helpers, copyfile-with-overwrite semantics, and confirms the release
packager needs no change (glob-discovered). CLAUDE.md plan pointer
moved to feature 011.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H5E6YjrQ6V7d2t1otjFYiN
github-actions Bot added a commit that referenced this pull request Jul 10, 2026
24 tasks across setup, foundational (skeleton/parser/gram-folder
view), the three user stories (verify+report MVP, apply, ambiguity
classes), and polish (wrapper, docs, packaging spot-check, full
gate). Tests ride each phase per constitution Principle III.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H5E6YjrQ6V7d2t1otjFYiN
github-actions Bot added a commit that referenced this pull request Jul 10, 2026
New prep-time stage that imports author analysis-tool screenshots from a
parallel incoming tree and relinks wav-backed GLCs, in two phases:

- verify (default, read-only): match incoming doc/gram folders and image
  stems (duration token stripped) against the wavs referenced by each
  gram's .glc files; write ingest_report.txt grouped by outcome class
  with difflib nearest-candidate suggestions, an unparseable-duration
  survey, and token-drift trend aggregation. Operator fixes the incoming
  tree and re-runs.
- apply (--apply): copy each matched image beside its .glc under the
  wav's stem, rewrite <filename>, and insert
  <bitmap_crop_values><bottom_crop>N</bottom_crop></bitmap_crop_values>
  (duration in seconds) via a single-write targeted text edit. The .wav
  is deliberately left in place (diverging from relink_glc_to_image.py);
  idempotency rides on the "GLC already references an image" skip.

Ambiguous/unreadable/already-cropped cases warn-and-skip, never guess.
Reuses parse_glc, FILENAME_TAG_RE and setup_logging; no new dependency;
stdlib-only tests (42 cases over synthetic tempfile trees). Adds the
ingest.py wrapper, threads ingest_gram_images into the other wrappers'
module-pop lists, extends the readiness/wrapper meta-tests, and
documents the stage + the wav-retention divergence in README/CLAUDE.md.
Packager picks up both files by glob (no change needed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H5E6YjrQ6V7d2t1otjFYiN
github-actions Bot added a commit that referenced this pull request Jul 10, 2026
@IanMayo IanMayo merged commit 7873fa6 into main Jul 10, 2026
4 checks passed
@IanMayo IanMayo deleted the claude/gram-image-matching-metadata-365z6d branch July 10, 2026 15:15
github-actions Bot added a commit that referenced this pull request Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants