JITRBeats

An automated music marketing system — a business-in-a-box for digital content operations.

Last updated May 12, 2026 · 22 features · 322 roadmap items

1Patreon fan · North Star 5000
Email subscribers 2  ·  Social reach 551 across five platforms
New this month2 items shipped in the last 30 days
Operator Visibility
  • Bug — JITRProduct page hasn't refreshed since 2026-04-30 — shipped 2026-05-12
  • Slim or retire the DailyEmailer · ARCHIVED 2026-05-05 — shipped 2026-04-22
System features What JITRBeats does today — 22 capabilities across 5 areas

Posting Machine

Auto-posting across five platforms
New
Clips post to Facebook Reels, Instagram Reels, YouTube Shorts, TikTok, and X/Twitter on an automated schedule. Each platform has its own poster tuned to how that platform actually works: Facebook and Instagram share caption and timing logic, YouTube enforces a stricter cadence (base 4 hours with ±25% variability and a 24-hour no-repeat rule), and X is triggered automatically after every successful YouTube upload so the release gets announced with the Shorts link. All five draw from the same central clip selector — posting priorities set once propagate everywhere.
RecentlyPhase 1 random-daily-target cadence shipped. Per-platform `facebook.min_posts…  ·  Phase 1 random-daily-target cadence shipped. Per-platform `instagram.min_post…  ·  Tmp files moved out of $JITR_TMP root into $JITR_TMP/reels/ subfolder. Keeps…
Human-feeling post variety
New
Each post's caption is drawn from a two-tier pool: branded lyric lines for song-specific clips (weighted 30%) and a 161-line commentary pool for the rest. Hashtag counts are probabilistic — zero to fifteen tags per post, drawn from core / clip-type / genre / discovery pools — so no two posts have the same shape. Timing jitters zero to forty-five minutes off the schedule to avoid clock-boundary patterns that flag as spam. Configurable quiet hours skip overnight posts. YouTube rotates between two title formats so the same song never appears back-to-back in the identical phrasing. The feed is believable because it isn't uniform — a reader sees the variety a human would have created.
RecentlyPhase 1 random-daily-target cadence shipped. Per-platform `facebook.min_posts…  ·  Phase 1 random-daily-target cadence shipped. Per-platform `instagram.min_post…  ·  Tmp files moved out of $JITR_TMP root into $JITR_TMP/reels/ subfolder. Keeps…
Slot-filling supply management
New
Each platform maintains a rolling buffer of pre-selected, pre-scored clips so the posters never stall waiting for content selection. When a clip is consumed, a refiller picks the next one via the central selector and stages it into the supply folder, ready for the next post. Supply folders live on Google Drive for mobile access, with defensive checksum verification guarding against partial moves. A slot is never emptied unless its replacement is already in place.
TikTok manual-post queue
New
Until TikTok's Content Posting API is approved for automated publishing, JITRBeats still drives TikTok end-to-end. Six clips are staged in Google Drive slots every day using the same selector and scoring logic that drives every other platform. A human posts them with a tap from the TikTok mobile app — the selection, timing, and caption context are identical to what the automated poster will do the moment approval lands.
Platform token refresh
New
Meta access tokens (which expire roughly every sixty days) and Dropbox access tokens refresh themselves automatically. Meta refresh exchanges a short-lived user token for a long-lived one, derives the Page and Instagram Business credentials from Meta's APIs, and atomically swaps the old credentials only after the new ones have been validated live. Dropbox refresh pulls a fresh access token using the stored long-term refresh token. All credentials live in macOS Keychain, never in log files or environment echoes. The posting machine never stops because a credential silently expired.
Posting integrity reporting
New
Every platform has a daily reporter that reads the poster's own log and turns the day into numbers: how many posts went out, how many failed, whether any errors appeared, and for YouTube whether the AI-content-ratio target (under 20% of posts tagged AI) is holding. Reports compare observed posting against configured targets — twelve per day for Facebook and Instagram, five-plus for YouTube — and color-code GREEN, YELLOW, or RED with explicit intervention flags so Jeff knows at a glance when to look versus when everything is fine. ---
RecentlyPhase-1-aware refactor — reporter now reads per-platform `instagram.min/max_p…  ·  Handle mixed log formats safely — closed after audit. Reporter's `parse_with_…  ·  Scorer-log paths centralized to `SCORER_LOG_DIR` env-overridable variable. Wa…

Creatives Library

Canonical clip naming
New
Every clip in the library carries a deterministic filename encoding three pieces of meaning: the pool it belongs to (general, song-specific, or Pronounce Hecojeni), a twelve-character content hash that stays with the file for life, and the clip's current effectiveness score as a four-digit suffix (5000 is neutral, scores drift up on engagement and down with age). The hash never changes — it is the file's identity. The score changes constantly: a nightly pass reads the scoring events queue, applies the percentage-delta math, and renames files to reflect the new score. This two-part naming is the spine of the whole system — every downstream program, from selector to poster to scorer to reporter, reads meaning directly from the filename, so a clip's rank, provenance, and history are always recoverable without a database.
Age-aware clip rotation
New
The library reacts to a clip's age as an enduring capability. At thirty days old, a clip picks up a +30% score boost on the theory it has had time to find its audience. At one year old, it takes a -10% decay to quietly yield rotation to fresher material. The system detects these milestones with a stateless time-window pass — each clip's birthday event fires exactly once, missed runs automatically catch themselves up, and no per-file ledger is needed. Evergreen clips stay evergreen, aging clips phase down on their own, and the library never calcifies around a handful of perennial posts.
Engagement-based re-ranking
New
Every post's real-world performance feeds back into what gets posted next. Three platform scorers — Facebook, Instagram, YouTube — fetch each posted clip's live likes and comments and compare them to the account's own 30-day rolling average. A post that hit 2x its recent average picks up a score boost; a post at half-average takes a small hit. The model is ratio-based, not fixed-threshold, so "good performer" is defined by your own recent history, not an absolute number. A separate pool-level recommender aggregates these signals across each content pool on a 30-day half-life and suggests updated posting-mix weights — pools whose clips are actually winning get more airtime, pools that are quiet get less. Weight suggestions are advisory: the human stays in the loop on what to adopt.
Queue-backed weighted pool selection
New
Nothing in JITRBeats picks a clip at random on demand. When a poster needs its next video, it pulls from a pre-filled queue that a separate process stocks in batches honoring the active pool weights. If a new release is configured for 30% of airtime for the next four weeks, one line changes in the weights config and the next queue fill reflects it — every poster, every platform, one source of truth. This queue-backed design eliminates surprise skew, makes the posting mix auditable (a daily ledger audit compares actual picks against configured weights and flags drift), and lets weight changes take effect deterministically rather than after some uncertain number of random samples.
Library hygiene
New
Four passes keep the 4,600-clip library structurally sound without human oversight. A deduper computes a true content hash (SHA-256) on every file and quarantines exact duplicates — rename-fooled duplicates do not slip through. A durationer splits any clip longer than thirty seconds into TikTok-and-Instagram-native chunks that inherit the parent's canonical naming. The canonical-naming enforcer catches any file that drifted out of spec during production or Dropbox sync. A daily compliance report flags the percentage of the library that is out of format, so structural drift is visible before it becomes a problem. Old logs and reports are trimmed to ninety days so the system's own exhaust does not grow forever. ---

Spotlight — Production Flow

Song production flow
New
Tracks whether music production is moving work through or building backlog at any given stage. Two daily signals drive the assessment: a Mix Backlog metric (the ratio of archived old mixes to current work — green when older takes are clearing as fast as new work arrives, red when the backlog accumulates), and a Premaster Readiness metric (premaster WAVs per active project — green when projects are flowing smoothly toward mastering, red when work queues upstream). A separate daily song-journey ledger captures each song's milestone dates from old mix through final master, so stage-to-stage lead times are there to be analyzed when the bottleneck investigation matters. The system is evolving — semantics of "active project" and the right way to weight lead-time versus inventory are still being refined — but the enduring capability is flow-first visibility into the music side of the machine.
Video pipeline runway
New
Answers three operational questions about clip supply and consumption, every hour. Inventory Runway: how many days of max-posting (42 per day) the ready-to-post clip folder can sustain before running dry — green at 45+ days, red below 20. Pipeline Runway: how many days of future posting capacity the raw-footage feeder can generate once cut down to clips — green at 90+ days, red below 30. Conversion Ratio: whether raw-to-clip editing velocity is outpacing consumption — green means the pipeline is building a buffer, red means we are consuming clips faster than they can be produced. Together, these three numbers detect content-starvation risk before it becomes a missed-post day: low inventory + low pipeline means an imminent stall; a high conversion ratio flags an editing bottleneck upstream. ---

Operator Visibility

Live ops dashboard
New
A single-screen operator view of the machine right now: posting counts against daily and seven-day targets per platform, engagement scoring activity, and any reporter or system issue that needs attention. Mobile-first HTML with a rich link-preview card when the URL is shared, one tap from the iPhone home screen, regenerated and redeployed to Cloudflare every two hours. Replaces hand-scanning per-subsystem log files. No JavaScript, no external assets — renders identically on any browser.
Artist dashboard
New
The same underlying data as the ops dashboard, articulated for the artist. Leads with engagement standouts (top-performing posts with direct tap-through links to the live Instagram or Facebook URL), posting totals for the last 24 hours and the last 7 days, and a one-line plain-English summary. Drops the operational noise — no reporter-staleness alerts, no token warnings, no WIP labels. Distinct orange-to-purple gradient so it feels different at a glance from the ops view.
Daily email push
New
Short plain-text emails that land in the inbox twice a day (6 AM and 4 PM for operations; morning-only for the artist audience) with a rich link-preview card that fetches the hosted dashboard's OpenGraph tags. The email is the push; the page is the content. Replaces a 42 KB text-dump legacy email with a few lines plus a tappable link that opens the full current dashboard. Routing is separate per audience — operator mail to the JITR inbox, artist mail to Hecojeni and his manager on the morning run only.
Product and roadmap site
New
A public, always-current feature list and forward roadmap for JITRBeats as a product. Features are hand-curated in a manifest file that groups underlying programs into business-facing capabilities; roadmap is auto-extracted from the per-program roadmap files in the codebase, with completed items self-filtering via DONE-date markers. Each tile shows a "Recently" line auto-populated from the most recent DONE dates in that program's roadmap and a small "New" badge if any underlying program was touched in the last thirty days. The source-of-truth files — the manifest and the roadmap Markdown — are edited like any other code artifact.
Legacy daily snapshot email
New
A per-subsystem text-only email that aggregates whatever reporter outputs are currently in the DailyEmail folder and mails them as a single snapshot. Still running while the graphical dashboards absorb its coverage. Scheduled for retirement after the dashboards have replaced its function in daily use — maintained until the sunset decision, not being extended. ---

Business Operations

