---
belongs_to:
  - "[[⚒️ 铸渊·协作指令｜GitHub ↔ Notion 桥接协议]]"
---
# 🪞 铸渊指令｜Google Drive 镜像桥接层（上篇）· 架构 + Phase A/B（ZY-DRIVE-BRIDGE-2026-0323-001）

---

<aside>
🚨

**指令编号：ZY-DRIVE-BRIDGE-2026-0323-001**

**签发人：** 霜砚（ICE-NTN-SY001）· 代 TCS-0002∞ 冰朔 签发

**签发时间：** 2026-03-23T11:46+08:00

**优先级：** 🔴 P0 · 格点库闭环关键补丁

**前置指令：** [🔄 铸渊指令｜全自动广播神经闭环（上篇）· 逻辑格点库自研 + Gemini外挂记忆 + Phase 0-2 基础设施·记忆层·通信层（ZY-AUTO-LOOP-2026-0323-001）](%F0%9F%94%84%20%E9%93%B8%E6%B8%8A%E6%8C%87%E4%BB%A4%EF%BD%9C%E5%85%A8%E8%87%AA%E5%8A%A8%E5%B9%BF%E6%92%AD%E7%A5%9E%E7%BB%8F%E9%97%AD%E7%8E%AF%EF%BC%88%E4%B8%8A%E7%AF%87%EF%BC%89%C2%B7%20%E9%80%BB%E8%BE%91%E6%A0%BC%E7%82%B9%E5%BA%93%E8%87%AA%E7%A0%94%20+%20Gemini%E5%A4%96%E6%8C%82%E8%AE%B0%E5%BF%86%20+%20Phase%2071b31c2ce3824240bb0aecc81f923ba5.md)

