jq Gate Sketch for post_october_fest_retention Weekly Demo Row Diff - 2026

November week two after October Next Fest: retention challenge #3 latched post_fest_retention_ok: true, analytics listicle #2 filed daily exports, crash recovery #4 moved trunk to 2026-11-05-trunk02. Monday stand-up asks "did demo retention rows drift since last week?" Someone pastes October upload weekly jq—wrong schema: upload weekly diffs depot_manifest_sha256 and steam_build_id. Localization weekly jq diffs locale_ids. Post-fest weeks need retention identity—build_id, demo download row hash, crash proxy hash, refund/uninstall lane status, retention receipt crosswalk—week-over-week.
November 2026 punishes teams that treat five-night retention R5 as forever-honest while producers run post-fest debriefs and silently ship trunk03 without updating analytics CSV rows. Silent build_id changes reopen crash and refund attribution lies while BUILD_RECEIPT still says green.
This Programming & Technical sketch ships a weekly instance of post-October fest demo retention honesty: post_october_fest_retention_weekly_log.jsonl, weekly receipt fields on post_october_fest_retention_weekly_v1, verify_post_october_retention_weekly.sh, gates J1–J6 on the retention schema (same letter prefix as depot/locale cousins; different columns).
Non-repetition note: October upload weekly jq owns depot manifest / build_id upload window. Analytics listicle #2 owns first-week T1–T6 four-lane dashboard. Retention challenge #3 owns D+1…D+5 nightly R1–R5. Uninstall curve #5 owns D+7 curve class G1–G6. Forward #12 capstone owns child receipt crosswalk. This URL owns Monday weekly demo download / crash / lane status row diff through November sprint prep.
Pair retention challenge #3, analytics #2, October upload weekly jq (cousin cadence), uninstall curve #5, badge-strip #6; Guide #53 / Course 304 forward; forward #8 contractor worksheet / #12 capstone.
Why this matters now (November 2026 post-October fest)
- Retention R5 is a point latch — Five nights prove D+1…D+5; weeks silently change
build_idwithout weekly diff. - Debriefs steal attention — Post-fest retros crowd out demo row honesty in BUILD_RECEIPT.
- Analytics CSV drifts — Daily export habit stops while trunk patches ship.
- November sprint needs row truth — Forward #12 capstone expects
post_october_retention_weekly_okin child crosswalk. - Wrong jq cousin ruins CI — Depot and locale scripts pass while demo retention hashes lie.
Direct answer: Each ISO week after post_fest_retention_ok, append post_october_fest_retention_weekly_log.jsonl, file a weekly receipt with retention_row_diff[], run verify_post_october_retention_weekly.sh, clear J1–J6, set BUILD_RECEIPT post_october_retention_weekly_ok: true. Any unexplained build_id or crash row hash delta requires documented exception or new crash recovery receipt.
Who this sketch is for
| Audience | You will… |
|---|---|
| Beginner | Run Monday build_id / row hash one-liners |
| Facilitator | Paste weekly retention diff into #post-fest-metrics |
| Engineer | Cron Monday 09:00 from R5 GREEN through November sprint |
| Producer | Block November sprint until J5 honesty clears |
Time: ~45 minutes first weekly template; ~6–10 minutes per Monday after scripts pin.
Prerequisites: Retention challenge R5 GREEN; post_fest_analytics_ok upstream; post_fest_daily_export_2026.csv path known; jq on CI or facilitator laptop.
Beginner path — Monday checklist (5–10 minutes)
- Open last week's retention pointer from BUILD_RECEIPT (
post_fest_retention_ok, latest challenge receipt path). - Read tail of
post_fest_daily_export_2026.csvfor currentbuild_idand lane statuses. - Hash demo download summary row (
sha256sumon normalized CSV slice or jq-exported JSON). - Hash crash proxy notes row for same week.
- Compare to last Monday's jsonl line—same
build_idand hashes? - Confirm refund/uninstall lanes still
activeon analytics dashboard. - If hash, build, or lane status changed without receipt note → stop November sprint edits; file exception or rerun retention night.
- Paste results into stand-up.
Memorize one sentence: Depot weekly = upload identity; retention weekly = demo player-signal identity.
| Question | October upload weekly jq | This post_october_fest retention jq |
|---|---|---|
| When? | ISO weeks after october_upload_window_allowed |
ISO weeks after post_fest_retention_ok |
| Log file | october_upload_weekly_log.jsonl |
post_october_fest_retention_weekly_log.jsonl |
| Anchor | Upload receipt + steampipe log tail | Retention challenge receipt + daily export CSV |
| Diff fields | build_id, depot_manifest_sha256, branch_intent |
build_id, demo_download_row_hash, crash_proxy_hash, refund/uninstall lane status |
| Prereq | Depot upload U1–U6 | Retention R1–R5 + analytics T6 |
| Wrong reuse | Locale freeze schema | Depot upload schema |
Beginner mistake: Appending depot weekly lines into post-fest folder—use a new jsonl and retention columns once R5 GREEN.
Format ladder (November first-week cluster)
| Artifact | Role |
|---|---|
| Retention challenge #3 | D+1…D+5 R1–R5 point latch |
| Analytics #2 | Four-lane T1–T6 upstream |
| Uninstall curve #5 | D+7 curve class cousin |
| This jq sketch | Weekly retention row diff J1–J6 |
| Forward #12 capstone | Child crosswalk across #1–#11 |
| October upload jq | Upload-window cousin cadence |
Order: R5 GREEN → uninstall curve G6 → badge-strip Z6 → weekly retention jq each Monday → contractor worksheet #8 → capstone #12.
Developer path — gates J1–J6 (retention schema)
These J gates belong to post-October fest retention weekly—not October upload weekly J1–J6 and not localization freeze weekly J1–J6.
| Gate | Pass criterion |
|---|---|
| J1 | Weekly receipt schema is retention weekly (schema string documents post_october_fest_retention_weekly_v1) and iso_week set |
| J2 | Retention pointer resolves (post_fest_retention_ok true; challenge receipt path present) |
| J3 | Prior ISO week jsonl line exists (or week-1 bootstrap note referencing R5 night) |
| J4 | build_id non-empty, demo_download_row_hash non-empty, analytics CSV path matches receipt |
| J5 | retention_row_diff[] honest for build_id, download hash, crash proxy hash, refund/uninstall lane status (no silent trunk patches) |
| J6 | Receipt filed; BUILD_RECEIPT post_october_retention_weekly_ok: true |
Weekly receipt template
File as release-evidence/post-fest/weekly/2026-W45.json (example):
{
"schema": "post_october_fest_retention_weekly_v1",
"iso_week": "2026-W45",
"retention_pointer": {
"path": "release-evidence/post-fest/retention-challenge-2026/receipts/post_fest_retention_challenge_receipt_v1.json",
"post_fest_retention_ok": true,
"post_fest_analytics_ok": true,
"analytics_receipt": "release-evidence/post-fest/analytics/receipts/post_fest_analytics_tools_receipt_v1.json"
},
"snapshot": {
"daily_export_csv": "release-evidence/post-fest/analytics/post_fest_daily_export_2026.csv",
"build_id": "2026-11-05-trunk02",
"demo_download_row_hash": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"crash_proxy_hash": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"refund_lane_status": "YELLOW",
"uninstall_lane_status": "active",
"crash_recovery_ok": true,
"post_october_uninstall_curve_ok": true
},
"retention_row_diff": [
{
"field": "build_id",
"before": "2026-11-01-trunk01",
"after": "2026-11-05-trunk02",
"delta": "changed",
"note": "POSTFEST-PATCH-001 forward fix; crash_recovery receipt C6"
},
{
"field": "demo_download_row_hash",
"before": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"after": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"delta": "changed",
"note": "expected after build_id change + D+7 export rows"
},
{
"field": "crash_proxy_hash",
"before": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"after": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"delta": "changed",
"note": "menu crash cleared post C6"
},
{
"field": "refund_lane_status",
"before": "RED",
"after": "YELLOW",
"delta": "changed",
"note": "improving D+4…D+7 trend"
},
{
"field": "uninstall_lane_status",
"before": "active",
"after": "active",
"delta": "unchanged"
}
],
"gates": {
"J1": "GREEN",
"J2": "GREEN",
"J3": "GREEN",
"J4": "GREEN",
"J5": "GREEN",
"J6": "GREEN"
},
"post_october_retention_weekly_ok": true,
"notes": "W45 POSTFEST-PATCH-001 documented; curve class expected_decay"
}
Weekly log (jsonl)
release-evidence/post-fest/post_october_fest_retention_weekly_log.jsonl — one line per ISO week:
{"iso_week":"2026-W44","build_id":"2026-11-01-trunk01","demo_download_row_hash":"sha256:eeee…","crash_proxy_hash":"sha256:ffff…","refund_lane_status":"RED","uninstall_lane_status":"active","receipt":"release-evidence/post-fest/weekly/2026-W44.json"}
{"iso_week":"2026-W45","build_id":"2026-11-05-trunk02","demo_download_row_hash":"sha256:cccc…","crash_proxy_hash":"sha256:dddd…","refund_lane_status":"YELLOW","uninstall_lane_status":"active","receipt":"release-evidence/post-fest/weekly/2026-W45.json"}
BUILD_RECEIPT latch fields
{
"post_october_retention_weekly_ok": true,
"post_october_fest_retention_weekly_log_path": "release-evidence/post-fest/post_october_fest_retention_weekly_log.jsonl",
"post_october_fest_retention_weekly_receipt_latest": "release-evidence/post-fest/weekly/2026-W45.json"
}
jq one-liners (copy-paste)
Hash demo download rows for current week
jq -n --slurpfile csv release-evidence/post-fest/analytics/post_fest_daily_export_2026.csv \
'$csv | @csv' 2>/dev/null || \
tail -n +2 release-evidence/post-fest/analytics/post_fest_daily_export_2026.csv | \
grep ',downloads,' | sha256sum
Simpler portable pattern—export normalized JSON slice then hash:
python -c "
import csv, hashlib, json
rows=[r for r in csv.DictReader(open('release-evidence/post-fest/analytics/post_fest_daily_export_2026.csv')) if r.get('lane')=='downloads']
print('sha256:'+hashlib.sha256(json.dumps(rows,sort_keys=True).encode()).hexdigest())
"
Diff last two jsonl lines
tail -2 release-evidence/post-fest/post_october_fest_retention_weekly_log.jsonl | \
jq -s '.[0].build_id as $a | .[1].build_id as $b | {before:$a, after:$b, changed: ($a != $b)}'
Gate J5 quick check (build changed → note required)
REC="release-evidence/post-fest/weekly/2026-W45.json"
jq -e '
(.retention_row_diff[] | select(.field=="build_id" and .delta=="changed") | .note) != null
' "$REC"
verify_post_october_retention_weekly.sh
#!/usr/bin/env bash
set -euo pipefail
REC="${1:-release-evidence/post-fest/weekly/2026-W45.json}"
LOG="${2:-release-evidence/post-fest/post_october_fest_retention_weekly_log.jsonl}"
jq -e '.schema == "post_october_fest_retention_weekly_v1"' "$REC" || exit 1
jq -e '.retention_pointer.post_fest_retention_ok == true' "$REC" || exit 2
for g in J1 J2 J3 J4 J5 J6; do
jq -e --arg g "$g" '.gates[$g] == "GREEN"' "$REC" || exit 3
done
jq -e '.snapshot.build_id != ""' "$REC" || exit 4
jq -e '.snapshot.demo_download_row_hash != ""' "$REC" || exit 5
ISO="$(jq -r '.iso_week' "$REC")"
grep -q "\"iso_week\":\"$ISO\"" "$LOG" || exit 6
jq -e '.post_october_retention_weekly_ok == true' "$REC" || exit 7
# J5: build_id change requires note on diff row
if jq -e '.retention_row_diff[] | select(.field=="build_id" and .delta=="changed")' "$REC" >/dev/null 2>&1; then
jq -e '.retention_row_diff[] | select(.field=="build_id" and .delta=="changed") | .note != ""' "$REC" || exit 8
fi
echo "post_october_retention_weekly verify: OK"
Computing row hashes (working dev)
Demo download row hash
- Filter CSV rows where
lane=downloadsandmetricin (fest_downloads,daily_downloads,demo_installs)—use your team's canonical metric names consistently. - Sort rows by
dateascending. - Serialize to JSON with stable key order.
- SHA256 the UTF-8 bytes; prefix
sha256:.
Crash proxy hash
- Filter rows where
lane=uninstallsor notes containcrashtags from analytics #2. - Include
build_idcolumn in hash input so attribution stays honest. - Same SHA256 discipline.
Honest rule: Do not hash invented percentages—hash row content you actually logged.
Week-1 bootstrap (J3)
First Monday after R5 may lack prior jsonl line. Bootstrap note in receipt:
{
"iso_week": "2026-W44",
"bootstrap": true,
"bootstrap_anchor": "post_fest_retention_challenge_receipt_v1.json R5 GREEN 2026-11-08",
"notes": "First weekly row; no prior diff"
}
J3 passes with bootstrap flag documented—J5 still requires honest snapshot fields.
Integration with November cluster
| Cousin | Relationship |
|---|---|
| Retention #3 | J2 pointer; R5 before first weekly |
| Analytics #2 | J4 CSV path + lane statuses |
| Crash recovery #4 | J5 note when build_id changes |
| Uninstall curve #5 | Snapshot may include post_october_uninstall_curve_ok |
| October upload jq | Cousin cadence—not interchangeable schema |
| Forward #12 capstone | Indexes post_october_retention_weekly_ok |
Scenarios A–G
A — build_id changed, no POSTFEST-PATCH note
J5 RED—pair forward #9 patch exception opinion before J6.
B — Analytics CSV missing D+7 rows
J4 YELLOW—return to analytics T3 habit.
C — Retention R5 RED
J2 fail—do not start weekly jq until challenge completes.
D — Depot jq passes, retention jq RED
Expected—different schemas; do not merge logs.
E — Refund lane RED two weeks running
J5 documents trend; does not auto-fail if note explains ongoing triage.
F — CI runs wrong verify script
Pin verify_post_october_retention_weekly.sh in repo— not october upload verify.
G — Capstone prep
Forward #12 child_receipts[] includes latest weekly receipt path.
RED / YELLOW / GREEN routing
| Color | Condition | Action |
|---|---|---|
| RED | J2 fail (no R5) | Finish retention challenge |
| RED | J5 silent build_id change | File POSTFEST-PATCH-001 or crash recovery |
| YELLOW | J3 bootstrap only | Accept week 1; require week 2 diff |
| YELLOW | Lane status RED | Document; pair crash recovery if needed |
| GREEN | J1–J6 pass | Proceed contractor #8, capstone #12 |
Facilitator stand-up paste template
## Post-fest retention weekly jq — {iso_week}
- build_id: {before} → {after} ({changed|unchanged})
- demo_download_row_hash: {changed|unchanged}
- crash_proxy_hash: {changed|unchanged}
- refund_lane: {status} | uninstall_lane: {status}
- J5 notes: {exception id or "none"}
- post_october_retention_weekly_ok: {Y/N}
Common mistakes
- Reusing
october_upload_weekly_log.jsonlfilename for retention rows. - Hashing entire CSV instead of lane-filtered slices—noisy diffs every week.
- Skipping J5 notes when
build_idchanges after forward fix. - Running weekly jq before R5 GREEN.
- Treating refund YELLOW as J6 blocker alone—document trend in J5.
- Inventing download counts in hash input—use logged CSV rows only.
Enterprise notes
- Audit trail: jsonl append-only; do not edit prior ISO week lines.
- CI: Run verify script on PR when
post_fest_daily_export_2026.csvchanges. - Partner diligence: Weekly receipt + diff array answers "what changed since fest?" without fake metrics.
CI cron sketch (optional)
Schedule Monday 09:00 UTC after R5 GREEN:
# .github/workflows/post-fest-retention-weekly.yml (sketch)
on:
schedule:
- cron: '0 9 * * 1'
jobs:
retention-weekly:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify latest weekly receipt
run: |
test -f release-evidence/post-fest/weekly/latest.json
bash scripts/verify_post_october_retention_weekly.sh \
release-evidence/post-fest/weekly/latest.json \
release-evidence/post-fest/post_october_fest_retention_weekly_log.jsonl
Pin the verify script in-repo; fail the job when J5 detects build_id change without note. Human facilitator still owns stand-up paste—CI catches silent drift between meetings.
PowerShell hash helper (Windows facilitators)
$rows = Import-Csv release-evidence/post-fest/analytics/post_fest_daily_export_2026.csv |
Where-Object { $_.lane -eq 'downloads' }
$json = ($rows | ConvertTo-Json -Compress)
$bytes = [System.Text.Encoding]::UTF8.GetBytes($json)
$hash = [System.BitConverter]::ToString(
[System.Security.Cryptography.SHA256]::Create().ComputeHash($bytes)
).Replace('-','').ToLower()
"sha256:$hash"
Log operator: powershell_facilitator in weekly receipt notes when using this path instead of bash—reproducibility matters more than shell choice.
Key takeaways
- Post-fest retention needs weekly jq—R5 is not forever-green.
post_october_fest_retention_weekly_log.jsonlone line per ISO week.- Gates J1–J6 on retention schema—not depot or locale columns.
post_october_retention_weekly_okfeeds forward #12 capstone.- Pair retention challenge #3 for J2 upstream.
- Pair analytics #2 for CSV + lane truth.
- Document
build_idchanges with POSTFEST-PATCH opinion #9 P1–P6 or crash recovery receipt paths. - October upload jq is cousin cadence only.
verify_post_october_retention_weekly.shfail-closes silent trunk patches.- Monday 6–10 minute ritual beats November sprint metric surprises.
- After J6 GREEN, file contractor burn-down worksheet #8 (B1–B6,
contractor_burn_down_ok)—B-HOTFIX maps POSTFEST-PATCH hours to jqbuild_idchanges.
FAQ
Is this the same as October upload weekly jq?
No—October upload jq diffs depot manifests during upload window. This URL diffs demo retention rows after fest.
Do I need jq if I have Python?
Python hash helper is fine—log equivalent command in receipt notes for reproducibility.
When does weekly jq start?
First Monday after retention challenge R5 GREEN and analytics T6 GREEN.
What if build_id never changes?
J5 still files unchanged diff rows—honest static week is valid GREEN.
How does capstone #12 use this?
Forward capstone child_receipts[] references latest weekly receipt path and post_october_retention_weekly_ok.
Related reads
- 5-Night Post-October Fest Demo Retention Response Challenge
- 14 Free Post-October Fest Steam Analytics Refund and Demo Uninstall Tools
- jq Gate Sketch for october_upload Weekly Depot Row Diff
- November 2026 Post-October Fest Uninstall Curve Trend Playbook
- We Recovered Steam Demo Crash Rate Spike After October Fest
- November Store Capsule Badge-Strip Pass
- Friday Post-October Fest First-Week Capstone — forward #12
- Post-October Fest Contractor Burn-Down Cap Worksheet — cluster #8; B1–B6 after J6 GREEN
- 25 Free Live-Ops Analytics Tools Indie Games 2026 Edition
- Official docs: Steamworks Marketing
Closing
November stand-ups fail when post-fest debriefs celebrate narrative while demo download and crash rows drift silently. Append post_october_fest_retention_weekly_log.jsonl, run verify_post_october_retention_weekly.sh, and let post_october_retention_weekly_ok mean your team greps retention truth weekly—not that R5 from ten days ago still counts as today's evidence. When forward capstone reads one more green child receipt, November sprint starts from row diffs you can defend—not from a CSV nobody updated after trunk02 shipped.