jq and Bash Sketch for rclone Team Drive ID Sanity During Q4 Diligence Mirror Week - 2026
Your nightly rclone copy cron exits 0. The log says Transferred: 0 / 0, 0%. Partner diligence opens the Shared drive folder Monday and finds last month's 07-observability/ annex—or nothing. You pasted a My Drive shortcut URL into README while rclone targets a Team Drive root that 404s in headless CI.
Q4 2026 partners script mirrors of release-evidence/ and 07-observability/ beside demo evidence packets. Browser UI "looks fine" because humans browse shortcuts; rclone lsd fails on wrong team_drive IDs. This Programming & Technical post is a copy-paste bash + jq sketch: validate Shared drive ID, fail-closed before live copy, file diligence_mirror_receipt_v1.json—strategy layer above Resolve archive rclone preflight (R1–R6) and below partner zip send.
Non-repetition note: Resolve archive handoff owns .drp bundle; Q4 telemetry analysis owns observability annex narrative; ffprobe duration matrix owns audio batch jq. This URL owns Team Drive ID + nightly mirror index—not Drive 403 OAuth fixes (Help #17 cousin) nor path-not-found triage (Help #28 forward).
Why this matters now (Q4 2026 mirror week)
- Partner offline mirrors — Due diligence runs parallel to October fest; broken cron = stale telemetry rows.
- My Drive vs Shared drive —
rclone configwithoutteam_drive = truelists wrong roots. - Service account drift — CI uses SA; producer validates in browser—two truths.
- Resolve + Blender cousins — Lesson 264 and Lesson 271 forward need one
team_drive_idin README. - Receipt culture — Thursday row review should diff
rclone_path_oklikedemo_smoke.
Direct answer: Pin team_drive_id in diligence_mirror_config_v1.json, run rclone lsd + jq guard, archive dry-run log, file diligence_mirror_receipt_v1.json with mirror_job_allowed: true before partner zip.
Who this sketch is for
| Audience | You will be able to… |
|---|---|
| Beginner | Copy/paste rclone lsd and know pass vs fail |
| Solo founder | Stop silent zero-byte mirror nights |
| Engineer | Wire jq gate in CI before rclone copy |
| Producer | Require receipt before diligence send |
Time: ~45 minutes first mirror week setup; ~5 minutes per nightly run after config pinned.
Mental model — three IDs that must agree
| Surface | What it stores | Common drift |
|---|---|---|
| Google Admin / Shared drive URL | 0ABC…xyz folder ID |
Shortcut alias, not root |
rclone.conf remote |
team_drive + root_folder_id |
My Drive remote |
diligence_mirror_config_v1.json |
Canonical ID for jq | Stale ID after drive rename |
Rule: README, receipt JSON, and rclone.conf must cite the same team_drive_id string.
Folder layout partners expect (Q4 mirror week)
Partners do not audit your Google Admin console—they audit paths on disk inside the mirror and the README bullet map in the partner zip. A typical Q4 tree after Q3 packet anatomy plus Q4 observability annex:
release-evidence/
├── diligence/
│ ├── diligence_mirror_config_v1.json
│ ├── DILIGENCE_MIRROR_RECEIPT.json
│ ├── RESOLVE_ARCHIVE_RCLONE_RECEIPT.json # cousin — Resolve handoff
│ ├── MIRROR_README.md # actors + SA policy
│ └── partner_mirror_index.csv # optional nightly row log
├── 07-observability/
│ ├── diligence_telemetry_receipt_v1.json
│ ├── crash_symbolicate_receipt_v1.json
│ └── telemetry_summary_redacted.csv
└── marketing-and-demo/
└── store_capture_receipt_v1.json
Beginner framing: If 07-observability/ is missing from the mirror, partners assume you never instrumented crashes—not that cron failed silently.
Developer framing: diligence_mirror_receipt_v1.json is the index that says which cousin receipts were included in the last successful mirror job and whether rclone_path_ok was true at copy time.
How this differs from Help #17 (Drive 403) and Help #28 (path not found)
| Lane | Symptom | Owner |
|---|---|---|
| This post (preventive) | Wrong ID before copy; zero-byte nights | M1–M6 jq + lsd |
| Help #17 forward | OAuth / SA 403 on valid-looking path | Auth + membership fix |
| Help #28 forward | couldn't find file after path rename |
Path triage + config refresh |
| Resolve archive preflight | .drp bundle integrity |
R1–R6 |
Run this sketch first on mirror week Monday—then route failures to the help lane that matches the error string, not the calendar day.
rclone.conf remote sketch (Team Drive)
Pin a dedicated remote—do not reuse a personal My Drive remote named gdrive::
[diligence_team]
type = drive
scope = drive
service_account_file = /run/secrets/mirror-ci-sa.json
team_drive = 0ABCxyz123SharedDriveIdExample
root_folder_id =
Beginner check: In rclone config, when asked about Shared drives, answer yes and paste the Shared drive ID from Google Admin—not a folder inside My Drive.
Developer check: team_drive in rclone.conf must equal team_drive_id in diligence_mirror_config_v1.json. M3 jq can diff them:
jq -e --argfile cfg release-evidence/diligence/diligence_mirror_config_v1.json \
'.team_drive_id == $cfg.team_drive_id' diligence_mirror_config_v1.json
If you maintain ID only in JSON (not in conf), skip the conf line and pass --drive-root-folder-id on every command—as in M2.
Beginner path — five commands
# 1) List Shared drives you can see
rclone listremotes
rclone lsd diligence_team: --drive-team-drive
# 2) List target folder (replace folder path)
rclone lsd "diligence_team:partner_mirror/" --drive-team-drive
# 3) Dry-run mirror (no writes)
rclone copy release-evidence/diligence/ \
"diligence_team:partner_mirror/2026-10-22/" \
--dry-run --checksum -v 2>&1 | tee logs/rclone_mirror_dry_run.log
# 4) jq guard (after pinning config JSON below)
./scripts/verify_diligence_mirror_config.sh
# 5) File receipt when guard passes
# → diligence_mirror_receipt_v1.json
Success check: rclone lsd returns folder names without couldn't find file or directory not found.
Developer path — gates M1–M6
| Gate | Check | Pass when |
|---|---|---|
| M1 | diligence_mirror_config_v1.json pinned |
team_drive_id + remote name |
| M2 | rclone lsd exit 0 |
Lists destination root |
| M3 | jq ID format guard | 20+ char alphanumeric ID |
| M4 | Dry-run log archived | Non-empty planned transfers |
| M5 | Session table documented | SA vs human actor |
| M6 | diligence_mirror_receipt_v1.json |
mirror_job_allowed: true |
M1 — diligence_mirror_config_v1.json
Pin under release-evidence/diligence/diligence_mirror_config_v1.json:
{
"schema": "diligence_mirror_config_v1",
"team_drive_id": "0ABCxyz123SharedDriveIdExample",
"rclone_remote": "diligence_team",
"mirror_dest_prefix": "partner_mirror/",
"source_roots": [
"release-evidence/diligence/",
"release-evidence/07-observability/"
],
"resolve_archive_receipt": "release-evidence/diligence/RESOLVE_ARCHIVE_RCLONE_RECEIPT.json",
"build_label": "october-fest-2026-rc5",
"mirror_schedule_utc": "0 3 * * *"
}
Red flag: team_drive_id copied from browser folder URL that is a shortcut inside another drive—rclone needs the Shared drive ID from Admin or rclone backend drive id.
M2 — rclone lsd validation
TEAM_ID="$(jq -r '.team_drive_id' release-evidence/diligence/diligence_mirror_config_v1.json)"
REMOTE="$(jq -r '.rclone_remote' release-evidence/diligence/diligence_mirror_config_v1.json)"
rclone lsd "${REMOTE}:" --drive-team-drive --drive-root-folder-id "${TEAM_ID}"
Fail-closed: non-zero exit → do not run live rclone copy.
M3 — jq guard script
scripts/verify_diligence_mirror_config.sh:
#!/usr/bin/env bash
set -euo pipefail
CFG="release-evidence/diligence/diligence_mirror_config_v1.json"
ID="$(jq -r '.team_drive_id' "$CFG")"
REMOTE="$(jq -r '.rclone_remote' "$CFG")"
# Format guard — Shared drive IDs are long opaque strings
jq -e '.team_drive_id | length >= 20' "$CFG" >/dev/null
# Live list guard
rclone lsd "${REMOTE}:" --drive-team-drive --drive-root-folder-id "${ID}" >/dev/null
echo "M2+M3 OK: team_drive_id=${ID}"
Wire in CI before nightly mirror job.
M4 — dry-run before live copy
DATE_TAG="$(date -u +%Y-%m-%d)"
rclone copy release-evidence/diligence/ \
"diligence_team:partner_mirror/${DATE_TAG}/" \
--dry-run --checksum --include "/**" \
-v 2>&1 | tee "logs/rclone_mirror_dry_run_${DATE_TAG}.log"
Fail: log shows only ERROR lines or zero files when source folder is non-empty—fix paths before live job.
M5 — service-account vs human session table
| Actor | Auth mode | rclone use | Risk |
|---|---|---|---|
| Producer laptop | OAuth browser | Manual rclone lsd validation |
Personal Google account |
| CI nightly job | Service account JSON | rclone copy |
SA not added to Shared drive |
| Partner | Read-only share | None (consumes mirror) | Writer token leaked in zip |
Document in release-evidence/diligence/MIRROR_README.md:
## Mirror actors
| Actor | Shared drive role | Validates |
|-------|-------------------|-----------|
| [email protected] | Content manager on dest subfolder | M2 nightly |
| [email protected] | Manager (human) | Weekly M2 spot-check |
| [email protected] | Reader | N/A |
Never commit SA JSON to git—mount from secret store; reference path in receipt only.
M6 — diligence_mirror_receipt_v1.json
{
"schema": "diligence_mirror_receipt_v1",
"build_label": "october-fest-2026-rc5",
"team_drive_id": "0ABCxyz123SharedDriveIdExample",
"rclone_remote": "diligence_team",
"mirror_dest": "partner_mirror/2026-10-22/",
"config_path": "release-evidence/diligence/diligence_mirror_config_v1.json",
"dry_run_log": "logs/rclone_mirror_dry_run_2026-10-22.log",
"source_file_count": 42,
"cousin_receipts": {
"resolve_archive": "release-evidence/diligence/RESOLVE_ARCHIVE_RCLONE_RECEIPT.json",
"diligence_telemetry": "07-observability/diligence_telemetry_receipt_v1.json",
"blender_glb_mirror": "release-evidence/diligence/BLENDER_GLB_MIRROR_RECEIPT.json"
},
"gates": {
"M1_config": "pass",
"M2_rclone_lsd": "pass",
"M3_jq_guard": "pass",
"M4_dry_run": "pass",
"M5_session_table": "pass",
"M6_receipt": "pass"
},
"rclone_path_ok": true,
"mirror_job_allowed": true
}
Pin under release-evidence/diligence/DILIGENCE_MIRROR_RECEIPT.json. BUILD_RECEIPT columns: rclone_path_ok, diligence_mirror_receipt_path.
Relationship to Resolve archive vs observability vs partner zip
| Artifact | Role |
|---|---|
| This sketch | Nightly mirror index + Team Drive ID truth |
| Resolve archive preflight | .drp bundle + resolve_archive_rclone_receipt |
| Q4 telemetry analysis | 07-observability/ annex |
| Partner upload ZIP standard | Final send packaging |
| Lesson 264 | archive_handoff_ok BUILD_RECEIPT |
Order: Resolve archive (if applicable) → mirror config + M1–M6 → nightly rclone copy → partner zip → Thursday row review.
Nightly GitHub Actions job sketch (fail-closed)
Wire mirror validation before live copy in the same workflow—pair GitHub Actions cache bust tutorial fail-closed culture:
name: diligence-mirror-nightly
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
jobs:
mirror-preflight:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install rclone + jq
run: sudo apt-get update && sudo apt-get install -y rclone jq
- name: Mount SA secret
env:
SA_JSON: ${{ secrets.DILIGENCE_MIRROR_SA_JSON }}
run: |
echo "$SA_JSON" > /tmp/mirror-ci-sa.json
export RCLONE_CONFIG_DILIGENCE_TEAM_TYPE=drive
export RCLONE_CONFIG_DILIGENCE_TEAM_SCOPE=drive
export RCLONE_CONFIG_DILIGENCE_TEAM_SERVICE_ACCOUNT_FILE=/tmp/mirror-ci-sa.json
- name: M2+M3 verify
run: ./scripts/verify_diligence_mirror_config.sh
- name: M4 dry-run archive
run: |
DATE_TAG=$(date -u +%Y-%m-%d)
rclone copy release-evidence/diligence/ \
"diligence_team:partner_mirror/${DATE_TAG}/" \
--dry-run --checksum -v 2>&1 | tee "logs/rclone_mirror_dry_run_${DATE_TAG}.log"
- name: M6 receipt jq gate
run: |
jq -e '.mirror_job_allowed == true' release-evidence/diligence/DILIGENCE_MIRROR_RECEIPT.json
mirror-copy:
needs: mirror-preflight
runs-on: ubuntu-latest
steps:
- name: Live copy (only after preflight)
run: |
DATE_TAG=$(date -u +%Y-%m-%d)
rclone copy release-evidence/diligence/ \
"diligence_team:partner_mirror/${DATE_TAG}/" \
--checksum -v
rclone copy release-evidence/07-observability/ \
"diligence_team:partner_mirror/${DATE_TAG}/07-observability/" \
--checksum -v
Do not merge receipt JSON with mirror_job_allowed: true until M4 log shows planned transfers for non-empty source folders. A green workflow with 0 files is a false green—cousin to blog #17 Addressables CI challenge.
Cousin receipt jq cross-check (developer)
Before filing M6, verify cousin paths exist on disk:
for path in \
release-evidence/diligence/RESOLVE_ARCHIVE_RCLONE_RECEIPT.json \
release-evidence/07-observability/diligence_telemetry_receipt_v1.json; do
test -f "$path" || { echo "missing cousin: $path"; exit 1; }
done
jq -e '.cousin_receipts.resolve_archive' release-evidence/diligence/DILIGENCE_MIRROR_RECEIPT.json
Optional: require archive_handoff_ok from Lesson 264 when Resolve bundle is in scope for that build.
Q4 mirror week calendar (solo founder)
| Day | Task | Gate | Minutes |
|---|---|---|---|
| Mon | Pin M1 config + rclone.conf |
M1 | 30 |
| Mon | Human rclone lsd on producer laptop |
M2 | 5 |
| Mon | File M6 receipt after dry-run | M4–M6 | 15 |
| Tue–Thu | Nightly cron / Actions | M2–M4 auto | 0 (watch alerts) |
| Wed | Wednesday smoke | S4–S6 | 15 |
| Thu | Thursday row review diff rclone_path_ok |
BUILD_RECEIPT | 10 |
| Fri | Partner zip + README bullet map | Partner ZIP standard | 90 |
Defer marketing bursts during mirror week using founder time-box worksheet—mirror failures are engineering-floor work, not deferrable fluff.
Proof table (audit row)
| Row | Evidence | Pass when |
|---|---|---|
| Config pinned | diligence_mirror_config_v1.json in repo or release-evidence |
team_drive_id matches Admin |
| List guard | rclone lsd log snippet |
Exit 0; folder names visible |
| jq guard | CI step output | M3 script exits 0 |
| Dry-run | logs/rclone_mirror_dry_run_*.log |
Non-zero planned transfers if sources non-empty |
| Session policy | MIRROR_README.md |
SA + human roles documented |
| Receipt | DILIGENCE_MIRROR_RECEIPT.json |
mirror_job_allowed: true |
| BUILD_RECEIPT | Weekly row | rclone_path_ok: true |
Archive logs under logs/ for 90 days—partners may ask which nightly job produced the observability folder they opened.
MIRROR_README.md excerpt (partner-facing)
# Diligence mirror index (read-only)
**Build:** october-fest-2026-rc5
**Last mirror UTC:** 2026-10-22T03:14:00Z
**Receipt:** release-evidence/diligence/DILIGENCE_MIRROR_RECEIPT.json
## Included roots
- release-evidence/diligence/ (Resolve archive cousin optional)
- release-evidence/07-observability/ (telemetry + crash receipts)
## Not included
- Partner upload zip (separate send)
- Raw playtest VOD (see Whisper pipeline blog)
## Validation
Run `rclone lsd` with read-only share—do not request writer tokens.
Pair player-visible build label in README so partners correlate mirror folders to the build players saw.
PowerShell variant (Windows producer spot-check)
$config = Get-Content release-evidence/diligence/diligence_mirror_config_v1.json | ConvertFrom-Json
$teamId = $config.team_drive_id
rclone lsd "$($config.rclone_remote):" --drive-team-drive --drive-root-folder-id $teamId
Use before trusting a laptop cron that only ran on Linux CI.
Common mistakes
- My Drive remote on Team path (M2 fail).
- Shortcut URL as
team_drive_id(M3 jq pass but M2 fail). - Silent zero transfer treated as success (M4 empty log).
- SA not on Shared drive — 403 on CI only (M5).
- Stale ID after Google Admin rename—re-run M1 weekly during mirror month.
- Mixing
diligence_mirror_receiptwithresolve_archive_rclone_receipt—usecousin_receiptsonly.
Troubleshooting
| Symptom | Lane |
|---|---|
couldn't find file on lsd |
M1 ID; Help #28 forward |
403 on copy |
M5 SA membership |
| Browser shows files, rclone empty | Wrong remote type |
| jq pass, dry-run zero files | Source path typo in config |
| Partner sees old observability | Cron succeeded with wrong dest prefix |
Transferred: 0 / 0 exit 0 |
M4 false green—treat as fail |
| Human OAuth works, CI fails | M5—SA not on Shared drive |
| Resolve opens, observability stale | Mirror job skipped 07-observability/ root |
Receipt true but partner 404 |
Wrong mirror_dest_prefix date folder |
Two team_drive_id in README vs JSON |
Re-pin M1; Thursday row diff |
Extended scenario notes (A–G)
A — First mirror week: Run M1–M6 manually once before enabling cron. Partners forgive a late first mirror; they do not forgive three weeks of stale 07-observability/ with green Slack emoji.
B — Admin restructure: When marketing renames partner_mirror/ to diligence_inbound/, update mirror_dest_prefix and re-run M2—browser bookmarks do not update rclone paths.
C — Resolve archive mid-week: Add resolve_archive to cousin_receipts after Resolve preflight R6 passes; do not re-use last week's receipt JSON without bumping build_label.
D — CI green, partner 404: Classic two-session drift—producer validated with personal OAuth; CI uses SA without Shared drive membership. Fix M5, not M3.
E — Personal OAuth on CI: Headless runners cannot complete browser consent—dedicated SA is mandatory for nightly jobs.
F — Dry-run huge, live copy skipped: Teams archive a 200 MB dry-run log then never run live copy—M4 is not a substitute for transfer. Check source_file_count in receipt against dry-run line count.
G — Zip without receipt: Block partner send; partner ZIP standard expects receipt paths in README bullets.
Seven scenarios (A–G)
| ID | Situation | Response |
|---|---|---|
| A | First Q4 mirror week | Run full M1–M6 manually once |
| B | Drive admin restructured folders | Update mirror_dest_prefix; re-M2 |
| C | Resolve archive added mid-week | Add resolve_archive cousin path |
| D | CI green, partner 404 | Human M2 on producer account |
| E | Personal OAuth on CI | M5 fail—dedicated SA |
| F | Dry-run huge, live copy skipped | M4 log review—not a pass |
| G | Zip sent without receipt | Block send; file M6 first |
BUILD_RECEIPT wiring
{
"build_id": "october-fest-2026-rc5",
"rclone_path_ok": true,
"diligence_mirror_receipt_path": "release-evidence/diligence/DILIGENCE_MIRROR_RECEIPT.json",
"team_drive_id": "0ABCxyz123SharedDriveIdExample",
"notes": "M1-M6 pass 2026-10-22; dry-run log archived"
}
Tools and sibling reads
- rclone Google Drive docs
- Q3 diligence packet anatomy
- Q4 telemetry diligence
- 12 setlive preflight checks — parallel Thursday ops lane
- Resource #20 forward — diligence mirror tool list refresh
- Help #28 forward — path-not-found fix
Key takeaways
- Browser UI ≠ rclone truth—run
rclone lsdheadless (M2). - Pin
team_drive_idin JSON—jq guard before copy (M3). diligence_mirror_receipt_v1.jsonindexes nightly mirror—not only Resolve.- Service account vs human must be explicit (M5).
- Dry-run log before live copy (M4).
- Resolve archive preflight is cousin—not duplicate.
- Lesson 264 links
archive_handoff_ok; this receipt linksrclone_path_ok. - Help #28 forward owns fix lane; this post owns preventive guard.
- Pair Q4 observability annex in
source_roots. - Forward #16 OBS OneDrive case study—different path drift class. See OneDrive KFM case study.
FAQ
Can we mirror to S3 instead of Team Drive?
Yes—change rclone_remote and receipt schema fields; M2–M3 adapt to provider list commands.
Does this upload the partner zip?
No—mirrors source folders; partner ZIP standard packages separately.
One Shared drive or per-partner folders?
Use mirror_dest_prefix per partner; one team_drive_id if same drive.
How often re-validate M2?
Weekly during active diligence month; after any Google Admin change.
jq on Windows CI?
Use jq.exe or Git Bash; PowerShell spot-check for producers.
Should mirror include crash symbolicate receipts?
Yes—add 07-observability/ to source_roots; pair crash symbolicate evening tutorial.
What if we only use Google Drive web UI uploads?
Partners still ask for scripted mirror proof in Q4—web UI uploads do not produce diligence_mirror_receipt_v1.json or dry-run logs. Minimum: manual M2 + M6 with documented human actor in M5.
Does setlive promotion require mirror receipt?
Not for Steam depot promotion—12 setlive preflight checks own depot identity. Mirror receipt is parallel diligence lane during the same October week; both can appear on BUILD_RECEIPT.
How does this relate to ffprobe audio matrix?
ffprobe duration matrix owns marketing audio batch jq; this post owns Drive ID + mirror index—different source_roots, same receipt culture.
Conclusion
Q4 partners cannot audit offline mirrors when team_drive IDs 404 nightly. Pin config, rclone lsd, jq guard, dry-run, file diligence_mirror_receipt_v1.json—then run live copy and send the zip.
Next reads: Resolve archive rclone preflight, Lesson 264, Q4 telemetry diligence, Thursday row review.
Found this useful? Pin diligence_mirror_config_v1.json beside your nightly cron before Q4 mirror week—not after the partner asks why 07-observability/ is stale.