Files
dingtalk-workspace-cli/docs/batch-auth-prd.json
T

553 lines
59 KiB
JSON

{
"title": "DWS Batch Authorization and Login Recommend Flow",
"version": "2026-06-16",
"owners": {
"cli": "dingtalk-workspace-cli",
"gateway": "lippi-open-mcpserver-gw",
"patCore": "lippi-pat-core-wukong-capability",
"bff": "lippi-open-app-dev",
"frontend": "lippi-open-dev-front"
},
"context": {
"problem": "DWS login --recommend and product-line batch authorization need a user-visible authorization page instead of silent bulk grants or local --yes-only blocking.",
"reference": {
"larkCli": {
"loginRecommend": "lark-cli auth login --recommend",
"domainAll": "lark-cli auth login --domain all",
"noWait": "lark-cli auth login --no-wait --json",
"deviceCode": "lark-cli auth login --device-code <code>",
"exclude": "lark-cli auth login --exclude <scope>",
"scopeCatalog": "lark-cli auth scopes",
"scopeCheck": "lark-cli auth check --scope <scope...>",
"qrCode": "lark-cli auth qrcode <url>",
"yesFlag": "lark-cli auth login has no --yes flag; lark-cli auth login --yes --no-wait --json returns Error: unknown flag: --yes. DWS intentionally differs because --yes is an inherited batch-auto-confirm flag: dws auth login --recommend --yes must skip the browser confirmation flow and grant the service-selected scopes directly."
},
"ralphCli": {
"model": "PRD-driven long-running development with explicit task ledger, progress notes, verification gates, and failure analysis.",
"evidence": "ralph v0.16.0 help and /Users/xuan/knowledge/META-ralph-reference.md",
"mapping": "This PRD keeps a single SSOT for goals, contracts, tasks, security gates, acceptance criteria, and blocked evidence so implementation can continue across multiple repositories without redefining done."
},
"existingDingTalkPage": "/src/app/personalAuthorization/index.jsx",
"targetPage": "Reuse the personalAuthorization route and render multiple scopes grouped by product."
},
"accessNotes": [
"The frontend GitLab repo was cloned through SSH to /Users/xuan/lippi-open-dev-front and implemented on branch codex/batch-auth-page-flow.",
"The DWS PAT BFF lives in /Users/xuan/lippi-open-app-dev and needs to be part of the chain because it owns /dingtalk-workspace-cli/oauth/device/action.",
"Acceptance is not complete after local build. It is complete only after prepub package/build succeeds for every changed repo and prepub functional verification passes.",
"The referenced DingTalk minutes URL could not be fetched because local dws is not logged in."
]
},
"goals": [
"After dws auth login --recommend succeeds, DWS starts a PAT recommended batch plan and opens the authorization page.",
"For PAT batch authorization commands through dws pat chmod without --yes, including multi-scope, product-line, and recommend modes, DWS opens the same authorization page instead of returning a local validation error.",
"The server, not the CLI, selects grantable scopes. CLI must grant only selectedScopes from pat.batch_plan.",
"Recommended login scope selection is controlled by prepub Diamond: open-source visible scopes are the enabled template set, recommendation is the low-risk subset, and the 22 medium-risk scopes are excluded from default login recommend.",
"High-risk scopes remain pending and must not be silently granted."
],
"nonGoals": [
"Do not trust CLI-provided orgId or uid.",
"Do not add a second authorization UI path.",
"Do not make medium-risk or high-risk destructive scopes part of default login recommend."
],
"userFlows": [
{
"name": "loginRecommend",
"steps": [
"User runs dws auth login --recommend.",
"CLI completes OAuth loopback or device login, lets the user choose the DingTalk organization through the normal login flow, and saves the token.",
"CLI does not show the product-domain TUI for --recommend.",
"CLI calls pat.batch_plan with recommend=true, grantType=permanent, caller=auth_login_recommend, dryRun=true.",
"PAT core loads the Diamond-driven recommended set, excludes non-recommended medium-risk scopes from the default plan, and returns selectedScopes plus warnings/skipped scopes.",
"CLI calls pat.batch_grant with scopes=selectedScopes, startFlow=true, noWait=true, caller=auth_login_recommend.",
"PAT core creates a single batch Device Code Flow and returns PAT_BATCH_AUTH_PENDING with flowId/userCode/uri.",
"CLI opens uri, polls flow status, and retries the original grant after approval."
]
},
{
"name": "loginInteractiveTuiWithoutRecommend",
"steps": [
"User runs dws auth login without --recommend in an interactive terminal.",
"CLI completes OAuth loopback or device login, lets the user choose the DingTalk organization through the normal login flow, and saves the token.",
"After the login identity and organization are settled, CLI shows the Feishu-like terminal authorization guide: 选择操作, then 授权范围选择.",
"CLI calls pat.batch_plan with recommend=true when the user selected 推荐授权, or recommend=false when the user selected 全部授权.",
"CLI shows the product-domain selector with all product lines selected by default; user can toggle, filter, or confirm.",
"CLI re-plans with the selected productCodes before starting the grant flow.",
"Without --yes, CLI calls pat.batch_grant with scopes=selectedScopes, startFlow=true, noWait=true, then opens/polls the returned authorization URL."
]
},
{
"name": "batchChmodWithoutYes",
"steps": [
"User runs dws pat chmod --recommend --product <product> without --yes.",
"CLI plans first, then starts a batch Device Code Flow instead of direct grant.",
"The authorization page displays all grantable selected scopes grouped by product.",
"Approve writes selected grants; reject leaves all grants unchanged."
]
},
{
"name": "batchChmodWithYes",
"steps": [
"User runs the same command with --yes.",
"CLI continues the existing non-interactive grant path.",
"PAT core writes grantable low/medium-risk scopes directly and returns high-risk scopes as pending."
]
}
],
"larkCliParity": [
{
"lark": "auth login --recommend",
"dws": "dws auth login --recommend",
"serverContract": "pat.batch_plan recommend=true caller=auth_login_recommend, then pat.batch_grant selectedScopes startFlow=true noWait=true",
"status": "implemented locally in CLI, gateway, PAT core, BFF, and frontend; prepub package and verification pending"
},
{
"lark": "auth login --domain <domain>|all",
"dws": "dws pat chmod --product <productCode[,productCode]> or --products <...>",
"serverContract": "pat.batch_plan productCodes=[...] resolves service-owned product scope templates",
"status": "implemented for PAT chmod product-line flow"
},
{
"lark": "auth login --scope <scopes>",
"dws": "dws pat chmod <scope...>",
"serverContract": "one scope preserves direct grant behavior; multiple scopes enter batch plan/flow when --yes is absent",
"status": "implemented for multi-scope PAT chmod"
},
{
"lark": "auth login --exclude <scope>",
"dws": "batch authorization page selectedScopes",
"serverContract": "frontend sends selectedScopes; PAT core rejects any selected scope outside flow scopes and treats unchecked flow scopes as rejectedScopes",
"status": "implemented locally in PAT core, BFF selectedScopes passthrough, and frontend grouped selection; prepub verification pending"
},
{
"lark": "auth login --no-wait --json and later --device-code",
"dws": "PAT_BATCH_AUTH_PENDING JSON with uri/authUrl/flowId/userCode plus polling retry",
"serverContract": "host-owned JSON mode returns structured pending and does not block; local interactive mode opens browser and polls",
"status": "implemented in CLI retry path and PAT pending response"
},
{
"lark": "auth login --yes",
"dws": "supported only as dws auth login --recommend --yes; inherited --yes skips local TUI and web confirmation and directly grants the PAT-core selected safe recommend scopes",
"serverContract": "auth login --recommend without --yes must still open or return the authorization page. With --yes, the CLI omits startFlow/noWait and relies on PAT core to grant only service-selected safe scopes; server-side pending/high-risk/page-required responses still win.",
"status": "verified on 2026-06-16 with local lark-cli: unknown flag --yes; DWS --yes semantics are product-specific and intentionally bypass the web confirmation page for recommend direct grant"
},
{
"lark": "auth scopes and auth check",
"dws": "pat.batch_plan dryRun and existing PAT auth check result",
"serverContract": "plan exposes selected/skipped/pending/already-granted scope sets; check/auth retry carries missing scope and grant options",
"status": "partially aligned; no new public scope-catalog command added in this slice"
}
],
"ralphExecutionPlan": {
"project": "dws-batch-authorization-page",
"tasks": [
{
"id": "1",
"title": "Build PRD and command parity map",
"description": "Use product-design style requirements plus Ralph-style SSOT to map DWS batch authorization against lark-cli.",
"steps": [
"Define user flows for login recommend, product-line grant, multi-scope grant, yes direct grant, and JSON no-wait mode.",
"Record frontend access and DingTalk minutes access blockers explicitly.",
"Keep acceptance criteria tied to command outputs and service contracts."
],
"done": true
},
{
"id": "2",
"title": "Implement DWS CLI batch authorization entry points",
"description": "dws auth login --recommend and dws pat chmod batch/product/recommend without --yes start the page-based flow.",
"steps": [
"Add --recommend to auth login and run PAT recommended plan after login.",
"Route product-line, recommend, and multi-scope chmod without --yes to pat.batch_grant startFlow.",
"Keep --yes as the explicit direct-write path."
],
"done": true
},
{
"id": "3",
"title": "Harden gateway identity and caller allowlist",
"description": "The gateway must derive orgId/uid from trusted identity and allow intended DWS batch callers.",
"steps": [
"Keep CLI-provided orgId/uid untrusted.",
"Allow dws-cli alongside openclaw for intended batch write callers.",
"Preserve caller/source checks for default grant writes."
],
"done": true
},
{
"id": "4",
"title": "Implement PAT core recommended filtering and batch DCF",
"description": "PAT core owns selectedScopes, Diamond-driven recommendation, batch Device Code Flow, selected approval, and idempotent writes.",
"steps": [
"Keep recommended scope selection config-driven: preauth Diamond recommends the low-risk subset and excludes the 22 medium-risk scopes.",
"Create/reuse one batch flow for selected scopes.",
"Approve only selectedScopes and reject out-of-flow selections.",
"Fail closed on critical storage failures and leave flow retryable."
],
"done": true
},
{
"id": "5",
"title": "Implement lippi-open-dev-front batch authorization UI",
"description": "Reuse /src/app/personalAuthorization/index.jsx and render grouped product permissions with selectable scopes.",
"steps": [
"Load flow detail and detect multiple scopes.",
"Default-check all server-selected flow scopes.",
"Allow product and individual-scope deselection.",
"Submit selectedScopes on approve and no orgId/uid.",
"Handle PAT_BATCH_PARTIAL_FAILURE by keeping the page retryable."
],
"done": true
},
{
"id": "6",
"title": "Submit all repos to prepub and verify package plus behavior",
"description": "Acceptance only passes after prepub package/build succeeds and prepub functional verification is OK.",
"steps": [
"Push or submit branches for CLI, gateway, PAT core, BFF, and frontend.",
"Trigger prepub package/build for every changed repo.",
"Verify prepub deployed versions include the current change set.",
"Run login recommend and batch chmod functional checks on prepub.",
"Open the prepub authorization page and verify layout and approve/reject callbacks."
],
"done": false
}
]
},
"prepubReleaseGate": {
"overallStatus": "not_passed_until_prepub_validation_and_full_batch_page_e2e_pass",
"changedRepos": [
{
"repo": "dingtalk-workspace-cli",
"localPath": "/Users/xuan/dingtalk-workspace-cli",
"branch": "codex/dws-auth-login-recommend",
"commit": "f0552dd20e6a722add6ae0af366abd9ec8e753b7",
"prepubPackage": "pushed to GitHub branch codex/dws-auth-login-recommend with CLI commit f0552dd20e6a722add6ae0af366abd9ec8e753b7; rebuilt local default /usr/local/bin/dws -> /Users/xuan/bin/dws and /Users/xuan/.local/bin/dws from current source with identical sha256 22c18538db5dd7d5d32557e2183646fd6535824fb8bd9eb4b67251b4ec4dfc75 before the latest docs-only evidence commit. Local focused and broad Go regressions passed after the auth-login wait-only fix. Still blocked_no_aone_app_for_current_github_repo_lippi_dws_release_uses_gitlab_release_repo for formal prepub package evidence.",
"prepubFunctionalVerification": "local_cli_tui_contract_ok: dws auth login --recommend skips terminal TUI/product-domain selection and directly uses server recommend=true selectedScopes. Interactive default dws auth login without --recommend follows the terminal usage chain after login/org selection: 选择操作, 选择授权范围, then default-all-selected product domains before grant. 推荐授权 uses recommend=true; 全部授权 first discovers products with recommend=true, then replans selected product domains with recommend=false only after selected productCodes are available; a local guard rejects recommend=false with empty productCodes before any PAT call to avoid PAT_BATCH_AUTH_SCOPE_REQUIRED. explicit --format json and any non-TTY stdin/stdout/stderr keep structured non-interactive mode. local_wait_only_contract_ok: after the auth-login batch authorization page is approved, CLI prints the final success result and returns; it no longer prints 授权完成,正在重试... and no longer re-enters the post-login TUI flow. local_yes_contract_ok: dws auth login --recommend --yes skips the TUI/browser flow and calls pat.batch_grant without startFlow/noWait, preserving direct recommended direct grant behavior."
},
{
"repo": "lippi-open-mcpserver-gw",
"localPath": "/Users/xuan/lippi-open-mcpserver-gw",
"branch": "codex/pat-batch-auth-service-gate-20260616",
"commit": "89f6ea8c16cf95678e999d082e3fe94a578d0b6a",
"aoneAppId": 296391,
"aoneCrId": 34656146,
"aoneCrStatus": "INTG",
"aoneCrStatusLabel": "发布中",
"prepubPipelineId": 66,
"prepubPipelineInstanceId": 3095206675,
"prepubPackage": "Aone CR 34656146 pipeline 66 instance 3095206675 has code merge SUCCESS tasks 3391854522/3391854523, build+scan SUCCESS tasks 3391854524/3391854525, prepub deploy SUCCESS task 3391854526 completed 2026-06-18T02:11:34+08:00, and prepub integration SUCCESS task 3391854527. It is RUNNING/WAITING in prepub verification task 3391854528. CR newestRevision/current pushed head is 89f6ea8c16cf95678e999d082e3fe94a578d0b6a.",
"prepubFunctionalVerification": "prepub_deploy_and_integration_success_for_login_recommend_default_compat; full_batch_auth_e2e_pending"
},
{
"repo": "lippi-pat-core-wukong-capability",
"localPath": "/Users/xuan/lippi-pat-core-wukong-capability",
"branch": "codex/batch-auth-page-flow",
"commit": "dab26d3474ded776e7e1abb6419e75bdb43e75bf",
"aoneAppId": 312546,
"aoneCrId": 34656143,
"aoneCrStatus": "INTG",
"aoneCrStatusLabel": "发布中",
"aoneBranchRevision": "b38e29e9e9c0f55dc71762c37d261180cb30692b",
"aoneNewestRevision": "dab26d3474ded776e7e1abb6419e75bdb43e75bf",
"prepubPipelineId": 66,
"prepubPipelineInstanceId": 3095206676,
"prepubPackage": "Aone CR 34656143 pipeline 66 instance 3095206676 has code merge SUCCESS tasks 3391854529/3391854530, build+scan SUCCESS tasks 3391854531/3391854532, prepub deploy SUCCESS task 3391854533 completed 2026-06-18T02:10:33+08:00, and prepub integration SUCCESS task 3391854534. It is RUNNING/WAITING in prepub verification task 3391854535. CR newestRevision/current pushed head is dab26d3474ded776e7e1abb6419e75bdb43e75bf.",
"prepubFunctionalVerification": "prepub_deploy_and_integration_success_for_login_recommend_default_compat; full_batch_auth_e2e_pending"
},
{
"repo": "lippi-open-app-dev",
"localPath": "/Users/xuan/lippi-open-app-dev",
"branch": "codex/batch-auth-bff-selected-scopes",
"commit": "df53f856c31be3abee220b738022f861cbf78b93",
"aoneAppId": 154450,
"aoneCrId": 34656145,
"aoneCrStatus": "PREINTG",
"aoneCrStatusLabel": "待发布",
"aoneBranchRevision": "f4222f3b2acba1899446d338c4b3788b8a58b29f",
"aoneNewestRevision": "df53f856c31be3abee220b738022f861cbf78b93",
"prepubPipelineId": 66,
"prepubPipelineInstanceId": 3095182503,
"prepubPackage": "Aone CR 34656145 pipeline 66 instance 3095182503 has code merge/build/prepub deploy/prepub integration SUCCESS and is WAITING in prepub verification task 3391762849. The previous code-merge CONFLICT is no longer active. Deploy orders 155430894/155430896 succeeded at 2026-06-17 21:21-21:32+08:00 for 预发环境 and 新加坡预发; task 3391762848 prepub integration completed SUCCESS at 2026-06-17 21:44:04+08:00. CR newestRevision/current head is df53f856c31be3abee220b738022f861cbf78b93.",
"prepubFunctionalVerification": "prepub_deploy_and_integration_success; selectedScopes_fail_closed_local_tests_passed; full_batch_auth_e2e_pending"
},
{
"repo": "lippi-open-dev-front",
"localPath": "/Users/xuan/lippi-open-dev-front",
"branch": "codex/batch-auth-page-flow",
"commit": "aafa687c3ce23a9292c7890d9af40a18ce07fb2a",
"aoneAppId": null,
"aoneCrId": null,
"prepubPackage": "O2 assets app still does not support pub-env=pre. Latest branch head aafa687c3ce23a9292c7890d9af40a18ce07fb2a is pushed and local npm run build passed with existing bundle-size warnings only. The latest recorded non-production daily assets build/deploy is still task 149432767 for commit f33e349b2c29c7ba139e48fdfbdd70759ce3a4c4, build id 53073038, asset count 203, published to dev.g.alicdn.com/dingding/lippi-open-dev-front/5.219.0/; a new O2/daily package for aafa687c3ce23a9292c7890d9af40a18ce07fb2a is still pending.",
"prepubFunctionalVerification": "frontend_local_build_ok_for_account_subtitle_centering_and_batch_description_fix; latest_daily_cdn_package_pending; full_e2e_pending_server_current_heads",
"o2AppId": 8780,
"o2IterationId": 16804012,
"o2TaskId": 149432767,
"o2FlowId": 114592657,
"o2ReleaseVersion": "5.219.0",
"o2PublishEnv": "daily"
}
],
"requiredEvidence": [
"Every changed repo has a pushed branch or prepub release submission tied to the current change set.",
"Prepub package/build succeeds for CLI, gateway, PAT core, BFF, and frontend.",
"Prepub deployed versions include the selectedScopes frontend-to-BFF-to-PAT core chain.",
"Prepub functional verification covers login recommend, chmod without --yes page flow, chmod with --yes direct flow, selectedScopes subset approval, reject, Diamond-driven low-risk recommendation, high-risk pending, and JSON no-wait pending response.",
"Prepub UI screenshot matches visualDesignTarget.",
"Frontend O2 assets app uses daily as the available non-production channel because prepub is unsupported for assets pub type."
],
"latestPrepubVerification": {
"verifiedAt": "2026-06-16T17:22:12+08:00",
"recommendationPolicy": {
"sourceOfTruth": "prepub Diamond plus product_scope_template DB",
"openWhitelistDataId": "com.dingtalk.pat.opensource-scope-whitelist",
"openWhitelistScopeCount": 173,
"preauthDataId": "com.dingtalk.pat.wukong-preauth-config",
"preauthVersion": "2026-06-16-dws-low-risk-151-preauth-v1",
"recommendedLowRiskScopeCount": 151,
"excludedMediumRiskScopeCount": 22,
"slsReceipt": "2026-06-16 17:19:26 prehost logs: OpenSourceScopeWhitelistConfigManager scopeCount=173; WukongPreAuthConfigManager recommendAllScopes=false scopeCount=151"
},
"dryRun": {
"command": "go run ./cmd/main.go pat chmod --recommend --dry-run --agentCode dingmbw5n9ktkkbbjv3g --format json",
"result": "items=151, selected=43, skipped=108, risk_counts={LOW:151}, skipped_reasons={already granted:108}",
"localReceipt": "/tmp/dws-pat-chmod-recommend-dryrun-after-diamond.json"
},
"loginRecommendApproval": {
"command": "go run ./cmd/main.go auth login --recommend --format json",
"flowId": "a4ef35755fb04c248b0d4319ce73651c",
"userCode": "E9CL-YJCV",
"authorizationUrl": "https://pre-open-dev.dingtalk.com/fe/old?hash=%23%2FpersonalAuthorization%3FflowId%3Da4ef35755fb04c248b0d4319ce73651c%26userCode%3DE9CL-YJCV#/personalAuthorization?flowId=a4ef35755fb04c248b0d4319ce73651c&userCode=E9CL-YJCV",
"pageObservedText": "DingTalk-Workspace请求你的授权; 可授权的权限(已选43/43项); 同意并授权; 授权成功",
"slsReceipt": "DeviceCodeFlowService.grantApprovedScopesBatch approved permanent via batch insert, flowId=a4ef35755fb04c248b0d4319ce73651c, orgId=439446171, uid=2010955235, agentCode=dingmbw5n9ktkkbbjv3g, scopeCount=43"
},
"databaseEvidence": {
"dmsGroup": "lippi_pat_core_product_logic",
"db": "product",
"agentCode": "dingmbw5n9ktkkbbjv3g",
"orgId": 439446171,
"uid": 2010955235,
"lowRiskRecommendedGranted": "151 rows, status=1, grant_scope=3",
"selectedIncrementGranted": "43 rows",
"activeMediumRiskGrants": "18 rows existed as historical grants; they were not part of this recommend plan because dry-run risk_counts had no MEDIUM rows",
"resultFiles": [
"/Users/xuan/dms-alibaba/db-groups/lippi_pat_core_product_logic/sql/quick_product/_results/2026-06-16/172211_product.json",
"/Users/xuan/dms-alibaba/db-groups/lippi_pat_core_product_logic/sql/quick_product/_results/2026-06-16/172212_product.json"
]
},
"currentSmoke": {
"verifiedAt": "2026-06-17T23:10:00+08:00",
"command": "/usr/local/bin/dws auth login --recommend --no-browser --format json --verbose; /Users/xuan/.local/bin/dws auth login --recommend --no-browser --format json --verbose; DINGTALK_DWS_AGENTCODE=dingmbw5n9ktkkbbjv3g dws pat chmod --recommend --dry-run --format json",
"result": "both rebuilt dws binary paths exited 0, printed 推荐权限已全部授权或没有可授权项, and returned token_valid=true without PAT_BATCH_AUTH_SCOPE_REQUIRED; pat chmod recommend dry-run returned success=true, code=OK, allGranted=true, items=151, selectedScopes=0, skippedScopes=151. /usr/local/bin/dws, /Users/xuan/bin/dws, and /Users/xuan/.local/bin/dws were rebuilt from current source and share sha256 e6b6fe37e1a7503a3b83486ce830b025f476b6e77ddcb383a1ed237b92f2b31f",
"serverPrepubState": "gateway instance 3095206675, PAT instance 3095206676, and BFF instance 3095182503 all have code merge/build/prepub deploy/prepub integration SUCCESS and are WAITING in prepub verification"
},
"notes": [
"2026-06-18 compatibility fix: repeated PAT_BATCH_AUTH_SCOPE_REQUIRED was traced to legacy caller-only login recommend requests. Current prepub SLS for auth_login_recommend shows new CLI requests already carry recommend=true/productCodes=[]/scopes=null and PAT core had 0 recent PAT_BATCH_AUTH_SCOPE_REQUIRED hits; nevertheless gateway branch codex/pat-batch-auth-service-gate-20260616 now normalizes pat.batch_plan caller=auth_login_recommend with no scopes/productCodes/recommend to recommend=true, and PAT core branch codex/batch-auth-page-flow applies the same default only when request.recommend is null. Verification: uv run python -m pytest test/test_pat_batch_bridge.py -q => 27 passed; JAVA_HOME=Azul 11 mvn -pl lippi-pat-core-service -am -Dtest=com.dingtalk.pat.manager.PatBatchAuthManagerTest -DfailIfNoTests=false -DfailIfNoSpecifiedTests=false -Dsurefire.failIfNoSpecifiedTests=false test -s /Users/xuan/Downloads/settings.xml => BUILD SUCCESS, Tests run: 24, Failures: 0, Errors: 0. Prepub redeploy evidence: gateway Aone pipeline 66 instance 3095206675 and PAT core instance 3095206676 both reached code merge/build/prepub deploy/prepub integration SUCCESS and are waiting only at manual prepub verification.",
"2026-06-18 CLI interaction fix: auth login post-login authorization now waits for the PAT batch authorization page to complete and then returns; it no longer runs the original TUI/plan/grant function again after APPROVED, so the terminal will not show 授权完成,正在重试... followed by a second 选择要授权的业务域. Verification: env GOCACHE=/tmp/go-cache go test ./internal/app -run 'TestRunDirectPATAuthCheckWaitOnly_ApprovedDoesNotRetry|TestRunDirectPATAuthCheck_ApprovedRetriesCallback|TestAuthLoginPostLoginTUIModeRespectsRecommendAndFormat|TestAuthLoginRecommendSkipsPostLoginTUI' => ok; env GOCACHE=/tmp/go-cache go test ./internal/app ./internal/pat ./internal/errors ./internal/auth ./test/unit => ok. Local default binaries /Users/xuan/bin/dws and /Users/xuan/.local/bin/dws rebuilt from current source with sha256 22c18538db5dd7d5d32557e2183646fd6535824fb8bd9eb4b67251b4ec4dfc75."
]
},
"latestDiagnostics": [
"PAT core Aone compile error at PatAuthCheckService.java:517 was caused by a two-argument tryConsumeOnceTokenFromTair call after the method signature changed to require effective risk level. Current feature and release-merge worktrees use RiskLevelEnum.MEDIUM.getCode() for the high-risk-to-medium DCF bypass path and compile locally.",
"The Maven warning about requested profile lippi-pat-core is an Aone/Maven parameter warning: the root POM has no profile with id lippi-pat-core. It is not the cause of the Java compilation failure and does not justify a POM change in this slice.",
"PAT core API version is explicitly aligned: root property lippi-pat-core-api.version is 1.0.5-SNAPSHOT and lippi-pat-core-api/pom.xml project.version evaluates to 1.0.5-SNAPSHOT. Verification passed with Java 11 Maven help:evaluate and lippi-pat-core-api compile.",
"PAT core root POM now defines lippi-enterprise-soc-api.version as 1.0.30-SNAPSHOT, matching local reference repos /Users/xuan/lippi-pat-core and /Users/xuan/lippi-pat-core-prepub-merge-34465221. Verification passed with Java 11 Maven lippi-pat-core-service compile.",
"PAT core Aone build task 3390400102 failed because release branch commit 3555c3aa resolved lippi-open-app-dev-api as 1.0.103, which lacks PatConnectorQueryService and PatConnectorQueryResult. Feature branch commit 78c1c311e91e2c2d204622b6219b8c1a179b6932 changes lippi-open-app-dev.version to 1.2.0-SNAPSHOT, matching /Users/xuan/lippi-pat-core and release merge worktree. Local Java 11 lippi-pat-core-service compile passed and the 1.2.0-SNAPSHOT jar contains both missing classes.",
"PAT core prepub runtime failure for flowId 8b35d5b6373c4cb9a7a67b339516fff2 was TDDL-4603 ERR_ACCROSS_DB_TRANSACTION. The failing path approved a batch flow by looping single-scope INSERT INTO agent_pat in one transaction, crossing sharding groups. Commit 0b805ff changes permanent/session batch approval and direct batch grant to PatAuthGrantService#grantScopesBatch, which uses AgentPatDAO.batchInsert and PatAuthRecordDAO.batchInsert where applicable, while DeviceCodeFlowService#handleFlowAction runs with Propagation.NOT_SUPPORTED to avoid opening a strict cross-shard transaction around the flow action.",
"PAT core local regression passed on 2026-06-16 with Java 11: mvn -pl lippi-pat-core-service -Dtest=PatAuthGrantServiceBatchTest,PatBatchGrantIdempotencyTest,DeviceCodeFlowServiceTransactionTest,DeviceCodeFlowServiceBatchSelectionTest test -s /Users/xuan/Downloads/settings.xml and full mvn -pl lippi-pat-core-service test -s /Users/xuan/Downloads/settings.xml.",
"PAT core Aone pipeline 66 instance 3094916508 reached SUCCESS for code merge, build, prepub deploy, and prepub integration test; prepub validation remained RUNNING when checked.",
"BFF now depends on com.dingtalk.pat:lippi-pat-core-api:1.0.5-SNAPSHOT and uses HandleFlowActionRequest#setSelectedScopes directly. The old reflection fallback has been removed.",
"BFF local verification passed with Java 11: mvn -pl lippi-open-app-dev-start -am -DskipTests compile -s /Users/xuan/Downloads/settings.xml.",
"BFF latest branch head is df53f856c31be3abee220b738022f861cbf78b93. It rejects malformed HTTP selectedScopes before HSF: missing field remains legacy-compatible and forwards null, but present null/non-array/non-string/blank entries return INVALID_PARAM_TYPE and skip PatAuthService#handleFlowAction. Verification passed with Java 11: mvn -pl lippi-open-app-dev-start -am -Dtest=com.dingtalk.open.appdev.http.DWSPatAuthRpcServiceTest -DfailIfNoTests=false -DfailIfNoSpecifiedTests=false test -s /Users/xuan/Downloads/settings.xml. The first Java 22 attempt failed on old aspectjweaver Zip64/PowerMock compatibility, so Java 11 remains the recorded build runtime.",
"Gateway latest branch head is a0873a6a98b96eaa86a1e8e9f75726a3f8dc16a9. It rejects pat.batch_grant calls that carry plan-only recommend/productCodes fields, normalizes non-empty selected scopes before forwarding to PAT core, and has local verification uv run python -m pytest test/test_pat_batch_bridge.py -q: 26 passed.",
"Frontend latest branch head is 356dcbab5d02c9f0225baabbd80a98b28d6f92b3. It only renders the batch page when the server explicitly marks batchFlow/isBatchFlow/flowType=BATCH, and reject success falls back to FLOW_REJECTED so the terminal page shows 已拒绝授权 instead of 授权失败. Verification: npm run build passed with existing bundle-size warnings.",
"lark-cli parity check on 2026-06-16: lark-cli auth login --help does not list --yes, and lark-cli auth login --yes --no-wait --json exits with Error: unknown flag: --yes. Lark recommended login therefore still requires Device Flow/browser authorization and does not provide a --yes bypass.",
"Non-PAT side verification on 2026-06-16 passed: CLI go test ./internal/app ./internal/pat ./internal/errors, gateway py_compile plus diff check, and frontend npm run build with existing bundle-size warnings only.",
"2026-06-16 23:59+08:00 frontend review follow-up: src/app/personalAuthorization/index.jsx now matches requested batch copy: title 可授权的权限, product group count as N 项, footer link 个人数据授权管理. Commit 065178a7011174c14952c89992022968a8a49a7b pushed to codex/batch-auth-page-flow.",
"Frontend O2 release route confirmed: app lippi-open-dev-front id=8780, iteration 16804012 named pat页面授权, branch codex/batch-auth-page-flow. O2 iteration id 86573 from the provided Dbase URL maps to an old pmod iteration in a1 o2, so 16804012 is the correct O2 release target discovered from app 8780.",
"Frontend O2 non-production task 149432667 succeeded for commit 065178a7011174c14952c89992022968a8a49a7b, flow 114592128, version 5.219.0, pub_env daily. Attempting pub_env pre returned: assets does not support prepub.",
"Independent cross-repo review found no P0/P1 contract break in CLI -> gateway -> BFF -> PAT -> frontend for selectedScopes. The important contract is that gateway pat.batch_grant takes scopes, while CLI/BFF use selectedScopes only at their own API boundaries before converting/passing to PAT.",
"CLI recommend login TUI default-selects all product domains before plan/grant, matching the Lark-like pre-authorization selector requirement. Local verification passed with go test ./internal/pat ./internal/app.",
"Frontend CDN verification after O2 task 149432667: https://dev.g.alicdn.com/dingding/lippi-open-dev-front/5.219.0/bundle.js contains 个人数据授权管理 and 可授权的权限, and no longer contains 应用授权管理 or 可授权的权限(已选.",
"2026-06-17 CLI fix: Bacon review found plain dws auth login --recommend skipped the Lark-like product selector because global --format defaults to json. Commit 9ee8ea552406d1804f062f2f9165a031b1f87ab3 changes auth login recommend selector gating so default json still shows the TUI in an interactive terminal, while explicit --format json and non-interactive shells skip it. Verification: go test ./internal/app ./internal/pat passed.",
"2026-06-17 local default dws binary refreshed: /usr/local/bin/dws -> /Users/xuan/bin/dws was rebuilt from dingtalk-workspace-cli commit 9ee8ea552406d1804f062f2f9165a031b1f87ab3; dws version --format json reports version dev, edition open.",
"2026-06-17 CLI follow-up: commit 70b9f39715566a8306f8d437cc62ad2f12934449 changes interactive dws auth login --recommend to use a human recommend flow when --format is not explicitly set. This prevents the PAT authorization wait path from falling back to machine JSON after the TUI. Default interactive behavior is now: login success summary, all-selected product-domain TUI, server re-plan, complete authorization URL print/open, browser approval polling. Explicit --format json and non-interactive shells remain structured/no-block. Verification: go test ./internal/app ./internal/pat passed, and /usr/local/bin/dws -> /Users/xuan/bin/dws was rebuilt from this commit.",
"2026-06-17 CLI TUI design follow-up: commit 5e1983b3df4a35f2e694972ecfc4207132c79671 aligns the recommend selector with the MGDone terminal target: title 选择要授权的业务域, description 空格选择 回车确认, default-selected all product domains, and product labels rendered as productCode + productName + summary, e.g. approval 审批 - 审批实例,审批模板,审批任务管理. It also tightens interactive detection to require stdin/stdout/stderr all be TTY so piped systems stay in structured mode. Verification passed: go test ./internal/app ./internal/pat ./internal/errors; go test ./test/unit; /usr/local/bin/dws -> /Users/xuan/bin/dws rebuilt from this commit.",
"2026-06-17 CLI --yes follow-up: commit 3ec35e30e828b088a8e9415d76804f56feed6354 fixes dws auth login --recommend --yes to behave like batch auto-confirm: resolveAuthLoginConfig reads inherited --yes, recommend human TUI is skipped, and RunLoginRecommendAuthorizationWithOptions calls pat.batch_grant without startFlow/noWait so no browser authorization page is created. No --yes keeps the previous TUI plus batch authorization page flow. Verification passed: go test ./internal/pat -run TestLoginRecommendAuthorization; go test ./internal/app -run TestAuthLoginRecommendSelectorRespectsExplicitFormat|TestLoginRecommendProductLabelMatchesTUITarget|TestResolveAuthLoginConfigReadsInheritedYes; go test ./internal/app ./internal/pat ./internal/errors; go test ./test/unit; /usr/local/bin/dws -> /Users/xuan/bin/dws rebuilt from this commit.",
"2026-06-17 CLI TUI chain correction: commit 2264743e78f71d3664b21d90e3a6a36f383beed7 changes TUI from a single product selector into the intended terminal usage chain from the MGDone screenshots. Interactive dws auth login --recommend now shows 选择操作 (直接使用CLI / 一键配置智能体应用 / 手动输入应用凭证), then 选择授权范围 (推荐授权 / 全部授权), then the default-all-selected 选择要授权的业务域 product-domain multiselect. 推荐授权 keeps recommend=true; 全部授权 replans with recommend=false for selected product domains. Complete runtime AppKey/AppSecret overrides now skip MCP clientId fetch so manual credentials are real rather than decorative. Verification passed: go test ./internal/pat -run TestLoginRecommendAuthorization; go test ./internal/app -run TestAuthLoginRecommendSelectorRespectsExplicitFormat|TestLoginRecommendProductLabelMatchesTUITarget|TestResolveAuthLoginConfigReadsInheritedYes; go test ./internal/auth -run TestDeviceFlow|TestOAuth|TestCredential|TestReset|TestAppConfig|TestClient; go test ./internal/app ./internal/pat ./internal/errors ./internal/auth; go test ./test/unit; /usr/local/bin/dws -> /Users/xuan/bin/dws rebuilt from this commit.",
"2026-06-17 CLI TUI sequence correction: commit 537719c677a9c79d8c45115c7bbbb29fff8dfe1f moves the terminal authorization guide into runRecommend, so dws auth login --recommend first completes DingTalk login, organization selection, and token persistence, then starts 选择操作 -> 选择授权范围 -> default-all-selected 选择要授权的业务域. A new app-layer regression test asserts the token is already readable before any TUI selector runs. Verification passed: go test ./internal/app -run TestAuthLoginRecommendTUIRunsAfterLoginTokenSaved|TestAuthLoginRecommendSelectorRespectsExplicitFormat|TestLoginRecommendProductLabelMatchesTUITarget|TestResolveAuthLoginConfigReadsInheritedYes; go test ./internal/pat -run TestLoginRecommendAuthorization; go test ./internal/app ./internal/pat ./internal/errors ./internal/auth; go test ./test/unit; go build -o /Users/xuan/bin/dws ./cmd/main.go; /usr/local/bin/dws version --format json reports version dev, edition open.",
"2026-06-17 CLI TUI condition correction: dws auth login --recommend no longer shows 选择操作, 授权范围选择, or product-domain TUI. It directly calls pat.batch_plan recommend=true and grants the server-selected recommended scopes. The post-login TUI now belongs only to interactive dws auth login without --recommend, after login/org selection/token persistence. Verification target: TestAuthLoginRecommendSkipsPostLoginTUI and TestAuthLoginWithoutRecommendTUIRunsAfterLoginTokenSaved.",
"2026-06-17 CLI all-scope TUI bugfix: repeated PAT_BATCH_AUTH_SCOPE_REQUIRED errors were caused by the no --recommend TUI path selecting 全部授权 before product selection, which sent an initial pat.batch_plan with recommend=false and empty productCodes. The fix makes the first TUI discovery plan always use recommend=true when no productCodes are known, then applies recommend=false only on the second plan after selected productCodes are available. Regression coverage: TestLoginRecommendAuthorizationAllScopeModePlansAllProductScopes and TestAuthLoginWithoutRecommendTUIRunsAfterLoginTokenSaved.",
"2026-06-17 CLI current-head verification: commit dcf132a7e3223288a7fc82882560ab642fb63899 is pushed to origin/codex/dws-auth-login-recommend and /usr/local/bin/dws points to /Users/xuan/bin/dws rebuilt from that source. Verification passed: go test ./internal/app ./internal/pat ./internal/errors ./internal/auth ./test/unit; /usr/local/bin/dws auth login --recommend --format json completed without PAT_BATCH_AUTH_SCOPE_REQUIRED and printed 推荐权限已全部授权或没有可授权项 for the current account. The earlier diagnostics that described --recommend showing a TUI are superseded; the final rule is --recommend direct plan/grant, and the terminal TUI is only for interactive dws auth login without --recommend.",
"2026-06-17 MGDone MCP receipt: Cursor mastergo-magic-mcp server was started from /Users/xuan/.cursor/mcp.json with token redacted. tools/list exposed mcp__getDesignSections/mcp__getDsl/mcp__getDesignSvgs/mcp__getDesignTexts. mcp__getDesignSections for fileId=187681481694834, layerId=74:36608 returned design-sections API not available; fallback mcp__getDsl with the same page_id returned an empty nodes/components DSL. Therefore current terminal implementation uses the visible MGDone screenshot target for TUI text/label/control behavior and records that a true layer_id/source_layer_id is still needed for pixel-level DSL extraction.",
"2026-06-17 frontend account-row fix: commit f33e349b2c29c7ba139e48fdfbdd70759ce3a4c4 makes the authorization account row prefer userAvatar/userName before orgLogo/orgName to avoid mixed org icon + user name rendering. Verification: npm run build passed with existing bundle-size warnings only.",
"Frontend O2 non-production task 149432767 succeeded for commit f33e349b2c29c7ba139e48fdfbdd70759ce3a4c4, flow 114592657, version 5.219.0, pub_env daily, build id 53073038, assetCount 203. CDN bundle contains userAvatar|| and no longer contains the old orgLogo|| account-row priority; old title 可授权的权限(已选 remains absent.",
"2026-06-17 server release audit: gateway current head a0873a6 and PAT current head 79a8fa5 are not proven deployed because their successful prepub deploy receipts predate the current commits. BFF current head 9ac576c is also not proven deployed by deploy-order revision: latest pipeline 3095011879 deployed, but deploy-order 155348765 records revision f4222f3b2acba1899446d338c4b3788b8a58b29f and integration-test task 3390965943 is FAIL. Gateway deploy-order 155284562 records revision ffaa951f13a107a08fb04c6246ba99bf7d583477; PAT deploy-order 155318893 records revision b38e29e9e9c0f55dc71762c37d261180cb30692b. Full prepub e2e remains blocked on current-head redeploy plus BFF integration-test resolution or accepted exception.",
"2026-06-17 15:46+08:00 Aone recheck: gateway pipeline 66 instance 3095046153 has deploy/integration SUCCESS but deploy orders still show deployed branchRevision ffaa951, one commit behind CR newestRevision/current head a0873a6; PAT pipeline 66 instance 3095097702 has deploy/integration SUCCESS but deploy order 155387876 still shows deployed branchRevision b38e29e, 12 commits behind CR newestRevision/current head 79a8fa5; BFF pipeline 66 instance 3095097708 is WAITING at code merge task 3391355335 with build/deploy INIT, and latest successful deployed revision remains f4222f3, 199 commits behind current head 9ac576c. Therefore PRD acceptance remains not passed until current revisions are demonstrably active and functional verification is rerun.",
"2026-06-17 16:06+08:00 Aone task drill-down: BFF task 3391355335 progress says 合并代码存在冲突,请查看冲突并解决. componentData.status=CONFLICT and nextSteps instruct resolving change 34571941 from feature/robot-openapi-pop revision db24ed483eaa89a59fd34f763cfb2ee4adf45c06 into release branch releases/20260616153930479_r_release_154450_lippi-open-app-dev-code, then rerunning a1 app pipeline. Gateway verification task 3391110450 is CANCEL; PAT verification task 3391355313 remains WAITING for CR34656143.",
"2026-06-17 20:22+08:00 BFF contract hardening: commit df53f856c31be3abee220b738022f861cbf78b93 was pushed to codex/batch-auth-bff-selected-scopes. DWSPatAuthRpcService now fail-closes malformed HTTP selectedScopes so bad input cannot be converted into PAT core's legacy null=approve-all DTO semantics. Local Java 11 regression passed with 7 tests in DWSPatAuthRpcServiceTest.",
"2026-06-17 21:45+08:00 prepub release recheck: gateway Aone pipeline 66 instance 3095163678, PAT instance 3095097702, and latest BFF instance 3095182503 all reached code merge, build, prepub deploy, and prepub integration SUCCESS. Latest deploy orders: gateway 155420965/155420967, PAT 155387876, BFF 155430894/155430896. All three remain RUNNING/WAITING at the prepub verification stage, so release gate is not complete. Current CLI smoke /usr/local/bin/dws auth login --recommend --no-browser --format json exited 0 and returned 推荐权限已全部授权或没有可授权项 without PAT_BATCH_AUTH_SCOPE_REQUIRED.",
"2026-06-17 22:17+08:00 CLI empty-plan hardening: commit d09fca4b9b29c9a85746894956d469a6dfda7ae7 adds a local guard in planLoginRecommend so recommend=false with empty productCodes fails before any pat.batch_plan call. This prevents all-scope/TUI edge paths from reaching PAT as an empty plan and surfacing PAT_BATCH_AUTH_SCOPE_REQUIRED. Regression coverage: TestLoginRecommendAuthorizationAllScopeWithoutProductsFailsBeforePlan plus go test ./internal/pat ./internal/app. Local default binaries were rebuilt and unified: /usr/local/bin/dws, /Users/xuan/bin/dws, and /Users/xuan/.local/bin/dws all have sha256 daf26190d6a95f8fe3c9d2f1a513c6bdf4bdb8791da0f150ddc645b609b8945c. Smoke passed for both dws auth login --recommend paths and dws pat chmod --recommend --dry-run with 151 all-granted recommended items.",
"2026-06-17 23:10+08:00 repeated PAT_BATCH_AUTH_SCOPE_REQUIRED report rechecked. Current local default dws paths were rebuilt again from branch codex/dws-auth-login-recommend, now sharing sha256 e6b6fe37e1a7503a3b83486ce830b025f476b6e77ddcb383a1ed237b92f2b31f. /usr/local/bin/dws auth login --recommend --no-browser --format json --verbose and /Users/xuan/.local/bin/dws auth login --recommend --no-browser --format json --verbose both exited 0 and returned 推荐权限已全部授权或没有可授权项. SLS receipt: lippi-pat-core/lippi-pat-core-logging had 0 PAT_BATCH_AUTH_SCOPE_REQUIRED or requires-scopes hits in the recent window; lippi-open-mcpserver-gw-log prepub auth_login_recommend plan entries carried caller=auth_login_recommend, productCodes=[], recommend=true, scopes=null. A separate production mcp-gw direct tools/call with arguments={} had no trusted identity and did not enter PAT-core, so it is not the current dws auth login --recommend path.",
"2026-06-18 03:20+08:00 Git remote sync audit: lippi-open-mcpserver-gw commit 89f6ea8c16cf95678e999d082e3fe94a578d0b6a and lippi-pat-core-wukong-capability commit dab26d3474ded776e7e1abb6419e75bdb43e75bf are present on their GitLab HTTPS branches. SSH remote push/fetch fails with Permission denied (publickey), so local origin tracking refs were refreshed via HTTPS fetch; both branches now match origin and only unrelated untracked local files remain.",
"2026-06-18 03:23+08:00 frontend source-of-truth audit: the batch product-row description was previously derived from DeviceCodeFlowDetailResult.ScopeInfo.operationSummary. BFF /dingtalk-workspace-cli/oauth/device/detail only forwards PAT queryFlowDetail, and PAT DeviceCodeFlowService#resolveOperationSummary falls back to product_scope_template.description when flowData.operationSummary is absent; therefore text such as 按DWS v0.2.55授权项清单同步默认策略:sheet delete-dimension comes from PAT template description, not frontend hardcoding. Frontend commit aafa687c3ce23a9292c7890d9af40a18ce07fb2a changes grouped rows to prefer productSummary/productDescription/productDesc and otherwise fall back to the first two scope display names, keeps scope-level operationSummary out of the product row, centers 请求以下钉钉账号进行授权, and makes product-row descriptions single-line ellipsis with stable row height. Verification: git diff --check passed and npm run build passed with existing bundle-size warnings only."
]
},
"serviceContract": {
"pat.batch_plan": {
"request": {
"scopes": "optional string[]",
"productCodes": "optional string[]",
"recommend": "boolean",
"grantType": "once|session|permanent",
"dryRun": "boolean",
"caller": "auth_login_recommend|batch_chmod_interactive|..."
},
"response": {
"selectedScopes": "server-selected grantable scopes",
"skippedScopes": "not grantable or filtered scopes",
"pendingScopes": "high-risk scopes requiring separate confirmation",
"warnings": "recommendation filter and partial selection warnings"
},
"compatibility": {
"loginRecommendCallerDefault": "If an older caller sends caller=auth_login_recommend without scopes/productCodes/recommend, gateway and PAT core default the plan to recommend=true. Explicit recommend=false with empty productCodes is still invalid so all-scope mode cannot silently downgrade into recommend mode."
}
},
"pat.batch_grant": {
"request": {
"scopes": "required string[], must be selectedScopes from plan",
"grantType": "once|session|permanent",
"startFlow": "boolean; true opens authorization page",
"noWait": "boolean; true returns URL immediately",
"clientRequestId": "idempotency key",
"caller": "auth_login_recommend|batch_chmod_interactive|..."
},
"pendingResponse": {
"success": false,
"code": "PAT_BATCH_AUTH_PENDING",
"data": {
"flowId": "batch device flow id",
"userCode": "device user code",
"uri": "opaque authorization URL",
"authUrl": "same URL for compatibility",
"pollIntervalSeconds": 3,
"expiresInSeconds": "PatSwitch.deviceCodeFlowTtlSeconds"
}
}
},
"deviceFlowDetail": {
"route": "personalAuthorization",
"fields": [
"agentCode",
"appName",
"appIcon",
"userName",
"userAvatar",
"status",
"batchFlow",
"defaultGrantType",
"scopes[]"
],
"scopeFields": [
"scope",
"displayName",
"productCode",
"productName",
"riskLevel",
"effectiveRiskLevel",
"riskDesc",
"operationSummary"
]
},
"handleFlowAction": {
"request": {
"flowId": "required string",
"userCode": "required string",
"action": "approve|reject",
"grantType": "optional once|session|permanent; batch page omits it so PAT core uses defaultGrantType from the flow",
"selectedScopes": "required for the new batch page when action=approve; must be a non-empty subset of flow.scopes"
},
"compatibility": {
"selectedScopesMissing": "legacy clients that omit selectedScopes approve all flow-stored scopes through PAT core's DTO null compatibility",
"selectedScopesPresentNullOrMalformed": "BFF returns INVALID_PARAM_TYPE and does not call PAT core",
"selectedScopesEmpty": "INVALID_PARAMETER",
"selectedScopesOutsideFlow": "INVALID_PARAMETER"
},
"response": {
"status": "APPROVED|REJECTED",
"approvedScopes": "scopes written by this approve action",
"rejectedScopes": "flow scopes not approved by this action"
},
"errorBehavior": {
"approveStorageFailure": "PAT_BATCH_PARTIAL_FAILURE; flow remains PENDING and the page can retry. Once tokens written by the current flow are cleaned by flowId ownership; permanent/session grants rely on transaction rollback and grant idempotency."
}
}
},
"frontendRequirements": [
"Reuse personalAuthorization page and API detail/action callbacks.",
"When scopes length is greater than one, render a grouped batch authorization surface.",
"Group by productCode/productName with product-level checkbox and expandable scope details.",
"Default checked state is all safe selected scopes.",
"Users can uncheck a product group or individual scopes; approving with zero selected scopes is disabled.",
"Approve must send selectedScopes matching the current checked scope list.",
"Reject rejects the whole flow.",
"Do not expose orgId or uid as trusted client input."
],
"visualDesignTarget": {
"sourceImage": "/var/folders/hz/2sm0ql493cv6jngtjk7xsby00000gp/T/codex-clipboard-2078e5f6-b389-4435-8ea5-0f0a94363462.png",
"mgdoneReference": "https://mgdone.alibaba-inc.com/file/187681481694834?file=187681481694834&page_id=74%3A36608&shareId=3b3db511-38e1-4f3d-a859-ab891ed85617",
"page": "A white authorization card centered on a light #f5f6fa page, with the footer links below the card.",
"card": "Single white 480x680 desktop card with rgba(131,137,143,0.16) border, no shadow, and 12px radius.",
"header": "Top centered dynamic app icon only, 56x56 with 8px radius. Do not render the right-side target app icon or any blue/red debug frame. Title is DingtalkWorkSpace, subtitle is 请求以下钉钉账号进行授权.",
"accountBlock": "Light #fafafa rounded 424x60 account row below the header, with real org/user avatar at left and the current account name next to it.",
"permissionBlock": "Light #fafafa rounded 424x300 permission panel titled 可授权的权限. Product rows use a blue checked checkbox, bold product name, gray count such as 12 项, gray description text, and a right chevron for expandable details.",
"selectionBehavior": "All recommended groups are checked by default. Product checkbox toggles the entire group; expanding a product reveals individual scope checkboxes.",
"manageTip": "Under the permission panel, show the existing 个人数据授权管理 link text for later review or revoke.",
"buttons": "Bottom two-button layout: left outlined white 拒绝 button, right primary blue 同意并授权 button, same height and rounded pill style.",
"mobile": "On narrow screens the same hierarchy must remain visible without text overlap; buttons share the available width."
},
"terminalTuiTarget": {
"sourceImages": [
"/var/folders/hz/2sm0ql493cv6jngtjk7xsby00000gp/T/codex-clipboard-82ad41c5-7e1c-46b8-938c-ae31945d61de.png",
"/var/folders/hz/2sm0ql493cv6jngtjk7xsby00000gp/T/codex-clipboard-18bbc325-ced5-4dfe-855e-514755d4e01f.png",
"/var/folders/hz/2sm0ql493cv6jngtjk7xsby00000gp/T/codex-clipboard-16c11a9e-7ae7-4703-aa66-4251f7b59f16.png",
"/var/folders/hz/2sm0ql493cv6jngtjk7xsby00000gp/T/codex-clipboard-5aff04a6-9a45-4ba5-8741-b7abcd4f2303.png"
],
"usageGuide": "Interactive dws auth login without --recommend starts the terminal authorization guide only after OAuth/device login, DingTalk organization selection, login summary, and token persistence are complete. dws auth login --recommend skips this TUI entirely and uses the server recommended set. The first guide screen for the non-recommend TUI is 使用引导 / 选择操作 with options 直接使用CLI, 一键配置智能体应用, 手动输入应用凭证. 直接使用CLI continues directly to authorization setup; manual credentials collect AppKey/AppSecret for subsequent runtime credential use and do not replace the already selected login organization.",
"authorizationScopeSelector": "After the usage guide, the TUI presents 授权范围选择 with 推荐授权 and 全部授权. 推荐授权 is the default safe path and calls pat.batch_plan with recommend=true. 全部授权 replans the selected product domains with recommend=false so PAT core/server risk handling decides pending/grant behavior.",
"loginRecommendSelector": "After the login is already complete and the usage/scope guides have run, interactive dws auth login without --recommend presents 选择要授权的业务域 with all product domains selected by default. The --recommend flag does not show this selector.",
"rowFormat": "Product rows follow the MGDone terminal target: selected checkbox, left-aligned product code, Chinese product name, and short operation summary separated by a plain hyphen, such as approval 审批 - 审批实例,审批模板,审批任务管理.",
"controls": "TUI must support space toggle, up/down navigation, slash filter, enter confirm, and ctrl+a select all through the underlying selector component. Description text is 空格选择 回车确认 while the component renders the detailed key hints.",
"nextStep": "Without --yes, --recommend directly prints/opens the complete encoded authorization URL returned by the server for the recommended scope set. In the non-recommend TUI path, the CLI prints/opens that URL after product confirmation. With --yes, the CLI skips TUI and web authorization page and directly grants the service-selected safe scopes when a direct-grant path is available."
},
"securityRules": [
"Gateway derives orgId and uid from trusted token/header only.",
"Gateway allowlist must include openclaw and dws-cli for batch grant callers that are intended to write.",
"PAT core consumes the Diamond recommendation set for recommend=true and caller=auth_login_recommend; prepub Diamond currently recommends 151 low-risk scopes and excludes the 22 medium-risk scopes.",
"PAT core must use flow-stored scopes as the allowlist and reject any selectedScopes value outside the flow.",
"PAT core must only clear pending keys owned by the current flow and leave the flow pending if approve write fails after precheck, so the same authorization page can retry safely.",
"Critical approve/reject storage writes must fail closed with PAT_BATCH_PARTIAL_FAILURE instead of reporting success on partial persistence.",
"Batch flow approval must be idempotent; repeated approval or retry must not duplicate grants."
],
"acceptanceCriteria": [
"Prepub package/build succeeds for every changed repo: dingtalk-workspace-cli, lippi-open-mcpserver-gw, lippi-pat-core-wukong-capability, lippi-open-app-dev, and lippi-open-dev-front.",
"Prepub deployed versions include the current branch commits for CLI, gateway, PAT core, BFF, and frontend.",
"On prepub, dws auth login --recommend opens the batch authorization URL after successful login without showing terminal product-domain selection.",
"On prepub, interactive dws auth login without --recommend first completes DingTalk login and organization selection, then displays the terminal authorization chain: 选择操作, 授权范围选择, and default-all-selected product-domain TUI before opening the authorization URL.",
"On prepub, dws auth login --recommend --yes does not open the authorization page and grants the service-selected recommended scopes directly.",
"On prepub, dws pat chmod --recommend --product calendar without --yes opens the authorization URL.",
"On prepub, dws pat chmod --recommend --product calendar --yes preserves the existing direct grant behavior.",
"On prepub, a recommended config containing a delete/recall/remove/destroy/drop scope returns warnings/skipped scopes and never grants that scope.",
"On prepub, approving a batch flow grants only selectedScopes and rejects scopes outside the flow.",
"On prepub, rejecting a batch flow writes no new grants.",
"On prepub, JSON mode returns structured PAT_BATCH_AUTH_PENDING with uri/openBrowser fields and does not block.",
"On prepub, the authorization page visual result matches visualDesignTarget and the provided screenshot style."
],
"reviewPlan": {
"implementationCommander": "Check end-to-end CLI, gateway, PAT core integration contracts.",
"aiNativeUiArchitect": "Requested by goal but no local skill was available; use Product Design and existing frontend constraints as fallback.",
"qinzePuaReviewer": "Review security, idempotency, tests, and failure modes.",
"muskChiefOperator": "Review the product flow for speed, minimum surface area, and user clarity.",
"computerUse": "Verify prepub/front-end page only after frontend repo and build credentials are available."
},
"updatedAt": "2026-06-18T01:05:00+08:00"
}