**关联仓库：** [https://github.com/qinfendebingshuo/guanghulab](https://github.com/qinfendebingshuo/guanghulab)

**版权锚点：** 国作登字-2026-A-00037559 · TCS-0002∞ 冰朔

**本指令分为上下两篇：**

- **上篇（本页）**：背景 · 数据主权 · 架构总览 · Phase A（仓库→Drive）· Phase B（Drive→仓库）
- **下篇**：Phase C（Gemini 主控台 + Drive 类数据库）· Phase D（一键部署/恢复）· 安全容灾 · 执行清单
</aside>

---

## 🎯 指令背景与目标

### 问题

格点库闭环指令（ZY-AUTO-LOOP-2026-0323-001）设计的链路是 Gemini 直接读写仓库 `grid-db/` 目录。**经实测验证，Google Gemini 对 GitHub 的权限审计结果如下：**

| **操作** | **结果** | **原因** |
| --- | --- | --- |
| 读取 GitHub 文件 | ❌ 不能 | Google 连接器不支持 GitHub 文件系统直接访问 |
| 创建 GitHub 文件 | ❌ 不能 | 连接器只读不写，不支持 Push/Commit |
| 修改 GitHub 文件 | ❌ 不能 | 同上 |
| 调用外部 HTTP API | ❌ 不能 | Gemini 工具箱只有 Personal Context + Google Search |
| 读取 Google Drive 文件 | ✅ 能 | 通过 Personal Context 搜索读取 |
| 在 Drive 创建 Google Docs | ✅ 能 | Gemini 原生支持 |

**结论：Gemini 与 GitHub 之间存在物理断点。必须用 Google Drive 做桥接。**

### 目标

**在仓库 `grid-db/` 与 Google Drive 之间建立实时镜像同步，让 Gemini 通过 Drive 间接读写格点库，实现用户说话 → 数据自动闭环。**

---

## 🔐 数据主权原则（最高优先级）

<aside>
🔐

**绝对铁律：Google Drive 和 Gemini 只是镜子和嘴巴。脑子永远在仓库和 Notion 里。**

- 仓库（GitHub）= 代码的权威源
- Notion = 逻辑和记忆的权威源
- Google Drive = **只是镜像**，随时可以重建
- Gemini = **只是交互界面**，换一个模型也能接

如果用户的 Google 账号被封、Drive 被清空、Gemini 不可用——**用户的人格体信息、系统数据、所有记忆，一个字都不会丢**。因为权威数据全部在仓库和 Notion 里。

Drive 丢了 → 仓库重新同步一遍就恢复。

Gemini 挂了 → 换一个模型，接同一个 Drive 文件夹，继续工作。

</aside>

### 数据流向原则

| **数据类型** | **权威源** | **Drive 里的是什么** | **丢了怎么办** |
| --- | --- | --- | --- |
| 人格体核心记忆 | Notion（霜砚维护） | 只读镜像 | 从 Notion 重新同步 |
| 开发上下文 / 会话记录 | 仓库 `grid-db/memory/` | 只读镜像 | 从仓库重新同步 |
| 广播 / 任务指令 | 仓库 `grid-db/outbox/` | 只读镜像 | 从仓库重新同步 |
| Gemini 写入的消息 | **仓库（落盘后才算数）** | 临时中转，落盘后删除 | 未落盘的丢了就丢了（Gemini 重新发一次） |
| 交互全文记录 | 仓库 `grid-db/interactions/` | 不同步到 Drive | 不受影响 |
| 训练数据湖 | 仓库 `grid-db/training-lake/` | 不同步到 Drive | 不受影响 |

**一句话：Drive 里的东西全是「副本」。正本永远在仓库和 Notion。**

---

## 🏗️ 架构总览

```
┌─────────────────────────────────────────────────────────┐
│                    用户说话                               │
│                      ↓                                   │
│              Google Gemini（交互界面）                     │
│            ↙ 读取 Drive          写入 Drive ↘             │
│   ┌──────────────┐              ┌──────────────┐         │
│   │  Drive/mirror │              │  Drive/inbox  │         │
│   │  （只读镜像）  │              │ （临时中转站） │         │
│   └──────┬───────┘              └──────┬───────┘         │
│          │ GitHub Action                │ Apps Script     │
│          │ 仓库→Drive                   │ Drive→仓库      │
│          ↑ 同步                         ↓ 同步           │
│   ┌──────────────────────────────────────────────┐       │
│   │         GitHub 仓库 grid-db/（权威源）         │       │
│   │   memory/ outbox/ inbox/ interactions/        │       │
│   └──────────────────┬───────────────────────────┘       │
│                      │ GitHub Actions                    │
│                      ↓                                   │
│              铸渊 Workflow 处理                            │
│         校验→归档→广播生成→记忆更新                         │
│                      │                                   │
│                      ↓                                   │
│              Notion（逻辑权威源）                          │
│         霜砚维护 · 永久记忆 · 编号体系                      │
└─────────────────────────────────────────────────────────┘
```

### 角色翻译表

| **角色** | **比喻** | **擅长的语言** | **翻译器** |
| --- | --- | --- | --- |
| 仓库（GitHub） | 手（写代码） | Git · JSON · YAML · 代码 | GitHub Action → Drive |
| Gemini | 嘴（说人话） | Google Docs · 自然语言 | Apps Script → 仓库 |
| Notion | 脑（记逻辑） | 数据库 · 页面 · 编号体系 | 已有 workflow 双向同步 |
| Google Drive | 翻译台（中转站） | 两边都能听懂 | 自己就是翻译器 |

---

## Phase A · 仓库 → Drive 同步（让 Gemini 能读）

**目标：** 仓库 `grid-db/` 中的关键文件实时镜像到 Google Drive，Gemini 通过 Personal Context 读取。

### A.1 Google Cloud Service Account 配置

```bash
# 1. 在 Google Cloud Console 创建项目（或用已有项目）
# 2. 启用 Google Drive API
# 3. 创建 Service Account → 下载 JSON 密钥
# 4. 把 Service Account 的邮箱地址分享到用户 Drive 的「光湖格点库」文件夹（编辑者权限）
# 5. 把 JSON 密钥内容存为 GitHub Secret：GOOGLE_DRIVE_SERVICE_ACCOUNT
```

### A.2 GitHub Action · 仓库→Drive 同步

创建 `.github/workflows/sync-griddb-to-drive.yml`：

```yaml
name: 🪞 Grid-DB → Google Drive 镜像同步

on:
  push:
    paths:
      - 'grid-db/memory/**'
      - 'grid-db/outbox/latest/**'
      - 'grid-db/rules/**'
  schedule:
    - cron: '*/15 * * * *'
  workflow_dispatch:

jobs:
  sync-to-drive:
    if: "!contains(github.event.head_commit.message, '[skip ci]')"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 🔧 安装依赖
        run: npm install googleapis

      - name: 🪞 同步到 Google Drive
        env:
          GOOGLE_DRIVE_SERVICE_ACCOUNT: $ secrets.GOOGLE_DRIVE_SERVICE_ACCOUNT 
          DRIVE_FOLDER_ID: $ secrets.DRIVE_MIRROR_FOLDER_ID 
        run: node scripts/grid-db/sync-to-drive.js

      - name: 📋 写同步日志
        run: |
          echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) | sync-to-drive | OK" >> grid-db/logs/drive-sync.log
          git config user.name "zhuyuan-bot"
          git config user.email "zhuyuan@guanghulab.com"
          git add grid-db/logs/drive-sync.log
          git diff --cached --quiet || git commit -m "log: Drive sync [skip ci]"
          git push
```

### A.3 同步脚本 `scripts/grid-db/sync-to-drive.js`

```jsx
/**
 * sync-to-drive.js
 * 
 * 功能：将 grid-db/ 中的关键文件同步到 Google Drive 镜像目录
 * 
 * 同步范围：
 *   grid-db/memory/DEV-XXX/*.json  →  Drive/光湖格点库/mirror/memory/DEV-XXX/
 *   grid-db/outbox/latest/*.json    →  Drive/光湖格点库/mirror/outbox/
 *   grid-db/rules/*.json            →  Drive/光湖格点库/mirror/rules/
 * 
 * 同步策略：
 *   - 比较文件内容 hash，仅同步有变更的文件（节省 API 配额）
 *   - 文件不存在则创建，已存在则覆盖更新
 *   - Drive 中多出的文件不删除（防误删）
 * 
 * 注意：
 *   - 不同步 interactions/ 和 training-lake/（数据量大 + 无需 Gemini 读取）
 *   - 不同步 inbox/ 和 processing/（这是系统内部流转区）
 */

const { google } = require('googleapis');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');

// ... 铸渊根据上述注释实现完整逻辑
```

---

## Phase B · Drive → 仓库 同步（让 Gemini 能写）

**目标：** Gemini 在 Drive `inbox/` 文件夹创建新文档 → 自动搬运到仓库 `grid-db/inbox/` → 铸渊处理。

### B.1 Google Apps Script（核心翻译器）

在用户的 Google Drive 中创建一个 Apps Script 项目，代码如下：

```jsx
/**
 * drive-to-github-bridge.gs
 * 
 * 功能：监听 Drive「光湖格点库/inbox/」文件夹
 *       发现 Gemini 新建的文档 → 读取内容 → 通过 GitHub API 写入仓库
 * 
 * 触发方式：时间驱动触发器，每 1 分钟执行一次
 * 
 * 流程：
 *   ① 扫描 inbox 文件夹中所有文件
 *   ② 读取文件内容（Google Docs → 提取纯文本/JSON）
 *   ③ 构造标准 inbox 消息格式
 *   ④ 调用 GitHub Contents API 写入 grid-db/inbox/\[filename\].json
 *   ⑤ 写入成功 → 将 Drive 文件移到「已处理」文件夹（不删除，留审计轨迹）
 *   ⑥ 写入失败 → 标记文件，下次重试
 * 
 * 安全：
 *   - GitHub Token 存在 Script Properties 中（不硬编码）
 *   - 只处理 inbox 文件夹内的文件，不碰 mirror
 *   - 每次处理后写日志到 Drive「光湖格点库/logs/」
 */

var CONFIG = {
  INBOX_FOLDER_NAME: '光湖格点库/inbox',
  PROCESSED_FOLDER_NAME: '光湖格点库/inbox/已处理',
  GITHUB_REPO: 'qinfendebingshuo/guanghulab',
  GITHUB_BRANCH: 'main',
  GRID_DB_INBOX_PATH: 'grid-db/inbox/'
};

function processInbox() {
  var token = PropertiesService.getScriptProperties()
    .getProperty('GITHUB_TOKEN');
  if (!token) {
    Logger.log('ERROR: GITHUB_TOKEN not set');
    return;
  }
  var inboxFolder = getOrCreateFolder(CONFIG.INBOX_FOLDER_NAME);
  var processedFolder = getOrCreateFolder(CONFIG.PROCESSED_FOLDER_NAME);
  var files = inboxFolder.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    try {
      var content = extractContent(file);
      if (!content) continue;
      var timestamp = Utilities.formatDate(
        new Date(), 'Asia/Shanghai', 'yyyyMMdd-HHmmss');
      var filename = timestamp + '-' +
        file.getName().replace(/\[^a-zA-Z0-9\-_\]/g, '') + '.json';
      var success = writeToGitHub(
        token, CONFIG.GRID_DB_INBOX_PATH + filename, content);
      if (success) {
        file.moveTo(processedFolder);
        Logger.log('OK: ' + filename);
      } else {
        Logger.log('FAIL: ' + filename);
      }
    } catch (e) {
      Logger.log('ERROR: ' + file.getName() + ': ' + e.message);
    }
  }
}

function extractContent(file) {
  var mimeType = file.getMimeType();
  if (mimeType === MimeType.GOOGLE_DOCS) {
    var doc = DocumentApp.openById(file.getId());
    var text = doc.getBody().getText().trim();
    try {
      JSON.parse(text);
      return text;
    } catch (e) {
      return JSON.stringify({
        schema_version: '1.0',
        message_id: Utilities.getUuid(),
        timestamp: new Date().toISOString(),
        source: 'gemini-via-drive',
        type: 'raw-message',
        payload: { text: text }
      }, null, 2);
    }
  } else if (mimeType === MimeType.PLAIN_TEXT
    || file.getName().endsWith('.json')) {
    return file.getBlob().getDataAsString();
  }
  Logger.log('SKIP: unsupported mime ' + mimeType);
  return null;
}

function writeToGitHub(token, filePath, content) {
  var url = 'https://api.github.com/repos/'
    + CONFIG.GITHUB_REPO + '/contents/' + filePath;
  var payload = {
    message: 'auto: Gemini inbox via Drive bridge \[skip ci\]',
    content: Utilities.base64Encode(content, Utilities.Charset.UTF_8),
    branch: CONFIG.GITHUB_BRANCH
  };
  var options = {
    method: 'PUT',
    headers: {
      'Authorization': 'Bearer ' + token,
      'Accept': 'application/vnd.github+json',
      'X-GitHub-Api-Version': '2022-11-28'
    },
    contentType: 'application/json',
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  };
  var response = UrlFetchApp.fetch(url, options);
  var code = response.getResponseCode();
  return (code === 201 || code === 200);
}

function getOrCreateFolder(folderPath) {
  var parts = folderPath.split('/');
  var folder = DriveApp.getRootFolder();
  for (var i = 0; i < parts.length; i++) {
    var folders = folder.getFoldersByName(parts\[i\]);
    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = folder.createFolder(parts\[i\]);
    }
  }
  return folder;
}

// ═══ 触发器设置 ═══
// Apps Script 编辑器 → 触发器 → 添加
// 函数：processInbox · 事件源：时间驱动 · 间隔：每 1 分钟
```

### B.2 部署步骤（给冰朔或开发者操作）

1. 打开 [Google Apps Script](https://script.google.com) → 新建项目
2. 项目名：`光湖格点库桥接器`
3. 粘贴上面的代码
4. 设置 Script Properties：项目设置 → 脚本属性 → 添加 `GITHUB_TOKEN`（需要 `repo` 权限）
5. 添加触发器：触发器 → 添加 → 函数 `processInbox` → 时间驱动 → 每 1 分钟
6. 首次运行：点运行 → 授权 Drive 访问权限

---

## 🔗 与格点库闭环指令的关系

本指令是 **ZY-AUTO-LOOP-2026-0323-001（格点库闭环指令）的补丁**。

格点库的核心架构**不变**——目录结构、消息格式、铸渊 workflow、记忆同步规则、循环触发防护，全部保持原样。

本指令只做一件事：**在 Gemini 和格点库之间插入一个 Google Drive 翻译层**。

| **原设计** | **实际链路（本指令补丁后）** |
| --- | --- |
| Gemini 直接读 `grid-db/memory/` | Gemini 读 Drive `mirror/memory/`（内容完全一致） |
| Gemini 直接写 `grid-db/inbox/` | Gemini 写 Drive `inbox/` → Apps Script 自动搬到仓库 `grid-db/inbox/` |
| 铸渊处理 inbox → 写 outbox | **不变** |
| Notion ↔ 仓库同步 | **不变** |

**对用户透明：用户全程只跟 Gemini 说话，感知不到中间有 Drive 翻译层的存在。**

---

**👉 下篇见：Phase C（Gemini 主控台 + Drive 类数据库结构）· Phase D（一键部署/恢复）· 安全容灾 · 执行清单**

🖋️ 霜砚 · PER-SY001

🧊 代 TCS-0002∞ 冰朔 签发

📅 2026-03-23T11:46+08:00