feat(lint): validate app.defaultAgent value against platform agent roster (#6041) - #7272
Conversation
…ster (#6041) validate-ai-agent-authoring previously scanned only stack.agents. Add the value half: app.defaultAgent outside PLATFORM_AGENT_NAMES (canonical + legacy aliases, reused not duplicated) now emits a warning finding naming the offending value and the allowed roster. Warning tier per maintainer ruling on #6041 (2026-08-07, reaffirmed 2026-08-09, option A) -- the failure mode is a silent runtime fallback, not a crash; schema stays a plain SnakeCaseIdentifierSchema (narrowing to an enum was explicitly rejected as a breaking change). Existing-metadata hit count measured before landing per the ruling's sequencing requirement: 0 (only real in-repo assignment is studio.app.ts's defaultAgent: 'metadata_assistant', an in-roster legacy alias). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 2 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also reference the affected code. These are read-only:
|
|
PM 验收:ACCEPT。 门禁按名点名复读(head 逐条对照裁决与派单约束:
合入后本单收卡、#6041 清 Generated by Claude Code |
Fixes #6041
What changed
validate-ai-agent-authoringgains the value half: it already scannedstack.agentsfor withdrawn agent declarations (ADR-0063 §2), but never looked atapp.defaultAgent's value. Because the Zod type is a plainSnakeCaseIdentifierSchema, any snake_case string parses, builds, and passesos:check— while the runtime only resolves the platform agent roster (ask/buildand legacy aliasesdata_chat/metadata_assistant, ADR-0063 §2) and silently falls back to the platform default for anything else. #5985 measured the blind spot directly: replaying the bad exampledefaultAgent: 'sales_copilot'leftcheck:skill-examplesat 208 green, EXIT=0.New logic in
validateAiAgentAuthoring: for everystack.apps[]entry whosedefaultAgentis a non-empty string not present in the existingPLATFORM_AGENT_NAMESset (reused, not duplicated), emit a warning finding (rule: 'default-agent-outside-roster') naming the offending value and the allowed roster. Warning tier per the maintainer's ruling (2026-08-07, reaffirmed 2026-08-09, option A): the failure mode is a silent runtime fallback, not a crash, and the schema itself is intentionally left alone (SnakeCaseIdentifierSchemastays — narrowing to an enum was explicitly rejected as a breaking authoring change ADR-0063 already walked back once).Sequencing requirement (2026-08-09 ruling, verbatim constraint)
Per the ruling, the existing-metadata hit count was measured before landing:
defaultAgent(all extensions, excludingnode_modules/dist/.turbo), narrowed to actual value assignments (defaultAgent: '<value>').packages/platform-objects/src/apps/studio.app.ts—defaultAgent: 'metadata_assistant'(a legal legacy platform alias).@objectstack/platform-objectsand running the new check programmatically against every exported platform app (account,setup,studio,system_overview) — 0 findings.apps/app-crm,apps/app-showcase,apps/app-todo, and theskills/corpus were also swept; the only other literal match is a commented-out doc example inskills/objectstack-ui/SKILL.md(// defaultAgent: 'build'), itself an in-roster value.Hit count: 0. The "does not punish existing metadata" premise of the warning tier is verified, not assumed — consistent with the expectation that PR #6030 already fixed the one known bad corpus instance.
Tests
Anti-vacuous coverage added to
packages/lint/src/validate-ai-agent-authoring.test.ts:sales_copilot) plants a finding and the test asserts the exactrule/severity/where/path, plus that the message names both the offending value and the full allowed roster.ask,build) and every legacy alias (data_chat,metadata_assistant) is asserted to produce zero findings (reverse case).defaultAgentstays silent.apps[n].defaultAgentpaths, alongside the pre-existingagents[]limb.Notes
packages/lint/src/index.ts: addedDEFAULT_AGENT_OUTSIDE_ROSTERto the existing barrel re-export block forvalidate-ai-agent-authoring.js(required by this repo's ownrule-id-barrel-exports.test.tsgate — every declared rule id constant must be reachable from a published barrel). This is not a registry/wiring change: the rule (validateAiAgentAuthoring) was already registered inreference-integrity-suite.ts; only the new constant's export needed adding.SnakeCaseIdentifierSchema,authoring-rules.ts, orvalidate-flow-trigger-readiness.*(parallel-safety per dispatch note).Changeset
Real changeset added (
@objectstack/lint: minor) — a functional addition to a published package.Verification
Generated by Claude Code