Skip to content

fix(base): harden agent recovery for fields and views - #2153

Open
huarenmin13 wants to merge 6 commits into
larksuite:mainfrom
huarenmin13:agent/base-agent-reliability
Open

fix(base): harden agent recovery for fields and views#2153
huarenmin13 wants to merge 6 commits into
larksuite:mainfrom
huarenmin13:agent/base-agent-reliability

Conversation

@huarenmin13

@huarenmin13 huarenmin13 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Harden Base shortcuts around three reusable contracts: canonical field types, concrete view-creation evidence, and parse-time recovery aliases for common resource-name flags. This combines the retained purposes from the two evaluated internal MRs without changing the reference PR #2133.

The base_table_043 view UI capability-boundary changes and the same-Base single-table-copy guidance are intentionally excluded from this PR.

Changes

  • Validate one canonical field-type catalog across +field-create, +field-update, +table-create --fields, and +base-create --fields; malformed field arrays and unsupported types fail before dry-run or execution.
  • Require at least one +view-create item, normalize alternate view_id responses to views[].id, and fail closed when a create response has no ID.
  • Emit the existing ok:false partial-failure contract when a later view in a batch fails, preserving earlier views and structured failure metadata so callers do not repeat successful writes.
  • Accept local resource-name aliases through pflag's parse-time normalizer without registering duplicate flags or adding help/completion metadata.
  • Keep concise view-creation rules in the existing skills/lark-base/SKILL.md; no separate leaf reference is added.

Generic and minimal rationale

  • Field validation has one catalog and one validator rather than command-specific allowlists.
  • View batching reuses the repository's existing OutPartialFailure protocol instead of adding a new output or exit mechanism.
  • Aliases reuse the established Sheets/Slides normalization pattern and add no separate conflict or empty-value behavior.
  • Skill/document parity is checked in the existing Base Skill contract test; command unit tests no longer read repository Markdown directly.
  • No frozen-column, row-height, column-width, raw-API, Gantt-specific, or single-table-copy guidance remains in the PR diff.

Test Plan

  • go test ./shortcuts/base -count=1
  • go vet ./shortcuts/base ./tests/cli_e2e/base
  • Built the current commit and ran targeted Base E2E for aliases, field catalogs/create/update validation, table/Base field validation, and view creation against that fresh binary
  • git diff --check

Related Issues

改动范围: Base 字段类型校验及创建入口、视图创建结果与部分失败输出、资源名 flag 别名、lark-base Skill 指引、单元测试和 dry-run E2E 覆盖。
思考过程: 字段类型由单一运行时目录驱动;视图批量失败复用既有部分失败协议;别名复用仓库已有的 pflag 解析期归一化;短视图规则直接并入现有 Skill,文档目录一致性放在既有 Skill 契约测试,避免新增孤立文件和单题分支。
改动原因: 原有入口对不支持字段类型与缺失视图 ID 的处理不一致,可能导致 Agent 猜类型、误报创建成功或重复写入;同时初版修复落点偏重,本次按通用最小原则收敛后再更新现有 PR。
Break Change: 否

Co-authored-by: BASE Infra Harness ai@base-infra-harness.noreply.local
AI-SHA256: 69994e6e64df828d727826fea9ad275028c4c705609ad1399e881ba524118418

1. Reject unknown field types before dry-run or execution with typed recovery guidance.
2. Normalize created view IDs and fail closed when the API omits creation evidence.
3. Add scoped hidden name aliases and deduplicated table-copy and view guidance with regression cove
    rage.