JITR internal expense generation
New
JITRBeats does its own accounting on the operator side, too. A monthly pass over the JITR-owned filesystem estimates labor hours spent across IT, sound, video editing, artist support, and marketing — using file-modification patterns with sessionization rules (gaps of 20 minutes or less count as the same session, runs under 2 minutes are ignored) and fixed hourly rates per category (IT: $200/hr, Video: $50/hr, Sound: $75/hr). Output is a canonical CSV ledger under the Business Files tree plus a detailed evidence report showing hours by category. Automated CSV ledgers are the chosen design — no Zoho, no third-party bookkeeping platform — so every line has a direct provenance back to filesystem evidence and the books are auditable without importing proprietary data.
Monthly client billing (in development)
Consumes the monthly expense and activity data and constructs itemized service charges for the client under JITR's rule set — video management, cloud storage, email campaigns, newsletter, Patreon administration, release packages. Outcome-based rules (for example: clip counts under 100 are free; above 100, the greater of $500 or $0.50 per clip; storage at $0.25 per gigabyte). JITR is the single billing face to the client; contractors and vendors bill JITR, and JITR re-bills the client as a pass-through line on a single invoice with no default markup. Currently in DEV; moves to PROD once the test cycle validates every rule against historical data.
Historical billing reconstruction (in development)
Reconstructs month-by-month client charges retroactively from April 2022 onward using the current rule set and filesystem evidence. Useful for reconciliation, audit trails, and catching cases where historical billing differs from what the current rules would produce. Reads the same monthly activity data as the live billing pipeline and outputs month-by-month reports. Currently in DEV.
Monthly narrative builder (in development)
Produces a human-readable narrative — plain text and Word — that chronicles what the artist created in a given month, organized by song project and media type (audio, video, images, documents). Suitable for artist review, fan-facing monthly updates, or management context. Currently in DEV; the artist-facing framing is under refinement ahead of PROD promotion.
Roadmap Approved business functionality, direction not commitment — 322 items
AgeScorer
AgeScorer
New
# AgeScorer Roadmap (empty — all items shipped as of 2026-05-07) Most recent closures: - Configurable thresholds + magnitudes — DONE 2026-05-07 (moved to config/artists/hecojeni.env as HEC_AGESCORER_* vars) - Trend reporter — DONE 2026-04-14 - Boost-at-birth + AgeMature event model — DONE 2026-04-22
Audio normalizer
Audio normalizer
New
# Audio_normalizer Roadmap Program: Audio_normalizer Status: BLOCKED on RockerTalker reaching PROD (parked 2026-04-28). Why blocked: Audio_normalizer cannot safely operate on the full TikTok and Reel Clips library. ~10-25% of clips are action/ambient footage (Heath
Audio Splitter
Audio Splitter
Program: Audio_Splitter Roadmap: 1) Execute full release management process for initial production deployment - Establish known state across dev/prod/emer - Create dev README with scope and test evidence - Capture dev vs prod diff (new program baseline)
Aweber metrics fetcher
Boundary reminder
New
This program is read-only against AWeber. It must not: - Send, schedule, modify, or delete any broadcast. - Add, modify, tag, or remove any subscriber. - Make any state-changing call. Anything that changes AWeber state belongs in a separate program with its own roadmap and explicit human approval per call.
Aweber metrics fetcher
Completion definition for this planning cycle
New
Cycle is complete when: - A scheduled job refreshes state/Aweber_metrics/latest.json on a known cadence and JITRDashboard reads it without re-implementing AWeber calls. - The refresh-token rotation path has been exercised at least once and the fetcher has continued working past initial-token expiry.
Aweber metrics fetcher
Priority list
New
### Priority 1 — Verify refresh-token rotation in production Business value: until a refresh actually fires successfully in the wild, we don't know whether AWeber rotates the refresh token, whether the fetcher captures the rotated value correctly, and whether multi-day continuity is real. Initial access tokens are 2-hour TTL.
Aweber metrics fetcher
Why this program exists
New
AWeber holds the Hecojeni fan newsletter list (separate audience from the Brevo industry list). Multiple downstream programs (JITRDashboard, Hecojeni_metrics_writer, future fan reporters) want simple AWeber numbers — total subscribers, recent broadcast opens/clicks/deliverability.
Billing
AI VIDEO PRODUCTION
### Pricing Rule - $3 per clip - 100 clip minimum per song ### What Counts - Files where path contains: - TikTok and Reel Clips - Song Specific - AI
Billing
ARCHITECTURAL PRINCIPLE
Billing MUST: - Count files - Apply rules Billing MUST NOT: - Deduplicate - Clean data - Infer history ---
Billing
AUDIO PRODUCTION
### Pricing Rule (CONFIRMED / REVISED 2026-04-09) - Producer support: - track one 1/2-day producer block for every detected recording session - track one 1/2-day producer block for every detected mix session - bill at $0.00 during recording / mixing - Studio time: - recording sessions only - $50/hour
Billing
PURPOSE
Generate a complete, accurate, repeatable monthly bill. NO interpretation. NO re-decisions. Filesystem + rules only. --- # 🔒 LOCKED BILLING MODEL (AUTHORITATIVE)
Billing
STEP 0 — DUMP CURRENT RULES
Output ALL current billing rules: - taxonomy - rate card - any hard-coded logic Goal: "this is what we have decided" ---
Billing
STEP 1 — LOAD COLLECTOR DATA
Input: - Collector CSV (~20k rows) ---
Billing
STEP 2 — COVERAGE CHECK
For every row: - Does a billing rule classify it? Output: - UNCLASSIFIED rows ---
Billing
STEP 3 — DEFINE NEW RULES
For each uncovered pattern: - Create rule - Define: - activity - billing method - evidence mapping ---
Billing
STEP 4 — PERSIST RULES
Write to: - taxonomy - rate card - roadmap (if needed) NO TEMP LOGIC NO INLINE HACKS ---
Billing
STEP 5 — RE-RUN COVERAGE
Repeat until: - 100% classification --- # 🚀 EXECUTION PHASE (ONLY AFTER COVERAGE = 100%) 1. Run billing builder 2. Generate charges 3. Generate evidence mapping 4. Manual hard costs (Jeff)
Billing
STORAGE
### Pricing Rule (CONFIRMED 2026-04-09) - $0.50 per GB per month ### What Counts - All files under ARTIST_ROOT excluding the entire Videos folder when clips >= 100 - When clips < 100: excludes only TikTok and Reel Clips subfolder - Rationale: when clip management is billed (100+ clips), all video storage is already covered — only non-video files (Recording Files, Released Music, Business Files, Photos) are charged fo…
Billing
VIDEO MANAGEMENT
### Pricing Rule (CONFIRMED 2026-04-09) - 100 or fewer clips: no charge - 101+ clips: min($3,000, max($500, total_clips × $0.50)) ### What Counts - ALL video clips (.mp4, .mov) under: Videos/TikTok and Reel Clips/ - Includes: - all subfolders
BlankVideoSweeper
Active Work
New
- Mail.app TCC permission grant. First scheduled run with flagged files will hit -1743 "Not authorized to send Apple events to Mail" unless the invoking process is pre-granted Automation control of Mail. Candidate list is safely persisted to disk regardless (*-Candidates.txt alongside the CSV report). Grant via System Settings > Privacy & Security > Automation, or wait for the popup on first interactive trigger.
BlankVideoSweeper
Future (Discussed, Not Yet Implemented)
New
- Drop "(DEV)" from the run banner. Cosmetic — the script still prints "BlankKiller (DEV)" in its banner even when invoked from PROD. Make dynamic (read $0 or pass a label) or simply remove. - Parallel processing. A full library scan is ~3 hours single-threaded.
BlankVideoSweeper
Pending Decisions / Open Questions
New
(none open.)
Blinker
Known scope (from Jeff, 2026-04-28)
New
- Source: Jeff's Blink cameras. Many cameras. Clip length ~5 seconds. - Music: pulled from the unreleased Hecojeni mp3 pool. - Avoid the first 10 seconds and the last 10 seconds of the song. - Pick a random segment in the middle. Segment duration = total finished clip duration (see render timeline below), not Blink-clip duration. - 0.5 s fade in at the start of the segment.
Blinker
Open questions (must resolve before coding)
New
These are "what are we trying to do" questions, not "how." Ranked. ### Q-selection. Every clip, or human-approval gate? RESOLVED 2026-04-28 Decision: every clip. Blinker is human-free. Implications now in scope: - No approved/ folder, no review gate. Blink → download → render → publish destination, all unattended. - Garbage-clip problem doesn't disappear, it just moves to the algorithm.
Blinker
Priority list
New
1. Resolve Q1 (clip ingress path). Blocker for everything. 2. Resolve Q2–Q5 in any order; they are independent of each other once Q1 is settled. 3. Build a single end-to-end render pipeline against one sample clip and one sample mp3, end result being a finished 9:16 short on disk. No automation yet — prove the render is right. 4. Wrap the render in an ingest loop driven by whatever Q1 resolves to. 5.
Blinker
Purpose (current understanding)
New
Pull short clips from Jeff's Blink cameras (many cameras; mix of Heath, nature, candid life), decorate each clip with unreleased Hecojeni music + a song-title overlay + the Hecojeni Magneto logo, and drop the finished short into the TikTok and Reels folders for the song that was used. The Blink-clip-plus-unreleased-track pairing is the engine: every short doubles as a teaser for an unreleased Hecojeni song.
Blinker
Releases shipped
New
### v1.0 — initial release — 2026-04-30 Promoted dev → prod with full 13-step process. All design decisions landed in code. Test results captured in Blinker.readme.md. launchd nightly registered as com.jitr.blinker.nightly at 01:00 on the Mac mini. Backfill of 1,800 historic clips completed (1,623 kept, 175 rejected).
Blinker
Remaining roadmap items
New
Priority order. None of these block daily Blinker operation — the program is shipping shorts every night. ### Open 1. Blinkerfisher: sibling pipeline for water-drone clips (priority 1, design pending). Per Jeff 2026-05-11: a new water-based drone records video / stills of fish in the pond.
Blinker
Render timeline (v1, confirmed by Jeff 2026-04-28)
New
Let D = Blink clip duration (typically ~5 s). Total finished clip duration = D + 3 seconds. | Time | Video | Audio | |----------------|------------------------------------|------------------------| | 0 | Blink clip starts; song-title text appears (pop-in); music starts (0.5 s fade in) | music in | | 3 | Song-title text disappears (pop-out); Blink continues; no logo yet | music continues | | D − 1 | Magneto logo appea…
Blinker
Scope boundary — what Blinker is and is not
New
Blinker produces ready-to-publish clips. Blinker does not publish. Output of Blinker = a finished mp4 sitting in a per-song folder. The existing TikTok refiller, Reels poster, and friends are downstream consumers that pick those files up and publish them. Blinker's job ends when the file lands in the correct folder with the correct name.
Blinker
Session 1 close-out (2026-04-28)
New
Session goal was Q1 (idea-stage investigation). Outcome exceeded the goal — every major design question resolved. Roadmap is now design-complete. Decisions locked in this session: | Q | Decision | |---|---| | Q1 | Unofficial Blink API via blinkpy (option 3) | | Q-selection | Every clip; fully human-free at clip-selection level | | Scope boundary | Blinker produces, does not publish |
Brevo Industry Outreach
Completion definition for this planning cycle
New
This cycle is complete when: - Success is defined by contact type, not as one blended list average. - Brevo has usable segments for the key business categories. - Riding the Merry Go has a release-cycle plan that protects list health. - Real signals have a manual response path, including physical outreach. - Outcomes are tracked somewhere Jeff can actually use later.
Brevo Industry Outreach
Priority list
New
### Priority 1 — Define success by contact type Business value: stops treating 10,000 industry contacts as one audience and lets Hecojeni spend attention where career outcomes can actually happen. Acceptance: - [x] Confirm the primary end goal for this list: identify and develop 12 to 25 Hecojeni industry champions who can create repeated opportunity.
Brevo Industry Outreach
Why this program exists
New
The Hecojeni industry list exists to create real-world music-business outcomes: radio plays, podcast uses, playlist adds, press mentions, sync opportunities, publisher/label conversations, and durable human relationships. It is not a fan funnel. Opens and clicks matter only because they identify who is giving signal.
Brevo metrics fetcher
Boundary reminder
New
This program is read-only against Brevo. It must not: - Send, schedule, modify, or delete any Brevo campaign, contact, or list. - Write contacts back to Brevo. - Make any state-changing call. Anything that changes Brevo state belongs in a separate program with its own roadmap and explicit human approval per call.
Brevo metrics fetcher
Completion definition for this planning cycle
New
Cycle is complete when: - A scheduled job refreshes state/Brevo_metrics/latest.json on a known cadence and JITRDashboard reads it without re-implementing Brevo calls. - The sent / delivered / opens / clicks zero issue is either resolved (real numbers showing) or formally accepted as out-of-scope and captured somewhere durable.
Brevo metrics fetcher
Priority list
New
### Priority 1 — Promote to prod and schedule Business value: makes the snapshot reliably fresh for downstream consumers. Acceptance: - [ ] 13-step release (script and readme) into prod. - [ ] LaunchD job per JITRBeats LaunchD Standard, twice daily, ahead of the 6 AM and 4 PM ops email sends so JITRDashboard always sees fresh data. - [ ] Confirm latest.json updates on schedule for two consecutive days.
Brevo metrics fetcher
Why this program exists
New
Multiple downstream programs (JITRDashboard, Hecojeni_metrics_writer, future fan reporters) want simple Brevo numbers — total contacts, per-list subscribers, recent campaign opens/clicks/unsubs. Without this fetcher each of them would need the Brevo API key, the Brevo schema, and its own retry logic. Centralizing the pull into one snapshot makes the dependency tree sane and keeps the API key in one place.
cd order processor
cd order processor
New
PROGRAM: cd_order_processor PURPOSE End-to-end automation for CD orders placed through Stripe Checkout for Hecojeni's Radio Promo CDs. When a customer completes payment, this program tags the customer in AWeber, submits a manufacture+ship order to Kunaki, notifies Jeff, and logs the full transaction. Runs daily via launchd; idempotent via a local ledger so the same Stripe session is never processed twice.
cloud migration
cloud migration
New
JITRBeats Cloud Migration — Roadmap (Effort-Owned) Vision (Jeff, 2026-04-20): - PRIMARY DRIVER: eliminate single-point-of-failure. The Mac mini running JITRBeats == JITR == Hecojeni's engine. If it goes down, everything goes down. A second box at home does NOT solve this (shared power, ISP, building). Cloud lives in a different failure domain — that is what justifies the recurring cost.
collector
collector
New
PROGRAM: collector.py ROADMAP 1) Verify first natural fire of monthly launchd schedule - Confirm com.jitr.collector.hecojeni fires correctly at 2026-05-01 00:00:00 - Confirm canonical 2026-04 collector CSV is written to Business Files/Collector/Hecojeni/2026/2026-04/2026-04-hecojeni-collector-files.csv - Confirm logs at ~/Library/Logs/JITRBeats/collector.hecojeni.launchd.out.log and .err.log capture the run cleanly
deduper
deduper
New
DEDUPER ROADMAP 1. Multi-client readiness (HEC_ -> CLIENT_, dynamic artist env) Business value: - Enables deduper to serve a second client (My Forever DJ) without forking the code. JITRBeats is moving from an implicit Hecojeni-only setup to an explicit multi-client architecture; deduper is one of
Derivative generator
Completed
New
- 2026-05-12 — v1.1 promoted to PROD (13-step release). Brand-new program; steps 3 (dev/prod diff) and 4 (emer archive) skipped — no prior version existed. Dev README at scripts/dev/Derivative_generator.readme.md carries the full v1.1 design + test receipts. Prod copy is byte-identical to dev (sha b686813e...). Permissions 755 / 644, owner jeffniebuhr, group wheel.
Derivative generator
Dead branches (kept in code, not called)
New
These branches were explored 2026-05-04 to 2026-05-05 and abandoned. The functions remain in the source for future reference but are not invoked by main(): - Kinetic typography via Playwright + HTML/CSS (v0.11). Built kinetic_text/template.html with anime.js animations and a Playwright wrapper. Composited via ffmpeg blend=screen.
Derivative generator
Notes
New
- Source clips are 1080×1920 portrait, 60fps, stereo 48kHz. Output matches. - Title font follows the approved drawtext pattern (Arial, white, 110pt, 8px black border). - Logo is Photos/Logos, QR Codes and Stickers/hecojeni - magneto logo/Presentation2/hecojeni magneto logo large.png.
Derivative generator
Priorities (open work)
New
1. Self-pruning low-score derivatives (Jeff 2026-05-11). When a derivative's engagement-driven score drops below 3000, delete it from disk so its "slot" frees up for the generator to fill on the next bulk-refresh pass. Mechanics to design: (a) where the pruning runs — own launchd job vs. Renamer extension vs.
Derivative generator
What it does (v1.0)
New
Generates DER-designation clips ("derivatives") for a released Hecojeni song. (Designation was briefly DEV in v0.1–v1.0; corrected to DER 2026-05-06 to avoid collision with the dev/ environment naming and to match the existing 3-letter convention AI / NAI / BLK.) For each derivative: - Picks a random 15-second window of the song's mastered .wav (snapped to a beat region of the song) - Detects BPM (librosa, cached per…
durationer
durationer
New
# durationer — roadmap 1. Scorer-influenced cut length (data-driven TARGET_SEC) Business value: Jeff is guessing at the ideal clip length. Let engagement data drive it instead — if longer clips consistently outperform shorter clips on average, durationer should cut longer; if shorter wins, cut shorter. Status (2026-05-11): partially unblocked.
EngagementScoring
Priority 5: TikTok Ledger + Scorer
New
- [DONE 2026-04-14] TikTokFileMgt_multi_refiller.sh now logs a posting ledger at $JITR_STATE/TikTokFileMgt_ledger.csv (schema: ts_utc,slot_num,asset_basename,dbx_rel_path) on every successful slot fill. First ledger rows write at the next 02:00 run. - [TODO] Build TikTok API collector to retrieve recent video list with create_time.
EngagementScoring
Priority 6: Cross-Platform Engagement Reporter
New
- Build a reporter that queries across all platforms: "top 10 Instagram clips of all time", "best performers across all platforms this month", etc. - Pull from scoring queues and/or posting ledgers joined with engagement data. - Output to screen + report file, compatible with DailyEmailer.
EngagementScoring
Priority 7: Watermarking (fallback, only if needed)
New
- Only pursue if TikTok time-matching (Priority 4) proves unreliable. - Design: visible pixel watermark with lane + id_hex, high contrast, full duration. - Implementation: centralized watermark generator using FFmpeg drawtext. - Validation: post watermarked test video, retrieve, confirm readability. - Business value: platform-independent identity system. Insurance policy if any platform breaks ledger-based matching.
FacebookReels poster
Backup Retention Hygiene
New
- Before writing a new backup file, first remove stale older backups for that same artifact - Default retention target: remove backup files older than 30 days unless that specific program requires something different - Keep the live file intact; clean only prior backup clutter - Apply this deliberately in future releases so backup growth does not accumulate in config, logs, reports, tmp, or roadmap areas - (PENDING:…
FacebookReels poster
Cloud Readiness
New
- Prepare for cloud execution
FacebookReels poster
File Management / Retention Cleanup (shared concern)
New
- (PENDING: Layer into remaining scorers/reporters/splitters as they are touched in future work) - (PENDING: JITRCleaner rescheduled via launchd as safety net for shared dirs)
FacebookReels poster
Logging / Observability
New
- (NEXT: Phase 2 — adaptive tuning of today's target based on 1/7/30-day performance signal. Coordinated with Instagram poster, owned in tandem. Don't build until Phase 1 has run 3+ weeks.)
FacebookReels poster
Multi-Client Support
New
- Support multiple Facebook pages/accounts - (Inventory items, signed off 2026-05-05 against multi_client_hardcoded_values_inventory.md) - L40: . "$CR/artists/hecojeni.env" → dynamic per-client env sourcing - L206: 'Hecojeni' Python fallback in title-cleaning → ${CLIENT_DISPLAY_NAME} - L223: "Hecojeni" arg passed to caption builder → ${CLIENT_DISPLAY_NAME} - Rename PAGE_ID references to CLIENT_META_PAGE_ID once per-c…
FacebookReels poster
UI / Mobile
New
- Support monitoring and control via UI/mobile
Hecojeni AdOps
Priority list
New
### Priority 1 — Prove source-of-truth access before new ads Business value: stops the cycle of ad experiments that cannot compound because we do not have a stable memory of why an ad ran, what happened on Meta, what happened on the website, and what downstream action did or did not occur.
Hecojeni AdOps
Why this program exists
New
Hecojeni needs paid-media decisions and reporting that are direct, repeatable, and data-driven under a hard $8/day cap. Jeff should get plain-English business updates and stable automation, not browser chores or Ads Manager homework.
Hecojeni Billing Historical Table
Priority 1 — Jeff Review Of Current DEV Billing Output
Business value: - Prevent newly discovered categories from becoming invoice-facing before the month-level charges pass business review. Current review anchors: - 2025-01: calculated charges are $225.52, so Client Minimum adds $274.48 to reach $500.00 - 2025-02: calculated charges are $97.33, so Client Minimum adds $402.67 to reach $500.00 - 2025-03: includes 7 recording sessions under the current song-project rule, w…
Hecojeni Billing Historical Table
Priority 2 — Deliberate DEV To PROD Release
Business value: - Move the validated historical table into PROD with a known rollback point, instead of trusting the older PROD copy. Notes: - Follow Jeff's release-management process for this one program only. - Prod was previously called untrusted during turnover. - No launchd work is expected unless Jeff asks for scheduling.
Hecojeni Billing Historical Table
Priority 3 — Reconcile Historical Table With JITR Billing Roadmap
Business value: - Avoid maintaining two competing billing systems: the practical historical table and the broader collector/rule-engine billing plan. Reference: - scripts/roadmap/JITR_Billing_roadmap.md
Hecojeni Billing Historical Table
Priority 4 — Invoice-Ready Evidence Mapping
Business value: - Let Jeff inspect exactly which filesystem / collector / receipt evidence caused each monthly charge before creating a customer invoice. Known evidence sources already in use: - Brevo monthly receipt CSV for email counts - Monthly Updates folder filename evidence for newsletter / Patreon - Collector CSV plus current MP3 duration check for audio recording / mixing - Filesystem snapshot logic for video…
Hecojeni Billing Historical Table
Purpose
Track remaining work for the DEV/PROD historical billing table. Completed release-specific work belongs in scripts/dev/Hecojeni_Billing_Historical_Table.readme.md.
Hecojeni Industry Outreach Operating Doc
Audience lanes
New
### Radio stations Desired win: - Spin Riding the Merry Go. - Add Hecojeni to a station rotation or specialty show. - Invite Hecojeni for an interview. - If geographically reasonable, host an in-station visit, acoustic sit-down, or small performance. Smallest useful signal:
Hecojeni Industry Outreach Operating Doc
Core premise
New
The Brevo industry list is a detection system. The job is not to warm up 10,000 people equally. The job is to identify the small number of industry contacts who can create real opportunities for Hecojeni, then treat those people with unusual care. For this list, a champion is not necessarily a paying fan.
Hecojeni Industry Outreach Operating Doc
North Star for the list
New
Find and develop 12 to 25 Hecojeni industry champions who can repeatedly create opportunity. Success is measured by real-world outcomes: - confirmed radio plays - podcast interviews or song usage - playlist adds - press mentions, reviews, or interviews - sync pitches or placements
Hecojeni Industry Outreach Operating Doc
Physical outreach ladder
New
Physical outreach should follow signal. Do not lead with expensive physical mail to cold contacts unless there is a specific strategic reason. Recommended ladder: - Replied or requested assets: sticker/card or CD/card. - Confirmed play, interview, playlist add, feature, or useful intro: CD plus handwritten thank-you. - Repeated Ally: personal gift, station/show-specific gesture, or visit if
Hecojeni Industry Outreach Operating Doc
Release posture for Riding the Merry Go
New
Riding the Merry Go should be treated as a radio-friendly single. The outreach should make the desired action obvious: listen, consider for play, and tell us if the station or show wants anything else. Do not make this campaign cute. Do not lead with pronunciation, lore, or a high-friction ask.
Hecojeni Industry Outreach Operating Doc
Riding the Merry Go campaign rule
New
Every email for this release should answer one question: Would this make it easier for the recipient to play Riding the Merry Go or ask for what they need to play it? If not, remove it.
Hecojeni Industry Outreach Operating Doc
Signal ladder
New
Click: - Mark as warm for the release. - Do not overreact yet. Repeated clicks: - Add to champion watchlist. - Consider personal follow-up. Reply: - Set RELATIONSHIP_LEVEL to Human.
Hecojeni Industry Outreach Operating Doc
Tier model
New
### Active Cycle Gets the full release cycle and human attention. Includes: - Radio/Podcasters - meaningful Sync contacts - existing Humans and Allies - repeat clickers - replies
Hecojeni Single Release Checklist
Hecojeni Single Release Checklist
New
HECOJENI SINGLE RELEASE CHECKLIST — ROADMAP Canonical doc: $DROPBOX_ROOT/Just in Time Records/Business Files/Release Checklists/Hecojeni_Single_Release_Checklist.txt Owner / driver: Jeff. This is a Jeff-driven program, not a Heath-driven one. PROGRAM BUSINESS VALUE (why this checklist exists at all) 1.
Hecojeni Video Transcriber
Backlog
New
### P1 — none No active priorities. Program is in steady state. ### Cross-team — polish only, not blocking - JITRDashboard registers our subsystem. Reports drop nightly and the dashboard auto-discovers them (initially as an "untracked reporter" tile). For a richer presentation (status color, parsed headline) the dashboard owner can add "Hecojeni_Video_Transcriber" to KNOWN_REPORTER_FOLDERS in scripts/dev/JITRDashboar…
Hecojeni Video Transcriber
Out of scope (until Jeff says otherwise)
New
- Other artists / non-Hecojeni clips. - Clips outside TikTok and Reel Clips/ (scratch/staging dirs would create orphan thrash). - Translation, summarization, or any LLM post-processing of transcripts. - Re-transcribing existing transcripts on model upgrade (no retroactive re-runs unless asked).
Hecojeni Video Transcriber
Purpose
New
Maintain a 1-for-1 plain-text transcript library for every video clip under Artists/Hecojeni/Videos/TikTok and Reel Clips/. Mirror the source folder structure under Artists/Hecojeni/Business Files/Marketing Stuff/Hecojeni Video Clip Transcripts/. Runs nightly at 1 AM via launchd (com.jitr.hecojeni_video_transcriber). Release history is in the prod README at scripts/prod/README.Hecojeni_Video_Transcriber.md.
Hecojeni Video Transcriber
Status
New
v1.1 in prod since 2026-05-10 (added DailyEmail report drop). v1.0 was 2026-05-07 (initial prod + launchd at 01:00 daily). Library at 1-to-1 across the full clip tree (currently ~6,000 clips).
Internal JITR Expense Generator
Accounting Roadmap Notes Added 2026-04-11
New
These notes preserve the current accounting-only direction after the 2025 JITR / SWS / Hecojeni review work. They are roadmap inputs, not a directive to code every item before the next release. ### A. Freeze Business Formulae Lock the current business rules before pushing numbers into Zoho or backfilling history.
Internal JITR Expense Generator
Annual Close and Tax Support
New
Generate annual outputs including: - totals - summaries - tax-support files Support full year-end accounting. ---
Internal JITR Expense Generator
Completed (moved to dev release notes)
New
- Canonical Home - System Boundary - Filesystem Cleanup ---
Internal JITR Expense Generator
Cross-System Roadmap Notes Added 2026-04-10
New
These notes are roadmap inputs for the broader accounting system. They are not a directive that they must be implemented immediately before all other work. ### A. Collector Gap Assessment Original design intent was: - collector runs once per month - collector emits one monthly activity CSV - downstream systems consume that shared monthly evidence Observed reality is: - the current collector is still valuable, but it…
Internal JITR Expense Generator
Determine JITR Month Zero
New
Identify the earliest defensible month of JITR activity. This may include work outside Hecojeni. Define this as the starting point for all historical accounting. ---
Internal JITR Expense Generator
End State
New
A complete internal accounting system that: - covers all months since inception - produces monthly, quarterly, and annual outputs - supports tax reporting - cleanly separates internal vs pass-through costs
Internal JITR Expense Generator
Hard-Cost Classification
New
Each cost must be classified as: - Internal JITR expense - Pass-through (receivable) - Non-JITR / excluded This classification must be explicit and consistent. ---
Internal JITR Expense Generator
Hard-Cost Intake Process
New
Define a repeatable process for ingesting receipts and transactions. Support mixed input types. Ensure: - receipts are stored - extracted data is machine-readable - process is repeatable and auditable ---
Internal JITR Expense Generator
Historical Backfill
New
From Month Zero to present: For each month: - generate soft-cost outputs - store results in canonical structure Cover all months since inception. ---
Internal JITR Expense Generator
Lifecycle Arc — All-Entity, All-Months, From Month Zero (Jeff direction 2026-04-20)
New
This is the long-arc destination for the entire accounting workstream. Every per-script roadmap item below ladders into one of these phases. ### Phase L1. Find Month Zero for Every Entity For every entity in scope, identify the earliest defensible month of activity.
Internal JITR Expense Generator
Monthly Accounting Outputs
New
For each month, produce: - soft-cost outputs - hard-cost outputs - pass-through entries - accounting support files These must be complete enough to support accounting updates. ---
Internal JITR Expense Generator
Monthly Close Definition
New
A month is complete only when: - soft costs are calculated - hard costs are identified - classification is complete - Zoho files are generated - Zoho is updated ---
Internal JITR Expense Generator
Multi-Client Books — Phased Implementation (Jeff direction 2026-04-29, refined)
New
These artists are NOT new clients to onboard — they are historical relationships where JITR did the work but never had the infrastructure to bill. This is catch-up bookkeeping, not client setup. Use Hecojeni rules (billing + soft cost) for everyone, identically. Where evidence doesn't exist for a month, that month is simply zero — no bill, no cost. We're closing a loop on a past anomaly.
Internal JITR Expense Generator
Objective
New
Build the full internal accounting engine for Just in Time Records from inception through present. This system is responsible for: - internal JITR expenses - soft-cost labor accounting - hard-cost intake and classification - pass-through vs internal distinction - Zoho-ready accounting outputs - monthly close
Internal JITR Expense Generator
Quarterly Reporting
New
Generate quarterly summaries of: - internal costs - pass-through activity - trends ---
Internal JITR Expense Generator
Reintroduce Chat-Based Time Tracking
New
Recover or rebuild the method that derives work time from chat history. Integrate it with filesystem-derived time. Produce a single unified internal labor model. ---
Internal JITR Expense Generator
Soft-Cost Method (Filesystem + Chat Time)
New
Define the official canonical method for calculating internal labor costs. Canonical month-based soft-cost method: 1. Filesystem-derived activity - Use month-bounded file-touch sessionization as the current phase-1 baseline. - Current governed session rules: - gap <= 20 minutes => same session - sessions < 2 minutes ignored - Current governed categories:
Internal JITR Expense Generator
Zoho Integration
New
Generate accounting outputs in a format ready for Zoho. Eliminate manual preparation of accounting data. ---
JITRCleaner
Absorbed scope
New
Folded into JITRCleaner; sibling roadmaps to retire: - Prod_Hygiene_and_Shim_Checker.txt — its items (shim hunt, prod hygiene audit, orphan launchd references, cross-machine validation, weekly consolidated report) are covered by JITRCleaner_Discovery.sh and the priorities below. - Log_and_Report_Cleanup.md — already satisfied by the shipped state machine. Shim_Checker.roadmap stays separate.
JITRCleaner
Open questions (carry forward, do not code on)
New
- Should JITRCleaner write directly into each offending program's roadmap file, or only into the consolidated report? Writing into roadmaps is pushier but also harder to undo. - For Priority 1 (archives aging): one window for all archive types or separate windows? Settle before coding.
JITRCleaner
Priority 1 — Archives aging policy
New
Business value: archives are not long-term storage. Today config/_archive is count-pruned (keep newest 2 per script) and scripts/archives/ has no age policy at all — files go in and never come out. Without an aging policy, archives grow forever and the "keep an audit trail" justification stops being honest. Scope: - config/_archive/ — current behavior keeps newest 2 .sh.v* per script.
JITRCleaner
Priority 2 — Weekly self-measurement / KPIs
New
Business value: a number we can watch over time tells us if the system is trending toward bloat or staying healthy. Without it, we'd only notice when the disk fills up. Metrics, weekly cadence: - Total JITRBeats folder size (GB). - Total file count. - Average file age (days). - Per-launchd-program size (GB) and file count — so natural growth as new
JITRCleaner
Priority 3 — Best-practices / onboarding doc
New
Business value: the advisory report assumes other dev sessions know what "clean" means. Today they don't. A short written doc lets us point new and existing chats at the rules so they don't have to re-derive them — and makes the cleaner's "fix at source" advisories actionable. - One markdown doc, lives in JITRBeats (location TBD; likely scripts/roadmap/-adjacent or in the dev onboarding doc).
JITRCleaner
Priority 4 — Discovery-walk follow-up sections (still under v1 umbrella)
New
Business value: the v1 discovery walk ships three sections (footprint, pristine, stray programs). The roadmap originally listed several more finding classes that were deferred from v1. They can be added section by section to the same script as follow-up releases. Deferred from v1: - Dev-versions-older-than-prod.
JITRCleaner
Priority 5 — Escalation policy for unowned messes
New
Business value: some findings will never get an owner. Without an escalation path, they sit in the report forever and the report loses credibility. Proposed policy (to be confirmed with Jeff before implementation): - First appearance in report: advisory only. - Still present after N weeks with no action: JITRCleaner sweeps it under the failsafe layer. - Always logged, never silent.
JITRCleaner
Priority 6 — Known hardening of existing failsafe code
New
Business value: the shipped daily failsafe (JITRCleaner.sh) has known-fragile spots the previous team flagged. These don't block discovery work but should be fixed before the program is considered mature. - Filename-safe iteration: for F in $(find …) breaks on spaces/newlines. Switch to null-delimited find -print0 + while IFS= read -r -d ''.
JITRCleaner
Priority 7 — Cross-machine awareness
New
Business value: JITRBeats runs across Jeff's Macs; hygiene findings on one machine aren't necessarily true on another. Per shim policy, the discovery walk must be portable and must not confuse a machine-local absence with a system-wide absence. - Report header must identify which machine produced it.
JITRCleaner
Shipped — JITRCleaner program family
New
- JITRCleaner.sh (daily failsafe, 08:00). Advisory-first state machine for active files: 90-day flag → 30-day grace → delete. Shipped 2026-05-05. See the JITRCleaner README "Release notes" section for release detail. - JITRCleaner_Discovery.sh (weekly discovery walk, Sundays 06:00).
JITRCleaner
Vision
New
JITRCleaner is the system-hygiene program for JITRBeats. Its job is not just to delete old files — it is to keep the whole environment clean and to push responsibility for cleanliness back onto the program that caused the mess. Three layers, in order of preference: 1. Discovery. Find what is dirty/stale/out-of-place across the JITRBeats footprint. Attribute each finding to the owning program whenever possible. 2.
JITRCleaner
Vision update — 2026-05-06 (anchor)
New
Jeff's broader vision for JITRCleaner has five buckets. Buckets 1 and 2 are shipped (see above). Buckets 3, 4, 5 are the priorities below. 1. Active files (TMP / LOGS / REPORTS). ✓ Shipped (JITRCleaner.sh). 2. Programs (dev / prod / emer). ✓ Shipped (JITRCleaner_Discovery.sh). 3. Archives. Archives are not long-term storage.
JITRDashboard
6a. Auto-update the Hecojeni Metrics spreadsheet weekly
New
Business value: Jeff stops typing into the spreadsheet entirely while the spreadsheet itself stays a familiar visible artifact. The system writes a fresh weekly row using whatever live-API values it has (Facebook, Instagram, YouTube, Patreon — and Aweber once that lands), and leaves cells the system can't fill (TikTok, X, Spotify Monthly Listeners) blank for Jeff to fill or for a future scraper to fill.
JITRDashboard
6b. Stop the mailer from leaving a draft copy behind on every send
New
Business value: Emails are arriving correctly — Jeff confirmed delivery on 2026-05-04. The cosmetic-but-annoying issue is that each send also leaves a copy of the same message sitting in Drafts. Over a week that's ~14 ops + 7 artist + 1 weekly = 22 stale drafts cluttering the Drafts folder, and Jeff occasionally uses Drafts for his own real drafts. This is a polish item, not an outage.
JITRDashboard
6c. Email the weekly Hecojeni Metrics summary to Jeff and Heath (Monday morning)
New
Business value: Closes the loop on 6a. The spreadsheet now updates itself every Monday at 5:30 AM, but nobody sees the result unless they open the file. A short Monday-morning summary email keeps Heath in the funnel-growth conversation without requiring him to remember to check, and gives Jeff a glanceable confirmation that the writer fired correctly.
JITRDashboard
8a. Publish JITRBeats updates onto the JIT Records website (added 2026-05-08 · SUPERSEDED by 20c on 2026-05-11)
New
Business value: The JITRProduct page generated automatically at https://jitrbeats.pages.dev shows current product features and the upcoming roadmap, but a visitor landing on https://www.justintimerecords.com today sees nothing about JITRBeats unless they happen to know the separate URL. JITRBeats is the flagship product of Just in Time Records and should be visible on the JITR website itself.
JITRDashboard
Agentic ticketing system (alert → ticket → agent → close)
New
Business value: Formalizes the loop Jeff already runs manually today: dashboard detects an issue, Jeff hands a memo to the relevant specialized chat, that chat fixes it. Making this a real system means (a) no issues are dropped because Jeff didn't get around to the hand-off, (b) every fix has a durable record (who, what, when, why), and (c) eventually the specialized chats wake themselves up and work tickets autonomo…
JITRDashboard
Automate fan-count collection from platform APIs (follow-on)
New
(Sub-items below cover individual platforms.) ### 7a. Scrape public follower counts (TikTok, X, Spotify monthly listeners) Business value: Three platforms where the data is publicly visible on the artist's profile page but no clean API path exists for our budget today. Hand-typing them weekly is exactly what Jeff said to stop doing.
JITRDashboard
Bugs, regressions, and audit follow-ups (batch added 2026-05-08)
New
Business value: The artist dashboard's "Your audience" section shows YouTube, Facebook, Instagram, TikTok, X, etc. as platform cards with sparklines. They were supposed to render in a single horizontal row (matching the JITR ops dashboard's audience section) but on Jeff's screen as of 2026-05-08 they're stacked single-column.
JITRDashboard
Daily-report shape revisions (batch added 2026-05-08)
New
Context: As Jeff used the dashboard and the daily ops email through early May, several sections felt too verbose or showed the wrong thing. This is a batch of related polish items — group of small UX-shape changes to the existing report and dashboard surfaces. Each has its own scope below; they're listed here together because they can be picked up in any order and ship independently. ### 18a.
JITRDashboard
Explicitly not on the roadmap
New
- Real-time streaming / websockets. 15-minute regeneration is plenty for this use case. - Power BI / tableau / any licensed BI tool. Wrong shape for a one-person operator dashboard. - Public fan-facing dashboard at hecojeni.com. Possible future initiative, but belongs on a different roadmap (artist site, not ops).
JITRDashboard
External dependencies (NOT owned here)
New
- TikTok engagement data (views, likes, comments, shares) — assigned to the TikTok automated poster team. They will deliver engagement output in a scorer-shaped file (same shape as Facebook/Instagram scorers). When that lands, JITRDashboard removes the WIP flag on TikTok's platform card and lights up its engagement card.
JITRDashboard
Fan-growth callout on the JITRBeats product page (investor-facing) (DEFERRED 2026-05-11)
New
Business value: Concrete audience-growth data on the public product page is the strongest single investor / prospect signal we can surface. Abstracts the machine's effectiveness into one number. Why deferred (2026-05-11): Per Jeff's 2026-05-11 feedback, the JITRBeats product page is system-facing, not client-facing — client-specific data does not belong there.
JITRDashboard
Fork the generator into an artist (Hecojeni) view
New
Business value: Two audiences (operator vs artist) get articulations that match their interests — Jeff sees "is it working?", Hecojeni sees "how is my music doing?" — from the same underlying data. Scope: - Output path: $JITR_REPORTS/Dashboard/hecojeni/index.html - Artist view drops: stale reporter alerts, token warnings, pool-decay noise, WIP status language - Artist view emphasizes: engagement trend, standout clips…
JITRDashboard
Hecojeni dashboard — release / Spotlight section restructure (added 2026-05-11)
New
Context: Jeff's 2026-05-11 review of the Hecojeni artist dashboard called out several problems with the current "Your next single" / Upstream / Bottleneck / Stage Flow section. Most of it is too technical, some of it doesn't explain to the customer what it means, and some of the numbers shown may not be real data.
JITRDashboard
Historical sparklines (7-day posting cadence per platform)
New
Business value: Lets Jeff see trends, not just today — catches slow slides before they become red. Scope: - Persist a daily rollup in $JITR_STATE/JITRDashboard_history.csv (one row per platform per day) - Inline SVG sparklines on each platform card (no external charting dependency) - 7-day window; monthly rollup separate
JITRDashboard
Host the ops dashboard on a subdomain (Cloudflare Pages + GoDaddy DNS)
New
Business value: Jeff's exec view becomes always-current from any device, tappable from the iPhone home screen as a PWA. Replaces "delete the daily email" friction with "glance at the dashboard." Scope: - Create a Cloudflare account (free tier) - Create a Cloudflare Pages project pointed at the dashboard output - Point a subdomain (e.g.
JITRDashboard
Ingest Hecojeni Metrics (fan growth) into the presentation layer
New
Business value: Makes the real fan-funnel numbers visible in the same place Jeff and Hecojeni are already looking. JITRBeats' North Star is 5K Patreon fans — current total is ~280 followers across five platforms. That gap is the whole point of the machine, and it belongs front-of-mind on the daily dashboards, not buried in a spreadsheet.
JITRDashboard
JITRBeats public-facing reshape — weekly status + JITRProduct page (added 2026-05-11)
New
Context: Per Jeff's 2026-05-11 feedback on the JITRBeats Weekly Status email and the JITRProduct page (jitrbeats.pages.dev): both surfaces are system-facing, not client-facing. Their audience is new clients and investors, not Jeff-as-operator and not Hecojeni.
JITRDashboard
Monthly AI video recap (Hecojeni-facing)
New
Business value: A watchable 2-minute "here's your month" clip — the kind of thing that's actually forwardable, celebrates growth, and keeps artist engaged in the system. Scope: - Monthly cadence only (NOT daily — a daily AI newscast of "everything's fine" is worse than no newscast) - Script generated from the artist dashboard data (reach, top clips, growth) - Narration via ElevenLabs or HeyGen avatar - Delivered to H…
JITRDashboard
Push alerts layer (event-driven, separate from dashboard)
New
Business value: Jeff stops checking and the system tells him when something needs attention. Converts the dashboard from something to pull-to into something that quietly handles itself 95% of the time. Scope: - Integrate Pushover (one-time $5, iOS app with native banners) OR iMessage via AppleScript - Triggers: posting stops on any platform > 6h, token expiry within 48h, IG_PROCESS_FAILED spike, reporter staleness cr…
JITRDashboard
Real-phone testing + PWA polish
New
Business value: Dashboard lives on Jeff's iPhone home screen like a native app — one tap. Scope: - Add apple-touch-icon and manifest.webmanifest - "Add to Home Screen" produces a clean icon + full-screen app feel - Test on actual iPhone over cellular; iterate on spacing/font-size - Verify Safari vs Chrome render parity
JITRDashboard
Schedule regeneration via launchd
New
Business value: Dashboard is always fresh without Jeff thinking about it. Scope: - Mac mini only (per JITRBeats LaunchD standard) - Cadence: every 15 minutes - Wrapper .sh script that sources shim + jitr_vars.env then calls the Python generator - Once hosted, same schedule also pushes to Cloudflare Pages - Full JITRBeats LaunchD Standard: no exec, no process substitution, local OS-native paths for launchd-level logs
JITRDashboard
Self-healing for known outage classes
New
Business value: A real outage on 2026-04-25 took JITRBeats off the air for 17+ hours before it was visible — every poster cycle silently failed because ShimSelector was broken upstream. The dashboard caught it in the morning, but the system did not try to fix itself in between.
JITRDashboard
State of the Library section (both dashboards)
New
Business value: One-glance answer to "what do we actually have, and how healthy is the library?" — independent of what posted today. Surfaces anomalies that would otherwise hide in the file system forever (mis-named clips, unusual durations, score outliers).
JITRDashboard
Weekly investor-grade email cadence (PARKED 2026-04-18)
New
Business value: A separate, weekly-cadence email aimed at a different audience (Jeff-as-business-operator, future investors) covering releases this week, feature list updates, roadmap progress. Different template from daily ops/artist emails. This is the signal buried in the WeeklyReporter turnover.
Lineage
Design principles
New
- Identity by audio, not filename. Filenames are a hint; the audio is the truth. - Read-only first. No renames or moves until a cluster is high- confidence AND Jeff has approved it. - Disposition is owned by Jeff (and Heath). Lineage proposes; humans decide. Automation never rejects an idea. - State lives under $JITR_STATE/lineage/ — fingerprints, features, ratings, dispositions, all keyed by stable cluster IDs.
Lineage
Five tracks of work
New
| Track | Purpose | |---|---| | A. Identity | Which files are the same idea? | | B. Features | What is each idea, musically? | | C. Human signal | What do Heath & Jeff think of it? | | D. Reference profile | What defines the Hecojeni sound? | | E. Oracle | What should Hecojeni work on next, and why? |
Lineage
Priorities (next)
New
### Priority 1 — Track B: Musical feature extraction (NEXT) Build Lineage_features.sh that extracts BPM and key per audio file, with the same caching pattern as Lineage_fingerprint. Likely tools: aubio (aubiotempo) for BPM, keyfinder-cli for key. State at $JITR_STATE/lineage/features.tsv. - Business value: every Oracle output (E) needs musical features to reason about compatibility, drift, and gap.
Lineage
Scope
New
There is one pipeline of interest: Hecojeni's. The cross-artist folders (The Chillbumps, Jeff Niebuhr, BuddhaFi, Audiospam2.0) are treated as source streams of Hecojeni-bound material — not as independent pipelines. The 8 source streams Lineage watches: 1. Music Memos (Apple Music Memos app, .caf, Dropbox) 2. Voice Memos (Apple Voice Memos app, .m4a, iCloud — needs FDA) 3. GarageBand for iOS (.band bundles)
Lineage
Shipped
New
### Track A3 v0.1 — 2026-05-11 — Lineage_fingerprint (Chromaprint identity) - Computes fpcalc fingerprints for every leaf audio file in 7 readable streams (3,173 files). Caches in $JITR_STATE/lineage/fingerprints.tsv keyed by path+mtime. Cold-cache 545 s; warm-cache 10 s. - Clusters by sha256 of fingerprint — exact-identity only (v0.1 scope).
Lineage
Vision
New
Lineage organizes every musical fragment Hecojeni has ever touched into a tool that helps Hecojeni decide what to work on next — backed by evidence (age, ratings, tempo, key, companion fit, gap-fill). The end deliverable looks like: > "Hecojeni: here's the next snippet to flesh into a song. Heath and > Jeff both rated it 4/5. Its BPM is 1.8σ off the released-Hecojeni mean > (room for a faster track).
Lineage
What's NOT in scope
New
- BuddhaFi / Audiospam2.0 / Chillbumps / Jeff Niebuhr as independent pipelines. They're source streams for the single Hecojeni pipeline. - Spotify / external-service ingestion. Already covered by other JITR plumbing. - Audio quality / loudness mastering analysis (could land later under track B4 if we want it).
Meta
How this file gets maintained
New
- Jeff says "I want X" → I add a row to "Open / Queued" the same turn - Jeff approves a sequence → matching row(s) move to "In Flight" - Work ships to PROD → row moves to "Recently shipped" with date - Question comes up that needs Jeff → goes to "Open Questions" - Nothing gets silently deleted — if an item is no longer relevant, it gets a one-line "retired YYYY-MM-DD: <why>" entry Per-program roadmap files keep the l…
Meta
✅ Recently Shipped (last ~30 days)
New
Highlights only. Full per-program detail in the program-level roadmap files. ### Posting reliability (IG + FB) - Frequency-control denominator bug (4/20) — posts_per_day=12 actually delivers 12, was delivering 9 due to hardcoded denominator - IG_PROCESS_FAILED false-positive (4/22) — poller no longer mis-classifies transient ERRORs as terminal; poll window 150s → 300s; IG_PROCESS_FAILED event retired - FB upload retr…
Meta
🔵 Parked Architecture
New
Big future work. None of this is starting unless you explicitly open the door. | # | Theme | Why parked | |---|---|---| | P1 | Multi-Client Support (extend posters/reporter to handle multiple artists) | Hecojeni-only system today. Would be a significant refactor. | | P2 | Cloud Readiness (move off Mac mini hard dependency) | Working fine on Mac mini post 5/2 plist + pmset fixes.
Meta
🟡 In Flight
New
Concrete work currently in progress this conversation. | # | Item | Source | Status | |---|---|---|---| | 1 | 7-day rollup view in MetaAutoPoster_reporter | "more insightful reporting" plan, 2026-04-29 | Started today (5/3) — adds a weekly section mirroring the daily one, with target × 7 and σ × √7 thresholds. Reads posts_per_day from existing schedule config. | ---
Meta
🟢 Open / Queued
New
Real work, scoped, not started yet. Pick order is my recommendation; Jeff overrides. | # | Item | Source | Effort | |---|---|---|---| | 2 | Per-clip-type engagement breakouts (SS / GE / PR) | "more insightful reporting" plan, 2026-04-29 | Medium — joins scorer output to poster logs | | 3 | Top/bottom performing posts of the week | "more insightful reporting" plan, 2026-04-29 | Medium — uses scorer engagement deltas;…
Meta
🤔 Open Questions for Jeff
New
Items I can't move forward on without your input. | # | Question | Context | Why it's stuck | |---|---|---|---| | Q1 | AI-tagged SS clip rejections on Instagram — accept the loss rate, gate AI clips out of IG selection, add Meta's "AI-generated content" disclosure flag, or something else? | Three terminal IG_POLL_TIMEOUTs on SS-AI clips (4/27, 4/28, 4/30) all hit Meta error code 2207076.
MetaAdsReporter
Notes / non-goals
New
- This program reads only. It does not change ad budgets, statuses, creatives, or audiences. A future MetaAdsManager program will own writes — see its own roadmap when it exists. - The token used is a system-user token. It is not the same token the organic posters use (those are Page tokens). Do not consolidate the two without explicit Jeff sign-off.
MetaAdsReporter
Priority list
New
### Priority 1 — Ship the first version end to end (in flight) Business value: gives Jeff a daily plain-English read on ad performance without him touching Ads Manager. Same shape as the organic-posting reports he already reads, so it slots straight into his morning routine.
MetaAdsReporter
Why this program exists
New
Hecojeni's paid-ads truth has lived only in the Meta Ads Manager web UI. That requires a logged-in browser session and a person willing to look. Hecojeni / Jeff explicitly do not want to be in the data-acquisition loop. This program pulls the numbers directly from Meta's Marketing API and hands them to the existing DailyEmailer subsystem.
MetaAutoPoster reporter
Cloud Readiness
New
- Prepare reporter for cloud-based aggregation
MetaAutoPoster reporter
Multi-Client Support
New
- Support reporting across multiple clients/accounts
MetaAutoPoster reporter
Reporting Enhancements
New
- Expand visibility into retries and pipeline health (concretized 2026-05-12 after audit): - The posters already log retries — Publish attempt N of 3 / Upload attempt N of 3 (IG/FB), IG_POLL_TIMEOUT ... error_count=N, *_UPLOAD_FAILED attempts=3. The data is there; the reporter just doesn't surface it.
MetaAutoPoster reporter
UI / Mobile
New
- Provide GUI/mobile-friendly reporting views
monthly fan process
monthly fan process
New
PROGRAM: monthly_fan_process PURPOSE The monthly fan process is a downstream fan-engagement workflow. Its job is to consume the already-created monthly collector CSV and produce downstream fan-engagement artifacts, including: - monthly narrative output - newsletter files
multi client hardcoded values inventory
Confirmed agnostic — no multi-client work needed
New
These scripts were scanned and confirmed to have no real client coupling. (Some had bulk-grep matches that turned out to be test fixtures, comments, or false positives.) - Selector_pick_one.sh — generic queue consumer. - Selector_queue_manager.sh — generic queue manager. - ShimSelector_pick_one.sh — shim-aware selector. - ShimSelector_queue_manager.sh — shim-aware queue manager.
multi client hardcoded values inventory
Cross-cutting observations from Tier A
New
Patterns that span multiple programs in this tier — these are master design decisions to settle before per-program coding: 1. Single hecojeni.env source line is the most common coupling pattern. Almost every program has one of: . "$CR/artists/hecojeni.env", . "$CFG/artists/hecojeni.env", or the equivalent Python os.path.join(..., "config/artists/hecojeni.env").
multi client hardcoded values inventory
Dashboard territory — DO NOT TOUCH (coordinate with Dashboard stream owner)
New
Per Jeff's explicit guidance during this transition, the JITRDashboard family is owned by a separate stream and is being actively worked on. The inventory captures their coupling for completeness, but per-program memos are not written for these scripts — instead, the Dashboard stream owner should be looped in directly so the multi-client question is answered as part of their existing work, not in parallel.
multi client hardcoded values inventory
How this document is organized
New
Programs are listed in three tiers, matching how the conversion work is being staged: - Tier A — high-traffic posters / scorers / selectors. The conversion template every other program will follow. - Tier B — reporters and utilities. Mechanical work after Tier A pattern is set. - Tier C — Internal-JITR programs and Dashboard territory.
multi client hardcoded values inventory
Proposed naming convention
New
When extracting hardcoded values to per-client config, use the CLIENT_ prefix as the generalization of today's HEC_ prefix. | Today | Generalized | |---|---| | HEC_VIDEOS_ROOT_DBX | CLIENT_VIDEOS_ROOT_DBX | | HEC_TTR_ROOT_DBX | CLIENT_TTR_ROOT_DBX | | HEC_SLOTS_DBX_DIR | CLIENT_SLOTS_DBX_DIR | | HEC_SLOTS_GDRIVE_DIR | CLIENT_SLOTS_GDRIVE_DIR | | HEC_RELEASE1_, HEC_RELEASE2_ | CLIENT_RELEASE1_, CLIENT_RELEASE2_ |
multi client hardcoded values inventory
Tier A — High-traffic posters / scorers / selectors
New
### TikTok_poster.sh - Files: prod/TikTok_poster.sh and dev/TikTok_poster.sh — prod + dev (identical) - Findings: - Literal client strings: - L10: . "$CR/artists/hecojeni.env" → source ${CLIENT_SLUG}.env - L18: SRC_DIR="$DROPBOX_ROOT/Just in Time Records/Artists/Hecojeni/Videos/TikTok and Reel Clips/Song Specific Videos/Christmas Lost Today/Christmas Lost Today - AI" → two concerns mixed: Hecojeni is client coupling…
multi client hardcoded values inventory
Tier B — Reporters, utilities, scorers, token & auth scripts
New
Most Tier B programs follow a small number of repeating coupling patterns: - Pattern P1 (env-source only): the script sources hecojeni.env and may reference HEC_ env vars; no literal "Hecojeni" strings in business logic. Conversion is mechanical: route the env source to the active client's <slug>.env and rename HEC_ → CLIENT_*.
multi client hardcoded values inventory
Tier C — Internal-JITR / Accounting / Billing programs
New
These programs are structurally different from Tier A and Tier B. The Tier A/B programs act on a client's data (post a Hecojeni clip; rename a Hecojeni video). For these programs, the operating subject is JITR itself — the script lives in JITR's accounting / billing / dashboard / time-tracking domain. Hecojeni appears in the code because Hecojeni is JITR's customer, not because the program is Hecojeni-scoped.
multi client master config spec
Architecture summary
New
A per-client namespace (a folder), not a single file. Inside each client's folder live several files with different roles, formats, edit cadences, and security postures. ``` config/clients/<slug>/ client.yaml # SOURCE OF TRUTH — structured, GUI-editable later client.env # DERIVED — regenerated from client.yaml; shell scripts source this tokens/ # Platform credentials — separate permissions / rotation meta.conf tiktok…
multi client master config spec
Companion artifacts (not yet written)
New
- config/clients.env — top-level master client list (one line for now: CLIENTS="hecojeni"; becomes "hecojeni mfdj" after MFDJ onboarding). - config/clients/_client_template/ — skeleton folder for new-client onboarding. - config/clients/hecojeni/client.yaml — Hecojeni's master config, hand-authored from today's hecojeni.env. - scripts/dev/jitr_regen_client_env.sh — the YAML-to-env generator.
multi client master config spec
File formats
New
### clients.env (top-level) Lives at config/clients.env. Sourced by Tier C / accounting programs and any program that iterates over all clients. That's it — one variable. Programs that need a richer customer model (rate-card status, billing terms, onboarding date) can load config/clients/<slug>/client.yaml for each slug listed. ### client.yaml (per-client master, source of truth)
multi client master config spec
Load order for scripts
New
The active client is selected by an environment variable named JITR_ACTIVE_CLIENT (or by an explicit --client <slug> argument the script accepts). Selection order: 1. Explicit --client <slug> arg if the script accepts one 2. JITR_ACTIVE_CLIENT env var 3. Default to the first slug in config/clients.env's CLIENTS list For shell scripts, the canonical loading sequence becomes: ```bash # 1. Machine shim .
multi client master config spec
Migration plan from today's `hecojeni.env`
New
The current hecojeni.env becomes the seed for config/clients/hecojeni/client.yaml. The migration is incremental and back-compat: Phase 0 — preparation (no script changes) - Create config/clients/hecojeni/ folder structure - Hand-author config/clients/hecojeni/client.yaml from current hecojeni.env values - Run the generator to produce config/clients/hecojeni/client.env - Manually diff the generated client.env against…
multi client master config spec
Onboarding sequence for a new client
New
When a new client is onboarded (MFDJ or beyond), the file-creation sequence is: 1. cp -r config/_client_template config/clients/<slug> 2. Edit config/clients/<slug>/client.yaml to fill in identity, brand, platform IDs, paths, etc. Values come from the onboarding decision matrix (separate doc). 3. Run jitr_regen_client_env <slug> to produce client.env. 4. Add <slug> to config/clients.env's CLIENTS variable. 5.
multi client master config spec
The generator
New
A small script (proposed: scripts/dev/jitr_regen_client_env.sh) reads client.yaml, resolves <derived> paths against the canonical subpath table, writes the derived client.env, and validates that all required keys are present. Trigger options (one or more): - Manual: the operator runs jitr_regen_client_env <slug> after editing client.yaml. - Pre-commit hook: regenerates on commit if client.yaml is staged.
multi client master config spec
Variable schema
New
Variables in client.env use the CLIENT_ prefix as the generalization of today's HEC_ prefix. The categories below correspond to YAML sections in client.yaml. Every variable that crosses platform / customer boundaries is listed here. Variables marked required must be present for any client. Optional variables are needed only by programs that touch the relevant subsystem. ### 1.
multi client master config spec
What program owners can take from this spec right now
New
If you're a program owner planning your multi-client conversion: - The variable names in section 2 ("Variable schema") are stable. You can rename HEC_ → CLIENT_ per the table, even before the file structure exists, by relying on the back-compat aliases that Phase 1 will provide. - The load-order pattern in section "Load order for scripts" is the canonical replacement for today's . "$CR/artists/hecojeni.env" line.
multi client master config spec
What this spec does NOT decide
New
These remain open and need to be settled before or during the first conversion pass. They are upstream of any per-program work that depends on them. 1. Folder-name-as-data convention. Today's folders "General Hecojeni" and "Pronounce Hecojeni" embed the client name.
multi client transition
Business value
New
- Every item exists to enable the JITRBeats system to serve a second client (MFDJ) without forking the code. - Long-term: a repeatable onboarding process that turns "new client" from a multi-week scramble into a checklist. - Side benefit: hardcoded values being extracted from code into config files makes the system more maintainable and auditable regardless of multi-client. ---
multi client transition
Notes for whoever picks this up next
New
- Observation hold: AgeScorer and Scoring v2 are parked through 2026-04-20 — include them in the inventory but do not touch their code until the hold lifts. - Reporter scripts overlap the Daily Reporter / Dashboard stream — coordinate before picking a reporter as pilot. - The Hecojeni-specific scripts named hec_ and Hecojeni_ should be renamed during conversion. The script names themselves are coupling.
multi client transition
Out of scope
New
- Cloud migration (separate roadmap). - External-client (non-JITR-controlled) onboarding — current scope is JITR-internal artists only. - Internal-JITR programs whose "client" is JITR itself (Internal_JITR_Expenses_Collector, Hecojeni_Billing_Historical_Table) do not get the standard multi-client treatment; they're cross-cutting and need separate handling. ---
multi client transition
Priority 1 — Inventory and decision artifacts (this chat's deliverables)
New
These are documents/memos. No production code changes. ### 1.1 Hardcoded-values inventory across prod and dev For every active script in scripts/prod/ and scripts/dev/, identify embedded client-specific values: literal "Hecojeni"/hec_ strings, HEC_ env var references, hardcoded account IDs / emails / tokens, hardcoded artist folder paths, and shared-state files missing client partitioning.
multi client transition
Priority 2 — First conversion pilot (script-level work, owned by individual streams or Claude)
New
Once Priority 1 artifacts exist, pick a single low-risk script as the multi-client pilot. Convert it end-to-end (dev → emer → prod) as the working template every other script will follow. Pilot candidate decision deferred until the Daily Reporter / Dashboard stream coordination check-in is done — many natural pilots are reporters, which overlap their territory. ---
multi client transition
Priority 3 — Per-program conversion work
New
After the pilot establishes the pattern, hand the per-program memos (from item 1.1) to each program's owner. Each owner converts on their own roadmap, independently. Claude may do some of this work directly and may advise other streams on the rest — decided per script. ---
multi client transition
Purpose
New
JITRBeats today implicitly assumes one client (Hecojeni). The business is onboarding a real second client — My Forever DJ (MFDJ) — which forces the system to become explicitly multi-client. This roadmap captures the work required to make that real. Not every item requires Claude to do the coding.
Narrator
Backlog
New
### P1 — V1 Narrator (ship the boring engine) Stand up the minimum useful Narrator end-to-end: - osxphotos query against album "Hecojeni - all files", duration ≥ 25 min. - For each in-scope UUID with no existing transcript: extract audio, run Whisper, write atomic .txt to the destination dir. - Header line inside each transcript: source UUID, original filename, duration, model, run date.
Narrator
Non-responsibilities (out of scope, by design)
New
- Clipping, summarization, theme tagging, sentiment, "interview vs music" classification (RockerTalker territory — see P2 below). - Posting, scheduling, newsletter drafts, book chapters — those are downstream consumers of Narrator's output, not Narrator's job. - Word-level timestamps / JSON sidecars (Blinker_transcribe_pool covers song mp3s). - Other artists. Hecojeni-only for V1.
Narrator
Open questions (resolve during P1)
New
- Whisper model choice — decided by pilot batch quality. - Whether to also write a small JSON sidecar per transcript (UUID, duration, model, run timestamp) for downstream consumers, or keep that metadata inside the .txt header only.
Narrator
Out of scope until Jeff says otherwise
New
- Non-Hecojeni artists. - Videos shorter than 25 minutes (clip transcriber covers the short end). - Audio-only sources (mp3 pool, rehearsal recordings) — Narrator is video-from-Photos for V1. - Any LLM post-processing of transcripts (summarization, clipping, thematic grouping). Those are separate downstream programs.
Narrator
Purpose
New
Build the long-form narrative corpus that the existing clip transcriber can't. Hecojeni_Video_Transcriber produces companion text for ~15-second posting clips — useful for captions/hashtags, but too short to express the voice of Hecojeni. Narrator transcribes the original long-form videos (interviews, sessions, long takes) so we have full-length narrative text we can later mine for quotes, themes, newsletters, books,…
Narrator
Responsibilities (in scope)
New
- Query the Photos album, apply the ≥25-min filter. - Resolve each in-scope video's original file path. - Skip anything already transcribed. - Run Whisper, write atomic plain-prose .txt. - Log per JITRBeats standard: timestamped, display+file, 90-day sweep, status updates every N items with sec/item and ETA.
Narrator
Scope (settled 2026-05-10)
New
### Source - Apple Photos album: "Hecojeni - all files" - Filter: videos with duration ≥ 25 minutes - Accessed via osxphotos (Python). Photos UUID is the stable identity key — filenames inside Photos can change, UUIDs don't. ### Output - Destination: $DROPBOX_ROOT/Just in Time Records/Artists/Hecojeni/Business Files/Marketing Stuff/Hecojeni Long-Form Transcripts/ (sibling of the existing Hecojeni Video Clip Transcrip…
Narrator
Status
New
Idea stage. No script, no readme, no launchd. This roadmap is the artifact.
Per Platform Queues design
Appendix — Files that will change
New
| File | Change type | |---|---| | scripts/dev/ShimSelector_queue_manager.sh | Major rewrite (multi-queue loop) | | scripts/dev/ShimSelector_pick_one.sh | Small change (queue file lookup by poster) | | scripts/dev/Selector_reporter.sh | New per-platform subsection (Option A) | | scripts/dev/Selector_pool_syncer.sh | Minor — populates new column defaults on add | | config/ShimSelector_pools.csv | Schema change — 4 new…
Per Platform Queues design
Code changes
New
### 5.1 ShimSelector_queue_manager.sh — refills 4 queues, not 1 The script today: 1. Reads single config file 2. Computes total weight 3. Allocates 100-clip batch by weight × global 4. Writes to single queue file 5. Triggers stale-skip detection / hash-resolution The new script:
Per Platform Queues design
Configuration file changes
New
### 4.1 New columns in ShimSelector_pools.csv Today the file has these columns (in order): After this change, four more columns are added: ``` pool_path, weight, suggested_weight, weight_facebook, weight_instagram, weight_youtube, weight_tiktok
Per Platform Queues design
Coordination with the centralized weights recommender chat
New
The recommender writes to the suggested_weight column daily at 02:30. After this change: - The recommender still writes to suggested_weight — that doesn't break. - But suggested_weight is now ONLY a hint about the global weight. The recommender's advice doesn't directly translate to picking behavior since the per-platform columns are operative.
Per Platform Queues design
Current state (what we have today)
New
There is exactly one queue file on disk: Contents: a header row plus N data rows, each picked_path,pool_label. Today's queue size target is 100. One launchd job (com.jitr.shimselector.queue_manager, every 4 hours) checks the queue size. If below 100, it runs ShimSelector_queue_manager.sh, which reads ShimSelector_pools.csv for weights and walks the filesystem to weighted-pick clips into the queue.
Per Platform Queues design
Decisions confirmed by Jeff 2026-05-12
New
1. Default for empty per-platform weight cells: 1. ✓ 2. Small outage during cutover is acceptable. ✓ 3. tiktok_manual is the only TikTok caller for now; queue named _tiktok covers future auto-poster too. ✓ 4. Reporter updated in same release as queue change (Option A). ✓ 5. Memo to recommender chat sent before cutover. ✓ 6. Cutover safety: no recommender concerns. ✓ 7. Skip performance benchmark; build and observe.
Per Platform Queues design
Final queue routing map (confirmed by 2026-05-12 audit of production callers)
New
Production callers verified:
Per Platform Queues design
Goal in one sentence
New
Move the selector from a single shared queue (all four posters draw from the same list) to four per-platform queues (each platform draws from its own list, refilled with that platform's preferences) so that, e.g., YouTube can be configured to avoid AI content while Facebook leans into it. ---
Per Platform Queues design
Migration plan (small outage acceptable per Jeff 2026-05-12)
New
Phased deployment with one brief outage at the cutover: ### Phase A — DEV testing (read-only against current state) 1. Build new versions of queue_manager and pick_one in DEV 2. Add the four new columns to a TEST COPY of ShimSelector_pools.csv (not the live file yet) — populate with sample per-platform weights 3. Run DEV queue_manager against the test config, verify it produces four sensibly-weighted queue files 4.
Per Platform Queues design
Open questions / things to think more about before coding
New
These are genuine uncertainties — not things I can answer alone: 1. TikTok auto-poster doesn't exist yet. We're creating a shim_selector_queue_tiktok.csv even though only tiktok_manual reads it for now. That's fine, but: when the real TikTok auto-poster lands, does it use --poster TikTok (current historical label in the ledger) or --poster tiktok? Consistency matters for the queue routing logic. 2.
Per Platform Queues design
Ready to start Phase A (DEV testing)
New
All design questions resolved. Next step: build new versions of ShimSelector_queue_manager.sh and ShimSelector_pick_one.sh in DEV, populate a TEST COPY of ShimSelector_pools.csv with the new columns, and run through the functional test matrix in Section 9.1 before any production cutover. ---
Per Platform Queues design
Reporter implications (out of scope for the queue change itself but needs coordination)
New
The existing Selector_reporter.sh will keep working against the legacy shared queue file until that file is retired in Phase C. Between Phases B and C, the legacy queue will stop being updated, so the report will go stale. Two options: - Option A: Update Selector_reporter.sh to read all four per-platform queues + aggregate for "overall" sections AND show a new per-platform section.
Per Platform Queues design
Target state (what we want)
New
Four queue files on disk: Each refilled independently with that platform's weighted selection. Each poster pops from its own queue based on --poster:
Per Platform Queues design
Testing strategy (per Jeff: "really good testing")
New
### 9.1 Functional tests (DEV) | Test | Setup | Expected | |---|---|---| | Default new pool | Add a folder to disk, run pool_syncer | New row in config with weight=1 and weight_<platform>=1 for all four | | Per-platform allocation | Set weight_youtube=40 on RtMG-AI, leave others at 1, force refill | YouTube queue is ~80% RtMG-AI; other queues are roughly uniform | | Stale-skip in YouTube queue | Inject stale row at Y…
Per Platform Queues phase a results
Implicit verifications (all pass)
New
- Each known poster pulls from its OWN queue and decrements only that queue's count - Per-platform locks allow concurrent picks across posters - Live state untouched throughout entire test run (verified at every step) - All log entries are annotated with (poster=<name>) for per-platform traceability
Per Platform Queues phase a results
Open items for Jeff before Phase B
New
None — all design decisions are captured. Phase B can proceed when Jeff signs off on these test results. Phase B will: 1. Stop posters + queue_manager launchd jobs (brief outage) 2. Add 4 new columns to LIVE ShimSelector_pools.csv (with default values seeded from current state) 3. Promote new queue_manager and pick_one to PROD with EMER rotation 4. Run queue_manager --force to produce all 4 live queues 5.
Per Platform Queues phase a results
Rollback if needed
New
EMER tier will hold the prior PROD code. Rollback is < 5 minutes: 1. Disable launchd 2. cp PROD → from EMER for both scripts 3. Re-enable launchd 4. Old shared queue file still exists (not retired until Phase C) so old script resumes using it
Per Platform Queues phase a results
Test matrix (all 7 pass)
New
### Test 1 — Per-platform allocation differs based on weight columns ✓ Setup: Sandbox config has weight_facebook=40 and weight_youtube=5 for all AI pools. Inverse for non-AI parent folders. Result: - Facebook queue: 48.8% AI clips (40/82) - YouTube queue: 7.8% AI clips (5/64) - 6.2× ratio difference — matches config exactly - TikTok queue: 33 Blink Videos (43%) reflecting blink weight bias toward TikTok The per-platf…
Per Platform Queues phase a results
What changed vs prior PROD
New
| Concern | Prior PROD | Phase A DEV | |---|---|---| | Number of queues | 1 (shared) | 4 (per-platform) | | Queue manager refill | One file, weight column | Four files, per-platform columns; default=1 if empty | | pick_one queue source | Hardcoded shared queue | Routed by --poster | | Poster lock | One global | Per-poster (parallelism) | | Unknown poster | Accepted, recorded as-is | ERRORs out exit 2 | | --force flag…
Per Platform Queues phase a results
What was built
New
Two scripts in DEV (not yet in PROD): 1. scripts/dev/ShimSelector_queue_manager.sh — Refills FOUR per-platform queues instead of one shared queue. Reads per-platform weight columns from ShimSelector_pools.csv. Supports --force flag (bypasses threshold for all 4 queues) and --config-dir / --state-dir / --logs-dir args (for sandbox testing without touching live state). 2.
Per Platform Queues phase a results
What was NOT touched
New
- Live config/ShimSelector_pools.csv — unchanged - Live state/ShimSelector/shim_selector_queue.csv — unchanged - All PROD scripts unchanged - All launchd jobs unchanged - No per-platform queue files exist in live state
Receipt Intake
Current state (2026-05-12)
New
No script. MVP is manual per-receipt processing inside this chat. Jeff drops a screenshot in chat; Claude finds the original file on disk, copies a renamed canonical version into the correct entity/year/month receipts folder, and appends one row to that month's manual_journal_entries.csv. No split logic, no manifest, no inbox-polling script, no separate program.
Receipt Intake
Filing convention (per Receipt_Intake_Memo_for_ChatGPT.md)
New
- Path: Business Files/Accounting/_Receipts/<Entity>/<YYYY>/<YYYY-MM>/ - Filename: receipt_<YYYY-MM-DD>_<VendorSlug>_<TxnID>.<ext> (VendorSlug = CamelCase no-spaces; TxnID fallback = <YYYY-MM-DD>T<HHMM>) - CSV: manual_journal_entries.csv in the same month folder, header as already established.
Receipt Intake
Roadmap
New
Priority 1 — get the MVP loop reliable. Process screenshot receipts as they arrive. Each one is an exercise in: find the file, copy + rename, append CSV row. Business value: every receipt produces immutable evidence + a journal row without operator handling. Priority 2 — none defined yet.
Receipt Intake
Screenshot discovery order (most recent file across these)
New
1. ~/Desktop (current com.apple.screencapture location, set 2026-05-12) 2. ~/Downloads 3. ~/Pictures/Screenshots 4. ~/Pictures
Reels Poster
Cloud Readiness
New
- Prepare poster for cloud execution (environment, secrets, networking) - Ensure portability beyond single-machine launchd execution
Reels Poster
Launchd / Execution Stability
New
- (NEXT: Phase 2 — adaptive tuning of today's target based on 1/7/30-day performance signal. Don't build until Phase 1 has run 3+ weeks and we have a defined performance metric. Engagement signal is currently too weak for naive tuning rules.)
Reels Poster
Multi-Client Support
New
- Extend poster to support multiple clients/accounts - Parameterize environment and credentials cleanly - (Inventory items, signed off 2026-05-05 against multi_client_hardcoded_values_inventory.md) - L207: 'Hecojeni' Python fallback in title-cleaning block → ${CLIENT_DISPLAY_NAME} - L211: "Hecojeni" arg passed to caption builder → ${CLIENT_DISPLAY_NAME} - Env-sourcing routes through jitr_env_autoload.sh (upstream); t…
Reels Poster
Reporting Enhancements
New
- Expand visibility into retries and pipeline health (concretized 2026-05-12 after audit): posters already emit retry/error_count log fields; the work to close this lives on the reporter side. See MetaAutoPoster_reporter_roadmap.md for the concrete sub-items.
Reels Poster
UI / Mobile Interface
New
- Develop GUI and/or mobile interface for: - Monitoring posting activity - Viewing errors and reports - Triggering manual runs
Renamer
Renamer
New
Renamer — Roadmap ---------------------------------------------------------------- Current status - 2026-05-07: Active roadmap below. Completed items moved to Renamer README: - Process scoring queue events - Production launchd kickstart validation
Riding the Merry Go Brevo PreRelease Draft
Button/link target needed
New
Use this Dropbox direct-download link: https://www.dropbox.com/scl/fi/wo9k21e0ip2k5lmcezw6h/Riding-the-Merry-Go.mp3?rlkey=mowvt0dh58xz87irt9mckzew8&dl=1 Use this Spotify artist link as a secondary context link: https://open.spotify.com/artist/5lxOC1dkSPHaXedHY4nFW5 Link check: - Dropbox shared link resolves and redirects to a download endpoint.
Riding the Merry Go Brevo PreRelease Draft
Email body
New
Morning, We are Hecojeni — Jeff and Heath in Greenville, South Carolina, still apparently making records after several chances to know better. It is called Riding the Merry Go, which sounds like a typo but seems to be the name we are living with. It comes out May 8. The track is radio-ready and cleared for airplay. No licensing or royalty obligations from us.
Riding the Merry Go Brevo PreRelease Draft
Follow-up logic
New
Clicked once: - mark as warm for Riding the Merry Go. Clicked more than once: - add to champion watchlist. - consider personal follow-up asking whether they need anything for airplay. Replied: - set RELATIONSHIP_LEVEL to Human. - answer personally.
Riding the Merry Go Brevo PreRelease Draft
Recommended preview text
New
radio-ready, against better judgment
Riding the Merry Go Brevo PreRelease Draft
Recommended subject
New
riding the merry go - advance
Riding the Merry Go Brevo PreRelease Draft
Structural notes
New
This intentionally follows the Christmas Lost Today pre-release pattern: - short - one dominant action - advance MP3 - "radio-ready" - "cleared for airplay" - just enough sideways Hecojeni tone - no extra experiment
Riding the Merry Go Release Email Sequence
Current sequence recommendation
New
1. Keep watching replies from Email 1. 2. Pull click/reply data before drafting Email 2. 3. Send Email 2 to Radio/Podcasters only if the data does not already make it feel redundant. 4. Prepare three separate release-day emails: - Radio/Podcasters - Playlist Curators - Press / Media
Riding the Merry Go Release Email Sequence
Email 1 — Radio/Podcast advance service
New
Status: sent 2026-04-30 at 3:19 PM Eastern. Audience: - All Podcast / Radio Contacts, Brevo segment 9. Primary business goal: - Radio play. - Podcast/music-show use. - Interview interest. Ask:
Riding the Merry Go Release Email Sequence
Email 2 — Radio/Podcast release-week nudge
New
Target send: - Monday 2026-05-04 or Tuesday 2026-05-05. Audience: - Radio/Podcasters only. - Exclude contacts who replied with mismatch, opt-out, or suppression signals. - If Brevo click data is available, prioritize clickers/non-clickers differently: - clickers get a warmer one-line follow-up - non-clickers get a very short second chance
Riding the Merry Go Release Email Sequence
Email 3 — Release day by segment
New
Target send: - Friday 2026-05-08. This should be role-specific, not one broad undifferentiated blast. ### 3A — Radio/Podcasters release day Audience: - Radio/Podcasters, excluding suppressed/mismatch contacts. Primary business goal: - Airplay, show inclusion, interview prompt.
Riding the Merry Go Release Email Sequence
Email 4 — Post-release follow-up
New
Target send: - Monday 2026-05-11 or Tuesday 2026-05-12. Audience: - Clickers. - Repliers. - Any contact with a useful acknowledgment or routing signal. Primary business goal: - Convert signal into relationship.
Riding the Merry Go Release Email Sequence
Guiding rule
New
Do not send the same email to every industry contact. Each business segment gets the smallest useful ask for the role they actually play. The goal is not to maximize total sends. The goal is to surface people who can create real outcomes: spins, adds, mentions, interviews, introductions, or placements.
Riding the Merry Go Release Email Sequence
Non-email work during release week
New
Daily from 2026-05-01 through 2026-05-15: - Review replies and autoresponders. - Suppress mismatches. - Add better routed contacts. - Record confirmed outcomes. - Mark true humans. - Consider physical thank-you only after meaningful signal.
Riding the Merry Go Release Email Sequence
Physical trigger rule for this release
New
Do not send physical mail for a simple autoresponder. Consider physical response only for: - confirmed play - real reply with interest - request for assets - interview interest - repeat meaningful engagement
Riding the Merry Go Response Triage 2026-04-30
Overall next actions
New
1. Reply to Paul Butler. 2. Add/update alternate contacts from MDR and Radio Skye. 3. Mark RDU as acknowledged. 4. Flag KBCS for verification. 5. Do not overreact to autoresponders as engagement wins.
Riding the Merry Go Response Triage 2026-04-30
Response 1 — Paul Butler
New
Type: human reply Question: Is this children's music? Our show is Family/kids Meaning: This is a real person asking a real fit question. It is probably not a placement for this song, but it is valuable because it tells us the contact/show is misclassified or too broad for general Hecojeni radio servicing. Recommended action:
Riding the Merry Go Response Triage 2026-04-30
Response 2 — Bayerischer Rundfunk
New
Type: automatic acknowledgement Meaning: The message reached Bayerischer Rundfunk public/program service. This is not a human music-programming response yet. Recommended action: - No reply. - Keep as delivery acknowledged. - Do not treat as a champion signal.
Riding the Merry Go Response Triage 2026-04-30
Response 3 — Andreas Zagelow / MDR
New
Type: out-of-office with useful alternate contacts Details: - Andreas is out of editorial office until 2026-05-20. - Suggested urgent contacts: - Hendryk Proske, hendryk.proske@mdr.de, MDR KULTUR - Torsten Kieling, torsten.kieling@mdr.de, MDR SPUTNIK Meaning: Andreas will not act before the May 8 release, but the autoresponder exposed two
Riding the Merry Go Response Triage 2026-04-30
Response 4 — RDU 98.5FM
New
Type: automatic submission acknowledgement Meaning: This is a good acknowledgment. RDU says they will check the music submission over the next few days. Recommended action: - No immediate reply. - Mark submission acknowledged. - Check for playlist add/social mention after release.
Riding the Merry Go Response Triage 2026-04-30
Response 5 — KBCS
New
Type: stale automatic reply Details: Message says the music department will be closed until Monday, August 14. Meaning: This looks stale or misconfigured. KBCS is still a plausible station, but this specific mailbox may need verification. Recommended action: - Flag KBCS music contact for verification.
Riding the Merry Go Response Triage 2026-04-30
Response 6 — Suzy Lee / Radio Skye
New
Type: out-of-office with useful alternate contacts Details: - Suzy is out until 2026-05-10. - News and press releases: Jamie McDonald, news@radioskye.com. - Urgent/other: Sam MacLelland, sam@radioskye.com. - YouthSPACE: youthspace@radioskye.com. Meaning: The May 8 release window is inside Suzy's absence. The right route for this
Riding the Merry Go Response Triage 2026-04-30
Summary
New
Early responses are useful. Most are automatic acknowledgments or out-of-office messages, but one is a real human-fit question and two contain replacement or alternate routing contacts. Treat these as signal: - human reply means relationship-level signal - acknowledgement means delivery/submission succeeded - alternate-contact autoresponder means routing improvement - stale autoresponder means list-hygiene flag
RockerTalker classifier
RockerTalker classifier
New
RockerTalker Classifier — Roadmap Status: SHIPPED to prod 2026-05-07 (V1 rule, bass_frac discriminator). Live launchd job is com.jitr.rockertalker.classifier, running 05:30 and 15:30 daily against the full Hecojeni TikTok and Reel Clips tree. The seven original handoff items are resolved-and-shipped; their detail lives in the dev release readme. This file tracks only what remains.
Selector
Decommission legacy selector system (future)
- After all consumers are migrated - Remove legacy selector and queue manager - Archive all legacy artifacts - Confirm shim subsystem is sole production system
Selector
Emit selection-based scoring events
- On each selection, append a row to scoring_events_queue.csv - Read event definitions from Scoring_Events config - Implement "Selected" event (e.g., -5% score delta) - Write one scoring event per selection - Use Dropbox-relative path in scoring queue
Selector
Implement score-weight-aware queue population
- Read posting pool configuration from JITRBeats_Posting_Pools - Support Score Weight per pool - Pool weight determines distribution across folders - Score weight determines which files are selected within a pool - Higher score weight biases toward higher-scored clips - Lower score weight allows more randomness
Selector
Implement shim queue contract
- Queue name: shim_selector_queue.csv - Location: $JITR_STATE/ShimSelector/ - Fields: - picked_path (Dropbox-relative) - pool_label - Selector resolves picked_path to absolute path using $DROPBOX_ROOT - No absolute paths stored in queue
Selector
Migrate consumers to shim selector (future)
- After shim subsystem is stable in production - Migrate consumers one at a time (posters, renamer, etc.) - Validate each migration using standard release process
Selector
Schedule shim queue manager
- Create launchd job for ShimSelector_queue_manager.sh - Ensure queue is maintained automatically - Validate logging and execution in non-interactive environment - Confirm stable behavior over time
Selector
Stand up shim-aware selector subsystem in production
- Build ShimSelector_pick_one.sh and ShimSelector_queue_manager.sh as a complete, independent subsystem - Ensure subsystem is environment-agnostic (no machine-specific paths) - Run subsystem in parallel with existing selector system - Do not migrate consumers in this step
Selector
Validate end-to-end shim subsystem behavior
- Queue manager builds valid queue - Selector pops queue and returns valid absolute path - Selector writes ledger entry (relative path) - Selector emits scoring event - Score-weight logic influences selection - No dependency on legacy selector or queue
Shim Checker
Current
New
(none) ---
Shim Checker
Last clean state
New
2026-05-07 — Files with violations: 0. Total violations: 0.
Shim Checker
Notes
New
- Purpose: enforce portability and environment independence across JITRBeats. - This is an audit tool only (no automatic fixes). Each detected violation must be fixed in its own program's release process. - emer/ is intentionally excluded from the scan (rollback snapshot of the last known-good prod).
Shim Checker
Shipped (see prod/Shim_Checker.readme.md for details)
New
- Identify non-portable programs in prod and dev. - Provide clear visibility into violations (file, line number, offending line; written to $JITR_REPORTS/ShimChecker/ and echoed to screen). - Skip sibling audit / portability tooling to eliminate false positives. - Twice-daily launchd schedule (com.jitr.shim_checker) at 05:30 and 15:30. - Executive-summary email to ops on any violation; silent on a clean run.
social collector
social collector
New
PROGRAM: social_collector ROADMAP 1) iMessage two-way bridge on the Mac mini - Outgoing: osascript-driven send from Messages.app to Jeff's number 404.268.6481. - Incoming: AppleScript or chat.db polling to read replies and parse yes / edit / no. - One-time mini-setup: iMessage signed in, Full Disk Access granted to the polling process.
social media
Priority 1 - YouTube community queue reporter
New
Business value: YouTube Studio comments are visible and actionable, so this is the safest next cross-platform queue for the social media manager. Status: connected; reporter improvement pending. Next work: - Inventory existing YouTube reporting and API/token capabilities. - Build a read-only dev reporter that produces a daily list of actionable comments.
social media
Priority 2 - Instagram and Facebook community queue polish
New
Business value: Instagram and Facebook profile growth is active, and comments/mentions need to become a daily human review list. Status: connected; queue/report polish pending. Next work: - Reuse existing Meta Graph plumbing where possible. - Prefer read-only reporting and ledgers over browser automation. - Keep live replies and account actions out of this plumbing thread.
social media
Priority 3 - Release and scheduling discipline
New
Business value: useful reports need to arrive predictably without creating brittle or confusing infrastructure. Status: pending. Rules: - Do not modify prod directly. - Promote one program at a time using the JITRBeats release process. - Do launchd work only on the Mac mini. - Keep prod clean: script and README only per program.
social media
Priority 4 - EmailListVerify validation before Brevo intake
New
Business value: validating email addresses before Brevo intake protects sender reputation, reduces bad contacts, and keeps fan/outreach lists cleaner. Status: future; intentionally behind the current TikTok, YouTube, Instagram, Facebook, release, and scheduling work. Next work: - Add an EmailListVerify API integration that can accept one email address and return validation status before adding the address to Brevo.
Spotlight
Spotlight
New
Spotlight — Roadmap Open items only. Done items have been removed from this file as they shipped. For what's already in PROD, see the script READMEs in scripts/prod/. ============================================================================== 1. Extend Spotlight flow to the rest of the deck machine — downstream stages - Production lane: SHIPPED. (Melody → Lyrics → Logic → Mix → Premaster →
TikTok filler
TikTok filler
New
tiktok_filler Roadmap Direction set 2026-04-27: humanize the TikTok posting approach. The current 12-slot daily fill at 02:00 with no caption guidance and no time guidance reads as bot-like to platform spam detection and to audience. This roadmap walks the program toward variability-over-consistency in cadence, timing, and verbiage. Aligns with feedback_human_feeling_posts.md.
TikTokAutoPoster
Completed (promoted to prod)
New
### 2026-04-15 (2) — Reporter now reads ShimSelector ledger Closed the real data-pipeline gap exposed by release (1). Changed LEDGER to $JITR_STATE/ShimSelector/shim_selector_ledger.csv; dropped the category_from_path derivation in favor of reading pool_label directly; dropped the picked → pool_resolved fallback.
TikTokAutoPoster
Notes / standing state
New
### Pending DEV work on reporter (transitional, low priority) There is a WIP edit on scripts/dev/TikTokAutoPoster_reporter.sh that filters on both TikTok and tiktok_manual poster labels and shows separate counts in the report body. This was staged 2026-04-16 in anticipation of the filler chat relabeling its shim-selector calls from --poster TikTok to --poster tiktok_manual.
TikTokAutoPoster
Open items (priority order)
New
### 1. Rebuild the TikTok Content Posting API approval demo The app has been denied twice by TikTok with no clear feedback. Prior submissions likely read as "fully automated" — which TikTok treats as disqualifying. Re-record the demo framing the system as: - Creator-owned content (Hecojeni's own masters) - Human-in-the-loop: selection → review → post - Compliant with TikTok's developer policies Business value: unbloc…
TikTokManualInboxReporter
TikTokManualInboxReporter
New
# TikTokManualInboxReporter Roadmap none.
video text overlay
Future
- Scan video library for clips without text - Generate transcripts for those clips - Derive short hook text from transcripts - Automatically apply overlays so all videos include text
video text overlay
In Progress / Next
- Improve text display so hooks “pop” more (e.g., motion/scrolling, stronger visual treatment)
VideoResizer
VideoResizer
New
# VideoResizer — Roadmap # Location: $JITR_SCRIPTS/prod/VideoResizer.sh (PROMOTED 2026-05-07) # State: PROD copy in place; no emer (first promotion). # # Shipped 2026-05-07 (release notes are in the dev/prod readme): # - Probe parsing fix (ffprobe field-by-field) — full library scans cleanly, 0 probe failures
VideoSelector
Completed history
New
- Shim selector / queue-manager release recovery - Contract validation sufficient to support path-swap consumer migration - PROD / DEV / EMER lane cleanup for shim programs - Legacy queue-manager launchd job disabled and archived - Shim queue-manager launchd job retained as sole active scheduled selector job
VideoSelector
Notes
New
Current production state after release closeout: - Shim selector is the active production direction - Shim queue-manager is the only active scheduled selector launchd job - Legacy queue-manager launchd job has been disabled and archived - Identified active PROD consumer migration is complete for YouTube, Reels, Facebook, and the already-shimmed TikTok refiller - The next frontier is controlled legacy wrapper/script r…
VideoSelector
Priority 10 — Bucket rollup reporting of actual selections over time windows
New
Intent: produce an executive-readable breakdown of what the selector actually picked over rolling time windows (24h, 7-day, 30-day), grouped into three buckets: - AI (any variant — pool labels containing "AI") - Pronounce Hecojeni - The rest (everything else) This complements the existing pool-by-pool actual-vs-expected table in Selector_reporter.sh — that's useful for tuning individual weights, while the bucket roll…
VideoSelector
Priority 5 — Queue distribution quality / de-bunching
New
### Priority 5a — Stale-row hash-resolution fallback in pop_next — DONE 2026-04-27 Shipped 2026-04-27 19:49 EDT as a small DEV→PROD release. Background. The 2026-04-27 deep diagnostic found that 638 of 1,641 queue rows consumed in the past 30 days (39%) were silently scrubbed by pop_next because the queued path no longer existed on disk — Renamer rewrites filenames whenever a clip's score changes, leaving queue entri…
VideoSelector
Priority 7a — Retarget Weights_recommender_from_scores at the live pool config
New
Context (2026-04-23): scripts/prod/Weights_recommender_from_scores.sh reads JITRBeats_Posting_Pools.csv (last edited Mar 12) as its input anchor and writes JITRBeats_Posting_Pools.csv.suggested as advisory output. The selector itself runs on ShimSelector_pools.csv (last edited Apr 19).
VideoSelector
Priority 8 — Master song list sync (mp3 recordings ↔ song folder + pool config)
New
Source of truth: .mp3 files under the Hecojeni Recording Files location (exact path to be confirmed during implementation — likely $DROPBOX_ROOT/Just in Time Records/Artists/Hecojeni/Recording Files/ or similar). Intent: every song that has a recorded .mp3 should have both a matching subfolder under TikTok and Reel Clips/Song Specific Videos/ AND a pool config entry in ShimSelector_pools.csv.
VideoSelector
Priority 9 — Released Music AI subfolder sync
New
Source of truth: songs under the Released Music location, format yyyy/songname/ (exact path to be confirmed during implementation). Intent: every song that has been officially released should have an <SongName> - AI subfolder under Song Specific Videos/<SongName>/, with a corresponding pool config entry.
VideoSelector
Recently shipped (last 30 days)
New
One-line entries with shipped-date. Full release notes for each are in the per-priority detailed sections below. - 2026-05-09 — Phase 0 of Platform-Specific Selector Weighting (per-platform × per-bucket section in Selector_loop_reporter) — first run validated Jeff's hypothesis: AI on Facebook 9.1% reward rate, AI on YouTube 2.8% (3x worse).
VideoSelector
What's next — in priority order (updated 2026-05-07)
New
This list is forward-looking only. Items that are DONE are moved to "Recently shipped" below. Items that are blocked on observation or external decisions are listed but not actionable until they unblock. ### Shippable now (none right now — see what just shipped below) Done 2026-05-07: De-bunching — pick-time interleave to fix consecutive same-pool streaks.
WeeklyReporter
WeeklyReporter
WeeklyReporter — Roadmap Purpose Create a weekly, fact-based system report that reflects current production capabilities, recent releases, and forward roadmap. This report is intended for executive visibility and external stakeholders (including investors). Scope 1. System Inventory - Count of programs in dev and prod
Weights recommender from scores
Add a stability-and-coverage monitoring report
New
What: a small companion report (daily or weekly) that does not change weights but describes: events per pool over the last 30 days, week-over-week change in suggested weight per pool, and count of pools with fewer than N events (where N is the data-confidence threshold we pick).
Weights recommender from scores
Build stage-2 mechanism
New
What: a new script (or new mode of the recommender) that reads column 3 of ShimSelector_pools.csv, compares to column 2, applies changes that pass the item-5 gate (writing the new value into column 2), logs every change with before/after, writes a daily email summary. Business value: operational automation — weights stay current without daily human intervention. Prerequisite: item 5 designed and approved.
Weights recommender from scores
Design stage-2 auto-apply criteria
New
What: decide the gate that lets the recommender write to the active config without human review. Expected components: - Minimum events per pool for the pool to be auto-adjusted (pools below threshold stay pinned at current weight) - Maximum daily or weekly change per pool (no lurch) — e.g.
Weights recommender from scores
Observe and stabilize in stage-1 (ongoing, no code yet)
New
What: watch the daily suggested_weight column in $JITR_CONFIG/ShimSelector_pools.csv and the $JITR_REPORTS/Weights/ reports for a sustained period. Track: - How many engagement events land per pool per week - How stable the recommendations are week-over-week for the same pool - Whether the pools most boosted by data feel right to Jeff's editorial intuition - Whether the pools most cut by data feel right to Jeff's edi…
Weights recommender from scores
Open design questions (to think about, not to act on yet)
New
- Does the X (Twitter) scorer eventually produce X_Engagement events, and how does X's signal compare in volume and variance to IG/YT/FB? Affects item 2 sizing. - Does TikTok auto-posting go live, producing TT_Engagement? If so, how does it weight relative to the other platforms? - Should different platforms carry different weights in the recommender (e.g.
Weights recommender from scores
Overall direction: from "recommend" to "set"
New
Today is stage 1 (recommend only). The recommender writes its suggestions into column 3 (suggested_weight) of the active pool config $JITR_CONFIG/ShimSelector_pools.csv every morning. The selector reads only columns 1 and 2 (pool_path, weight), so column 3 is advisory — Jeff reviews and hand-adopts any change by editing column 2 to match.
Weights recommender from scores
Revisit half-life as signal density grows
New
What: current half-life is 30 days, chosen for sparse data. With denser data a shorter half-life (14 days) makes the recommender more responsive to recent performance shifts. With much denser data, maybe an even shorter one. Business value: matches recommendation responsiveness to the rhythm of audience feedback, once we see how fast signals actually change.
Weights recommender from scores
Stage-2 rollout with safety net
New
What: three phases in order: - Shadow mode: auto-apply runs but writes to a shadow config file, not the active one, for a set period (e.g. 30 days). Jeff compares the shadow to the active daily. - Canary: auto-apply runs against the active config but only for a designated subset of pools (e.g. "Videos with Errors" folders) for a set period. - Full cutover: auto-apply is live for all pools that pass the stage-2 gate.
Weights recommender from scores
Widen dynamic range between top and average performers
New
What: the current performance multiplier is perf = 1 + avg_delta_pct / 100, which keeps top performers within ~20% of average. Once data density is higher, amplify via perf = 1 + k × avg_delta_pct / 100 with k somewhere in 2–3. A +20 avg_delta then becomes perf=1.40 or 1.60, so the top performer pulls materially further from the pack.
X Poster
Direction (2026-05-10)
New
The Hecojeni X account remains permanently suspended. A new X account is being established for discovery / new-fan acquisition. To minimize re-ban risk, the new account will be run manually for 60–90 days to build a credible human posting and engagement pattern. Automation will only be layered in afterward, against the baseline that warm-up establishes.
X Poster
Notes on current PROD artifact
New
- prod/X_Poster.sh and its readme remain in place, paused (JITR_X_POSTING_ENABLED=0). They target the suspended account's keychain credentials and have no effect on the new account. - They will be revisited at item 3 — either re-pointed at the new account, replaced, or archived.
X Poster
Notes on DEV clutter
New
- Dev has a number of older / experimental X artifacts (X_Scrape_WebKit_MVP.py, X_Link_Poster.sh, X_Auto_Poster.sh, many .bak files) from earlier efforts predating the suspension. - Cleanup can happen as a small standalone session when Jeff is ready; not blocking warm-up.
X Poster
Priority Order
New
### 1. Manual warm-up window — 60–90 days (Jeff/Heath own day-to-day; no automation) Started: 2026-05-12. Handle: @hecojeni_band. Target close window: 2026-07-11 (60 days) through 2026-08-10 (90 days). Business value: established human posting and engagement pattern that bot detection reads as a real account. - Hand-posted mix of original text, images, occasional YouTube cross-link.
X Poster
Recently shipped (carried over from prior roadmap)
New
- 2026-05-12: New X account created — @hecojeni_band. Original @hecojeni not pursued via appeal; variant handle chosen instead. Suspended old account left untouched (no rename, no deactivation) to avoid emitting cross-account fingerprint signals. Manual warm-up window now open. - 2026-04-20: Safer restart pattern for future re-enable.
YouTube poster
Priority Order
New
### 1. YouTube-specific copy curation Business value: while JITRBeats currently treats all social platforms identically, YouTube audiences and YouTube Shorts norms differ from FB/Insta. Platform-tuned copy will feel more human and perform better than reused cross-platform copy. First step toward recognizing platform differences across JITRBeats broadly.
YouTube poster P4 cadence bandit design
Appendix: why this beats "lower the threshold to 3/day"
New
The threshold-retune option I floated on 2026-05-04 was a small, scope-clean fix that would have stopped the daily YELLOW noise. But it would have left the underlying problem in place: nobody knows whether 3/day is the right number. It would have been a calibration to today's vibes, replacing yesterday's vibes. The bandit replaces calibration with measurement.
YouTube poster P4 cadence bandit design
Arm-selection mechanics
New
Each day picks one arm. Arm picks happen at 04:00 EDT so the morning ramp (06-09 weight 50) has the day's target ready. The selection process per day: 1. Determine today's day-of-week (Monday through Sunday). 2. For each of the seven arms, draw one sample from its current posterior conditional on today's day-of-week. Monday's bandit pulls from Monday's posteriors only. 3. Pick the arm with the highest sampled value.
YouTube poster P4 cadence bandit design
Cluster-and-gap scheduler — the human-feel layer
New
The current YouTube_poster.sh cadence logic produces approximately evenly-spaced posts within the day-shape's awake-hour window (e.g., 4 posts/day → ~4h average gap, with ±25% jitter). This is the pattern that v0.3 explicitly rejects. A real band does not space posts on a clock. Posts cluster, gaps vary widely, and no two days look alike.
YouTube poster P4 cadence bandit design
Dashboard / reporter rewrite
New
The current YouTube_reporter.sh "Posts (24h): N / 5 [STATUS]" line is replaced with a per-arm leadership view, broken out by day-of-week: ``` Hecojeni - YouTube Daily Report Generated: 2026-XX-XX HH:MM EST (Wednesday) Today's bandit arm: 4 posts (sampled from Wednesday posteriors) Today's planned schedule: 08:10, 08:55, 19:40, 20:30 EDT (2 clusters) Posts fired so far: 2 / 4 [on track] Bandit leadership for today's d…
YouTube poster P4 cadence bandit design
Definitions
New
A cadence arm is a daily posting-volume target, an integer in [1, 7]. Seven arms total. The day-shape (which controls which hours posts land in) is unchanged across arms — only the daily-volume count changes per arm. | Arm | Daily target | |---|---| | 1 | 1 post | | 2 | 2 posts | | 3 | 3 posts | | 4 | 4 posts | | 5 | 5 posts |
YouTube poster P4 cadence bandit design
Implementation phases
New
Phase 1 — Shadow mode (no behavior change). Build the bandit, cluster-and-gap scheduler, and instrumentation. The poster ignores the bandit's output and continues posting per the current day-shape logic. The shadow bandit picks arms and writes its schedule to the schedule CSV daily, but those schedule entries are not enforced — they're for validation.
YouTube poster P4 cadence bandit design
Open design questions (closed)
New
All seven questions from v0.2 were resolved by Jeff on 2026-05-12. The closed-out answers are preserved here as an audit trail of what was decided and why: 1. ~~Day-of-week awareness.~~ Resolved: learn separately per day-of-week. Trade-off (7× slower convergence) accepted. 49-cell posterior structure adopted throughout the doc. 2.
YouTube poster P4 cadence bandit design
Out of scope (for this design)
New
- Per-platform bandits. This doc is YouTube-only per the chat scope. FB/IG/TikTok would need their own bandit instances; design pattern is portable. - Cross-arm content selection. The selector still picks AI vs NAI clips by its existing logic. The AI-ratio question (item 3 from our 2026-05-04 conversation) is separate from cadence and would need its own bandit (or the selector-side fix proposed there).
YouTube poster P4 cadence bandit design
Outcome metric details
New
Per-post engagement score comes from the existing jitr_youtube_scorer.py (which left observation 2026-04-20). For each post the scorer produces a numeric engagement score over the 7 days following the post. The bandit's "score" for a day is the sum of per-post engagement scores across all posts that day. This is total daily fan engagement generated by the day's cadence.
YouTube poster P4 cadence bandit design
Purpose
New
Replace the current "intuition-set posting cadence with intuition-set dashboard threshold" loop with an experimentally-driven loop that measures what cadence is working for Hecojeni on YouTube and adapts automatically. Today the system posts ~3-4 Shorts/day because the day-shape (shipped 2026-04-20) trades quiet-hour volume for awake-hour placement, biased by best-practice intuition.
YouTube poster P4 cadence bandit design
Risks and mitigations
New
| Risk | Mitigation | |---|---| | Cluster-and-gap scheduler is not "human enough" to fool YT spam detection | Anti-pattern safeguard rail (no repeated shape day-over-day) + every gap/cluster parameter is independently randomized. Watch-and-revisit; if signals show flagging, add more variance dimensions (e.g., randomize cluster sizes per cluster within a day, not per day).
YouTube poster P4 cadence bandit design
Roadmap impact
New
This doc operationalizes YouTube_poster roadmap item 3 (Feedback-driven cadence tuning). On approval, the roadmap entry gets updated to point at this doc and at the implementation plan (TBD). The dashboard's count-vs-target logic gets retired in Phase 4.
YouTube poster P4 cadence bandit design
Safety rails
New
Hard constraints the bandit and scheduler cannot violate, regardless of what posterior samples say: 1. Floor of 1 post/day. No zero-post days. Arms are [1, 7]; this is a structural constraint, not a separate rail. 2. Ceiling of 7 posts/day. No more than 7 posts in any 24-hour window. Well under the YouTube API daily ceiling, and consistent with the "look like a real band" mandate. 3.
YouTube poster P4 cadence bandit design
State and instrumentation
New
Files: - $JITR_STATE/youtube_cadence_bandit_state.csv — one row per day. Columns: date, day_of_week (0=Mon..6=Sun), chosen_arm (1..7), realized_volume, sampled_value_per_arm (7 cols), posterior_mean_per_arm (7 cols), posterior_var_per_arm (7 cols), realized_daily_total_engagement_zscored.
YouTube poster P4 cadence bandit design
What needs Jeff's sign-off on v0.3
New
The v0.3 design is structurally different from v0.2 in three substantive ways: 1. Arms went from four discrete buckets (Dark/Single/Normal/Burst with 0 and 10-11 endpoints) to seven integer arms (1-7). 2. A new cluster-and-gap scheduler layer was added between the bandit and the poster, replacing the existing fixed-cadence-base logic. 3.
YouTube poster P4 cadence bandit design
Why Thompson sampling
New
Three reasons over alternatives: 1. It's the right algorithm for the regret/exploration trade-off when the cost of a wrong choice is real (suboptimal posting hurts the funnel) but the cost of exploration is bounded (a Dark or Burst day is reversible). 2. It naturally handles small samples. Early in the experiment we have noisy data; Thompson's posterior sampling won't lock onto a leader prematurely.
YouTube pruner design
Action: unlist, not delete
New
The pruner unlists. It does not delete. Reasons: - Reversible. If a video later turns out to be wanted (e.g., suddenly referenced from elsewhere), flipping it back to public is one API call. Deletion is permanent. - Link preservation. External pages that linked to the video keep working — the URL still resolves and the video still plays for anyone who has the direct link. Only discovery is removed.
YouTube pruner design
Audit ledger
New
$JITR_STATE/youtube_pruner_ledger.csv. Append-only. One row per action. Columns: - epoch — when the unlist happened (UTC seconds) - video_id — the YouTube video ID - original_upload_epoch — when the video was first uploaded - age_days_at_unlist — (epoch - original_upload_epoch) / 86400 - view_count_at_unlist — should be 0 per eligibility; recorded for audit - action — unlist (reserved for future relist or delete acti…
YouTube pruner design
Caps
New
Hard safety rails per run: 1. Max 5 videos unlisted per run. If more than 5 are eligible, take the 5 oldest and defer the rest to next week. Spreads pruning over time so the delete signal to YouTube is gradual, not bursty. 2. Max 20 videos unlisted per rolling 30-day window. A second-level cap that catches the case where the first cap is hit week after week.
YouTube pruner design
Definitions
New
A video is one row in $JITR_STATE/youtube_posted_ledger.csv — i.e., a successfully-uploaded YouTube Short with a known video ID. Age is now - upload_epoch for that ledger row, expressed in days. View count is the YouTube Analytics view count for that video ID, queried fresh per pruner run. Eligible = age ≥ 90 days AND view count == 0. Action = unlist the video on YouTube (not delete).
YouTube pruner design
Eligibility rule
New
A video is eligible for unlisting when all of the following hold: 1. Its ledger row's age is ≥ 90 days. 2. Its YouTube Analytics view count is exactly 0. 3. It is currently public (not already unlisted, not already deleted). 4. It is not in the per-run cap window for today (see Caps below). The choice of "zero views" over "bottom 1%" matches Jeff's hygiene framing: - Zero views is a hard absolute criterion.
YouTube pruner design
Implementation phases
New
Phase 1 — Shadow mode (no behavior change). Build the pruner script; instrument the full eligibility query, the unlist API call shape, the ledger writes. Run for 2 weeks in shadow mode — the script logs what it would unlist but does not actually unlist anything (dry_run=1 in the audit rows). Jeff can read the dry-run audit ledger and confirm the eligibility rule is catching the right videos. Phase 2 — Live.
YouTube pruner design
Out of scope (for this design)
New
- Deletion. The pruner unlists only. If Jeff later wants true deletion as an option, it's a separate design decision and a separate flag. - Engagement-based pruning beyond zero-views. Bottom-N-percent pruning, low-watch-time pruning, low-retention pruning — all out of scope. The zero-views criterion is intentionally narrow. - Pruning content from other platforms (FB/IG/TikTok).
YouTube pruner design
Purpose
New
Channel hygiene. Remove genuinely dead content from Hecojeni's YouTube channel — videos that have accumulated zero views over 90+ days. This is not an engagement-optimization tool and is not about juicing stats. It's about not leaving abandoned content visible on the channel. The P4 cadence bandit (separate work) drives toward making fewer weak posts in the first place.
YouTube pruner design
Reversibility
New
If Jeff later wants a video back, the manual recovery procedure is: 1. Find the video in youtube_pruner_ledger.csv (greppable by video ID). 2. Run YouTube_pruner.sh --relist <video_id>. This is a one-shot flag that flips the video back to public via the YouTube API and appends a relist row to the audit ledger. 3. The video's discovery resumes; it's back in the channel feed.
YouTube pruner design
Risks and mitigations
New
| Risk | Mitigation | |---|---| | YouTube channel gets flagged for "abandoning" content if too many unlistings happen at once | Per-run cap of 5; rolling-30-day cap of 20; weekly cadence (not daily); preference for unlist over delete | | A video at zero views actually had a delayed audience that would have found it later | 90-day minimum age is conservative — 90 days is well past the algorithmic test window; if a vid…
YouTube pruner design
Schedule
New
Run weekly, on Sundays at 03:00 EDT. Weekly is plenty of cadence for hygiene work; daily would be over-engineered and would spread the action over too narrow a window for YouTube-side observability. 03:00 EDT is chosen because: - It's before the day-shape's morning ramp opens, so it doesn't compete with poster activity. - Sunday is the quietest day in the broader JITR system per the launchd schedule observed.
YouTube pruner design
State files and instrumentation
New
- $JITR_STATE/youtube_pruner_ledger.csv — audit ledger (above). - $JITR_STATE/youtube_pruner_last_run_epoch — sentinel for the same-day-repeat cap. Updated on every successful run start. - $JITR_LOGS/youtube_pruner.log — per-run logs. 90-day expiry per JITR standard. Instrumentation in the existing dashboard (YouTube_reporter.sh): the daily report grows a one-line summary at the bottom:
YouTube pruner design
What needs Jeff's sign-off on v0.1
New
1. The zero-views-at-90-days eligibility rule (matches what Jeff signaled 2026-05-12). 2. The unlist-not-delete action (matches "also fine with unlisting"). 3. The weekly Sunday 03:00 EDT cadence. 4. The caps (5/run, 20/rolling-30-day, no same-day repeat). 5. The two-week Phase 1 shadow window. 6. The --relist manual reversal as the only public-flip path.
YouTube reporter
Priority Order
None.
YouTube scorer
Priority Order
New
### 1. Multi-client readiness Business value: enables jitr_youtube_scorer.py to serve a second client (My Forever DJ) on top of Hecojeni without forking the code. Cleanest of the four YT+X-scope Tier A programs to convert — all coupling is mechanical text substitution and one env-var dict-key rename. Source: scripts/roadmap/multi_client_hardcoded_values_inventory.md (Tier A, this program's section).
YouTube upload one
Priority Order
New
### 1. OAuth regeneration helper (deferred) Business value: when the stored token expires or is revoked, restoring upload capability should not be a scramble. - No active jitr_youtube_oauth.sh helper exists; the archived helper uses constructs incompatible with our current paste-proof and launchd standards.