Skip to content

feat: add lazy API catalog routing - #2232

Open
zhaojunlin0405 wants to merge 1 commit into
mainfrom
feat/catalog-lazy-routing
Open

feat: add lazy API catalog routing#2232
zhaojunlin0405 wants to merge 1 commit into
mainfrom
feat/catalog-lazy-routing

Conversation

@zhaojunlin0405

@zhaojunlin0405 zhaojunlin0405 commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Large API catalogs make every CLI startup pay the cost of assembling the full command tree, even when an agent invokes only one domain. This PR introduces an embedded, sharded catalog snapshot and invocation-aware assembly so standard execution loads only the reachable API and shortcut domains while preserving full-tree behavior for callers that use Build without invocation arguments.

Changes

  • Replace the legacy monolithic registry loader with an integrity-checked manifest and 15 embedded service shards in internal/registry/catalog.
  • Add PlanAssembly, BuildForArgs, and WithInvocationArgs to select None, Target, or Full assembly from one defensive copy of the invocation arguments.
  • Register shortcuts by selected domain and propagate the selected catalog through schema, auth scope, help, affordance, plugin policy, and completion paths.
  • Remove the legacy metadata fetch build dependency and the exported startup-brand helpers; callers using cmd.Execute() or the distributed binary require no integration changes, while custom cmd.Build() wrappers can opt into lazy assembly with cmd.WithInvocationArgs(args).
  • Add snapshot integrity, routing, compatibility, security scanning, benchmark, plugin, and command-surface regression coverage.

Test Plan

  • make unit-test passed with the race detector
  • go vet ./..., gofmt -l ., and go mod tidy passed
  • golangci-lint v2.1.6 --new-from-rev=origin/main passed with 0 issues
  • local-eval passed (sandbox E2E 5/5, skillave N/A)
  • acceptance-reviewer passed (5/5 cases)
  • manual verification: ./lark-cli drive +search --query quarterly --page-size 1 --as user completed a real read-only request with exit code 0

Related Issues

N/A

Summary by CodeRabbit

  • New Features
    • Added a committed API Catalog Snapshot covering Calendar, Drive, Mail, Sheets, Slides, Tasks, Wiki, and additional services.
    • Commands now load only APIs relevant to each operation, improving startup performance.
    • Added catalog-aware schema, help, completion, authentication, and shortcut behavior.
  • Bug Fixes
    • Preserved large integers and precise numeric bounds across requests, schemas, dry runs, and uploads.
    • Added clearer recovery handling for catalog integrity failures.
  • Quality Improvements
    • Added safety checks for sensitive content, internal hosts, and prompt-injection markers.

@coderabbitai

coderabbitai Bot commented Aug 7, 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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e3ed34ae-d033-47e7-930f-24149c264bca

📥 Commits

Reviewing files that changed from the base of the PR and between 46e2186 and be38883.

📒 Files selected for processing (133)
  • .github/workflows/arch-audit.yml
  • .github/workflows/ci.yml
  • .gitignore
  • AGENTS.md
  • Makefile
  • build.sh
  • cmd/assembly_plan.go
  • cmd/assembly_plan_fuzz_test.go
  • cmd/assembly_plan_test.go
  • cmd/auth/auth_test.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/auth/login.go
  • cmd/auth/login_brand_filter_test.go
  • cmd/auth/login_interactive.go
  • cmd/auth/login_test.go
  • cmd/auth/testmain_test.go
  • cmd/build.go
  • cmd/build_benchmark_test.go
  • cmd/build_memstats_test.go
  • cmd/build_target_test.go
  • cmd/build_test.go
  • cmd/cmdexample_test.go
  • cmd/diagnose_scope_test.go
  • cmd/error_auth_hint.go
  • cmd/error_presenter_test.go
  • cmd/global_flags.go
  • cmd/global_flags_test.go
  • cmd/platform_bootstrap.go
  • cmd/plugin_integration_test.go
  • cmd/root.go
  • cmd/root_risk_help_test.go
  • cmd/root_test.go
  • cmd/schema/schema.go
  • cmd/schema/schema_test.go
  • cmd/service/affordance.go
  • cmd/service/affordance_test.go
  • cmd/service/paramflags_test.go
  • cmd/service/paramhelp.go
  • cmd/service/service.go
  • cmd/service/service_test.go
  • cmd/service/testmain_test.go
  • cmd/startup_brand.go
  • cmd/startup_brand_test.go
  • cmd/testmain_test.go
  • content_embed_affordance_test.go
  • errs/subtypes.go
  • internal/affordance/affordance.go
  • internal/affordance/affordance_test.go
  • internal/affordance/application_source_test.go
  • internal/affordance/im_source_test.go
  • internal/apicatalog/catalog.go
  • internal/apicatalog/catalog_test.go
  • internal/cmdutil/factory.go
  • internal/cmdutil/factory_default.go
  • internal/cmdutil/fileupload.go
  • internal/cmdutil/fileupload_test.go
  • internal/cmdutil/json.go
  • internal/cmdutil/json_test.go
  • internal/cmdutil/testmain_test.go
  • internal/meta/normalize.go
  • internal/meta/normalize_test.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • internal/qualitygate/diff/diff.go
  • internal/qualitygate/diff/diff_test.go
  • internal/qualitygate/publiccontent/catalog.go
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/qualitygate/publiccontent/collect.go
  • internal/qualitygate/publiccontent/collect_test.go
  • internal/qualitygate/publiccontent/rules.go
  • internal/qualitygate/publiccontent/scan.go
  • internal/qualitygate/rules/dryrun.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/qualitygate/rules/run.go
  • internal/qualitygate/rules/run_test.go
  • internal/registry/catalog.go
  • internal/registry/catalog/manifest.json
  • internal/registry/catalog/services/approval.json
  • internal/registry/catalog/services/attendance.json
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/contact.json
  • internal/registry/catalog/services/drive.json
  • internal/registry/catalog/services/im.json
  • internal/registry/catalog/services/mail.json
  • internal/registry/catalog/services/mindnotes.json
  • internal/registry/catalog/services/minutes.json
  • internal/registry/catalog/services/okr.json
  • internal/registry/catalog/services/sheets.json
  • internal/registry/catalog/services/slides.json
  • internal/registry/catalog/services/task.json
  • internal/registry/catalog/services/vc.json
  • internal/registry/catalog/services/wiki.json
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/loader_embedded.go
  • internal/registry/loader_test.go
  • internal/registry/meta_data_default.json
  • internal/registry/registry_test.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/registrytest/registrytest.go
  • internal/registry/registrytest/registrytest_test.go
  • internal/registry/remote.go
  • internal/registry/remote_test.go
  • internal/registry/scope_hint_test.go
  • internal/registry/scopes.go
  • internal/registry/snapshot.go
  • internal/registry/snapshot_test.go
  • internal/registry/testmain_test.go
  • internal/schema/assembler.go
  • internal/schema/assembler_test.go
  • internal/schema/catalog_test_helpers_test.go
  • internal/schema/lint.go
  • internal/schema/lint_test.go
  • internal/schema/types.go
  • scripts/build-pkg-pr-new.sh
  • scripts/ci-workflow.test.sh
  • scripts/fetch_meta.py
  • shortcuts/application/slash_command_common.go
  • shortcuts/common/skill_references.go
  • shortcuts/im/affordance_migration_test.go
  • shortcuts/register.go
  • shortcuts/register_brand_guard_test.go
  • shortcuts/register_test.go
  • shortcuts/slides/slides_replace_slide.go
  • skills/lark-calendar/SKILL.md
  • tests/cli_e2e/dryrun/apps_member_dryrun_test.go
  • tests/plugin_e2e/degrade_subsystem_test.go
  • tests/plugin_e2e/harness.go
  • tests/plugin_e2e/restrict_test.go
  • tests/sidecar_e2e/roundtrip_test.go
💤 Files with no reviewable changes (27)
  • internal/qualitygate/rules/dryrun.go
  • .github/workflows/arch-audit.yml
  • cmd/startup_brand.go
  • build.sh
  • cmd/cmdexample_test.go
  • scripts/fetch_meta.py
  • internal/registry/remote.go
  • internal/registry/registrytest/registrytest_test.go
  • cmd/startup_brand_test.go
  • internal/cmdutil/factory_default.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/testmain_test.go
  • internal/registry/loader_embedded.go
  • .gitignore
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/registry/registrytest/registrytest.go
  • tests/cli_e2e/dryrun/apps_member_dryrun_test.go
  • internal/registry/remote_test.go
  • internal/registry/loader_test.go
  • scripts/build-pkg-pr-new.sh
  • internal/registry/scope_hint_test.go
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/catalog.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/registry/meta_data_default.json
🚧 Files skipped from review as they are similar to previous changes (105)
  • skills/lark-calendar/SKILL.md
  • shortcuts/common/skill_references.go
  • cmd/auth/testmain_test.go
  • internal/cmdutil/testmain_test.go
  • internal/qualitygate/rules/run.go
  • internal/qualitygate/rules/run_test.go
  • shortcuts/application/slash_command_common.go
  • internal/registry/catalog/services/mindnotes.json
  • cmd/auth/catalog_test_helpers_test.go
  • internal/qualitygate/diff/diff_test.go
  • internal/registry/catalog/services/contact.json
  • cmd/service/paramflags_test.go
  • internal/meta/normalize_test.go
  • cmd/diagnose_scope_test.go
  • cmd/auth/auth_test.go
  • cmd/build_benchmark_test.go
  • internal/qualitygate/publiccontent/scan.go
  • internal/apicatalog/catalog_test.go
  • cmd/service/affordance_test.go
  • cmd/schema/schema.go
  • internal/schema/types.go
  • internal/cmdutil/json_test.go
  • internal/affordance/im_source_test.go
  • internal/registry/catalog/services/attendance.json
  • internal/qualitygate/publiccontent/collect.go
  • cmd/build_test.go
  • internal/schema/lint.go
  • internal/qualitygate/publiccontent/rules.go
  • cmd/build_memstats_test.go
  • tests/sidecar_e2e/roundtrip_test.go
  • cmd/root_risk_help_test.go
  • scripts/ci-workflow.test.sh
  • tests/plugin_e2e/degrade_subsystem_test.go
  • internal/registry/catalog/manifest.json
  • internal/registry/catalog/services/mail.json
  • Makefile
  • cmd/global_flags.go
  • cmd/platform_bootstrap.go
  • internal/affordance/affordance_test.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/cmdutil/fileupload_test.go
  • shortcuts/im/affordance_migration_test.go
  • shortcuts/slides/slides_replace_slide.go
  • cmd/service/service.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • cmd/auth/login_brand_filter_test.go
  • internal/registry/catalog/services/wiki.json
  • internal/cmdutil/fileupload.go
  • internal/registry/registry_test.go
  • .github/workflows/ci.yml
  • cmd/assembly_plan_test.go
  • internal/cmdutil/factory.go
  • internal/schema/assembler.go
  • internal/registry/catalog/services/minutes.json
  • internal/registry/catalog/services/okr.json
  • cmd/assembly_plan.go
  • internal/registry/catalog/services/task.json
  • internal/qualitygate/publiccontent/catalog.go
  • AGENTS.md
  • internal/registry/snapshot.go
  • internal/apicatalog/catalog.go
  • internal/qualitygate/diff/diff.go
  • tests/plugin_e2e/restrict_test.go
  • internal/qualitygate/publiccontent/catalog_test.go
  • shortcuts/register_test.go
  • cmd/error_auth_hint.go
  • internal/qualitygate/publiccontent/collect_test.go
  • cmd/service/affordance.go
  • internal/schema/lint_test.go
  • internal/registry/catalog/services/approval.json
  • internal/cmdutil/json.go
  • cmd/assembly_plan_fuzz_test.go
  • cmd/root.go
  • cmd/auth/login_test.go
  • shortcuts/register_brand_guard_test.go
  • shortcuts/register.go
  • cmd/global_flags_test.go
  • cmd/service/service_test.go
  • internal/registry/snapshot_test.go
  • internal/registry/catalog/services/im.json
  • cmd/root_test.go
  • internal/affordance/application_source_test.go
  • internal/registry/scopes.go
  • cmd/auth/login_interactive.go
  • cmd/build_target_test.go
  • internal/registry/catalog/services/slides.json
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • cmd/service/testmain_test.go
  • internal/registry/catalog/services/sheets.json
  • internal/meta/normalize.go
  • tests/plugin_e2e/harness.go
  • internal/schema/assembler_test.go
  • cmd/plugin_integration_test.go
  • cmd/testmain_test.go
  • internal/registry/catalog/services/calendar.json
  • errs/subtypes.go
  • content_embed_affordance_test.go
  • internal/registry/catalog/services/vc.json
  • cmd/build.go
  • internal/affordance/affordance.go
  • cmd/schema/schema_test.go
  • internal/registry/catalog/services/drive.json
  • cmd/error_presenter_test.go
  • cmd/service/paramhelp.go
  • cmd/auth/login.go

