Skip to content

feat(risk): make the risk taxonomy typed and fail closed on a bad one - #2213

Open
sang-neo03 wants to merge 2 commits into
mainfrom
feat/typed-risk-level
Open

feat(risk): make the risk taxonomy typed and fail closed on a bad one#2213
sang-neo03 wants to merge 2 commits into
mainfrom
feat/typed-risk-level

Conversation

@sang-neo03

@sang-neo03 sang-neo03 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

A misspelled risk level silently disarmed the confirmation gate. Writing Risk: "high-risk-wrtie" on any high-risk write shortcut compiled, passed CI, and at runtime the gate compared the declaration against the literal "high-risk-write", missed, and executed the command — with --yes never registered, so the user could not have confirmed even if they had wanted to. 64 high-risk write commands sit behind that comparison, and the taxonomy was declared four times across the tree with only the plugin SDK's copy typed.

Scope is the risk-level path only. Config persistence and API-response decoding are untouched.

Changes

Type — one definition, typed at the seams

  • internal/core.Risk becomes a defined type with ParseRisk / IsValid / Rank, and is the single definition. internal/cmdutil and shortcuts/common re-export it; extension/platform keeps its own SDK-facing type (public signature unchanged) but derives its constants from core and converts with Core() / FromCore(); errs keeps the wire strings because it cannot import core without an import cycle. A consistency test pins the three value sets together.
  • Shortcut.Risk, SetRisk / GetRisk, cmdmeta.Meta.Risk and the service command spec are typed. The 548 Risk: declarations under shortcuts/ and the SetRisk calls under cmd/ now use the constants.
  • Values crossing a string boundary — the generated service catalog, cobra annotations — go through core.ParseRisk rather than a bare conversion. An out-of-taxonomy catalog value is kept as-is instead of being normalised to a default, so the runtime gate can refuse it.

CI — the layer that actually catches a typo

  • The quality gate rejects a manifest risk outside the closed enum. The manifest is exported from the live command tree, so this sees every mounted command's real annotation, including commands whose risk arrived as a string.
  • A new risk-literal rule rejects a hand-written level in cmd/ and shortcuts/, scanned in full at a zero baseline.
  • The sheets flag-defs generator validates its JSON input against the same enum.

Runtime — fail closed

  • cmdutil.EnforceRiskDeclaration refuses to run a command whose declared level is not in the taxonomy; RequiresConfirmation treats an unrecognised level as the highest tier rather than as read.
  • LARKSUITE_CLI_ALLOW_INVALID_RISK downgrades the refusal to "confirm first". It cannot downgrade it to "run". --yes is registered for an invalid declaration too, so the downgrade path is usable.
  • New error subtype internal / invalid_risk_declaration.

Test Plan

  • go build ./..., go vet ./..., gofmt clean
  • go test ./shortcuts/... -count=1 passes
  • go test ./internal/... ./errs/... ./extension/... ./cmd/... -count=1 — 15 failures, all pre-existing: the same set fails on a clean origin/main (local registry is not generated, e.g. service "im" not found in registry). Verified by stashing this branch and re-running the identical command.
  • Reproduction test verified red before the fix: temporarily restoring the old s.Risk == "high-risk-write" gate makes TestRiskGateRefusesMisspelledDeclaration fail with the fixture command executing.
  • New coverage: misspelled level must not execute with or without --yes; the downgrade switch still requires confirmation and then runs; the unchanged high-risk contract; lower tiers stay ungated; ParseRisk's absent/valid/invalid split; cross-package taxonomy consistency; manifest enum validation; the risk-literal rule and the tree's zero baseline.

Notes for review

Two choices worth a second opinion:

  1. Env var name. LARKSUITE_CLI_ALLOW_INVALID_RISK is my pick for the downgrade switch; happy to rename.
  2. New error subtype. invalid_risk_declaration under internal. Adding a subtype is additive to the error contract, but say the word if you would rather reuse an existing one.

Worth knowing for anyone reviewing the type change: a defined string type does not make a misspelled literal a compile error — Go converts untyped string constants implicitly, so Risk: "high-risk-wrtie" still builds. The type stops a string variable from flowing in and gives editors the candidate list; the actual typo defence is the CI rules plus the runtime gate. Making it a build error would require Risk to become a struct with an unexported field, which changes JSON/YAML handling and the plugin SDK signature.

