The leaf fallback chain read only string flags, so LeafInt/LeafInt64
flags could never satisfy Required via alias or env, alias values for
integer flags were silently dropped, and a registered Default shadowed
alias/env values. Resolution order is now explicit flag > alias > env >
Default > ArgDefault, aliases register with the primary flag's Kind, and
unparsable integer env values fail loudly.
Plain Required now validates the effective value (primary flag -> aliases
-> env) instead of only the primary flag, matching the declared fallback
semantics; whitespace-only values under Trim count as missing. Extracted
cmdutil.MissingRequiredFlagsError to keep the unified error format.
ResolveMeta copies Catalog aliases into CommandIdentity and registers each
alias path against the same metadata (primary cli_path wins on collision),
so compat paths like 'report list' resolve instead of returning ok=false.
Publishes all 210 public built-in shortcuts as reviewed Agent-visible
leaf tools across 16 product groups, with stable canonical identities,
executable +shortcut CLI paths, parameter and cross-parameter
constraints, selection guidance, interface metadata, and runtime-aligned
safety/confirmation semantics. Catalog grows from 603 to 813 tools.
- minutes: drop the minutesId/minutes_id candidate from the taskUuid mapping.
minutesId is the minutes document id, a different identifier from the
recording taskUuid that +record-pause/resume/stop consume via --id, so
substituting it would feed record control a wrong id. The backend list
already returns taskUuid; the guard test now asserts taskUuid/task_uuid.
- Rewrite the guard-test failure messages and fixture data in English to match
the repository convention (only the two assertions that match the
production Chinese validation string are kept).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Several read shortcuts returned an empty list with exit 0 and no error
envelope even though the underlying MCP tool returned data, so agents misread
"no data" and made wrong decisions.
Root causes:
- Container key mismatch: the resolver probed the wrong key —
processCodeList / values / wikiSpaces / itemList / groupList / recentItems /
emailAccounts / deptUserList / labelUserList / roles / report_list, plus
get_org_labels grouped labels[] needing a descend.
- Item fields nested under a VO wrapper, not unwrapped: shiftVO / entityVO /
userInfo.
- Param exceeded a backend limit: todo +created-todos sent pageSize=50 while
the backend silently returns empty for pageSize>20; now uses the shared pager
(pageSize=20).
Affected: contact/oa/wiki/drive/minutes/calendar/attendance/chat/report/smart
resolvers. Every fix ships a guard test that feeds the real backend response
shape (and, for minutes, both the taskUuid and minutesId item shapes) and
asserts the projection is non-empty with a usable id.
scripts/shortcut_real_result.py now compares the upper (projection) output
against the lower (raw backend) layer, and record_real_shortcut_run.py captures
the lower layer in memory (persisting only derived counts, never raw PII) so an
exit-0 empty projection over a non-empty backend is scored as
projection-data-loss instead of real-ok. The Python self-test runs in CI via
test/scripts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>