📝 Walkthrough

Walkthrough

This PR replaces fetched runtime metadata with a validated embedded API Catalog Snapshot. It adds target-aware command assembly, explicit catalog propagation, exact JSON-number handling, catalog publication checks, and selected shortcut registration.

Changes

Catalog Snapshot Migration

Layer / File(s) Summary
Snapshot loading and target-aware builds
internal/registry/snapshot.go, cmd/assembly_plan.go, cmd/build.go, shortcuts/register.go
Adds validated lazy catalog loading, argument-based assembly planning, catalog-failure roots, plugin freezing, and domain-scoped shortcut registration.
Explicit catalog propagation
cmd/auth/*, cmd/schema/*, cmd/service/*, internal/affordance/*, internal/schema/*, internal/registry/scopes.go
Passes selected catalogs through authentication, scopes, schema execution, service registration, help rendering, affordance lookup, and envelope assembly.
Exact numeric handling
internal/cmdutil/*, internal/meta/*, internal/schema/*
Preserves large integers and scientific notation through JSON parsing, schema bounds, validation, rendering, and multipart conversion.
Committed catalog and quality validation
internal/registry/catalog/*, internal/qualitygate/*
Adds service catalog shards and manifest data. Quality gates scan catalog content and classify catalog changes as global.
Build and test migration
.github/workflows/*, Makefile, build.sh, scripts/*, tests/*
Removes metadata fetching and registry fixture seeding. Integration tests use the committed Catalog Snapshot.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: liangshuo-1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.16% 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
Title check ✅ Passed The title clearly and concisely summarizes the primary change: lazy API catalog routing.
Description check ✅ Passed The description includes all required sections and provides clear scope, changes, verification results, and related-issue information.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/catalog-lazy-routing

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.

@github-actions github-actions Bot added domain/calendar PR touches the calendar domain domain/im PR touches the im domain size/XL Architecture-level or global-impact change labels Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@be38883817c0eb75dfb8756be2726f31bffa584f

🧩 Skill update

npx skills add larksuite/cli#feat/catalog-lazy-routing -y -g

@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: 4

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (17)
cmd/schema/schema_test.go-72-78 (1)

72-78: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert catalog-scoped execution directly.

drive resolves with both the drive-only catalog and the full catalog. This assertion can pass if schema execution ignores f.APICatalog.

Run im and assert an unknown-service validation error, or run without arguments and assert that every emitted envelope belongs to drive. As per coding guidelines, “Every behavior change must have an accompanying contract test that fails if the implementation is reverted and asserts the changed field or behavior directly.”

🤖 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 `@cmd/schema/schema_test.go` around lines 72 - 78, Strengthen the schema
command contract test around cmd.Execute so it verifies APICatalog scoping
directly: execute the command with “im” and assert the expected unknown-service
validation error, or execute without arguments and confirm every emitted
envelope belongs to “drive.” Keep the assertion focused on the catalog-selected
behavior rather than merely checking for drive text in the output.

Source: Coding guidelines

tests/plugin_e2e/degrade_subsystem_test.go-40-41 (1)

40-41: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert the schema service field structurally.

strings.Contains accepts malformed JSON and unrelated nested text. Parse res.stdout and assert that the returned schema service name is exactly im.

As per coding guidelines, “Every behavior change must have an accompanying contract test that fails if the implementation is reverted and asserts the changed field or behavior directly.”

🤖 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 `@tests/plugin_e2e/degrade_subsystem_test.go` around lines 40 - 41, Replace the
substring check in the schema output test with JSON parsing of res.stdout, then
assert the parsed schema’s service name field equals exactly "im". Keep the test
failure reporting tied to malformed output or an incorrect field value so it
directly validates the committed service.

Source: Coding guidelines

internal/cmdutil/fileupload_test.go-381-387 (1)

381-387: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert generic typed metadata with errs.ProblemOf.

Lines 381-387 inspect Subtype only through *errs.ValidationError. Assert Subtype through errs.ProblemOf(err). Keep errors.As for the Param assertion.

Proposed test update
+		problem, ok := errs.ProblemOf(err)
+		if !ok {
+			t.Fatalf("expected typed problem, got %T: %v", err, err)
+		}
+		if problem.Subtype != errs.SubtypeInvalidArgument {
+			t.Fatalf("problem subtype = %q, want %q", problem.Subtype, errs.SubtypeInvalidArgument)
+		}
 		var validationErr *errs.ValidationError
 		if !errors.As(err, &validationErr) {
 			t.Fatalf("expected typed validation error, got %T: %v", err, err)
 		}
-		if validationErr.Subtype != errs.SubtypeInvalidArgument || validationErr.Param != "--data" {
-			t.Fatalf("validation error = %#v, want invalid_argument for --data", validationErr)
+		if validationErr.Param != "--data" {
+			t.Fatalf("validation error param = %q, want --data", validationErr.Param)
 		}

As per coding guidelines, **/*_test.go: Error-path tests must assert typed metadata via errs.ProblemOf and cause preservation rather than relying only on message substrings.

🤖 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 `@internal/cmdutil/fileupload_test.go` around lines 381 - 387, Update the
validation-error assertions in the affected test to obtain generic typed
metadata from errs.ProblemOf(err) and assert the expected invalid-argument
subtype through that result. Retain errors.As with *errs.ValidationError
specifically to verify Param is "--data", and preserve the existing failure
diagnostics.

Source: Coding guidelines

internal/qualitygate/publiccontent/catalog_test.go-7-8 (1)

7-8: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use internal/vfs for the catalog read.

Line 23 uses os.ReadFile in an internal package test. Replace the direct os filesystem call with the repository vfs API. This keeps filesystem behavior consistent with the internal test policy.

As per coding guidelines, “Use internal/vfs filesystem APIs instead of os.” Based on learnings, “for any Go test file under internal/ … use internal/vfs for filesystem access.”

Also applies to: 23-25

🤖 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 `@internal/qualitygate/publiccontent/catalog_test.go` around lines 7 - 8,
Replace the direct os.ReadFile call in the catalog test with the repository’s
internal/vfs file-reading API, updating imports accordingly and removing the
now-unused os import. Preserve the existing catalog test behavior and error
handling.

Sources: Coding guidelines, Learnings

internal/qualitygate/publiccontent/collect.go-41-43 (1)

41-43: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Return a typed error for the catalog read failure.

Line 43 returns the raw gitOutput error. If readErr is already typed, return it unchanged. Otherwise wrap it with errs.NewInternalError(errs.SubtypeUnknown, ...).WithCause(readErr). This preserves the cause and the quality-gate error contract.

As per coding guidelines, “Command-facing failures must use typed errs.* errors” and “Preserve lower-layer typed errors, attach causes with .WithCause(err).”

🤖 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 `@internal/qualitygate/publiccontent/collect.go` around lines 41 - 43, Update
the gitOutput error handling in the catalog collection flow around readErr:
return readErr unchanged when it is already a typed errs error; otherwise wrap
it with errs.NewInternalError(errs.SubtypeUnknown, ...) and attach readErr via
WithCause(readErr), preserving the quality-gate error contract.

Source: Coding guidelines

internal/registry/catalog/services/attendance.json-383-383 (1)

383-383: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

risk is write for a read-only query.

user_task.query reads attendance results. The entry sets "risk": "write". See the consolidated comment for the shared cause.

🤖 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 `@internal/registry/catalog/services/attendance.json` at line 383, Update the
attendance service entry for user_task.query to set its risk value to read
instead of write, while leaving the query definition unchanged.
internal/registry/catalog/services/contact.json-166-167 (1)

166-167: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

danger: true is set on a read method.

user_profiles.batch_query reads profile data and declares "risk": "read". It also sets "danger": true. See the consolidated comment for the shared cause across shards.

🤖 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 `@internal/registry/catalog/services/contact.json` around lines 166 - 167,
Update the user_profiles.batch_query entry in the service catalog to remove
danger: true while preserving risk: "read" and the method’s existing read
behavior.
internal/registry/catalog/services/drive.json-770-771 (1)

770-771: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

danger: true is set on read methods.

file.comments.batch_query declares "risk": "read" and also "danger": true. metas.batch_query at lines 3742-3743 has the same combination. See the consolidated comment.

🤖 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 `@internal/registry/catalog/services/drive.json` around lines 770 - 771, Update
the metadata for the read-only batch_query methods, including
file.comments.batch_query and metas.batch_query, to remove the danger: true flag
while preserving risk: "read".
internal/registry/catalog/services/calendar.json-6442-6444 (1)

6442-6444: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Same danger/risk contradiction and empty docUrl.

calendar.event.share_info reads a share link. It sets "danger": true with "risk": "read" and an empty docUrl. See the consolidated comment for the shared cause and the fix.

🤖 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 `@internal/registry/catalog/services/calendar.json` around lines 6442 - 6444,
Update the calendar.event.share_info catalog entry so its danger and risk values
consistently represent a read-only share-link operation, and replace the empty
docUrl with the appropriate documentation URL used by the related calendar
tools.
internal/registry/catalog/services/approval.json-95-95 (1)

95-95: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Confirm the risk value for a read-only search.

approvals.search calls approvals/search_launchable, which only lists launchable approval definitions. The entry sets "risk": "write". Every other read operation in this file uses "risk": "read". The value looks derived from the POST verb rather than from the effect. If risk drives confirmation prompts or policy gating, this misclassifies a read as a write.

The same pattern exists in internal/registry/catalog/services/attendance.json for user_task.query.

🔧 Proposed change
-          "risk": "write",
+          "risk": "read",
🤖 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 `@internal/registry/catalog/services/approval.json` at line 95, Update the risk
classification for the read-only approvals.search operation to "read" instead of
"write", and apply the same correction to attendance.json's user_task.query
entry. Keep the operation definitions and HTTP methods unchanged.
internal/registry/catalog/services/drive.json-452-452 (1)

452-452: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a description for files.patch.

The description field is empty. Every other method in this shard has a description. The catalog description supplies the command summary in help output, so drive files patch will show no summary.

🔧 Proposed change
-          "description": "",
+          "description": "修改文件标题",
🤖 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 `@internal/registry/catalog/services/drive.json` at line 452, Add a concise,
user-facing description to the files.patch catalog entry’s description field,
matching the style of neighboring drive file methods and summarizing the
command’s purpose for help output.
internal/registry/catalog/services/calendar.json-1652-1652 (1)

1652-1652: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the <redacted> marker from the parameter description.

The description of instance_start_time_admin contains the literal text `<redacted>_1713168000`. This is a redaction artifact, not an example value. The catalog descriptions are rendered in command help, so users see the marker. Replace it with a placeholder event ID.