Related Issues

  • None

@sang-neo03
sang-neo03 requested a review from liangshuo-1 as a code owner August 6, 2026 08:49
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 423 files, which is 123 over the limit of 300.

To get a review, reduce the PR to 300 files or fewer by splitting it into smaller PRs or changing its base branch.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: dcbc754c-f0f6-4f37-b993-b7bf0b4bbaf8

📥 Commits

Reviewing files that changed from the base of the PR and between 9759167 and 67ed241.

⛔ Files ignored due to path filters (1)
  • shortcuts/sheets/internal/gen/main.go is excluded by !**/gen/**
📒 Files selected for processing (423)
  • cmd/api/api.go
  • cmd/auth/check.go
  • cmd/auth/list.go
  • cmd/auth/login.go
  • cmd/auth/logout.go
  • cmd/auth/scopes.go
  • cmd/auth/status.go
  • cmd/completion/completion.go
  • cmd/config/bind.go
  • cmd/config/default_as.go
  • cmd/config/init.go
  • cmd/config/keychain_downgrade.go
  • cmd/config/plugins.go
  • cmd/config/policy.go
  • cmd/config/remove.go
  • cmd/config/show.go
  • cmd/config/strict_mode.go
  • cmd/doctor/doctor.go
  • cmd/event/bus.go
  • cmd/event/consume.go
  • cmd/event/list.go
  • cmd/event/schema.go
  • cmd/event/status.go
  • cmd/event/stop.go
  • cmd/platform_bootstrap_test.go
  • cmd/plugin_integration_test.go
  • cmd/profile/add.go
  • cmd/profile/list.go
  • cmd/profile/remove.go
  • cmd/profile/rename.go
  • cmd/profile/use.go
  • cmd/prune_test.go
  • cmd/root_risk_help_test.go
  • cmd/service/affordance_test.go
  • cmd/service/service.go
  • cmd/skill/skill.go
  • cmd/update/update.go
  • cmd/whoami/whoami.go
  • errs/subtypes.go
  • extension/platform/risk.go
  • internal/cmdmeta/meta.go
  • internal/cmdpolicy/engine.go
  • internal/cmdutil/risk.go
  • internal/cmdutil/risk_gate.go
  • internal/cmdutil/risk_test.go
  • internal/core/risk.go
  • internal/core/risk_test.go
  • internal/envvars/envvars.go
  • internal/qualitygate/cmd/manifest-export/collect.go
  • internal/qualitygate/manifest/io_test.go
  • internal/qualitygate/manifest/schema.go
  • internal/qualitygate/rules/risklit.go
  • internal/qualitygate/rules/risklit_test.go
  • internal/qualitygate/rules/run.go
  • internal/schema/assembler.go
  • internal/schema/lint.go
  • shortcuts/application/slash_command_create.go
  • shortcuts/application/slash_command_delete.go
  • shortcuts/application/slash_command_list.go
  • shortcuts/application/slash_command_update.go
  • shortcuts/apps/apps_access_scope_get.go
  • shortcuts/apps/apps_access_scope_set.go
  • shortcuts/apps/apps_analytics.go
  • shortcuts/apps/apps_automation_create.go
  • shortcuts/apps/apps_automation_disable.go
  • shortcuts/apps/apps_automation_enable.go
  • shortcuts/apps/apps_automation_get.go
  • shortcuts/apps/apps_automation_list.go
  • shortcuts/apps/apps_automation_update.go
  • shortcuts/apps/apps_cache_clear.go
  • shortcuts/apps/apps_cache_delete.go
  • shortcuts/apps/apps_cache_get.go
  • shortcuts/apps/apps_chat.go
  • shortcuts/apps/apps_create.go
  • shortcuts/apps/apps_db_audit_list.go
  • shortcuts/apps/apps_db_audit_set.go
  • shortcuts/apps/apps_db_audit_status.go
  • shortcuts/apps/apps_db_changelog_list.go
  • shortcuts/apps/apps_db_data_export.go
  • shortcuts/apps/apps_db_data_import.go
  • shortcuts/apps/apps_db_env_create.go
  • shortcuts/apps/apps_db_env_migrate.go
  • shortcuts/apps/apps_db_execute.go
  • shortcuts/apps/apps_db_quota_get.go
  • shortcuts/apps/apps_db_recovery.go
  • shortcuts/apps/apps_db_table_get.go
  • shortcuts/apps/apps_db_table_list.go
  • shortcuts/apps/apps_env.go
  • shortcuts/apps/apps_env_pull.go
  • shortcuts/apps/apps_file_delete.go
  • shortcuts/apps/apps_file_download.go
  • shortcuts/apps/apps_file_get.go
  • shortcuts/apps/apps_file_list.go
  • shortcuts/apps/apps_file_quota_get.go
  • shortcuts/apps/apps_file_sign.go
  • shortcuts/apps/apps_file_upload.go
  • shortcuts/apps/apps_get.go
  • shortcuts/apps/apps_html_publish.go
  • shortcuts/apps/apps_init.go
  • shortcuts/apps/apps_list.go
  • shortcuts/apps/apps_logs.go
  • shortcuts/apps/apps_metrics.go
  • shortcuts/apps/apps_openapi_key_create.go
  • shortcuts/apps/apps_openapi_key_delete.go
  • shortcuts/apps/apps_openapi_key_disable.go
  • shortcuts/apps/apps_openapi_key_enable.go
  • shortcuts/apps/apps_openapi_key_get.go
  • shortcuts/apps/apps_openapi_key_list.go
  • shortcuts/apps/apps_openapi_key_reset.go
  • shortcuts/apps/apps_openapi_key_update.go
  • shortcuts/apps/apps_plugin_install.go
  • shortcuts/apps/apps_plugin_list.go
  • shortcuts/apps/apps_plugin_uninstall.go
  • shortcuts/apps/apps_release_create.go
  • shortcuts/apps/apps_release_get.go
  • shortcuts/apps/apps_release_list.go
  • shortcuts/apps/apps_role.go
  • shortcuts/apps/apps_role_member.go
  • shortcuts/apps/apps_role_test.go
  • shortcuts/apps/apps_session_create.go
  • shortcuts/apps/apps_session_get.go
  • shortcuts/apps/apps_session_list.go
  • shortcuts/apps/apps_session_messages_list.go
  • shortcuts/apps/apps_session_stop.go
  • shortcuts/apps/apps_traces.go
  • shortcuts/apps/apps_update.go
  • shortcuts/apps/git_credential.go
  • shortcuts/base/base_advperm_disable.go
  • shortcuts/base/base_advperm_enable.go
  • shortcuts/base/base_block_create.go
  • shortcuts/base/base_block_delete.go
  • shortcuts/base/base_block_list.go
  • shortcuts/base/base_block_move.go
  • shortcuts/base/base_block_rename.go
  • shortcuts/base/base_copy.go
  • shortcuts/base/base_create.go
  • shortcuts/base/base_data_query.go
  • shortcuts/base/base_form_create.go
  • shortcuts/base/base_form_delete.go
  • shortcuts/base/base_form_detail.go
  • shortcuts/base/base_form_get.go
  • shortcuts/base/base_form_list.go
  • shortcuts/base/base_form_questions_create.go
  • shortcuts/base/base_form_questions_delete.go
  • shortcuts/base/base_form_questions_list.go
  • shortcuts/base/base_form_questions_update.go
  • shortcuts/base/base_form_submit.go
  • shortcuts/base/base_form_update.go
  • shortcuts/base/base_get.go
  • shortcuts/base/base_resolve.go
  • shortcuts/base/base_role_create.go
  • shortcuts/base/base_role_delete.go
  • shortcuts/base/base_role_get.go
  • shortcuts/base/base_role_list.go
  • shortcuts/base/base_role_test.go
  • shortcuts/base/base_role_update.go
  • shortcuts/base/base_shortcuts_test.go
  • shortcuts/base/dashboard_arrange.go
  • shortcuts/base/dashboard_block_create.go
  • shortcuts/base/dashboard_block_delete.go
  • shortcuts/base/dashboard_block_get.go
  • shortcuts/base/dashboard_block_get_data.go
  • shortcuts/base/dashboard_block_list.go
  • shortcuts/base/dashboard_block_update.go
  • shortcuts/base/dashboard_create.go
  • shortcuts/base/dashboard_delete.go
  • shortcuts/base/dashboard_get.go
  • shortcuts/base/dashboard_list.go
  • shortcuts/base/dashboard_update.go
  • shortcuts/base/field_create.go
  • shortcuts/base/field_delete.go
  • shortcuts/base/field_get.go
  • shortcuts/base/field_list.go
  • shortcuts/base/field_search_options.go
  • shortcuts/base/field_update.go
  • shortcuts/base/record_batch_create.go
  • shortcuts/base/record_batch_update.go
  • shortcuts/base/record_delete.go
  • shortcuts/base/record_get.go
  • shortcuts/base/record_history_list.go
  • shortcuts/base/record_list.go
  • shortcuts/base/record_search.go
  • shortcuts/base/record_share_link_create.go
  • shortcuts/base/record_upload_attachment.go
  • shortcuts/base/record_upsert.go
  • shortcuts/base/table_copy.go
  • shortcuts/base/table_create.go
  • shortcuts/base/table_delete.go
  • shortcuts/base/table_get.go
  • shortcuts/base/table_list.go
  • shortcuts/base/table_update.go
  • shortcuts/base/view_create.go
  • shortcuts/base/view_delete.go
  • shortcuts/base/view_get.go
  • shortcuts/base/view_get_card.go
  • shortcuts/base/view_get_filter.go
  • shortcuts/base/view_get_group.go
  • shortcuts/base/view_get_sort.go
  • shortcuts/base/view_get_timebar.go
  • shortcuts/base/view_get_visible_fields.go
  • shortcuts/base/view_list.go
  • shortcuts/base/view_rename.go
  • shortcuts/base/view_set_card.go
  • shortcuts/base/view_set_filter.go
  • shortcuts/base/view_set_group.go
  • shortcuts/base/view_set_sort.go
  • shortcuts/base/view_set_timebar.go
  • shortcuts/base/view_set_visible_fields.go
  • shortcuts/base/workflow_create.go
  • shortcuts/base/workflow_disable.go
  • shortcuts/base/workflow_enable.go
  • shortcuts/base/workflow_get.go
  • shortcuts/base/workflow_list.go
  • shortcuts/base/workflow_update.go
  • shortcuts/calendar/calendar_agenda.go
  • shortcuts/calendar/calendar_create.go
  • shortcuts/calendar/calendar_freebusy.go
  • shortcuts/calendar/calendar_get.go
  • shortcuts/calendar/calendar_meeting.go
  • shortcuts/calendar/calendar_room_find.go
  • shortcuts/calendar/calendar_rsvp.go
  • shortcuts/calendar/calendar_search_event.go
  • shortcuts/calendar/calendar_suggestion.go
  • shortcuts/calendar/calendar_update.go
  • shortcuts/common/runner.go
  • shortcuts/common/runner_risk_gate_test.go
  • shortcuts/common/types.go
  • shortcuts/contact/contact_get_user.go
  • shortcuts/contact/contact_search_bot.go
  • shortcuts/contact/contact_search_user.go
  • shortcuts/doc/doc_media_download.go
  • shortcuts/doc/doc_media_insert.go
  • shortcuts/doc/doc_media_preview.go
  • shortcuts/doc/doc_media_upload.go
  • shortcuts/doc/doc_resource_cover.go
  • shortcuts/doc/docs_create.go
  • shortcuts/doc/docs_fetch.go
  • shortcuts/doc/docs_history.go
  • shortcuts/doc/docs_search.go
  • shortcuts/doc/docs_update.go
  • shortcuts/drive/drive_add_comment.go
  • shortcuts/drive/drive_add_reply.go
  • shortcuts/drive/drive_apply_permission.go
  • shortcuts/drive/drive_batch_query_comments.go
  • shortcuts/drive/drive_cover.go
  • shortcuts/drive/drive_create_folder.go
  • shortcuts/drive/drive_create_shortcut.go
  • shortcuts/drive/drive_delete.go
  • shortcuts/drive/drive_delete_reply.go
  • shortcuts/drive/drive_download.go
  • shortcuts/drive/drive_export.go
  • shortcuts/drive/drive_export_download.go
  • shortcuts/drive/drive_import.go
  • shortcuts/drive/drive_inspect.go
  • shortcuts/drive/drive_list_comments.go
  • shortcuts/drive/drive_list_replies.go
  • shortcuts/drive/drive_member_add.go
  • shortcuts/drive/drive_member_list.go
  • shortcuts/drive/drive_move.go
  • shortcuts/drive/drive_permission_get_setting.go
  • shortcuts/drive/drive_preview.go
  • shortcuts/drive/drive_pull.go
  • shortcuts/drive/drive_push.go
  • shortcuts/drive/drive_react_reply.go
  • shortcuts/drive/drive_resolve_comment.go
  • shortcuts/drive/drive_search.go
  • shortcuts/drive/drive_secure_label.go
  • shortcuts/drive/drive_status.go
  • shortcuts/drive/drive_sync.go
  • shortcuts/drive/drive_task_result.go
  • shortcuts/drive/drive_update_reply.go
  • shortcuts/drive/drive_upload.go
  • shortcuts/drive/drive_version.go
  • shortcuts/event/subscribe.go
  • shortcuts/im/im_chat_create.go
  • shortcuts/im/im_chat_list.go
  • shortcuts/im/im_chat_members_list.go
  • shortcuts/im/im_chat_messages_list.go
  • shortcuts/im/im_chat_search.go
  • shortcuts/im/im_chat_update.go
  • shortcuts/im/im_feed_group_list.go
  • shortcuts/im/im_feed_group_list_item.go
  • shortcuts/im/im_feed_group_query_item.go
  • shortcuts/im/im_feed_shortcut_create.go
  • shortcuts/im/im_feed_shortcut_list.go
  • shortcuts/im/im_feed_shortcut_remove.go
  • shortcuts/im/im_flag_cancel.go
  • shortcuts/im/im_flag_create.go
  • shortcuts/im/im_flag_list.go
  • shortcuts/im/im_messages_mget.go
  • shortcuts/im/im_messages_reply.go
  • shortcuts/im/im_messages_resources_download.go
  • shortcuts/im/im_messages_search.go
  • shortcuts/im/im_messages_send.go
  • shortcuts/im/im_threads_messages_list.go
  • shortcuts/mail/mail_decline_receipt.go
  • shortcuts/mail/mail_draft_create.go
  • shortcuts/mail/mail_draft_edit.go
  • shortcuts/mail/mail_draft_send.go
  • shortcuts/mail/mail_forward.go
  • shortcuts/mail/mail_lint_html.go
  • shortcuts/mail/mail_message.go
  • shortcuts/mail/mail_message_modify.go
  • shortcuts/mail/mail_message_trash.go
  • shortcuts/mail/mail_messages.go
  • shortcuts/mail/mail_reply.go
  • shortcuts/mail/mail_reply_all.go
  • shortcuts/mail/mail_send.go
  • shortcuts/mail/mail_send_receipt.go
  • shortcuts/mail/mail_share_to_chat.go
  • shortcuts/mail/mail_signature.go
  • shortcuts/mail/mail_template_create.go
  • shortcuts/mail/mail_template_update.go
  • shortcuts/mail/mail_thread.go
  • shortcuts/mail/mail_triage.go
  • shortcuts/mail/mail_watch.go
  • shortcuts/markdown/markdown_create.go
  • shortcuts/markdown/markdown_diff.go
  • shortcuts/markdown/markdown_fetch.go
  • shortcuts/markdown/markdown_overwrite.go
  • shortcuts/markdown/markdown_patch.go
  • shortcuts/minutes/minutes_apply_permission.go
  • shortcuts/minutes/minutes_detail.go
  • shortcuts/minutes/minutes_download.go
  • shortcuts/minutes/minutes_search.go
  • shortcuts/minutes/minutes_speaker_replace.go
  • shortcuts/minutes/minutes_summary.go
  • shortcuts/minutes/minutes_todo.go
  • shortcuts/minutes/minutes_update.go
  • shortcuts/minutes/minutes_upload.go
  • shortcuts/minutes/minutes_word_replace.go
  • shortcuts/note/note_detail.go
  • shortcuts/note/note_transcript.go
  • shortcuts/okr/okr_batch_create.go
  • shortcuts/okr/okr_create.go
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_indicator_update.go
  • shortcuts/okr/okr_patch.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/okr/okr_reorder.go
  • shortcuts/okr/okr_weight.go
  • shortcuts/sheets/backward/lark_sheets_cell_data.go
  • shortcuts/sheets/backward/lark_sheets_cell_images.go
  • shortcuts/sheets/backward/lark_sheets_cell_style_and_merge.go
  • shortcuts/sheets/backward/lark_sheets_dropdown.go
  • shortcuts/sheets/backward/lark_sheets_filter_views.go
  • shortcuts/sheets/backward/lark_sheets_float_images.go
  • shortcuts/sheets/backward/lark_sheets_row_column_management.go
  • shortcuts/sheets/backward/lark_sheets_sheet_management.go
  • shortcuts/sheets/backward/lark_sheets_spreadsheet_management.go
  • shortcuts/sheets/lark_sheet_batch_update.go
  • shortcuts/sheets/lark_sheet_changeset.go
  • shortcuts/sheets/lark_sheet_formula_verify.go
  • shortcuts/sheets/lark_sheet_history_list.go
  • shortcuts/sheets/lark_sheet_history_revert.go
  • shortcuts/sheets/lark_sheet_object_crud.go
  • shortcuts/sheets/lark_sheet_object_list.go
  • shortcuts/sheets/lark_sheet_range_operations.go
  • shortcuts/sheets/lark_sheet_read_data.go
  • shortcuts/sheets/lark_sheet_revision_get.go
  • shortcuts/sheets/lark_sheet_search_replace.go
  • shortcuts/sheets/lark_sheet_sheet_structure.go
  • shortcuts/sheets/lark_sheet_table_io.go
  • shortcuts/sheets/lark_sheet_workbook.go
  • shortcuts/sheets/lark_sheet_write_cells.go
  • shortcuts/slides/slides_add_slide.go
  • shortcuts/slides/slides_create.go
  • shortcuts/slides/slides_delete_slide.go
  • shortcuts/slides/slides_history.go
  • shortcuts/slides/slides_media_upload.go
  • shortcuts/slides/slides_replace_pages.go
  • shortcuts/slides/slides_replace_slide.go
  • shortcuts/slides/slides_screenshot.go
  • shortcuts/slides/slides_update_slide.go
  • shortcuts/slides/slides_xml_get.go
  • shortcuts/task/shortcuts.go
  • shortcuts/task/task_assign.go
  • shortcuts/task/task_comment.go
  • shortcuts/task/task_complete.go
  • shortcuts/task/task_followers.go
  • shortcuts/task/task_get_my_tasks.go
  • shortcuts/task/task_get_related_tasks.go
  • shortcuts/task/task_reminder.go
  • shortcuts/task/task_reopen.go
  • shortcuts/task/task_search.go
  • shortcuts/task/task_set_ancestor.go
  • shortcuts/task/task_tasklist_search.go
  • shortcuts/task/task_update.go
  • shortcuts/task/task_upload_attachment.go
  • shortcuts/task/tasklist_add_task.go
  • shortcuts/task/tasklist_create.go
  • shortcuts/task/tasklist_members.go
  • shortcuts/vc/vc_detail.go
  • shortcuts/vc/vc_meeting_events.go
  • shortcuts/vc/vc_meeting_join.go
  • shortcuts/vc/vc_meeting_leave.go
  • shortcuts/vc/vc_meeting_list_active.go
  • shortcuts/vc/vc_meeting_message_send.go
  • shortcuts/vc/vc_notes.go
  • shortcuts/vc/vc_recording.go
  • shortcuts/vc/vc_search.go
  • shortcuts/whiteboard/whiteboard_export.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/wiki/wiki_delete.go
  • shortcuts/wiki/wiki_member_add.go
  • shortcuts/wiki/wiki_member_list.go
  • shortcuts/wiki/wiki_member_remove.go
  • shortcuts/wiki/wiki_member_test.go
  • shortcuts/wiki/wiki_move.go
  • shortcuts/wiki/wiki_move_to_drive.go
  • shortcuts/wiki/wiki_node_copy.go
  • shortcuts/wiki/wiki_node_create.go
  • shortcuts/wiki/wiki_node_delete.go
  • shortcuts/wiki/wiki_node_get.go
  • shortcuts/wiki/wiki_node_list.go
  • shortcuts/wiki/wiki_space_create.go
  • shortcuts/wiki/wiki_space_list.go

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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/base PR touches the base domain domain/calendar PR touches the calendar domain domain/ccm PR touches the ccm domain domain/contact PR touches the contact domain domain/im PR touches the im domain domain/mail PR touches the mail domain domain/task PR touches the task domain domain/vc PR touches the vc domain size/XL Architecture-level or global-impact change labels Aug 6, 2026
@sang-neo03
sang-neo03 force-pushed the feat/typed-risk-level branch from 32d3481 to 528b201 Compare August 6, 2026 08:52
Misspelling a shortcut's risk level used to be silent and destructive:
`Risk: "high-risk-wrtie"` compiled, passed CI, and at runtime the
confirmation gate compared against the literal "high-risk-write", missed,
and ran the command. --yes was never even registered, so the user could
not have confirmed if they had wanted to. 64 high-risk write commands sit
behind that comparison.

The taxonomy was declared four times (internal/core, internal/cmdutil,
errs, extension/platform) and only the plugin SDK's copy was typed.

Three layers now, because no single one is enough:

- Type. internal/core.Risk is a defined type and the single definition;
  cmdutil and shortcuts/common re-export it, extension/platform keeps its
  own SDK-facing type but derives its constants from core and converts via
  Core/FromCore, and errs keeps the wire strings (it cannot import core
  without a cycle). A consistency test pins all three together.
  Shortcut.Risk, SetRisk/GetRisk, cmdmeta.Meta.Risk and the service command
  spec are typed; the 548 declarations under shortcuts/ and the SetRisk
  calls under cmd/ use the constants. Values crossing a string boundary —
  the generated service catalog, cobra annotations — go through
  core.ParseRisk instead of a bare conversion.

  Note what the type does not do: an untyped literal still converts, so
  `Risk: "high-risk-wrtie"` compiles. That is why the other two layers
  exist rather than being belt-and-braces.

- CI. The quality gate rejects a manifest risk outside the closed enum —
  the manifest is exported from the live tree, so this sees every mounted
  command's real annotation — and a new risk-literal rule rejects a
  hand-written level in cmd/ and shortcuts/, at a zero baseline. The sheets
  flag-defs generator validates its JSON input the same way.

- Runtime. cmdutil.EnforceRiskDeclaration refuses to run a command whose
  declared level is not in the taxonomy, and RequiresConfirmation treats an
  unrecognised level as the highest tier rather than as read.
  LARKSUITE_CLI_ALLOW_INVALID_RISK downgrades the refusal to "confirm
  first"; it cannot downgrade it to "run". --yes is registered for an
  invalid declaration too, so the downgrade path is usable.

Tests cover the reproduction (a misspelled level must not execute, with or
without --yes), the downgrade switch, the unchanged high-risk contract, the
lower tiers staying ungated, ParseRisk's absent/valid/invalid split, and
the cross-package consistency of the three declarations.
@sang-neo03
sang-neo03 force-pushed the feat/typed-risk-level branch from 528b201 to 83c052a Compare August 6, 2026 08:54
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/typed-risk-level -y -g

riskLiteralsInFile carried the whole ast.Inspect switch inline: two node
shapes, each with its own guard chain, at a cyclomatic complexity of 12.
Each shape is now its own function returning a riskLiteralUse, so the
walker reads as "did this node use a literal, and where", and no function
in the file is above 5.

invalidRiskDeclaration has no caller outside cmdutil, so it is no longer
part of the package's exported surface.
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.36842% with 43 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.08%. Comparing base (9759167) to head (67ed241).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/cmdutil/risk_gate.go 0.00% 18 Missing ⚠️
internal/qualitygate/rules/risklit.go 86.25% 6 Missing and 5 partials ⚠️
cmd/service/service.go 70.00% 2 Missing and 1 partial ⚠️
extension/platform/risk.go 75.00% 2 Missing ⚠️
internal/qualitygate/rules/run.go 50.00% 1 Missing and 1 partial ⚠️
cmd/event/schema.go 0.00% 1 Missing ⚠️
cmd/profile/add.go 0.00% 1 Missing ⚠️
cmd/profile/list.go 0.00% 1 Missing ⚠️
cmd/profile/remove.go 0.00% 1 Missing ⚠️
cmd/profile/rename.go 0.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2213      +/-   ##
==========================================
- Coverage   76.08%   76.08%   -0.01%     
==========================================
  Files         983      986       +3     
  Lines      103429   103556     +127     
==========================================
+ Hits        78692    78786      +94     
- Misses      18752    18781      +29     
- Partials     5985     5989       +4     

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

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

Labels

domain/base PR touches the base domain domain/calendar PR touches the calendar domain domain/ccm PR touches the ccm domain domain/contact PR touches the contact domain domain/im PR touches the im domain domain/mail PR touches the mail domain domain/task PR touches the task domain domain/vc PR touches the vc domain size/XL Architecture-level or global-impact change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant