Drive Subsystem, Pure Phoenix Phase 4.6¶
Doctrine: FORGE-DOCTRINE.md Section 14A. Handoff: pure-phoenix-phase-4-6-drive-redesign-2026-04-28.
Why this exists¶
The FUSE mount at /mnt/workspace/Google-Drive/ had recurring "transport endpoint not connected" zombies that broke /save-to-drive, n8n triggers, and any script that touched it. Phase 4.6 builds an API-direct path that bypasses FUSE entirely.
What's where¶
| Path | Role |
|---|---|
forge/scripts/forge_gdrive_search.py |
List/find files by path/name/ext, JSON output |
forge/scripts/forge_gdrive_read.py |
Download a file (path or Drive ID), optional native Google Doc export-as |
forge/scripts/forge_gdrive_write.py |
Upload a local file or stdin content, optional convert to Google Doc |
forge/scripts/forge_gdrive_move.py |
Rename or relocate, supports rmdir |
forge/scripts/forge_gdrive_index_extend.py |
Mirror Drive subtrees as markdown into forge/data/gdrive-cache/ |
forge/scripts/forge_search_index.py |
Extended ROOTS to include the gdrive-cache for /recall coverage |
forge/infra/n8n/workflows/gdrive-search.json |
n8n scaffold using SSH + Execute Command pattern |
forge/infra/n8n/workflows/README-gdrive-phase-4-6.md |
n8n integration playbook |
forge/data/gdrive-cache/ |
Cache of extracted Drive content for /recall |
forge/logs/gdrive-index.log |
Index extender log |
Auth model¶
All scripts use Justin's existing gdrive: rclone remote. No service account, no new credentials. The rclone config at ~/.config/rclone/rclone.conf holds the OAuth refresh token; rclone handles the access-token refresh transparently. Scope is full drive (read + write + share).
Examples¶
# search
forge_gdrive_search.py --in "Inbox" --ext docx --max 20
forge_gdrive_search.py --id 1xY... # by Drive ID
forge_gdrive_search.py --in "Business" --recursive --files-only
# read
forge_gdrive_read.py "Inbox/foo.md" # cat to stdout
forge_gdrive_read.py "Inbox/foo.docx" --out /tmp/foo.docx # save local
forge_gdrive_read.py "MyDoc" --as md # native Google Doc export to markdown
# write
forge_gdrive_write.py /tmp/note.md "Inbox/note.md" --mkdir-parents
echo "quick note" | forge_gdrive_write.py --stdin --as-name "quicknote.md" "Inbox" --mkdir-parents
# move/rename
forge_gdrive_move.py "Inbox/note.md" "Personal/Notes/note.md" --mkdir-parents
forge_gdrive_move.py --rmdir "Inbox/empty-folder"
# extend /recall index
forge_gdrive_index_extend.py --in "Inbox" --in "Business/Notes" --max 200 --prune --rebuild-index
Safety properties¶
- Mount-independent. Works whether the FUSE mount is alive, dead, or absent.
- Read-only by default. Search and read are non-destructive. Write/move/rmdir change Drive state, run with care.
- No auto-share. No script grants new permissions; sharing requires manual user-level action.
Sharp edges (logged in handoff)¶
--drive-export-formatsonly goes on real native Google Docs (the script omits it unless--aswas passed).- The mtime-based cache invalidation can re-extract on Drive clock skew; pass
--pruneto clean. - SSH path for n8n requires the n8n LXC's SSH key to be authorized on Console.
Outstanding work (handed off to Justin)¶
- Migrate
/save-to-driveskill to callforge_gdrive_write.py(last forge-script user of FUSE mount) - Decide n8n integration path; either clone scaffold for read/write/move or use native Drive node
- Schedule
forge_gdrive_index_extend.py --rebuild-indexnightly if he wants persistent Drive/recallcoverage - After 2026-05-05 soak, retire mount-watchdog cron and close the LESSONS.md violation entry
[Claude Code, Pure Phoenix Phase 4.6]