```ai-signature
改动范围: Base field and view shortcuts, scoped local aliases, skill references, and unit and dry-run tests.
思考过程: Compared the retained purposes from both internal MRs, kept complementary runtime behavior, split long guidance by workflow, and removed reverted, unvalidated, and duplicate prose-contract changes.
改动原因: Agents need deterministic validation, explicit creation evidence, and narrowly scoped recovery paths instead of guessing unsupported fields, reusing same-name views, or expanding aliases globally.
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 29b2a119a0822d5af6eaa70cc885e8d19144e48372f5acb6f6305a3cc097fddf
@github-actions github-actions Bot added domain/base PR touches the base domain size/M Single-domain feat or fix with limited business impact labels Aug 3, 2026
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds canonical field-type validation, hidden local resource-name aliases, stricter view-creation result handling, batch partial-failure reporting, updated view-management guidance, and unit and end-to-end tests.

Changes

Base capability updates

Layer / File(s) Summary
Canonical field-type validation
shortcuts/base/field_ops.go, shortcuts/base/base_ops.go, shortcuts/base/table_ops.go, shortcuts/base/base_shortcuts_test.go, tests/cli_e2e/base/*field*, tests/cli_e2e/base/*create*
Field creation, updates, base creation, and table creation validate canonical field types. Readback classification uses the same catalog. Tests cover accepted types, invalid values, and catalog synchronization.
Local resource-name aliases
shortcuts/base/local_flag_alias.go, shortcuts/base/field_get.go, shortcuts/base/table_get.go, shortcuts/base/view_list.go, shortcuts/base/base_shortcuts_test.go, tests/cli_e2e/base/base_resource_name_alias_dryrun_test.go
Hidden aliases resolve to canonical flags after pre-run validation. Canonical and alias flags cannot be combined. Tests cover metadata, help output, whitespace, URL encoding, and conflicts.
View-creation response contract
shortcuts/base/view_ops.go, shortcuts/base/view_create.go, shortcuts/base/base_execute_test.go, tests/cli_e2e/base/base_view_contract_dryrun_test.go, skills/lark-base/*
View creation rejects empty batches, requires returned identifiers, normalizes view_id to id, and reports prior successes when a later item fails. Guidance documents returned-ID and batch-creation rules.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant BaseViewCreate
  participant ViewAPI
  participant OutputEnvelope
  CLI->>BaseViewCreate: submit view creation batch
  BaseViewCreate->>ViewAPI: create each view
  ViewAPI-->>BaseViewCreate: return id or view_id
  BaseViewCreate->>OutputEnvelope: normalize successful identifiers
  ViewAPI-->>BaseViewCreate: return later item failure
  BaseViewCreate-->>CLI: return successes and partial-failure details
Loading

Possibly related PRs

  • larksuite/cli#2133: Related validation and documentation for unsupported Base field types.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main changes to harden field and view recovery behavior.
Description check ✅ Passed The description includes all required sections and provides clear scope, changes, testing, and related issue information.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@shortcuts/base/base_shortcuts_test.go`:
- Line 24: Remove the direct internal/vfs import from the shortcut test and
replace the vfs.ReadFile usage in the relevant test with the test’s existing
file I/O mechanism; only modify the shortcuts-no-vfs depguard rule if that
dependency is intentional.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ed82df0c-7f08-4afd-bea9-66091bb21d10

📥 Commits

Reviewing files that changed from the base of the PR and between 427cbd6 and b14c25e.

📒 Files selected for processing (17)
  • shortcuts/base/base_execute_test.go
  • shortcuts/base/base_shortcuts_test.go
  • shortcuts/base/field_get.go
  • shortcuts/base/field_ops.go
  • shortcuts/base/local_flag_alias.go
  • shortcuts/base/table_get.go
  • shortcuts/base/view_create.go
  • shortcuts/base/view_list.go
  • shortcuts/base/view_ops.go
  • shortcuts/base/view_set_visible_fields.go
  • skills/lark-base/SKILL.md
  • skills/lark-base/references/lark-base-table-copy.md
  • skills/lark-base/references/lark-base-view-create.md
  • tests/cli_e2e/base/base_field_dryrun_test.go
  • tests/cli_e2e/base/base_field_update_dryrun_test.go
  • tests/cli_e2e/base/base_resource_name_alias_dryrun_test.go
  • tests/cli_e2e/base/base_view_contract_dryrun_test.go

Comment thread shortcuts/base/base_shortcuts_test.go Outdated
huarenmin13 and others added 3 commits August 3, 2026 17:19
1. Remove the same-Base single-table copy route from the lark-base skill.
2. Delete the dedicated table-copy SOP while preserving independent field, view, and alias changes.

```ai-signature
改动范围: Base skill routing and the single-table copy reference introduced in PR larksuite#2153.
思考过程: Removed the complete single-table-copy purpose group while preserving independent field validation, view creation, and local alias behavior and tests.
改动原因: The reviewer requested that same-Base single-table copy guidance be excluded from this pull request.
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 40e5a1fcd3f006bb4c7102bb972c3ca5e9de3924f8f1fbaf53b7ba391cf19657
1. 统一字段类型目录并覆盖 field、table、base 的全部字段写入入口
2. 拒绝空视图批次,规范新建 ID,并在批量后项失败时保留已创建结果
3. 移除视图 UI 能力边界改动,保留隐藏资源名别名的最小恢复路径
4. 补充单元和编译后二阶段 dry-run 回归

```ai-signature
改动范围: Base 字段创建和更新校验、Base 与表创建字段数组、视图创建部分失败输出、隐藏资源名别名、Skill 路由与单元及 dry-run 测试。
思考过程: 按改动目的删除 base_table_043 的 UI 能力边界整组内容;字段类型复用单一目录覆盖所有写入口,视图批量失败复用已有部分失败协议,别名不进入 Shortcut 元数据且不扩大可见帮助。
改动原因: 现有 PR 只覆盖部分字段入口且批量视图失败会丢失已创建 ID,容易让 Agent 误报或重复写入;同时用户要求移除题目特化的 UI 边界内容并将剩余修复收敛为通用最小实现。
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 3fc8cee5c6e8f512794bfd97ecac862ca9a4a8c759c63076c93179f9d4ab1564
1. 使用标准库 os.ReadFile 读取字段类型参考文档
2. 保留字段类型目录与文档一致性的原有断言

