# Lark Miaoda Base Boundary

> 妙搭（Spark/Miaoda）× 飞书多维表格（Base）的隔离边界验证：在全新测试应用和哨兵表中验证开发态空壳、Feishu Base CRUD、Database 从 Base 导入/自动同步、App Preview 无刷新更新、0/空值、幂等、清理、Run history、Git 推送与发布历史，并防止 Web 配置和 lark-apps 推送互相覆盖。当用户要测试妙搭读写 Base、验证应用 A/B PoC、确认 Base 记录能否实时显示在 App、排查应用被覆盖/Page coming soon、比较 Web 与 lark-apps 开发路径或决定妙搭 Base 架构能否放行时使用；普通妙搭开发走 lark-apps，普通 Base 操作走 lark-base。

- Skill: `akazik-py/lark-miaoda-base-boundary` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add akazik-py/lark-miaoda-base-boundary`
- Raw SKILL.md: https://api.skillmd.com/api/skills/akazik-py/lark-miaoda-base-boundary/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: AKAZIK-py (https://skillmd.com/u/akazik-py)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/akazik-py/lark-miaoda-base-boundary

---


# 妙搭 × Base 隔离边界验证

把验证视为“受控实验”，不是普通应用开发。只在用户授权的可丢弃资产内制造状态变化，并用独立证据证明每个结论。

## 前置路由

1. 纯计划、审计或证据判定只读取本 Skill 和所需 reference；不要无条件加载操作手册。
2. 准备调用妙搭工具前，完整阅读并遵循可用的 `lark-apps` Skill；准备操作 Base 前，完整阅读并遵循 `lark-base` Skill。
3. 网页编辑器、左侧开发对话和扩展配置使用浏览器控制 Skill，并在首次浏览器动作前读取其说明。
4. 只有认证、身份或 scope 出错时才读取 `lark-shared` Skill。
5. 不用 Lark OpenAPI、外部后端或数据库替代核心 Feishu Base capability；若原生路径失败，停止并提交 DELTA。

开始 capability 编码或解释字段语义前，阅读 [references/plugin-contract.md](references/plugin-contract.md)。测试 Web/local 混合路径、Database 同步或 App 实时显示前，阅读 [references/hybrid-and-realtime.md](references/hybrid-and-realtime.md)。执行测试或宣称完成前，阅读 [references/test-matrix.md](references/test-matrix.md)。

## 身份与权限

- `lark-base` 建表与独立回读使用获授权的用户身份；具体 scope 和登录问题交给 `lark-shared`。
- Feishu Base capability 按妙搭 app owner 身份运行；owner 必须对目标测试 Base 有管理权限。
- 权限不足时只记录失败证据，不擅自改 owner、成员、角色或公开范围。
- 不把 app token、认证信息、Git 凭证或可复用密钥写入最终报告。

## 核心不变量

1. **资产隔离**：保护应用和测试应用必须是不同 app id；测试 Base 与生产 Base 必须独立。
2. **单一写入者**：同一 app 在一次实验中只能选择 Web-only 或 Local-only；网页保存/发布和本地推送不能混用。
3. **证据优先**：Agent 文案不是事实。开发轮、Git 提交、release、插件调用和 Base 落表分别取证。
4. **可逆实验**：只写带唯一 SentinelKey 的假数据；记录 recordId；结束时删除并独立回读为空。
5. **权限不扩张**：不改生产权限、所有者、公开范围、数据源或后端。发现需要扩权时先提交 DELTA。
6. **失败不兜底**：原生链路失败时不静默切换 Supabase、Lark OpenAPI、双写或 App→App 推送。

## 状态模型

分别追踪以下状态轴，不允许相互推断：

```text
scope: PROTECTED | ISOLATED
writer_mode: UNSET | WEB_ONLY | LOCAL_ONLY | HYBRID_CANARY
build_state: EMPTY | SHELL_READY | CAPABILITY_READY | HARNESS_READY
agent_state: IDLE | RUNNING | COMPLETED | FAILED
release_state: NONE | AUTO_SHELL_RELEASE | MANUAL_RELEASE
data_state: EMPTY | CREATED | UPDATED | DELETE_READY | CLEANED
protection_state: UNCHANGED | DRIFTED
workspace_state: CLEAN | MODIFIED | STALE_REMOTE | UNKNOWN
mirror_state: NONE | IMPORTING | STABLE | SYNCED | STALE
preview_state: NOT_BUILT | LOADED | AUTO_UPDATED | STALE
```

例如：`agent_state=COMPLETED` 不代表已发布，`release_state=MANUAL_RELEASE` 不代表 Base 已验证，插件返回成功也不代表字段已按契约落表。

同理：Database 出现记录不代表 App Preview 已显示；首次导入包含新记录不代表稳定期增量同步成立；远端 Git 已推送不代表已打开的 Web IDE 已拉取；Preview 保存成功不代表代码已提交或发布。

## 选择唯一开发路径

| 模式 | 允许的写操作 | 禁止项 |
|---|---|---|
| Web-only（默认） | 妙搭网页生成、网页扩展配置、网页内开发态提交 | 对同一 app 执行 `lark-apps +init`、`+plugin-install`、`git push`、`+release-create` |
| Local-only | 明确授权的本地初始化、代码推送和发布 | 网页保存扩展配置、网页代码提交或网页发布 |
| Hybrid canary | 仅在独立、一次性 app 上按获批顺序故意碰撞 | 复用保护应用、正式测试应用或有效数据 |

用户未指定时选择 Web-only。若用户要求比较两条路径，先分别完成 Web-only 与 Local-only，再为碰撞实验创建第三个 canary；提交 DELTA 后才能开始 Hybrid。

用户已明确要求“新测试应用 / 新测试 Base / 隔离 PoC / 边界验证”时，创建可丢弃测试 app、哨兵表和假数据属于已授权范围，不要重复请求批准。只有拟触碰保护/生产资产、发布、扩权、扩大访问范围、接入真实数据/外部后端或执行 Hybrid 碰撞时才提交 DELTA。

## 工作流

### 1. 锁定范围并建立基线

记录：

- 保护 app id、测试 app id、模式和明确禁用动作；
- Base 名称、表名、表 id、字段和测试数据范围；
- 两个 app 的 `main`、开发分支、latest release 与访问范围；
- 测试表初始记录数；
- app owner 对目标 Base 的实际管理权限。

保护 app 只做只读检查。若 app id、Base 或分支无法唯一确认，停止写入。
恢复与漂移判断以 Git commit/tree 等不可变对象为主；release 详情可用于发布审计，但不得作为唯一恢复依据。

Web-only 模式下，`lark-apps` 只可用于读取 app、session、release、日志或指标。例如：

```bash
lark-cli apps +session-get --app-id <test_app_id> --session-id <session_id> --json
lark-cli apps +release-list --app-id <test_app_id> --page-size 20 --json
lark-cli apps +release-get --app-id <test_app_id> --release-id <release_id> --json
```

### 2. 创建隔离哨兵资产

用 `lark-base` 在测试 Base 创建专用表。最小字段：

| 字段 | 类型 | 用途 |
|---|---|---|
| SentinelKey | Text，主字段 | 幂等键与查询键 |
| Label | Text | 可观察更新 |
| Value | Number | 验证数字 0 |
| NullableValue | Number | 验证空值语义 |
| Status | SingleSelect | `created / updated / delete-ready` |
| ContentHash | Text | 内容幂等与版本 |
| CreatedAt | CreatedTime | 审计，只读 |
| UpdatedAt | ModifiedTime | 审计，只读 |

创建后独立读取字段和记录数。Base CLI 可创建哨兵资产并回读，但主 CRUD 证据必须由妙搭 capability 发起，不能用 CLI 代写。

### 3. 生成首个开发态空壳

在妙搭网页从测试 Base/哨兵表创建全新应用。首轮只显示 app id、表名和字段；禁止创建影子 PG 表、业务数据或公开访问。

首次初始化可能较慢：

- `latest_turn.status=running` 且 `is_streaming=true` 只表示云端轮仍在运行；
- 若左侧对话明确停在等待继续开发，在同一 Web 会话提醒一次继续开发并继续轮询；
- 不得因为 running 或等待状态切换到本地写入路径；
- `completed` 只证明开发轮完成，不证明发布。

空壳完成后立刻比较 release history。若平台自动生成 release，记录 release id、commit、时间和访问范围；停止手动 Publish，不能采信 Agent 的“未发布”文案。

### 4. 配置 Feishu Base capability

只在测试 app 网页扩展面板添加 Feishu Base：

1. 核对执行身份是稳定的 app owner；
2. 精确选择测试 Base 与哨兵表；
3. 业务字段可读写，系统时间字段只读；
4. 提交配置，不同时触发代码生成或发布；
5. 只读检查 capability 文件、插件版本、app token/table id 与 `actionPlugins`；
6. 比较提交前后 Git 树，确认没有整仓模板覆盖。

### 5. 生成最小 CRUD 操作台

要求所有写入由用户点击触发；页面加载和测试编译不得自动写 Base。实现：

- Create 前按 SentinelKey 查询并阻断重复；
- Query 显示真实 recordId、结构化字段和原始响应；
- Update/Delete 只使用已查询或已创建的 recordId；
- Delete 必须二次确认；
- Value 必填、有限，且 0 合法；
- Status 做运行时白名单校验；
- 每次操作显示开始/结束时间、成功/失败/阻断和原始响应；
- 缺失 recordId、返回 id 不一致或回读不一致都必须失败，不能伪造成功；
- 不创建 PG、服务端中转、OpenAPI 客户端或其他数据源。

### 6. 按矩阵执行真实验证

严格按 [references/test-matrix.md](references/test-matrix.md) 顺序执行。每个写操作都采集三方证据：

1. 应用 UI 的真实结果和 recordId；
2. Feishu Base 扩展 Run history 的参数/结果；
3. `lark-base` 的独立记录回读。

不得把“代码已提交”“编译通过”或“插件返回 id”单独标为落表成功。

### 7. 清理并复核隔离

删除本轮哨兵记录，再从 Base 独立读取记录数。随后复核：

- 测试 app release list 是否发生意外变化；
- 保护 app 的 release、Git 分支和运行面是否不变；
- 测试 Base 是否回到基线；
- 没有新增 PG 表、外部后端、权限或公开范围。

保留哨兵表和开发态 app 供审计，除非用户明确要求删除资产。

### 8. 验证 Base → App 实时显示

仅当用户目标包含“Base 变化自动显示在 App”时执行。严格分开三层证据：

1. `Base → Database mirror`：在开发环境用 `Create table from Base` 选择哨兵表，开启 `Import source data` 与 `Auto sync data`，确认 `base_record_id` 映射。
2. `Database mirror → App Preview`：自行编写最小只读页面查询镜像表，显示 SentinelKey、Label、recordId 与页面最近查询时间；不要用 Database 管理界面代替 App 页面。
3. `Base → open Preview`：等首次导入完全稳定后再创建第二条唯一哨兵记录，保持 Preview 打开且不刷新，观察记录是否自动出现；随后分别验证 update 与 delete。

首次导入期间出现的记录只能证明导入快照包含它，不能证明持续同步。不要承诺固定秒数 SLA；记录观察窗口和实际延迟。若稳定期新增、更新或删除未在观察窗口出现，分别标记 `FAIL/UNKNOWN DELAY`，不得点手动同步后宣称自动更新通过。

### 9. 验证 Web 与 lark-apps 的树边界

仅在独立 `HYBRID_CANARY` 执行。详细规则见 [references/hybrid-and-realtime.md](references/hybrid-and-realtime.md)：

- Git push 提交完整树快照，不是妙搭的智能文件叠加；
- 只有从最新远端树克隆、局部修改、fast-forward 推送时，结果才表现为“做加法”；
- `apps +init` 可能在失败前改写工程文件，必须审查 diff，禁止初始化后直接 `git add -A`；
- 推送后用完整树对比证明基线文件没有删除，并单独检查 Web IDE 是否仍停留在旧工作区；
- 禁止 force push；发布与推送分开授权、分开验证。

## STOP 与 DELTA

遇到任一情况立即停止当前写操作：

- 写入目标指向保护 app 或非测试 Base；
- app id、Base、table id、owner 身份或分支不唯一；
- Web-only app 出现本地推送痕迹，或 Local-only app 出现网页保存；
- 空壳完成后出现未预期 release；
- capability 指向错误表、字段权限超出最小范围；
- recordId 缺失、0/空值混淆、重复记录、半批成功或 Base 回读不一致；
- Run history 缺失或只有 UI“成功”文案；
- 需要扩权、公开访问、真实业务数据、外部后端或双写；
- 保护 app 的 release、Git 树或运行面发生变化。

DELTA 必须包含：已批准基线、拟变更、原因、影响、可逆性、证据和需要用户决定的事项。通知、running 状态和沉默都不构成批准。

## 完成报告

分别报告，不合并状态：

```text
范围锁：protected app / test app / Base / 模式 / 禁用动作
已实现：代码与 capability 配置
开发态验证：编译、预览、session/turn 状态
Base 真实验证：CRUD、recordId、0/null、幂等、回读、清理
发布验证：未执行 / 自动 release / 手动发布及 release id
保护资产复核：Git、release、运行面是否不变
未验证门槛：权限失败、部分失败、断连重连、发布态等
```

只声明实际观察到的状态；未执行项目明确写“未验证”。不要输出凭证、授权令牌或可复用密钥。

开发态只在必跑矩阵全部通过、哨兵数据已清理且 `protection_state=UNCHANGED` 时标为 `DEV_PASS`。批量部分失败和获批后的发布态矩阵也通过时，才可标为 `FULL_PASS`。