🔧 Proposed change
-              "description": "The instance to be modified when accessing as an administrator.; Note:; - This parameter is only used to modify a event instance in a repeating event. This field does not need to be filled in for non-repeating events.;- You can call the [Get repeating event instance](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/calendar-v4/calendar-event/instances) interface to obtain the event_id of a event instance in the repeating event. The value of this parameter is the timestamp suffix of event_id. For example, the queried event instance ID is `<redacted>_1713168000`, then the current `instance_start_time_admin` value is `1713168000`.; Default: empty",
+              "description": "The instance to be modified when accessing as an administrator.; Note:; - This parameter is only used to modify a event instance in a repeating event. This field does not need to be filled in for non-repeating events.;- You can call the [Get repeating event instance](https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/calendar-v4/calendar-event/instances) interface to obtain the event_id of a event instance in the repeating event. The value of this parameter is the timestamp suffix of event_id. For example, the queried event instance ID is `xxxxxxxxx_1713168000`, then the current `instance_start_time_admin` value is `1713168000`.; Default: empty",
🤖 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 `@internal/registry/catalog/services/calendar.json` at line 1652, Update the
instance_start_time_admin description in the calendar catalog to replace the
literal `<redacted>` marker in the example event ID with a neutral placeholder
event ID, while preserving the surrounding explanation and timestamp suffix.
internal/registry/catalog/services/okr.json-1372-1375 (1)

1372-1375: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the items description.

items is the Objective list for cycle.objectives.list. The description says "Error code, non-zero means failure". Every sibling list endpoint in this file describes items as the returned list, for example line 3037 and line 4541.

📝 Proposed fix
             "items": {
               "type": "array",
-              "description": "Error code, non-zero means failure",
+              "description": "Objective list",
               "required": false,
🤖 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 `@internal/registry/catalog/services/okr.json` around lines 1372 - 1375, Update
the description of the items property in the cycle.objectives.list response
schema to describe it as the returned Objective list, matching the wording
pattern used by sibling list endpoints in the catalog; remove the unrelated
error-code description.
internal/registry/catalog/services/mail.json-5819-5821 (1)

5819-5821: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the template delete risk level with the other delete operations.

user_mailbox.template.delete uses "risk": "write". Every other permanent delete in this file uses "high-risk-write": draft delete (line 722), folder delete (line 1607), label delete (line 2006), and mail contact delete (line 2415). The description states the deletion cannot be undone.

🔧 Proposed fix
           "danger": true,
-          "risk": "write",
+          "risk": "high-risk-write",
           "docUrl": "https://open.feishu.cn/api-explorer?from=op_doc_tab&apiName=delete&project=mail&resource=user_mailbox.template&version=v1"
🤖 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 `@internal/registry/catalog/services/mail.json` around lines 5819 - 5821,
Update the risk value for the user_mailbox.template.delete entry from "write" to
"high-risk-write", matching the other permanent delete operations while
preserving its existing danger flag and docUrl.
internal/registry/catalog/services/okr.json-1286-1355 (1)

1286-1355: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the shifted parameter descriptions in cycle.objectives.list.

The descriptions are offset by one parameter across this whole block:

  • cycle_id (line 1290) describes a department ID.
  • page_size (line 1296) describes the user cycle ID, and its example 7342342398472398471 is a cycle ID, not a page size.
  • department_id_type (line 1338) describes page size, its example is 10, and its two option descriptions describe a page token and a department ID type.

Users read these strings as flag help for okr cycle.objectives list.

📝 Proposed fix
             "cycle_id": {
               "type": "string",
               "location": "path",
               "required": true,
-              "description": "Identify department by department_id. The ID type must match the value of the department_id_type parameter"
+              "description": "User cycle ID. Obtain by calling the \"Get user OKR Cycle list\" API. The ID type must match the value of the user_id_type parameter"
             },
             "page_size": {
               "type": "integer",
               "location": "query",
               "required": false,
-              "description": "User cycle ID. Obtain by calling the \"Get user OKR Cycle list\" API. The ID type must match the value of the user_id_type parameter",
+              "description": "Page size, maximum 100",
               "default": "10",
-              "example": "7342342398472398471",
+              "example": "10",
               "max": "100",
               "min": "1"
             },
             "department_id_type": {
               "type": "string",
               "location": "query",
               "required": false,
-              "description": "Page size, maximum 100",
+              "description": "Department ID type used in this call",
               "default": "open_department_id",
-              "example": "10",
+              "example": "open_department_id",
               "options": [
                 {
                   "value": "department_id",
-                  "description": "Page token. Leave empty for the first request to start from the beginning. When there are more items, a new page_token will be returned. Use this page_token for the next request to get more results."
+                  "description": "use department_id for department"
                 },
                 {
                   "value": "open_department_id",
-                  "description": "Department ID type used in this call"
+                  "description": "use open_department_id for department"
                 }
               ],
🤖 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 `@internal/registry/catalog/services/okr.json` around lines 1286 - 1355,
Correct the parameter metadata for cycle.objectives.list: make cycle_id describe
the user cycle ID, make page_size describe page size with example 10, and make
department_id_type describe the department ID type. Replace the
department_id_type option descriptions with accurate descriptions for
department_id and open_department_id, removing the misplaced page-token text and
cycle-ID example.
internal/registry/catalog/services/im.json-505-515 (1)

505-515: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Swap the group_message_type and chat_mode descriptions.

The descriptions are exchanged. group_message_type describes group editing permissions, and chat_mode describes the group message type. Users see these strings in schema output and help.

📝 Proposed fix
             "group_message_type": {
               "type": "string",
-              "description": "Group editing permissions; Optional values are:;- `only_owner`: only group owner and administrators;- `all_members`: all members",
+              "description": "Group message type; Optional values are:;- `chat`: chat;- `thread`: thread",
               "required": false
             },
             "chat_mode": {
               "type": "string",
-              "description": "group message type; Optional values are:;- `chat`: chat;- `thread`: thread",
+              "description": "Group mode; Optional values are:;- `group`: A group",
               "required": false,
               "example": "group"
             },
🤖 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 `@internal/registry/catalog/services/im.json` around lines 505 - 515, Correct
the descriptions for the group_message_type and chat_mode schema properties:
assign the group message type description to group_message_type and the group
editing permissions description to chat_mode, while leaving their types,
required flags, and example unchanged.
cmd/auth/login.go-93-101 (1)

93-101: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the same domain source for completion.

allKnownDomains includes brand-eligible shortcut services, but completeDomain only uses catalog services. For example, Feishu accepts apps, while completion cannot suggest it. Pass the brand into completeDomain and build candidates from sortedKnownDomains.

Proposed fix
- return completeDomain(f.APICatalog, toComplete), cobra.ShellCompDirectiveNoFileComp
+ return completeDomain(f.APICatalog, helpBrand, toComplete), cobra.ShellCompDirectiveNoFileComp

-func completeDomain(catalog apicatalog.Catalog, toComplete string) []string {
- allDomains := catalogServiceNames(catalog)
+func completeDomain(catalog apicatalog.Catalog, brand core.LarkBrand, toComplete string) []string {
+ allDomains := sortedKnownDomains(catalog, brand)

Add completion tests for apps on Feishu and its absence on Lark.

🤖 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 `@cmd/auth/login.go` around lines 93 - 101, The completeDomain function
currently derives candidates only from catalog services, omitting brand-specific
shortcut domains. Pass the brand through its callers into completeDomain, use
sortedKnownDomains to generate completion candidates, and add tests confirming
apps is suggested for Feishu but not Lark.
🧹 Nitpick comments (18)
cmd/assembly_plan_fuzz_test.go (1)

56-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Derive the exclusion from registered global flags.

Line 57 excludes only profile. PlanAssembly recognizes every long flag from registeredGlobalFlagArities. Keep this fuzz property limited to unknown flags when global flags change.

Proposed change
 func FuzzPlanAssemblyUnknownFlagValueIsNotDomain(f *testing.F) {
+	longGlobals, _ := registeredGlobalFlagArities()
 	for _, seed := range []string{"tenant", "profiled", "配置", "\x00", "x=y"} {
 		f.Add(seed)
 	}

 	f.Fuzz(func(t *testing.T, flagName string) {
-		if flagName == "" || flagName == "profile" || strings.ContainsAny(flagName, "=\t\r\n ") {
+		if flagName == "" || strings.ContainsAny(flagName, "=\t\r\n ") {
 			t.Skip()
 		}
+		if _, known := longGlobals[flagName]; known {
+			t.Skip()
+		}
 		plan := PlanAssembly([]string{"--" + flagName, "drive"}, []string{"drive"}, []string{"drive"})
🤖 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 `@cmd/assembly_plan_fuzz_test.go` around lines 56 - 63, Update the fuzz input
filter in the PlanAssembly test to exclude every long flag registered in
registeredGlobalFlagArities rather than hard-coding only "profile". Preserve the
existing empty-name and whitespace/equal-sign exclusions, and keep the assertion
focused on flags unknown to the current global-flag registry.
internal/qualitygate/publiccontent/catalog.go (2)

362-404: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

The shape heuristic for smtp_message_id is brittle.

safeTechnicalMessageID accepts a local part only when it is exactly 16 characters, has no two consecutive digits, has at least two digits, and has at least two uppercase runs of at most three characters. This encodes the exact shape of one current catalog fixture. If the upstream catalog changes that example by one character, the quality gate reports a public_content_catalog_pii finding and CI fails with a misleading "email address" message.

Consider replacing the shape heuristics with an explicit allowlist keyed by file path plus JSON path. That makes each suppression auditable and makes a catalog change produce a clear diff instead of a false PII finding. The same concern applies to technicalReferenceLocalPart and strongTechnicalHeaderLocalPart.

🤖 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 `@internal/qualitygate/publiccontent/catalog.go` around lines 362 - 404,
Replace the shape-based checks in safeTechnicalMessageID with an explicit
allowlist keyed by catalog file path and JSON path, and apply the same approach
to technicalReferenceLocalPart and strongTechnicalHeaderLocalPart. Update their
callers and data flow to provide those identifiers, allowing only documented
entries while rejecting all other values.

243-274: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

walkCatalogJSON duplicates the allowlist traversal and is effectively unreachable.

catalogUnsafeEmails runs only from scanCatalogRawSafety. scanCatalogRawSafety runs only when parseCatalogJSON returns an error at line 34. catalogUnsafeEmails then calls json.Unmarshal on the same bytes at line 246. Both parsers reject the same inputs, so the json.Unmarshal branch at line 246 almost always fails too and walkCatalogJSON never runs. The result is a second copy of the key, parent key, and description traversal that carries the safeCatalogEmail allowlist but is not exercised.

Consider deleting walkCatalogJSON and treating every email in the raw fallback as unsafe, because the fallback only applies to input that is not valid JSON.

🤖 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 `@internal/qualitygate/publiccontent/catalog.go` around lines 243 - 274,
Simplify catalogUnsafeEmails by removing the JSON unmarshal and walkCatalogJSON
traversal; the raw fallback receives invalid JSON, so treat every email found by
catalogEmailRE as unsafe and return the lowercase-email map. Delete the
now-unused walkCatalogJSON function and retain safeCatalogEmail filtering only
in the valid-JSON parsing path.
internal/qualitygate/cmd/manifest-export/main_test.go (1)

60-68: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Both isolation tests assert only a non-empty LARKSUITE_CLI_CONFIG_DIR. Each test clears the variable, calls the configure function, and then checks that the value is not empty. Neither test proves that the configured directory is isolated from the real user configuration directory, so a regression that points either tool at the user's real config still passes.

  • internal/qualitygate/cmd/manifest-export/main_test.go#L60-L68: assert that configureManifestExportEnvironment sets a process-local temporary directory and that the directory exists.
  • internal/qualitygate/cmd/quality-gate/main_test.go#L16-L24: apply the same assertion to configureQualityGateEnvironment.

As per coding guidelines: "Every behavior change must have an accompanying contract test that fails if the implementation is reverted and asserts the changed field or behavior directly."

🤖 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 `@internal/qualitygate/cmd/manifest-export/main_test.go` around lines 60 - 68,
Strengthen both isolation tests: in
internal/qualitygate/cmd/manifest-export/main_test.go lines 60-68, update
TestConfigureManifestExportEnvironmentIsolatesConfig to assert that
configureManifestExportEnvironment sets LARKSUITE_CLI_CONFIG_DIR to a
process-local temporary directory and that the directory exists; apply the same
direct assertions in internal/qualitygate/cmd/quality-gate/main_test.go lines
16-24 for configureQualityGateEnvironment, rather than checking only that the
variable is non-empty.

Source: Coding guidelines

internal/affordance/affordance.go (1)

66-76: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

DomainSkill parses the service markdown a second time.

DomainSkill keys on apicatalog.Catalog{}. When For already loaded the same service under a real catalog key, this forces a second fs.ReadFile and markdown parse for the same file, and stores a second cache entry.

The returned value stays correct, because skill does not depend on command mappings. The cost is one extra parse per service per process.

🤖 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 `@internal/affordance/affordance.go` around lines 66 - 76, Update DomainSkill
to reuse the already-loaded service data from For instead of calling loadService
with the empty catalog key. Locate the cached entry by the service identity
across existing catalog entries, return its skill and non-empty status, and
avoid creating another tried/byCatalog entry or rereading and reparsing the
markdown.
internal/schema/assembler.go (1)

219-221: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Mark the empty-catalog wrappers as deprecated.

EnvelopeOf and Envelopes now resolve affordances against an empty catalog. Command-form headings that need catalog resolution fall back to headingToKey, so a caller on these wrappers can silently lose an overlay that EnvelopeOfCatalog would return. Production code already uses the catalog-aware functions.

Add a Deprecated: doc line to both wrappers so new callers choose the catalog-aware form.

♻️ Proposed doc change
+// Deprecated: use EnvelopeOfCatalog with the selected catalog. This wrapper
+// resolves affordances against an empty catalog and can miss command-form
+// overlays.
 func EnvelopeOf(ref apicatalog.MethodRef) Envelope {
 	return EnvelopeOfCatalog(apicatalog.Catalog{}, ref)
 }
+// Deprecated: use EnvelopesCatalog with the selected catalog.
 func Envelopes(refs []apicatalog.MethodRef) []Envelope {
 	return EnvelopesCatalog(apicatalog.Catalog{}, refs)
 }

Also applies to: 238-240

🤖 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 `@internal/schema/assembler.go` around lines 219 - 221, Add a Go doc comment
with a Deprecated: notice to both empty-catalog wrappers, EnvelopeOf and
Envelopes, directing callers to use EnvelopeOfCatalog and the corresponding
catalog-aware function instead. Keep their existing implementations unchanged.
internal/affordance/im_source_test.go (1)

249-260: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Open the IM catalog once per test helper.

imAffordanceCatalog currently loads and verifies the embedded snapshot on every call, including the loop-invoked parsedIMAffordance. Memoize the catalog with a safe helper or tests-local sync.OnceValues variable to avoid repeated integrity verification during one test run.

🤖 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 `@internal/affordance/im_source_test.go` around lines 249 - 260, Update
imAffordanceCatalog to memoize the “im” catalog using a tests-local
sync.OnceValues or equivalent safe helper, so registry.OpenSnapshot and
snapshot.Catalog run only once while preserving existing error handling and
returned catalog behavior.
internal/registry/snapshot.go (2)

306-313: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider a recovery hint on service integrity errors.

catalogAccessError attaches WithHint("run lark-cli update to restore the embedded catalog"). serviceIntegrityError and manifestIntegrityError describe the same class of failure — a corrupted embedded catalog — but carry no hint. A user who hits a checksum mismatch gets no recovery guidance.

The coding guidelines require recovery guidance in .WithHint(...).

As per coding guidelines: "put recovery guidance in .WithHint(...)".

♻️ Proposed change
 func serviceIntegrityError(name, reason string, cause error) error {
 	return errs.NewInternalError(
 		errs.SubtypeCatalogIntegrity,
 		`embedded catalog service "%s" failed integrity validation: %s`,
 		safeServiceName(name),
 		reason,
-	).WithCause(cause)
+	).WithHint("run lark-cli update to restore the embedded catalog").WithCause(cause)
 }
🤖 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 `@internal/registry/snapshot.go` around lines 306 - 313, Update
serviceIntegrityError and the corresponding manifestIntegrityError helper to
attach the recovery guidance via WithHint("run lark-cli update to restore the
embedded catalog"), while preserving their existing error messages and causes.

Source: Coding guidelines


246-252: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use errors.Is for the io.EOF check.

decoder.Decode currently returns a bare io.EOF at end of input, so the direct comparison works today. errors.Is is the idiomatic form and stays correct if the decoder ever wraps the sentinel.

♻️ Proposed change
 	var trailing any
-	if err := decoder.Decode(&trailing); err != io.EOF {
+	if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) {
 		if err == nil {
 			return catalogIntegrityCause("JSON contains multiple values")
 		}
 		return err
 	}

Add "errors" to the import block.

🤖 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 `@internal/registry/snapshot.go` around lines 246 - 252, Update the
trailing-value Decode check in the snapshot validation flow to use
errors.Is(err, io.EOF) instead of directly comparing err to io.EOF, and add the
errors import. Preserve the existing handling for multiple JSON values and other
decode errors.
internal/registry/registry_test.go (1)

24-34: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

scopeTestCatalog re-reads and re-parses the whole snapshot on each call.

Snapshot.Catalog deliberately never caches service bodies, as documented in internal/registry/snapshot.go line 49. FullCatalog therefore reads, checksums, and unmarshals all 15 shards on every call. Several tests call scopeTestCatalog(t) two or three times, for example lines 480-481 and 540-541.

Build the catalog once per package with sync.OnceValues and reuse it. apicatalog.Catalog is read-only, so sharing it across tests is safe.

🤖 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 `@internal/registry/registry_test.go` around lines 24 - 34, Update
scopeTestCatalog to initialize and retain the apicatalog.Catalog once per
package using sync.OnceValues, then return the shared read-only catalog on
subsequent calls. Preserve existing error handling during the one-time
OpenSnapshot and FullCatalog initialization, and remove repeated snapshot
parsing from each test invocation.
internal/registry/snapshot_test.go (1)

137-151: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Two integrity branches have no test coverage.

The table covers a missing file and an extra file. Two rejection paths in internal/registry/snapshot.go remain untested:

  • Line 224-227: a nested directory inside services/ is rejected with service file set does not match manifest.
  • Line 249: trailing JSON after the manifest object is rejected with JSON contains multiple values.

Both guard the integrity boundary. Add cases so a regression in either check fails the suite.

♻️ Proposed table entries
 		{
 			name: "extra file",
 			mutate: func(fsys fstest.MapFS) {
 				fsys["services/extra.json"] = &fstest.MapFile{Data: []byte(`{}`)}
 			},
 			reason: "service file set does not match manifest",
 		},
+		{
+			name: "nested directory in services",
+			mutate: func(fsys fstest.MapFS) {
+				fsys["services/nested/inner.json"] = &fstest.MapFile{Data: []byte(`{}`)}
+			},
+			reason: "service file set does not match manifest",
+		},
+		{
+			name: "trailing manifest value",
+			mutate: func(fsys fstest.MapFS) {
+				data := append(slices.Clone(fsys["manifest.json"].Data), []byte(`{}`)...)
+				fsys["manifest.json"] = &fstest.MapFile{Data: data}
+			},
+			reason: "invalid JSON",
+		},

fstest.MapFS synthesizes services/nested as a directory entry from the nested path, so fs.ReadDir reports it and the entry.IsDir() branch runs.

🤖 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 `@internal/registry/snapshot_test.go` around lines 137 - 151, Add two
table-driven cases to the snapshot integrity tests: mutate the MapFS with a
nested path under services/ so ReadDir encounters a directory and assert the
existing “service file set does not match manifest” reason, and provide manifest
JSON with trailing data after the object to assert “JSON contains multiple
values.” Keep the cases aligned with the existing missing-file and extra-file
entries.
internal/registry/catalog/services/wiki.json (1)

1219-1221: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Remove the empty annotation entry.

target_parent_token declares "annotations": [""]. Every other annotation list in the catalog holds meaningful tokens such as readOnly or open:x_user_id. Consumers that iterate annotations receive one empty token here. Drop the field.

♻️ Proposed change
               "description": "Target parent node token;- Target Wiki space ID and target parent token cannot be empty at the same time",
-              "required": false,
-              "annotations": [
-                ""
-              ]
+              "required": false
🤖 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 `@internal/registry/catalog/services/wiki.json` around lines 1219 - 1221,
Remove the empty annotation entry and its annotations field from the
target_parent_token definition in the wiki catalog, leaving only meaningful
annotation tokens on catalog entries.
internal/registry/scopes.go (2)

278-284: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

catalogServiceNames is duplicated in three places.

The same loop over catalog.Services() collecting service.Name also exists as snapshotServiceNames in internal/registry/registry_test.go lines 14-22 and as testCatalogServiceNames in cmd/auth/login_test.go. Move the helper to internal/apicatalog as an exported Catalog.ServiceNames() method and let all three call sites use it. That keeps the name-extraction rule with the type that owns the services.

#!/bin/bash
# Find every place that extracts service names from a catalog.
rg -nP -C4 'range .*\.Services\(\)' --type=go
🤖 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 `@internal/registry/scopes.go` around lines 278 - 284, The service-name
extraction loop is duplicated across production and test helpers. Add an
exported Catalog.ServiceNames() method in internal/apicatalog, move the logic
from catalogServiceNames into it, and update catalogServiceNames,
snapshotServiceNames, and testCatalogServiceNames call sites to use the method
while preserving their existing results.

263-265: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Avoid the name slice and match map for the all-services case.

GetReadOnlyScopes and ComputeMinimumScopeSet build a slice of every service name, then methodsForProjects builds a map[string]bool from that slice and tests every service against it. The filter accepts everything. Add a variant that walks the catalog directly for the all-services case.

Also applies to: 274-276

🤖 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 `@internal/registry/scopes.go` around lines 263 - 265, Update GetReadOnlyScopes
and ComputeMinimumScopeSet to use a catalog-wide scope collection path that
walks services directly, rather than creating catalogServiceNames slices and
service-name maps through methodsForProjects. Add or reuse a methodsForProjects
variant accepting the catalog for the all-services case, while preserving each
function’s existing scope filtering and minimum-set behavior.
cmd/build.go (2)

187-208: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Make the catalog-failure argument handling consistent with the success path.

Line 197 copies cfg.invocationArgs before SetArgs. Line 193 passes the slice directly. Both slices originate from the same field, so the two calls should use the same handling. Either copy in both places or in neither. WithInvocationArgs already owns a defensive copy, so a second copy at line 197 is redundant.

♻️ Proposed refactor
 		root := attachExecutionState(result)
-		root.SetArgs(append(make([]string, 0, len(cfg.invocationArgs)), cfg.invocationArgs...))
+		root.SetArgs(cfg.invocationArgs)
 		return root
🤖 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 `@cmd/build.go` around lines 187 - 208, Update the SetArgs call in the
successful buildForArgsWithConfig path within Build to pass cfg.invocationArgs
directly, matching the catalog-failure path; remove the redundant defensive copy
while preserving the existing argument ordering and behavior.

240-248: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the duplicated default resolution.

resolveBuildConfig already applies the streams and snapshotOpener defaults (lines 295-308). Both buildForArgsWithConfig and buildInternalWithConfig repeat the same defaults. Every current caller passes a config that came from resolveBuildConfig, so the repeated blocks never take effect. Three copies of the same default set will drift when a new default is added.

Keep one nil-config guard and delegate to resolveBuildConfig.

♻️ Proposed refactor
 	cfg *buildConfig,
 ) (*buildResult, error) {
 	if cfg == nil {
-		cfg = &buildConfig{}
-	}
-	if cfg.streams == nil {
-		cfg.streams = cmdutil.SystemIO()
-	}
-	if cfg.snapshotOpener == nil {
-		cfg.snapshotOpener = func() (catalogSnapshot, error) { return registry.OpenSnapshot() }
+		cfg = resolveBuildConfig(nil)
 	}
 func buildInternalWithConfig(ctx context.Context, inv cmdutil.InvocationContext, cfg *buildConfig) (*buildRuntime, *cobra.Command, *hook.Registry) {
 	if cfg == nil {
 		cfg = resolveBuildConfig(nil)
 	}
-	if cfg.streams == nil {
-		cfg.streams = cmdutil.SystemIO()
-	}
-	if cfg.snapshotOpener == nil {
-		cfg.snapshotOpener = func() (catalogSnapshot, error) { return registry.OpenSnapshot() }
-	}
 	catalog, err := fullCatalog(cfg)

Also applies to: 333-341

🤖 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 `@cmd/build.go` around lines 240 - 248, Remove the duplicated streams and
snapshotOpener default assignments from buildForArgsWithConfig and
buildInternalWithConfig. Keep a single nil-config guard in each entry point as
needed, then delegate configuration defaulting to resolveBuildConfig so it
remains the sole owner of these defaults.
cmd/build_target_test.go (2)

460-493: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The late-registration guard does not pin the freeze point.

frozenPlugins runs at the start of buildForArgsWithConfig, before the snapshot opener is called. The afterSnapshotOpen hook therefore fires after the plugin list is already frozen, so late.installs == 0 holds regardless of where the freeze happens between those two points. The test still guards against a regression that moves plugin collection after catalog selection, but it cannot detect a regression that moves it anywhere earlier in the same window.

Consider registering the late plugin from the snapshotOpener itself, or add a second hook that fires before the opener, to bracket the freeze point from both sides.

🤖 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 `@cmd/build_target_test.go` around lines 460 - 493, Strengthen
TestBuildForArgsLatePluginRegistrationDoesNotChangeFrozenTarget by registering
the late plugin from the snapshot opener itself, or otherwise adding a
pre-opener hook, so the test brackets the frozenPlugins collection point. Keep
the existing assertions verifying the drive-only catalog, zero late-plugin
installs, and unchanged command tree.

962-967: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Report which field differs.

compareContract returns a constant string. TestFullTargetCommandContract compares full and target trees across every catalog and shortcut domain. When it fails, the message names the command path but not the differing field, so the cause must be found by hand.

Compare the fields and name the first mismatch.

♻️ Proposed refactor
 func compareContract(want, got commandContract) string {
 	if reflect.DeepEqual(want, got) {
 		return ""
 	}
-	return "metadata or flags changed"
+	wantValue := reflect.ValueOf(want)
+	gotValue := reflect.ValueOf(got)
+	for i := 0; i < wantValue.NumField(); i++ {
+		if !reflect.DeepEqual(wantValue.Field(i).Interface(), gotValue.Field(i).Interface()) {
+			return fmt.Sprintf("field %s: want %#v, got %#v",
+				wantValue.Type().Field(i).Name,
+				wantValue.Field(i).Interface(),
+				gotValue.Field(i).Interface())
+		}
+	}
+	return "metadata or flags changed"
 }

Add "fmt" to the import block.

🤖 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 `@cmd/build_target_test.go` around lines 962 - 967, Update compareContract to
compare commandContract fields individually in a stable order, returning a
descriptive fmt-based message naming the first mismatched field; retain an empty
string when all fields match and add the required fmt import.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3685e38c-c3a9-4629-a333-a5e19dbf28c7

📥 Commits

Reviewing files that changed from the base of the PR and between 6402080 and 21fba26.

📒 Files selected for processing (131)
  • .github/workflows/arch-audit.yml
  • .github/workflows/ci.yml
  • .gitignore
  • AGENTS.md
  • Makefile
  • build.sh
  • cmd/assembly_plan.go
  • cmd/assembly_plan_fuzz_test.go
  • cmd/assembly_plan_test.go
  • cmd/auth/auth_test.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/auth/login.go
  • cmd/auth/login_brand_filter_test.go
  • cmd/auth/login_interactive.go
  • cmd/auth/login_test.go
  • cmd/auth/testmain_test.go
  • cmd/build.go
  • cmd/build_benchmark_test.go
  • cmd/build_memstats_test.go
  • cmd/build_target_test.go
  • cmd/build_test.go
  • cmd/cmdexample_test.go
  • cmd/diagnose_scope_test.go
  • cmd/error_auth_hint.go
  • cmd/error_presenter_test.go
  • cmd/global_flags.go
  • cmd/global_flags_test.go
  • cmd/platform_bootstrap.go
  • cmd/plugin_integration_test.go
  • cmd/root.go
  • cmd/root_risk_help_test.go
  • cmd/root_test.go
  • cmd/schema/schema.go
  • cmd/schema/schema_test.go
  • cmd/service/affordance.go
  • cmd/service/affordance_test.go
  • cmd/service/paramflags_test.go
  • cmd/service/paramhelp.go
  • cmd/service/service.go
  • cmd/service/service_test.go
  • cmd/service/testmain_test.go
  • cmd/startup_brand.go
  • cmd/startup_brand_test.go
  • cmd/testmain_test.go
  • content_embed_affordance_test.go
  • errs/subtypes.go
  • internal/affordance/affordance.go
  • internal/affordance/affordance_test.go
  • internal/affordance/application_source_test.go
  • internal/affordance/im_source_test.go
  • internal/apicatalog/catalog.go
  • internal/cmdutil/factory.go
  • internal/cmdutil/factory_default.go
  • internal/cmdutil/fileupload.go
  • internal/cmdutil/fileupload_test.go
  • internal/cmdutil/json.go
  • internal/cmdutil/json_test.go
  • internal/cmdutil/testmain_test.go
  • internal/meta/normalize.go
  • internal/meta/normalize_test.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • internal/qualitygate/diff/diff.go
  • internal/qualitygate/diff/diff_test.go
  • internal/qualitygate/publiccontent/catalog.go
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/qualitygate/publiccontent/collect.go
  • internal/qualitygate/publiccontent/collect_test.go
  • internal/qualitygate/publiccontent/rules.go
  • internal/qualitygate/publiccontent/scan.go
  • internal/qualitygate/rules/dryrun.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/qualitygate/rules/run.go
  • internal/qualitygate/rules/run_test.go
  • internal/registry/catalog.go
  • internal/registry/catalog/manifest.json
  • internal/registry/catalog/services/approval.json
  • internal/registry/catalog/services/attendance.json
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/contact.json
  • internal/registry/catalog/services/drive.json
  • internal/registry/catalog/services/im.json
  • internal/registry/catalog/services/mail.json
  • internal/registry/catalog/services/mindnotes.json
  • internal/registry/catalog/services/minutes.json
  • internal/registry/catalog/services/okr.json
  • internal/registry/catalog/services/sheets.json
  • internal/registry/catalog/services/slides.json
  • internal/registry/catalog/services/task.json
  • internal/registry/catalog/services/vc.json
  • internal/registry/catalog/services/wiki.json
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/loader_embedded.go
  • internal/registry/loader_test.go
  • internal/registry/meta_data_default.json
  • internal/registry/registry_test.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/registrytest/registrytest.go
  • internal/registry/registrytest/registrytest_test.go
  • internal/registry/remote.go
  • internal/registry/remote_test.go
  • internal/registry/scope_hint_test.go
  • internal/registry/scopes.go
  • internal/registry/snapshot.go
  • internal/registry/snapshot_test.go
  • internal/registry/testmain_test.go
  • internal/schema/assembler.go
  • internal/schema/assembler_test.go
  • internal/schema/catalog_test_helpers_test.go
  • internal/schema/lint.go
  • internal/schema/lint_test.go
  • internal/schema/types.go
  • scripts/build-pkg-pr-new.sh
  • scripts/ci-workflow.test.sh
  • scripts/fetch_meta.py
  • shortcuts/application/slash_command_common.go
  • shortcuts/common/skill_references.go
  • shortcuts/im/affordance_migration_test.go
  • shortcuts/register.go
  • shortcuts/register_brand_guard_test.go
  • shortcuts/register_test.go
  • shortcuts/slides/slides_replace_slide.go
  • skills/lark-calendar/SKILL.md
  • tests/plugin_e2e/degrade_subsystem_test.go
  • tests/plugin_e2e/harness.go
  • tests/plugin_e2e/restrict_test.go
  • tests/sidecar_e2e/roundtrip_test.go
💤 Files with no reviewable changes (26)
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/registry/loader_embedded.go
  • build.sh
  • internal/qualitygate/rules/dryrun.go
  • scripts/build-pkg-pr-new.sh
  • cmd/cmdexample_test.go
  • .gitignore
  • internal/registry/meta_data_default.json
  • internal/registry/catalog.go
  • cmd/startup_brand.go
  • .github/workflows/arch-audit.yml
  • internal/qualitygate/rules/dryrun_test.go
  • internal/cmdutil/factory_default.go
  • internal/registry/testmain_test.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/remote_test.go
  • scripts/fetch_meta.py
  • internal/registry/registrytest/registrytest.go
  • internal/registry/loader.go
  • internal/registry/loader_test.go
  • cmd/startup_brand_test.go
  • internal/registry/scope_hint_test.go
  • internal/registry/remote.go
  • internal/registry/catalog_test.go
  • internal/registry/registrytest/registrytest_test.go

Comment thread internal/affordance/affordance.go
Comment thread internal/registry/catalog/services/calendar.json
Comment thread internal/registry/catalog/services/mail.json
Comment thread internal/registry/registry_test.go Outdated
@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.96016% with 151 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.42%. Comparing base (bc0ba22) to head (be38883).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
internal/qualitygate/publiccontent/catalog.go 79.72% 44 Missing and 16 partials ⚠️
internal/registry/snapshot.go 86.93% 15 Missing and 8 partials ⚠️
cmd/build.go 87.32% 12 Missing and 6 partials ⚠️
internal/cmdutil/fileupload.go 85.24% 6 Missing and 3 partials ⚠️
cmd/root.go 60.00% 6 Missing and 2 partials ⚠️
internal/schema/lint.go 76.92% 4 Missing and 2 partials ⚠️
cmd/assembly_plan.go 93.90% 5 Missing ⚠️
cmd/auth/login.go 76.19% 5 Missing ⚠️
cmd/auth/login_interactive.go 50.00% 5 Missing ⚠️
...nternal/qualitygate/cmd/manifest-export/collect.go 42.85% 2 Missing and 2 partials ⚠️
... and 5 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2232      +/-   ##
==========================================
+ Coverage   76.33%   76.42%   +0.09%     
==========================================
  Files         993      991       -2     
  Lines      106633   107275     +642     
==========================================
+ Hits        81400    81987     +587     
- Misses      19032    19068      +36     
- Partials     6201     6220      +19     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zhaojunlin0405
zhaojunlin0405 force-pushed the feat/catalog-lazy-routing branch from 21fba26 to 70bf027 Compare August 7, 2026 07:48
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@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.

🧹 Nitpick comments (1)
cmd/build.go (1)

240-248: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider centralizing default resolution in resolveBuildConfig.

Lines 240-248 re-apply the same defaults that resolveBuildConfig already applies at lines 295-307, and buildInternalWithConfig repeats them again at lines 333-341. Three copies of the same streams and snapshotOpener fallbacks can drift.

Extract one applyDefaults(cfg *buildConfig) *buildConfig helper and call it from all three sites.

🤖 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 `@cmd/build.go` around lines 240 - 248, Centralize build configuration fallback
logic by extracting an applyDefaults(cfg *buildConfig) *buildConfig helper that
initializes nil configs, streams, and snapshotOpener. Replace the duplicated
default-resolution blocks in the current build flow, resolveBuildConfig, and
buildInternalWithConfig with calls to this helper, preserving the existing
defaults and return behavior.
🤖 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.

Nitpick comments:
In `@cmd/build.go`:
- Around line 240-248: Centralize build configuration fallback logic by
extracting an applyDefaults(cfg *buildConfig) *buildConfig helper that
initializes nil configs, streams, and snapshotOpener. Replace the duplicated
default-resolution blocks in the current build flow, resolveBuildConfig, and
buildInternalWithConfig with calls to this helper, preserving the existing
defaults and return behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: aaa11a9f-c8a4-4ab2-8ab1-2d6786bd096e

📥 Commits

Reviewing files that changed from the base of the PR and between 4ff2bd1 and 70bf027.

📒 Files selected for processing (131)
  • .github/workflows/arch-audit.yml
  • .github/workflows/ci.yml
  • .gitignore
  • AGENTS.md
  • Makefile
  • build.sh
  • cmd/assembly_plan.go
  • cmd/assembly_plan_fuzz_test.go
  • cmd/assembly_plan_test.go
  • cmd/auth/auth_test.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/auth/login.go
  • cmd/auth/login_brand_filter_test.go
  • cmd/auth/login_interactive.go
  • cmd/auth/login_test.go
  • cmd/auth/testmain_test.go
  • cmd/build.go
  • cmd/build_benchmark_test.go
  • cmd/build_memstats_test.go
  • cmd/build_target_test.go
  • cmd/build_test.go
  • cmd/cmdexample_test.go
  • cmd/diagnose_scope_test.go
  • cmd/error_auth_hint.go
  • cmd/error_presenter_test.go
  • cmd/global_flags.go
  • cmd/global_flags_test.go
  • cmd/platform_bootstrap.go
  • cmd/plugin_integration_test.go
  • cmd/root.go
  • cmd/root_risk_help_test.go
  • cmd/root_test.go
  • cmd/schema/schema.go
  • cmd/schema/schema_test.go
  • cmd/service/affordance.go
  • cmd/service/affordance_test.go
  • cmd/service/paramflags_test.go
  • cmd/service/paramhelp.go
  • cmd/service/service.go
  • cmd/service/service_test.go
  • cmd/service/testmain_test.go
  • cmd/startup_brand.go
  • cmd/startup_brand_test.go
  • cmd/testmain_test.go
  • content_embed_affordance_test.go
  • errs/subtypes.go
  • internal/affordance/affordance.go
  • internal/affordance/affordance_test.go
  • internal/affordance/application_source_test.go
  • internal/affordance/im_source_test.go
  • internal/apicatalog/catalog.go
  • internal/cmdutil/factory.go
  • internal/cmdutil/factory_default.go
  • internal/cmdutil/fileupload.go
  • internal/cmdutil/fileupload_test.go
  • internal/cmdutil/json.go
  • internal/cmdutil/json_test.go
  • internal/cmdutil/testmain_test.go
  • internal/meta/normalize.go
  • internal/meta/normalize_test.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • internal/qualitygate/diff/diff.go
  • internal/qualitygate/diff/diff_test.go
  • internal/qualitygate/publiccontent/catalog.go
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/qualitygate/publiccontent/collect.go
  • internal/qualitygate/publiccontent/collect_test.go
  • internal/qualitygate/publiccontent/rules.go
  • internal/qualitygate/publiccontent/scan.go
  • internal/qualitygate/rules/dryrun.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/qualitygate/rules/run.go
  • internal/qualitygate/rules/run_test.go
  • internal/registry/catalog.go
  • internal/registry/catalog/manifest.json
  • internal/registry/catalog/services/approval.json
  • internal/registry/catalog/services/attendance.json
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/contact.json
  • internal/registry/catalog/services/drive.json
  • internal/registry/catalog/services/im.json
  • internal/registry/catalog/services/mail.json
  • internal/registry/catalog/services/mindnotes.json
  • internal/registry/catalog/services/minutes.json
  • internal/registry/catalog/services/okr.json
  • internal/registry/catalog/services/sheets.json
  • internal/registry/catalog/services/slides.json
  • internal/registry/catalog/services/task.json
  • internal/registry/catalog/services/vc.json
  • internal/registry/catalog/services/wiki.json
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/loader_embedded.go
  • internal/registry/loader_test.go
  • internal/registry/meta_data_default.json
  • internal/registry/registry_test.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/registrytest/registrytest.go
  • internal/registry/registrytest/registrytest_test.go
  • internal/registry/remote.go
  • internal/registry/remote_test.go
  • internal/registry/scope_hint_test.go
  • internal/registry/scopes.go
  • internal/registry/snapshot.go
  • internal/registry/snapshot_test.go
  • internal/registry/testmain_test.go
  • internal/schema/assembler.go
  • internal/schema/assembler_test.go
  • internal/schema/catalog_test_helpers_test.go
  • internal/schema/lint.go
  • internal/schema/lint_test.go
  • internal/schema/types.go
  • scripts/build-pkg-pr-new.sh
  • scripts/ci-workflow.test.sh
  • scripts/fetch_meta.py
  • shortcuts/application/slash_command_common.go
  • shortcuts/common/skill_references.go
  • shortcuts/im/affordance_migration_test.go
  • shortcuts/register.go
  • shortcuts/register_brand_guard_test.go
  • shortcuts/register_test.go
  • shortcuts/slides/slides_replace_slide.go
  • skills/lark-calendar/SKILL.md
  • tests/plugin_e2e/degrade_subsystem_test.go
  • tests/plugin_e2e/harness.go
  • tests/plugin_e2e/restrict_test.go
  • tests/sidecar_e2e/roundtrip_test.go
💤 Files with no reviewable changes (26)
  • internal/qualitygate/cmd/quality-gate/main.go
  • cmd/cmdexample_test.go
  • cmd/startup_brand.go
  • internal/registry/registrytest/registrytest.go
  • internal/qualitygate/rules/dryrun.go
  • build.sh
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/registrytest/registrytest_test.go
  • internal/registry/loader_test.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/scope_hint_test.go
  • internal/registry/meta_data_default.json
  • internal/registry/testmain_test.go
  • .gitignore
  • scripts/fetch_meta.py
  • internal/registry/remote.go
  • internal/registry/remote_test.go
  • cmd/startup_brand_test.go
  • internal/registry/loader_embedded.go
  • internal/registry/catalog.go
  • .github/workflows/arch-audit.yml
  • internal/cmdutil/factory_default.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • scripts/build-pkg-pr-new.sh
🚧 Files skipped from review as they are similar to previous changes (103)
  • internal/meta/normalize_test.go
  • skills/lark-calendar/SKILL.md
  • internal/qualitygate/publiccontent/scan.go
  • cmd/global_flags.go
  • cmd/auth/testmain_test.go
  • internal/qualitygate/rules/run.go
  • AGENTS.md
  • cmd/service/paramflags_test.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/build_memstats_test.go
  • internal/schema/lint.go
  • internal/qualitygate/publiccontent/collect.go
  • cmd/build_test.go
  • internal/qualitygate/publiccontent/rules.go
  • shortcuts/slides/slides_replace_slide.go
  • internal/registry/catalog/manifest.json
  • cmd/root_risk_help_test.go
  • internal/cmdutil/factory.go
  • internal/cmdutil/fileupload_test.go
  • internal/schema/types.go
  • cmd/testmain_test.go
  • shortcuts/common/skill_references.go
  • internal/meta/normalize.go
  • cmd/service/service.go
  • cmd/global_flags_test.go
  • internal/qualitygate/diff/diff_test.go
  • cmd/platform_bootstrap.go
  • tests/sidecar_e2e/roundtrip_test.go
  • cmd/build_benchmark_test.go
  • cmd/service/testmain_test.go
  • cmd/service/paramhelp.go
  • internal/qualitygate/publiccontent/catalog.go
  • cmd/error_presenter_test.go
  • errs/subtypes.go
  • internal/schema/assembler.go
  • internal/registry/catalog/services/attendance.json
  • cmd/build_target_test.go
  • tests/plugin_e2e/harness.go
  • scripts/ci-workflow.test.sh
  • internal/schema/catalog_test_helpers_test.go
  • tests/plugin_e2e/restrict_test.go
  • cmd/root.go
  • internal/registry/catalog/services/contact.json
  • cmd/plugin_integration_test.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • cmd/error_auth_hint.go
  • internal/registry/catalog/services/mindnotes.json
  • internal/cmdutil/fileupload.go
  • internal/affordance/im_source_test.go
  • .github/workflows/ci.yml
  • internal/registry/catalog/services/wiki.json
  • cmd/auth/login_brand_filter_test.go
  • internal/qualitygate/diff/diff.go
  • cmd/auth/auth_test.go
  • cmd/root_test.go
  • shortcuts/application/slash_command_common.go
  • cmd/service/service_test.go
  • cmd/service/affordance.go
  • cmd/schema/schema.go
  • tests/plugin_e2e/degrade_subsystem_test.go
  • internal/registry/catalog/services/slides.json
  • internal/cmdutil/json.go
  • internal/apicatalog/catalog.go
  • internal/affordance/affordance_test.go
  • internal/registry/snapshot.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • shortcuts/im/affordance_migration_test.go
  • internal/qualitygate/rules/run_test.go
  • cmd/auth/login_interactive.go
  • internal/registry/catalog/services/approval.json
  • internal/affordance/application_source_test.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/registry/catalog/services/okr.json
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/sheets.json
  • cmd/auth/login.go
  • shortcuts/register_test.go
  • internal/qualitygate/publiccontent/collect_test.go
  • internal/registry/catalog/services/drive.json
  • internal/affordance/affordance.go
  • shortcuts/register_brand_guard_test.go
  • cmd/diagnose_scope_test.go
  • internal/cmdutil/json_test.go
  • Makefile
  • cmd/assembly_plan_test.go
  • internal/schema/lint_test.go
  • internal/registry/catalog/services/minutes.json
  • content_embed_affordance_test.go
  • cmd/service/affordance_test.go
  • internal/registry/catalog/services/task.json
  • internal/registry/snapshot_test.go
  • shortcuts/register.go
  • cmd/assembly_plan.go
  • internal/registry/catalog/services/mail.json
  • cmd/schema/schema_test.go
  • internal/cmdutil/testmain_test.go
  • internal/registry/catalog/services/im.json
  • internal/registry/scopes.go
  • cmd/auth/login_test.go
  • internal/schema/assembler_test.go
  • cmd/assembly_plan_fuzz_test.go
  • internal/registry/catalog/services/vc.json

@zhaojunlin0405
zhaojunlin0405 force-pushed the feat/catalog-lazy-routing branch from 70bf027 to b486e7a Compare August 7, 2026 08:14
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@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.

🧹 Nitpick comments (3)
cmd/build_target_test.go (3)

609-632: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the typed problem metadata on both guard paths.

Lines 594-600 assert the cause and the subtype for the build error. The two guard paths at lines 613-616 and 629-632 assert only the cause and the exit code. Add a subtype assertion so a regression that keeps the cause but changes the problem classification still fails.

♻️ Proposed assertion helper
+	assertCatalogGuard := func(t *testing.T, err error) {
+		t.Helper()
+		if !errors.Is(err, cause) {
+			t.Fatalf("guard error = %v, want preserved cause", err)
+		}
+		problem, ok := errs.ProblemOf(err)
+		if !ok || problem.Subtype != errs.SubtypeCatalogIntegrity {
+			t.Fatalf("guard problem = %#v, %v", problem, ok)
+		}
+		if output.ExitCodeOf(err) != output.ExitInternal {
+			t.Fatalf("guard exit = %d, want %d", output.ExitCodeOf(err), output.ExitInternal)
+		}
+	}

Then call assertCatalogGuard(t, err) after each Execute().

Based on the coding guideline "Use typed error metadata and cause preservation in error-path tests, asserting errs.ProblemOf fields and causes rather than message substrings alone."

🤖 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 `@cmd/build_target_test.go` around lines 609 - 632, The two guard-path
assertions after root.Execute and targetRoot.Execute only verify the cause and
exit code; update both to also validate typed problem metadata using the
existing assertCatalogGuard helper. Call assertCatalogGuard(t, err) after each
Execute while preserving the current cause and exit-code checks.

Source: Coding guidelines


963-968: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Report the differing fields instead of a fixed string.

compareContract returns the same message for every mismatch. When this contract test fails, the output at line 871 does not identify which field diverged between the full tree and the target tree. Include the differing field names so a failure is actionable.

♻️ Proposed diff detail
 func compareContract(want, got commandContract) string {
 	if reflect.DeepEqual(want, got) {
 		return ""
 	}
-	return "metadata or flags changed"
+	wantValue := reflect.ValueOf(want)
+	gotValue := reflect.ValueOf(got)
+	var fields []string
+	for i := range wantValue.NumField() {
+		if !reflect.DeepEqual(wantValue.Field(i).Interface(), gotValue.Field(i).Interface()) {
+			fields = append(fields, wantValue.Type().Field(i).Name)
+		}
+	}
+	return "fields differ: " + strings.Join(fields, ", ")
 }

As per the coding guideline "Design CLI errors, output formats, and flags as machine-consumable: errors must be structured, actionable, and specific", the same specificity helps here for contract-regression diagnosis.

🤖 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 `@cmd/build_target_test.go` around lines 963 - 968, Update compareContract to
inspect the differing fields of want and got and return an actionable message
listing each field that differs, rather than the fixed “metadata or flags
changed” string. Preserve the empty string result for equal commandContract
values and ensure the reported names identify the specific contract fields used
by the test.

Source: Coding guidelines


815-826: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace compactTestStrings with slices.Compact.

Keep the explicit append only if the caller needs a separate backing array; otherwise avoid out := values[:1] to prevent compacting into the caller’s slice. The Go 1.23 module enables slices.Compact.

🤖 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 `@cmd/build_target_test.go` around lines 815 - 826, Replace the
compactTestStrings helper implementation with the standard library
slices.Compact function, preserving its duplicate-removal behavior and nil
result for empty input. Remove the manual out := values[:1] logic; retain an
explicit append copy only if callers require isolation from the input slice.
🤖 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.

Nitpick comments:
In `@cmd/build_target_test.go`:
- Around line 609-632: The two guard-path assertions after root.Execute and
targetRoot.Execute only verify the cause and exit code; update both to also
validate typed problem metadata using the existing assertCatalogGuard helper.
Call assertCatalogGuard(t, err) after each Execute while preserving the current
cause and exit-code checks.
- Around line 963-968: Update compareContract to inspect the differing fields of
want and got and return an actionable message listing each field that differs,
rather than the fixed “metadata or flags changed” string. Preserve the empty
string result for equal commandContract values and ensure the reported names
identify the specific contract fields used by the test.
- Around line 815-826: Replace the compactTestStrings helper implementation with
the standard library slices.Compact function, preserving its duplicate-removal
behavior and nil result for empty input. Remove the manual out := values[:1]
logic; retain an explicit append copy only if callers require isolation from the
input slice.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1bd073a3-22c5-4d40-8176-2d02a4682650

📥 Commits

Reviewing files that changed from the base of the PR and between 4ff2bd1 and b486e7a.

📒 Files selected for processing (131)
  • .github/workflows/arch-audit.yml
  • .github/workflows/ci.yml
  • .gitignore
  • AGENTS.md
  • Makefile
  • build.sh
  • cmd/assembly_plan.go
  • cmd/assembly_plan_fuzz_test.go
  • cmd/assembly_plan_test.go
  • cmd/auth/auth_test.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/auth/login.go
  • cmd/auth/login_brand_filter_test.go
  • cmd/auth/login_interactive.go
  • cmd/auth/login_test.go
  • cmd/auth/testmain_test.go
  • cmd/build.go
  • cmd/build_benchmark_test.go
  • cmd/build_memstats_test.go
  • cmd/build_target_test.go
  • cmd/build_test.go
  • cmd/cmdexample_test.go
  • cmd/diagnose_scope_test.go
  • cmd/error_auth_hint.go
  • cmd/error_presenter_test.go
  • cmd/global_flags.go
  • cmd/global_flags_test.go
  • cmd/platform_bootstrap.go
  • cmd/plugin_integration_test.go
  • cmd/root.go
  • cmd/root_risk_help_test.go
  • cmd/root_test.go
  • cmd/schema/schema.go
  • cmd/schema/schema_test.go
  • cmd/service/affordance.go
  • cmd/service/affordance_test.go
  • cmd/service/paramflags_test.go
  • cmd/service/paramhelp.go
  • cmd/service/service.go
  • cmd/service/service_test.go
  • cmd/service/testmain_test.go
  • cmd/startup_brand.go
  • cmd/startup_brand_test.go
  • cmd/testmain_test.go
  • content_embed_affordance_test.go
  • errs/subtypes.go
  • internal/affordance/affordance.go
  • internal/affordance/affordance_test.go
  • internal/affordance/application_source_test.go
  • internal/affordance/im_source_test.go
  • internal/apicatalog/catalog.go
  • internal/cmdutil/factory.go
  • internal/cmdutil/factory_default.go
  • internal/cmdutil/fileupload.go
  • internal/cmdutil/fileupload_test.go
  • internal/cmdutil/json.go
  • internal/cmdutil/json_test.go
  • internal/cmdutil/testmain_test.go
  • internal/meta/normalize.go
  • internal/meta/normalize_test.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • internal/qualitygate/diff/diff.go
  • internal/qualitygate/diff/diff_test.go
  • internal/qualitygate/publiccontent/catalog.go
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/qualitygate/publiccontent/collect.go
  • internal/qualitygate/publiccontent/collect_test.go
  • internal/qualitygate/publiccontent/rules.go
  • internal/qualitygate/publiccontent/scan.go
  • internal/qualitygate/rules/dryrun.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/qualitygate/rules/run.go
  • internal/qualitygate/rules/run_test.go
  • internal/registry/catalog.go
  • internal/registry/catalog/manifest.json
  • internal/registry/catalog/services/approval.json
  • internal/registry/catalog/services/attendance.json
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/contact.json
  • internal/registry/catalog/services/drive.json
  • internal/registry/catalog/services/im.json
  • internal/registry/catalog/services/mail.json
  • internal/registry/catalog/services/mindnotes.json
  • internal/registry/catalog/services/minutes.json
  • internal/registry/catalog/services/okr.json
  • internal/registry/catalog/services/sheets.json
  • internal/registry/catalog/services/slides.json
  • internal/registry/catalog/services/task.json
  • internal/registry/catalog/services/vc.json
  • internal/registry/catalog/services/wiki.json
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/loader_embedded.go
  • internal/registry/loader_test.go
  • internal/registry/meta_data_default.json
  • internal/registry/registry_test.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/registrytest/registrytest.go
  • internal/registry/registrytest/registrytest_test.go
  • internal/registry/remote.go
  • internal/registry/remote_test.go
  • internal/registry/scope_hint_test.go
  • internal/registry/scopes.go
  • internal/registry/snapshot.go
  • internal/registry/snapshot_test.go
  • internal/registry/testmain_test.go
  • internal/schema/assembler.go
  • internal/schema/assembler_test.go
  • internal/schema/catalog_test_helpers_test.go
  • internal/schema/lint.go
  • internal/schema/lint_test.go
  • internal/schema/types.go
  • scripts/build-pkg-pr-new.sh
  • scripts/ci-workflow.test.sh
  • scripts/fetch_meta.py
  • shortcuts/application/slash_command_common.go
  • shortcuts/common/skill_references.go
  • shortcuts/im/affordance_migration_test.go
  • shortcuts/register.go
  • shortcuts/register_brand_guard_test.go
  • shortcuts/register_test.go
  • shortcuts/slides/slides_replace_slide.go
  • skills/lark-calendar/SKILL.md
  • tests/plugin_e2e/degrade_subsystem_test.go
  • tests/plugin_e2e/harness.go
  • tests/plugin_e2e/restrict_test.go
  • tests/sidecar_e2e/roundtrip_test.go
💤 Files with no reviewable changes (26)
  • scripts/build-pkg-pr-new.sh
  • cmd/cmdexample_test.go
  • internal/registry/registrytest/registrytest.go
  • cmd/startup_brand_test.go
  • scripts/fetch_meta.py
  • internal/registry/catalog_test.go
  • .gitignore
  • internal/registry/loader.go
  • cmd/startup_brand.go
  • internal/registry/loader_embedded.go
  • internal/registry/meta_data_default.json
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/remote.go
  • internal/registry/loader_test.go
  • internal/registry/testmain_test.go
  • build.sh
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/cmdutil/factory_default.go
  • internal/qualitygate/rules/dryrun.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/registry/catalog.go
  • internal/registry/remote_test.go
  • internal/registry/scope_hint_test.go
  • internal/registry/registrytest/registrytest_test.go
  • .github/workflows/arch-audit.yml
🚧 Files skipped from review as they are similar to previous changes (103)
  • skills/lark-calendar/SKILL.md
  • cmd/auth/login_brand_filter_test.go
  • shortcuts/slides/slides_replace_slide.go
  • cmd/service/paramhelp.go
  • scripts/ci-workflow.test.sh
  • cmd/build_benchmark_test.go
  • shortcuts/application/slash_command_common.go
  • cmd/service/service.go
  • cmd/global_flags_test.go
  • cmd/assembly_plan_test.go
  • internal/cmdutil/testmain_test.go
  • cmd/assembly_plan_fuzz_test.go
  • cmd/root_test.go
  • tests/plugin_e2e/restrict_test.go
  • internal/registry/catalog/services/mindnotes.json
  • internal/qualitygate/rules/run.go
  • internal/qualitygate/publiccontent/scan.go
  • internal/qualitygate/diff/diff.go
  • cmd/global_flags.go
  • errs/subtypes.go
  • cmd/assembly_plan.go
  • internal/registry/catalog/services/slides.json
  • internal/registry/catalog/services/attendance.json
  • AGENTS.md
  • internal/schema/catalog_test_helpers_test.go
  • internal/cmdutil/json_test.go
  • cmd/schema/schema.go
  • cmd/error_presenter_test.go
  • cmd/build_memstats_test.go
  • cmd/root.go
  • internal/meta/normalize.go
  • cmd/diagnose_scope_test.go
  • internal/registry/catalog/services/vc.json
  • internal/qualitygate/rules/run_test.go
  • tests/sidecar_e2e/roundtrip_test.go
  • internal/affordance/application_source_test.go
  • tests/plugin_e2e/harness.go
  • cmd/auth/testmain_test.go
  • internal/schema/types.go
  • shortcuts/common/skill_references.go
  • shortcuts/register_brand_guard_test.go
  • internal/qualitygate/publiccontent/collect_test.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/qualitygate/publiccontent/rules.go
  • cmd/service/service_test.go
  • cmd/platform_bootstrap.go
  • tests/plugin_e2e/degrade_subsystem_test.go
  • shortcuts/im/affordance_migration_test.go
  • internal/registry/catalog/manifest.json
  • internal/cmdutil/factory.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • internal/cmdutil/fileupload.go
  • content_embed_affordance_test.go
  • shortcuts/register_test.go
  • internal/registry/catalog/services/mail.json
  • internal/registry/catalog/services/sheets.json
  • internal/cmdutil/json.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/error_auth_hint.go
  • internal/qualitygate/publiccontent/catalog.go
  • shortcuts/register.go
  • internal/qualitygate/diff/diff_test.go
  • cmd/auth/auth_test.go
  • internal/affordance/im_source_test.go
  • cmd/root_risk_help_test.go
  • internal/registry/catalog/services/minutes.json
  • internal/affordance/affordance.go
  • internal/registry/catalog/services/drive.json
  • internal/schema/lint.go
  • cmd/service/paramflags_test.go
  • cmd/service/affordance.go
  • cmd/plugin_integration_test.go
  • internal/registry/registry_test.go
  • .github/workflows/ci.yml
  • internal/registry/catalog/services/approval.json
  • Makefile
  • cmd/schema/schema_test.go
  • internal/schema/assembler.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/qualitygate/publiccontent/collect.go
  • cmd/build_test.go
  • internal/registry/snapshot.go
  • internal/registry/catalog/services/task.json
  • cmd/testmain_test.go
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/registry/catalog/services/contact.json
  • cmd/service/testmain_test.go
  • internal/registry/snapshot_test.go
  • internal/schema/assembler_test.go
  • internal/registry/catalog/services/okr.json
  • internal/registry/catalog/services/im.json
  • cmd/auth/login_test.go
  • cmd/auth/login_interactive.go
  • internal/cmdutil/fileupload_test.go
  • internal/apicatalog/catalog.go
  • internal/schema/lint_test.go
  • internal/meta/normalize_test.go
  • cmd/auth/login.go
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/wiki.json
  • cmd/build.go
  • internal/registry/scopes.go
  • cmd/service/affordance_test.go

@zhaojunlin0405
zhaojunlin0405 force-pushed the feat/catalog-lazy-routing branch from b486e7a to eb7f343 Compare August 7, 2026 08:32
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@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 `@internal/apicatalog/catalog.go`:
- Around line 68-69: Update the documentation comment for Catalog.Source to use
source-neutral wording rather than describing embedded versus runtime, while
leaving the method implementation unchanged.
🪄 Autofix

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: 9945f228-84cf-4709-9c82-e49b97272662

📥 Commits

Reviewing files that changed from the base of the PR and between db102ab and eb7f343.

📒 Files selected for processing (132)
  • .github/workflows/arch-audit.yml
  • .github/workflows/ci.yml
  • .gitignore
  • AGENTS.md
  • Makefile
  • build.sh
  • cmd/assembly_plan.go
  • cmd/assembly_plan_fuzz_test.go
  • cmd/assembly_plan_test.go
  • cmd/auth/auth_test.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/auth/login.go
  • cmd/auth/login_brand_filter_test.go
  • cmd/auth/login_interactive.go
  • cmd/auth/login_test.go
  • cmd/auth/testmain_test.go
  • cmd/build.go
  • cmd/build_benchmark_test.go
  • cmd/build_memstats_test.go
  • cmd/build_target_test.go
  • cmd/build_test.go
  • cmd/cmdexample_test.go
  • cmd/diagnose_scope_test.go
  • cmd/error_auth_hint.go
  • cmd/error_presenter_test.go
  • cmd/global_flags.go
  • cmd/global_flags_test.go
  • cmd/platform_bootstrap.go
  • cmd/plugin_integration_test.go
  • cmd/root.go
  • cmd/root_risk_help_test.go
  • cmd/root_test.go
  • cmd/schema/schema.go
  • cmd/schema/schema_test.go
  • cmd/service/affordance.go
  • cmd/service/affordance_test.go
  • cmd/service/paramflags_test.go
  • cmd/service/paramhelp.go
  • cmd/service/service.go
  • cmd/service/service_test.go
  • cmd/service/testmain_test.go
  • cmd/startup_brand.go
  • cmd/startup_brand_test.go
  • cmd/testmain_test.go
  • content_embed_affordance_test.go
  • errs/subtypes.go
  • internal/affordance/affordance.go
  • internal/affordance/affordance_test.go
  • internal/affordance/application_source_test.go
  • internal/affordance/im_source_test.go
  • internal/apicatalog/catalog.go
  • internal/apicatalog/catalog_test.go
  • internal/cmdutil/factory.go
  • internal/cmdutil/factory_default.go
  • internal/cmdutil/fileupload.go
  • internal/cmdutil/fileupload_test.go
  • internal/cmdutil/json.go
  • internal/cmdutil/json_test.go
  • internal/cmdutil/testmain_test.go
  • internal/meta/normalize.go
  • internal/meta/normalize_test.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/qualitygate/cmd/manifest-export/main.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • internal/qualitygate/cmd/quality-gate/main.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • internal/qualitygate/diff/diff.go
  • internal/qualitygate/diff/diff_test.go
  • internal/qualitygate/publiccontent/catalog.go
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/qualitygate/publiccontent/collect.go
  • internal/qualitygate/publiccontent/collect_test.go
  • internal/qualitygate/publiccontent/rules.go
  • internal/qualitygate/publiccontent/scan.go
  • internal/qualitygate/rules/dryrun.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/qualitygate/rules/run.go
  • internal/qualitygate/rules/run_test.go
  • internal/registry/catalog.go
  • internal/registry/catalog/manifest.json
  • internal/registry/catalog/services/approval.json
  • internal/registry/catalog/services/attendance.json
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/contact.json
  • internal/registry/catalog/services/drive.json
  • internal/registry/catalog/services/im.json
  • internal/registry/catalog/services/mail.json
  • internal/registry/catalog/services/mindnotes.json
  • internal/registry/catalog/services/minutes.json
  • internal/registry/catalog/services/okr.json
  • internal/registry/catalog/services/sheets.json
  • internal/registry/catalog/services/slides.json
  • internal/registry/catalog/services/task.json
  • internal/registry/catalog/services/vc.json
  • internal/registry/catalog/services/wiki.json
  • internal/registry/catalog_test.go
  • internal/registry/loader.go
  • internal/registry/loader_embedded.go
  • internal/registry/loader_test.go
  • internal/registry/meta_data_default.json
  • internal/registry/registry_test.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/registry/registrytest/registrytest.go
  • internal/registry/registrytest/registrytest_test.go
  • internal/registry/remote.go
  • internal/registry/remote_test.go
  • internal/registry/scope_hint_test.go
  • internal/registry/scopes.go
  • internal/registry/snapshot.go
  • internal/registry/snapshot_test.go
  • internal/registry/testmain_test.go
  • internal/schema/assembler.go
  • internal/schema/assembler_test.go
  • internal/schema/catalog_test_helpers_test.go
  • internal/schema/lint.go
  • internal/schema/lint_test.go
  • internal/schema/types.go
  • scripts/build-pkg-pr-new.sh
  • scripts/ci-workflow.test.sh
  • scripts/fetch_meta.py
  • shortcuts/application/slash_command_common.go
  • shortcuts/common/skill_references.go
  • shortcuts/im/affordance_migration_test.go
  • shortcuts/register.go
  • shortcuts/register_brand_guard_test.go
  • shortcuts/register_test.go
  • shortcuts/slides/slides_replace_slide.go
  • skills/lark-calendar/SKILL.md
  • tests/plugin_e2e/degrade_subsystem_test.go
  • tests/plugin_e2e/harness.go
  • tests/plugin_e2e/restrict_test.go
  • tests/sidecar_e2e/roundtrip_test.go
💤 Files with no reviewable changes (26)
  • scripts/build-pkg-pr-new.sh
  • .gitignore
  • internal/cmdutil/factory_default.go
  • cmd/cmdexample_test.go
  • .github/workflows/arch-audit.yml
  • internal/registry/catalog.go
  • internal/registry/registrytest/registrytest.go
  • internal/registry/loader_test.go
  • build.sh
  • internal/registry/catalog_test.go
  • internal/registry/remote.go
  • cmd/startup_brand.go
  • internal/qualitygate/rules/dryrun_test.go
  • internal/registry/registrytest/fixture_meta.json
  • internal/qualitygate/cmd/manifest-export/main.go
  • cmd/startup_brand_test.go
  • internal/registry/meta_data_default.json
  • internal/registry/scope_hint_test.go
  • internal/registry/testmain_test.go
  • internal/registry/remote_test.go
  • internal/qualitygate/cmd/quality-gate/main.go
  • scripts/fetch_meta.py
  • internal/registry/loader_embedded.go
  • internal/registry/registrytest/registrytest_test.go
  • internal/qualitygate/rules/dryrun.go
  • internal/registry/loader.go
🚧 Files skipped from review as they are similar to previous changes (101)
  • internal/qualitygate/diff/diff.go
  • cmd/global_flags_test.go
  • internal/meta/normalize_test.go
  • internal/qualitygate/publiccontent/scan.go
  • errs/subtypes.go
  • AGENTS.md
  • cmd/platform_bootstrap.go
  • cmd/service/paramhelp.go
  • cmd/service/paramflags_test.go
  • shortcuts/common/skill_references.go
  • cmd/auth/catalog_test_helpers_test.go
  • cmd/auth/login_brand_filter_test.go
  • internal/cmdutil/factory.go
  • cmd/build_test.go
  • scripts/ci-workflow.test.sh
  • cmd/build_memstats_test.go
  • internal/registry/catalog/manifest.json
  • internal/registry/catalog/services/minutes.json
  • shortcuts/register_brand_guard_test.go
  • internal/qualitygate/rules/run_test.go
  • skills/lark-calendar/SKILL.md
  • shortcuts/application/slash_command_common.go
  • shortcuts/slides/slides_replace_slide.go
  • cmd/assembly_plan_test.go
  • internal/cmdutil/json.go
  • cmd/service/service_test.go
  • cmd/root_test.go
  • cmd/error_auth_hint.go
  • internal/qualitygate/rules/run.go
  • cmd/plugin_integration_test.go
  • cmd/assembly_plan_fuzz_test.go
  • internal/schema/lint_test.go
  • internal/schema/catalog_test_helpers_test.go
  • tests/sidecar_e2e/roundtrip_test.go
  • cmd/service/testmain_test.go
  • cmd/service/service.go
  • internal/qualitygate/cmd/quality-gate/main_test.go
  • internal/qualitygate/cmd/manifest-export/main_test.go
  • cmd/global_flags.go
  • cmd/assembly_plan.go
  • internal/cmdutil/json_test.go
  • cmd/service/affordance.go
  • internal/registry/catalog/services/mail.json
  • cmd/build_benchmark_test.go
  • tests/plugin_e2e/restrict_test.go
  • internal/qualitygate/publiccontent/collect_test.go
  • cmd/auth/testmain_test.go
  • internal/qualitygate/publiccontent/catalog.go
  • internal/schema/assembler.go
  • cmd/root_risk_help_test.go
  • internal/affordance/affordance.go
  • internal/cmdutil/fileupload_test.go
  • shortcuts/register.go
  • internal/qualitygate/publiccontent/collect.go
  • .github/workflows/ci.yml
  • cmd/auth/auth_test.go
  • cmd/schema/schema.go
  • internal/registry/snapshot.go
  • internal/affordance/affordance_test.go
  • cmd/auth/login_interactive.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/affordance/application_source_test.go
  • shortcuts/im/affordance_migration_test.go
  • cmd/testmain_test.go
  • internal/registry/scopes.go
  • internal/registry/catalog/services/drive.json
  • internal/registry/catalog/services/slides.json
  • cmd/auth/login_test.go
  • internal/registry/catalog/services/attendance.json
  • internal/cmdutil/testmain_test.go
  • internal/registry/catalog/services/calendar.json
  • internal/registry/catalog/services/contact.json
  • internal/schema/types.go
  • cmd/auth/login.go
  • cmd/service/affordance_test.go
  • content_embed_affordance_test.go
  • cmd/root.go
  • internal/registry/catalog/services/approval.json
  • internal/qualitygate/publiccontent/catalog_test.go
  • internal/registry/catalog/services/wiki.json
  • tests/plugin_e2e/harness.go
  • internal/registry/catalog/services/vc.json
  • internal/qualitygate/diff/diff_test.go
  • internal/schema/lint.go
  • shortcuts/register_test.go
  • internal/qualitygate/publiccontent/rules.go
  • internal/affordance/im_source_test.go
  • internal/registry/catalog/services/okr.json
  • cmd/build_target_test.go
  • internal/schema/assembler_test.go
  • internal/registry/registry_test.go
  • internal/meta/normalize.go
  • cmd/error_presenter_test.go
  • tests/plugin_e2e/degrade_subsystem_test.go
  • internal/registry/catalog/services/task.json
  • internal/registry/catalog/services/im.json
  • internal/registry/snapshot_test.go
  • internal/registry/catalog/services/mindnotes.json
  • cmd/schema/schema_test.go
  • cmd/diagnose_scope_test.go
  • cmd/build.go

Comment thread internal/apicatalog/catalog.go Outdated
@zhaojunlin0405
zhaojunlin0405 force-pushed the feat/catalog-lazy-routing branch from eb7f343 to 356f69e Compare August 7, 2026 09:09
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@zhaojunlin0405
zhaojunlin0405 force-pushed the feat/catalog-lazy-routing branch from 356f69e to be38883 Compare August 7, 2026 09:13
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/calendar PR touches the calendar domain domain/im PR touches the im domain feature size/XL Architecture-level or global-impact change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant