Skip to content

Pure Phoenix Phase 4.6, Drive Subsystem Redesign (forge side)

Forge-side CLI for Google Drive ships. n8n workflows are scaffolded; pure-API path is live and FUSE mount is now optional for forge scripts.

Plan: ~/.claude/plans/yes-lets-go-into-pure-phoenix.md Section 4.6. Doctrine: FORGE-DOCTRINE.md. Inventory: pure-phoenix-inventory-2026-04-28.

What ships

CLI (5 scripts)

All under forge/scripts/, doctrine-compliant flat-named, snake_case.

Script Operation Reuses
forge_gdrive_search.py list/grep Drive paths, JSON output rclone lsjson
forge_gdrive_read.py stream/download a Drive file (path or ID), optional Google-Doc export-as conversion rclone cat/copyto
forge_gdrive_write.py upload from local file or stdin, optional convert-to-Google-Doc on import rclone copyto
forge_gdrive_move.py rename or relocate inside Drive, optional rmdir rclone moveto/rmdir
forge_gdrive_index_extend.py mirror Drive subtrees into forge/data/gdrive-cache/ as extracted markdown for /recall rclone copyto + pandoc

All five run without depending on the FUSE mount. They talk to the Drive API through Justin's existing gdrive: rclone remote (full drive OAuth scope, refresh token, no new credentials needed).

/recall index extension

forge/scripts/forge_search_index.py ROOTS now includes forge/data/gdrive-cache/. Run forge_gdrive_index_extend.py [--in subtree] [--rebuild-index] to mirror Drive content as markdown into the cache, then re-embed. Default subtrees: Inbox, Business/Notes, Personal/Notes. Cap is 500 files per subtree per run.

Pandoc handles .docx to markdown and .pdf to plain text. Native Google Docs/Sheets/Slides convert via rclone's --drive-export-formats chain (md > html > txt for Docs).

n8n workflows

infra/n8n/workflows/gdrive-search.json shipped as scaffold using Execute Command + SSH-to-Console pattern. The other workflows (read, write, move, create-folder) follow the same shape; documented in infra/n8n/workflows/README-gdrive-phase-4-6.md. Justin's call whether to clone the scaffold or use n8n's native Google Drive node.

What's NOT done (deferred)

Item Why When
Brain tool surface (gdrive_read, gdrive_write, gdrive_search, gdrive_move) inbox + lifeos brains are themselves being redone in Phase 4.2 wire during Phase 4.2 bot redesign
Read/write/move n8n workflows beyond the scaffold needs Justin's call on SSH vs native Google Drive node after he picks
Drive share operation rclone alone cannot share to a specific email; needs google-api-python-client Phase 4.6b if needed
7-day parallel soak with FUSE mount live now, soak window starts here retire mount-watchdog cron after 2026-05-05
LESSONS.md mount-watchdog doctrine-violation closure gated on the 7-day soak 2026-05-05

Mount-watchdog status

Per CP-4 in the master plan, the FUSE mount + mount-watchdog cron stay alive through the soak. After 2026-05-05, if no script that anyone cares about still requires the mount, retire the cron entry and close the LESSONS.md violation entry.

The forge_gdrive_*.py scripts and the /recall extender are already mount-independent. The remaining mount-dependent surfaces are: - /save-to-drive skill (still uses cp /tmp/x.docx /mnt/workspace/Google-Drive/) - Any human file-browser usage (you opening Files.app on the mount) - Legacy scripts that haven't been moved over

The /save-to-drive skill should be migrated to call forge_gdrive_write.py directly. That's the last forge-script user of the mount. Do that and the mount becomes purely a human convenience.

Architecture

                     Justin
                       |
              writes/reads files
                       |
            +----------v-----------+
            |  Google Drive API    |
            +----------^-----------+
                       |
        +--------------+--------------+
        |                             |
  rclone (forge_gdrive_*.py)    n8n native Drive node
        |                             |
   forge scripts                  workflows
        |
+-------v--------+
|  /recall index |
| (gdrive-cache) |
+----------------+

The FUSE mount sits parallel as a human-convenience layer; it is no longer in the critical path for forge automation.

Verification done in this session

  • forge_gdrive_search.py --in / --max 5 returned 5 .docx records from Drive root.
  • forge_gdrive_write.py /tmp/p46_smoke.txt Inbox/p46_smoke.txt --mkdir-parents uploaded successfully.
  • forge_gdrive_move.py Inbox/p46_smoke.txt Inbox/p46_smoke_renamed.txt renamed.
  • forge_gdrive_read.py "2026-03-25_Water-Softener-Info.docx" --out /tmp/water2.docx downloaded the real .docx (6776 bytes).
  • forge_gdrive_index_extend.py --in "" --max 5 extracted 5 .docx files via pandoc into forge/data/gdrive-cache/ as markdown. Cache opens as readable text.
  • Test artifact in Drive cleaned up via rclone delete.

Known sharp edges

  1. --drive-export-formats flag is poison for non-native binary files. rclone interprets it as "this should be a Google Doc, look for the export"; if the file is already a real .docx, lookup fails with "directory not found". The scripts only pass the flag when --as is explicitly used on the CLI.
  2. rclone OAuth token refreshes automatically. Token at ~/.config/rclone/rclone.conf has the refresh token; rclone refreshes the access token transparently when it expires. No script changes needed if expiry hits mid-call.
  3. Cache de-dup uses mtime comparison. Drive's modified timestamp is parsed and compared against the cache file's mtime. If Drive's clock skews ahead, you'll re-extract every run. If you suspect this, run with --prune to also drop stale entries.
  4. Pandoc 3.1.3 is installed. Both .docx -> md and .pdf -> plain work. PDF extraction quality varies with the source PDF.

Manual actions Justin owns

Action When
Decide n8n integration path (SSH vs native) and either import + clone the scaffold or build via Drive node when he wants Drive operations from n8n
Migrate /save-to-drive skill to call forge_gdrive_write.py next time he touches the skill or before retiring mount-watchdog
Add 0 5 * * * forge_gdrive_index_extend.py --rebuild-index to crontab if he wants nightly Drive indexing after he reviews the cache size for his usage pattern
Retire mount-watchdog cron + close LESSONS.md violation entry after 2026-05-05 soak completes

Files created / modified

Path Action
forge/scripts/forge_gdrive_search.py created
forge/scripts/forge_gdrive_read.py created
forge/scripts/forge_gdrive_write.py created
forge/scripts/forge_gdrive_move.py created
forge/scripts/forge_gdrive_index_extend.py created
forge/scripts/forge_search_index.py added data/gdrive-cache to ROOTS
forge/infra/n8n/workflows/gdrive-search.json scaffold
forge/infra/n8n/workflows/README-gdrive-phase-4-6.md created
forge/data/gdrive-cache/ created (5 sample files mirrored from Drive root for verification)
forge/logs/gdrive-index.log created
~/.claude/projects/-home-justinwieb-forge/memory/reference_gdrive_subsystem.md created (this handoff's topic file)
~/.claude/projects/-home-justinwieb-forge/memory/MEMORY.md added gdrive subsystem pointer
forge/memory/handoffs/pure-phoenix-inventory-2026-04-28.md Phase 4.6 entry appended
forge/LESSONS.md Phase 4.6 closeout entry appended

[Claude Code, Pure Phoenix Phase 4.6]