```ai-signature
改动范围: shortcuts/base/base_shortcuts_test.go 的字段类型目录一致性测试及其 import。
思考过程: CodeRabbit 指出的 shortcuts 到 internal/vfs 依赖边界问题在当前代码中仍存在;测试只需读取静态文档,标准库 os.ReadFile 已满足需求,无需修改 depguard 规则或生产代码。
改动原因: 移除不必要的内部包依赖,使快捷命令测试遵守 shortcuts-no-vfs 边界,同时保持字段类型 SSOT 回归覆盖不变。
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 0597f6f205e613fe9f16ec945af102647792886a1b04c68b927180d71511587b

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
shortcuts/base/view_ops.go (1)

200-201: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider extracting the repeated partial-failure branch.

Line 200-201 and Line 209-210 repeat the same if len(created) > 0 { return viewCreateProgressError(runtime, err, created, index+1) } pattern. Extracting a small helper, e.g. failOrProgress(err), would remove the duplication and reduce the chance the two branches drift apart later.

♻️ Proposed refactor to consolidate the duplicated branch
+	fail := func(err error) error {
+		if len(created) > 0 {
+			return viewCreateProgressError(runtime, err, created, index+1)
+		}
+		return err
+	}
 	for index, body := range viewItems {
 		data, err := baseV3Call(runtime, "POST", baseV3Path("bases", baseToken, "tables", tableIDValue, "views"), nil, body)
 		if err != nil {
-			if len(created) > 0 {
-				return viewCreateProgressError(runtime, err, created, index+1)
-			}
-			return err
+			return fail(err)
 		}
 		newViewID := viewID(data)
 		if newViewID == "" {
 			err := errs.NewValidationError(errs.SubtypeFailedPrecondition, "view create response omitted the new view ID; creation state is unknown").
 				WithHint("Do not retry or configure a same-name view. If verification is required and read permission is available, run +view-list to reconcile the view IDs.")
-			if len(created) > 0 {
-				return viewCreateProgressError(runtime, err, created, index+1)
-			}
-			return err
+			return fail(err)
 		}

Also applies to: 209-210

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/base/view_ops.go` around lines 200 - 201, Extract the repeated
partial-failure handling around view creation into a small local helper, such as
failOrProgress, that checks len(created) and returns
viewCreateProgressError(runtime, err, created, index+1) when applicable. Replace
both duplicated branches near the view creation logic with this helper while
preserving their existing error behavior and control flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/cli_e2e/base/base_create_dryrun_test.go`:
- Line 136: Update the assertions at
tests/cli_e2e/base/base_create_dryrun_test.go:136 and
tests/cli_e2e/base/base_table_create_dryrun_test.go:25 to parse stderr with
gjson and assert the expected text against the decoded error.message field,
rather than matching a raw JSON substring.

---

Nitpick comments:
In `@shortcuts/base/view_ops.go`:
- Around line 200-201: Extract the repeated partial-failure handling around view
creation into a small local helper, such as failOrProgress, that checks
len(created) and returns viewCreateProgressError(runtime, err, created, index+1)
when applicable. Replace both duplicated branches near the view creation logic
with this helper while preserving their existing error behavior and control
flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6208717d-f016-4cf3-9a00-2bda8236b791

📥 Commits

Reviewing files that changed from the base of the PR and between 0d84091 and e075e70.

📒 Files selected for processing (12)
  • shortcuts/base/base_execute_test.go
  • shortcuts/base/base_ops.go
  • shortcuts/base/base_shortcuts_test.go
  • shortcuts/base/field_ops.go
  • shortcuts/base/local_flag_alias.go
  • shortcuts/base/table_ops.go
  • shortcuts/base/view_ops.go
  • skills/lark-base/SKILL.md
  • skills/lark-base/references/lark-base-view-create.md
  • tests/cli_e2e/base/base_create_dryrun_test.go
  • tests/cli_e2e/base/base_table_create_dryrun_test.go
  • tests/cli_e2e/base/base_view_contract_dryrun_test.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • shortcuts/base/local_flag_alias.go
  • skills/lark-base/SKILL.md
  • shortcuts/base/field_ops.go
  • skills/lark-base/references/lark-base-view-create.md
  • shortcuts/base/base_execute_test.go
  • shortcuts/base/base_shortcuts_test.go

Comment thread tests/cli_e2e/base/base_create_dryrun_test.go Outdated
huarenmin13 and others added 2 commits August 3, 2026 20:58
1. 从 stderr 的 error.message 读取 Base 创建字段类型错误
2. 对表创建字段类型错误使用相同结构化断言

```ai-signature
改动范围: Base 与表创建 dry-run 的未知字段类型 E2E 断言,共两个测试文件。
思考过程: 原断言直接在完整 stderr JSON 上匹配转义字符串,可能误命中其他字段;改为使用已有 gjson 读取 error.message,精确锁定本次校验契约且不改变生产代码。
改动原因: CodeRabbit 指出的结构化断言问题有效,修复能让测试直接验证错误消息字段并避免原始 JSON 串匹配造成的假阳性。
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 467afe0a49196831f9ae2965914cad2bcee1e67344376613916e811b4454959a
1. 将视图创建规则合并到现有 lark-base Skill,删除独立短 reference
2. 复用 pflag 解析期归一化实现资源名别名,删除额外冲突和空值分支
3. 把字段目录一致性校验移到现有 Skill 契约测试,并同步 E2E 文件名与覆盖清单

```ai-signature
改动范围: Base shortcut 通用 helper、三个资源读取 shortcut、lark-base Skill、字段与视图契约测试及 E2E 覆盖清单。
思考过程: 优先复用仓库中 Sheets 和 Slides 已采用的 pflag normalize 机制,并把只服务 Skill 文档的校验放回现有 Skill contract 测试,避免为短规则和局部别名各建独立文件。
改动原因: 当前 PR 中新增的短 view reference 和 alias helper 落点偏重,且冲突与空值处理超出目标问题;本次按通用且最小原则删除额外层次和单题化行为。
Break Change: 否
```

Co-authored-by: BASE Infra Harness <ai@base-infra-harness.noreply.local>
AI-SHA256: 3ea09e66102ca1442d21d17f265398fbe93e64edee66739deafc94ac0b131cc1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/base PR touches the base domain size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant