Skip to content

Commit 8d86f8d

Browse files
os-zhuangclaude
andauthored
feat(spec): 可作者化 key 的默认值进入门禁 —— authorable-defaults 指纹比对 (#4666) (#6360)
* feat(spec): 可作者化 key 的默认值进入门禁 —— authorable-defaults 指纹比对 (#4666) `authorable-surface/` 只比对 key 的集合,同一个 key 的 `.default()` 变了对它 完全不可见 —— 而默认值决定「作者没写这个 key 时会发生什么」,翻转它会**静默** 改变所有已部署元数据的行为。#4661 实测:把 `maxRetries` 默认值改一个字符, `check:authorable-surface` 全绿。 新增 `packages/spec/authorable-defaults/`(按 category 分片,与 authorable-surface 同构)记录每个有默认值的可作者化 key 的规范化指纹;比对基线优先取 origin/main merge base(本 commit 改不动的锚点),其次取树内已提交的记录。已存在 key 的默认值 发生 变更 / 新增 / 删除 一律红,除非在 `DEFAULT_CHANGES_BY_MAJOR` 显式声明。 ⛔ 约束(`.min()` / `.max()`)**不**纳入指纹 —— 维护者对 #4666 的裁决(方向 B): 约束收紧是**硬拒**,响亮可诊断;只有默认值翻转是静默的。该排除是结构性的:指纹 只读发出的 JSON Schema 的 `default` 一个字段。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5 * test(spec): check-mode 沙箱补种 authorable-defaults/ 记录 四个沙箱(顶层 + 三个 box)此前只种 authorable-surface/。默认值门禁每次调用 都会跑,缺少记录时 `--check` 报「产物缺失」,六条 fixture 因此在它们真正要测的 删除 / 改名判定之前就红了。补种后沙箱重新是真实树的缩影。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5 * chore(spec): rebase 后重生成 authorable-defaults 记录 `ui/ElementRecordPickerProps:multiple` 在 #6281(SDUI props enforce-or-remove) 中被 `retiredKey()` 墓碑化,默认值随之消失。门禁按设计对此保持沉默 —— 墓碑属于 check (b) 的 RETIRED_KEYS_BY_MAJOR 通道,在这里再要一次声明就是同一次退役被记两遍。 记录相应少一行。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 20931d1 commit 8d86f8d

22 files changed

Lines changed: 2585 additions & 9 deletions

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
packages/spec/spec-changes.json merge=os-regen
4747
packages/spec/authorable-surface/** merge=os-regen
4848
packages/spec/authorable-surface.base.json merge=os-regen
49+
packages/spec/authorable-defaults/** merge=os-regen
4950
packages/spec/json-schema.manifest/** merge=os-regen
5051
packages/spec/api-surface/** merge=os-regen
5152
packages/spec/api-surface-signatures.json merge=os-regen
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"description": "Ratchet of the DEFAULT VALUE of every authorable key in one category that has one (#4666) — what a metadata author gets when they omit the key, which for AI-authored metadata is most of the time. Sharded by category like authorable-surface/; the gate reads the whole authorable-defaults/ directory as ONE set. Each line is \"<def>:<key> = <canonical JSON>\". Additions (a NEW key that ships with a default) are auto-recorded — commit the change. CHANGING, ADDING or REMOVING the default of a key that already existed is NOT auto-recorded: it silently alters the behaviour of already-deployed metadata, so it fails check:authorable-surface until it is declared in DEFAULT_CHANGES_BY_MAJOR (scripts/lib/default-changes.ts). Constraints are deliberately NOT recorded here — a tightened bound REJECTS a document loudly, which is a different and self-announcing class (maintainer ruling on #4666, direction B). See #4666, #4661.",
3+
"category": "ai",
4+
"defaults": [
5+
"ai/AIModelConfig:provider = \"openai\"",
6+
"ai/AIModelConfig:temperature = 0.7",
7+
"ai/Agent:active = true",
8+
"ai/Agent:surface = \"ask\"",
9+
"ai/BlueprintNavItem:type = \"object\"",
10+
"ai/BlueprintView:type = \"list\"",
11+
"ai/CodeContent:language = \"text\"",
12+
"ai/ConversationAnalytics:pruningEvents = 0",
13+
"ai/ConversationAnalytics:summarizationEvents = 0",
14+
"ai/ConversationAnalytics:tokensSavedByPruning = 0",
15+
"ai/ConversationAnalytics:tokensSavedBySummarization = 0",
16+
"ai/ConversationMessage:pinned = false",
17+
"ai/ConversationSession:messages = []",
18+
"ai/ConversationSession:status = \"active\"",
19+
"ai/FileKnowledgeSource:mimeTypes = []",
20+
"ai/ImageContent:detail = \"auto\"",
21+
"ai/KnowledgeDocument:metadata = {}",
22+
"ai/KnowledgeHit:metadata = {}",
23+
"ai/KnowledgeRefreshPolicy:onRecordChange = true",
24+
"ai/KnowledgeSource:adapterConfig = {}",
25+
"ai/KnowledgeSource:aiExposed = true",
26+
"ai/KnowledgeSource:refresh = {}",
27+
"ai/MCPServerRef:active = true",
28+
"ai/MCPToolBinding:approval = \"never\"",
29+
"ai/ModelCapability:codeGeneration = false",
30+
"ai/ModelCapability:functionCalling = false",
31+
"ai/ModelCapability:imageGeneration = false",
32+
"ai/ModelCapability:imageUnderstanding = false",
33+
"ai/ModelCapability:reasoning = false",
34+
"ai/ModelCapability:textEmbedding = false",
35+
"ai/ModelCapability:textGeneration = true",
36+
"ai/ModelConfig:deprecated = false",
37+
"ai/ModelPricing:currency = \"USD\"",
38+
"ai/ModelRegistry:enableAutoFallback = true",
39+
"ai/ModelRegistryEntry:priority = 0",
40+
"ai/ModelRegistryEntry:status = \"active\"",
41+
"ai/ModelSelectionCriteria:excludeDeprecated = true",
42+
"ai/ObjectKnowledgeSource:metadataFields = []",
43+
"ai/PromptTemplate:version = \"1.0.0\"",
44+
"ai/PromptVariable:required = false",
45+
"ai/PromptVariable:type = \"string\"",
46+
"ai/Skill:active = true",
47+
"ai/Skill:surface = \"ask\"",
48+
"ai/SolutionBlueprint:assumptions = []",
49+
"ai/StructuredOutputConfig:maxRetries = 3",
50+
"ai/StructuredOutputConfig:retryOnValidationFailure = true",
51+
"ai/StructuredOutputConfig:strict = false",
52+
"ai/TokenBudgetConfig:bufferPercentage = 0.1",
53+
"ai/TokenBudgetConfig:enableSummarization = false",
54+
"ai/TokenBudgetConfig:reserveTokens = 500",
55+
"ai/TokenBudgetConfig:strategy = \"sliding_window\"",
56+
"ai/TokenBudgetConfig:warnThreshold = 0.8",
57+
"ai/TokenUsageStats:budgetUsed = 0",
58+
"ai/TokenUsageStats:completionTokens = 0",
59+
"ai/TokenUsageStats:messageCount = 0",
60+
"ai/TokenUsageStats:promptTokens = 0",
61+
"ai/TokenUsageStats:prunedMessageCount = 0",
62+
"ai/TokenUsageStats:summarizedMessageCount = 0",
63+
"ai/TokenUsageStats:totalTokens = 0",
64+
"ai/ToolCall:type = \"function\""
65+
]
66+
}
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
{
2+
"description": "Ratchet of the DEFAULT VALUE of every authorable key in one category that has one (#4666) — what a metadata author gets when they omit the key, which for AI-authored metadata is most of the time. Sharded by category like authorable-surface/; the gate reads the whole authorable-defaults/ directory as ONE set. Each line is \"<def>:<key> = <canonical JSON>\". Additions (a NEW key that ships with a default) are auto-recorded — commit the change. CHANGING, ADDING or REMOVING the default of a key that already existed is NOT auto-recorded: it silently alters the behaviour of already-deployed metadata, so it fails check:authorable-surface until it is declared in DEFAULT_CHANGES_BY_MAJOR (scripts/lib/default-changes.ts). Constraints are deliberately NOT recorded here — a tightened bound REJECTS a document loudly, which is a different and self-announcing class (maintainer ruling on #4666, direction B). See #4666, #4661.",
3+
"category": "api",
4+
"defaults": [
5+
"api/ApiDocumentationConfig:changelog = []",
6+
"api/ApiDocumentationConfig:codeTemplates = []",
7+
"api/ApiDocumentationConfig:enabled = true",
8+
"api/ApiDocumentationConfig:generateOpenApi = true",
9+
"api/ApiDocumentationConfig:generateTestCollections = true",
10+
"api/ApiDocumentationConfig:servers = []",
11+
"api/ApiDocumentationConfig:testCollections = []",
12+
"api/ApiDocumentationConfig:title = \"API Documentation\"",
13+
"api/ApiEndpoint:authRequired = true",
14+
"api/ApiTestCollection:variables = {}",
15+
"api/ApiTestRequest:headers = {}",
16+
"api/ApiTestRequest:queryParams = {}",
17+
"api/ApiTestRequest:variables = {}",
18+
"api/ApiTestingUiConfig:defaultModelsExpandDepth = 1",
19+
"api/ApiTestingUiConfig:displayRequestDuration = true",
20+
"api/ApiTestingUiConfig:enableCors = true",
21+
"api/ApiTestingUiConfig:enableFilter = true",
22+
"api/ApiTestingUiConfig:enableTryItOut = true",
23+
"api/ApiTestingUiConfig:path = \"/api-docs\"",
24+
"api/ApiTestingUiConfig:syntaxHighlighting = true",
25+
"api/ApiTestingUiConfig:theme = \"light\"",
26+
"api/AuthFeaturesConfig:magicLink = false",
27+
"api/AuthFeaturesConfig:organization = false",
28+
"api/AuthFeaturesConfig:passkeys = false",
29+
"api/AuthFeaturesConfig:twoFactor = false",
30+
"api/AuthProviderInfo:type = \"social\"",
31+
"api/BatchConfig:enabled = true",
32+
"api/BatchConfig:maxRecordsPerBatch = 200",
33+
"api/BatchEndpointsConfig:defaultAtomic = true",
34+
"api/BatchEndpointsConfig:enableBatchEndpoint = true",
35+
"api/BatchEndpointsConfig:maxBatchSize = 200",
36+
"api/BatchLoadingStrategy:associationLoading = \"batch\"",
37+
"api/BatchOptions:atomic = false",
38+
"api/BatchOptions:continueOnError = false",
39+
"api/BatchOptions:returnRecords = false",
40+
"api/BulkRequest:allOrNone = true",
41+
"api/CacheInvalidationRequest:cascade = false",
42+
"api/CreateExportJobRequest:encoding = \"utf-8\"",
43+
"api/CreateExportJobRequest:format = \"csv\"",
44+
"api/CreateExportJobRequest:includeHeaders = true",
45+
"api/CreateFlowRequest:runAs = \"user\"",
46+
"api/CreateFlowRequest:status = \"draft\"",
47+
"api/CreateFlowRequest:version = 1",
48+
"api/CreateImportJobRequest:createMissingOptions = false",
49+
"api/CreateImportJobRequest:dryRun = false",
50+
"api/CreateImportJobRequest:runAutomations = false",
51+
"api/CreateImportJobRequest:skipBlankMatchKey = false",
52+
"api/CreateImportJobRequest:treatAsHistorical = false",
53+
"api/CreateImportJobRequest:trimWhitespace = true",
54+
"api/CreateImportJobRequest:writeMode = \"insert\"",
55+
"api/CrossObjectBatchOperation:action = \"create\"",
56+
"api/CrossObjectBatchRequest:atomic = true",
57+
"api/CrudEndpointsConfig:dataPrefix = \"/data\"",
58+
"api/CrudEndpointsConfig:objectParamStyle = \"path\"",
59+
"api/DataLoaderConfig:batchScheduleFn = \"microtask\"",
60+
"api/DataLoaderConfig:cacheEnabled = true",
61+
"api/DataLoaderConfig:coalesceRequests = true",
62+
"api/DataLoaderConfig:maxBatchSize = 100",
63+
"api/DeviceRequestResponse:interval = 2",
64+
"api/DispatcherConfig:fallback = \"404\"",
65+
"api/DispatcherRoute:authRequired = true",
66+
"api/DispatcherRoute:criticality = \"optional\"",
67+
"api/ETag:weak = false",
68+
"api/EnhancedApiError:retryable = false",
69+
"api/ErrorHandlingConfig:enabled = true",
70+
"api/ErrorHandlingConfig:exposeInternalErrors = false",
71+
"api/ErrorHandlingConfig:includeDocumentation = true",
72+
"api/ErrorHandlingConfig:includeRequestId = true",
73+
"api/ErrorHandlingConfig:includeStackTrace = false",
74+
"api/ErrorHandlingConfig:includeTimestamp = true",
75+
"api/ErrorHandlingConfig:logErrors = true",
76+
"api/FieldMappingEntry:required = false",
77+
"api/FieldMappingEntry:transform = \"none\"",
78+
"api/GetMetaItemCachedResponse:notModified = false",
79+
"api/GetPresignedUrlRequest:scope = \"user\"",
80+
"api/ImportRequest:createMissingOptions = false",
81+
"api/ImportRequest:dryRun = false",
82+
"api/ImportRequest:runAutomations = false",
83+
"api/ImportRequest:skipBlankMatchKey = false",
84+
"api/ImportRequest:treatAsHistorical = false",
85+
"api/ImportRequest:trimWhitespace = true",
86+
"api/ImportRequest:writeMode = \"insert\"",
87+
"api/ImportValidationConfig:maxErrors = 100",
88+
"api/ImportValidationConfig:mode = \"strict\"",
89+
"api/ImportValidationConfig:trimWhitespace = true",
90+
"api/InitiateChunkedUploadRequest:chunkSize = 5242880",
91+
"api/InitiateChunkedUploadRequest:scope = \"user\"",
92+
"api/InstallPackageRequest:enableOnInstall = true",
93+
"api/ListExportJobsRequest:limit = 20",
94+
"api/ListFlowsRequest:limit = 50",
95+
"api/ListImportJobsRequest:limit = 50",
96+
"api/ListImportJobsRequest:offset = 0",
97+
"api/ListInstalledPackagesRequest:limit = 50",
98+
"api/ListNotificationsRequest:limit = 20",
99+
"api/ListRunsRequest:limit = 20",
100+
"api/LoginRequest:type = \"email\"",
101+
"api/MetadataBulkRegisterRequest:continueOnError = false",
102+
"api/MetadataBulkRegisterRequest:validate = true",
103+
"api/MetadataCacheResponse:notModified = false",
104+
"api/MetadataEndpointsConfig:cacheTtl = 3600",
105+
"api/MetadataEndpointsConfig:enableCache = true",
106+
"api/MetadataEndpointsConfig:prefix = \"/meta\"",
107+
"api/MetadataExportRequest:format = \"json\"",
108+
"api/MetadataImportRequest:conflictResolution = \"skip\"",
109+
"api/MetadataImportRequest:dryRun = false",
110+
"api/MetadataImportRequest:validate = true",
111+
"api/MetadataOverlaySaveRequest:active = true",
112+
"api/MetadataOverlaySaveRequest:scope = \"platform\"",
113+
"api/MetadataQueryRequest:page = 1",
114+
"api/MetadataQueryRequest:pageSize = 50",
115+
"api/MetadataQueryRequest:sortBy = \"name\"",
116+
"api/MetadataQueryRequest:sortOrder = \"asc\"",
117+
"api/Notification:read = false",
118+
"api/NotificationPreferences:digest = \"none\"",
119+
"api/NotificationPreferences:email = true",
120+
"api/NotificationPreferences:inApp = true",
121+
"api/NotificationPreferences:push = true",
122+
"api/ODataConfig:enabled = true",
123+
"api/ODataConfig:path = \"/odata\"",
124+
"api/ODataQueryAdapter:usePrefix = true",
125+
"api/ODataQueryAdapter:version = \"v4\"",
126+
"api/OpenApiGenerationConfig:apiVersion = \"1.0.0\"",
127+
"api/OpenApiGenerationConfig:enabled = true",
128+
"api/OpenApiGenerationConfig:generateSchemas = true",
129+
"api/OpenApiGenerationConfig:includeExamples = true",
130+
"api/OpenApiGenerationConfig:includeInternal = false",
131+
"api/OpenApiGenerationConfig:outputPath = \"/api/docs/openapi.json\"",
132+
"api/OpenApiGenerationConfig:title = \"ObjectStack API\"",
133+
"api/OpenApiGenerationConfig:uiFramework = \"swagger-ui\"",
134+
"api/OpenApiGenerationConfig:uiPath = \"/api/docs\"",
135+
"api/OpenApiGenerationConfig:version = \"3.0.3\"",
136+
"api/OpenApiSpec:openapi = \"3.0.0\"",
137+
"api/OpenApiSpec:servers = []",
138+
"api/PackageInstallRequest:enableOnInstall = true",
139+
"api/PackageRollbackRequest:rollbackCustomizations = true",
140+
"api/PackageUpgradeRequest:createSnapshot = true",
141+
"api/PackageUpgradeRequest:dryRun = false",
142+
"api/PackageUpgradeRequest:mergeStrategy = \"three-way-merge\"",
143+
"api/PackageUpgradeRequest:skipValidation = false",
144+
"api/QueryOptimizationConfig:enableQueryPlan = false",
145+
"api/RealtimeConfig:enabled = true",
146+
"api/RealtimeConfig:transport = \"websocket\"",
147+
"api/RequestValidationConfig:enabled = true",
148+
"api/RequestValidationConfig:includeFieldErrors = true",
149+
"api/RequestValidationConfig:mode = \"strict\"",
150+
"api/RequestValidationConfig:validateBody = true",
151+
"api/RequestValidationConfig:validateHeaders = false",
152+
"api/RequestValidationConfig:validateParams = true",
153+
"api/RequestValidationConfig:validateQuery = true",
154+
"api/ResponseEnvelopeConfig:enabled = true",
155+
"api/ResponseEnvelopeConfig:includeDuration = false",
156+
"api/ResponseEnvelopeConfig:includeMetadata = true",
157+
"api/ResponseEnvelopeConfig:includeRequestId = true",
158+
"api/ResponseEnvelopeConfig:includeTimestamp = true",
159+
"api/ResponseEnvelopeConfig:includeTraceId = false",
160+
"api/ResponseEnvelopeConfig:skipIfWrapped = true",
161+
"api/RestApiConfig:basePath = \"/api\"",
162+
"api/RestApiConfig:enableBatch = true",
163+
"api/RestApiConfig:enableCrud = true",
164+
"api/RestApiConfig:enableDiscovery = true",
165+
"api/RestApiConfig:enableMetadata = true",
166+
"api/RestApiConfig:enableOpenApi = true",
167+
"api/RestApiConfig:enableProjectScoping = false",
168+
"api/RestApiConfig:enableUi = true",
169+
"api/RestApiConfig:projectResolution = \"auto\"",
170+
"api/RestApiConfig:version = \"v1\"",
171+
"api/RestApiEndpoint:cacheable = false",
172+
"api/RestApiEndpoint:public = false",
173+
"api/RestApiPluginConfig:basePath = \"/api\"",
174+
"api/RestApiPluginConfig:enabled = true",
175+
"api/RestApiPluginConfig:version = \"v1\"",
176+
"api/RestApiRouteRegistration:authRequired = true",
177+
"api/RestQueryAdapter:fieldsParam = \"fields\"",
178+
"api/RestQueryAdapter:filterStyle = \"bracket\"",
179+
"api/RouteDefinition:category = \"api\"",
180+
"api/RouteDefinition:public = false",
181+
"api/RouteGenerationConfig:nameTransform = \"none\"",
182+
"api/RouterConfig:basePath = \"/api\"",
183+
"api/RouterConfig:mounts = {\"ai\":\"/ai\",\"analytics\":\"/analytics\",\"auth\":\"/auth\",\"automation\":\"/automation\",\"data\":\"/data\",\"i18n\":\"/i18n\",\"metadata\":\"/meta\",\"notifications\":\"/notifications\",\"packages\":\"/packages\",\"realtime\":\"/realtime\",\"storage\":\"/storage\",\"ui\":\"/ui\"}",
184+
"api/ScheduleExportRequest:format = \"csv\"",
185+
"api/ScheduledExport:enabled = true",
186+
"api/ScheduledExport:format = \"csv\"",
187+
"api/SessionUser:emailVerified = false",
188+
"api/SessionUser:language = \"en\"",
189+
"api/SessionUser:roles = []",
190+
"api/VersioningConfig:headerName = \"ObjectStack-Version\"",
191+
"api/VersioningConfig:includeInDiscovery = true",
192+
"api/VersioningConfig:queryParamName = \"version\"",
193+
"api/VersioningConfig:strategy = \"urlPath\"",
194+
"api/VersioningConfig:urlPrefix = \"/api\"",
195+
"api/WebSocketConfig:maxReconnectAttempts = 5",
196+
"api/WebSocketConfig:pingInterval = 30000",
197+
"api/WebSocketConfig:reconnect = true",
198+
"api/WebSocketConfig:reconnectInterval = 1000",
199+
"api/WebSocketConfig:timeout = 5000",
200+
"api/WebSocketServerConfig:cursorSharing = false",
201+
"api/WebSocketServerConfig:enabled = false",
202+
"api/WebSocketServerConfig:heartbeatInterval = 30000",
203+
"api/WebSocketServerConfig:path = \"/ws\"",
204+
"api/WebSocketServerConfig:presence = false",
205+
"api/WebSocketServerConfig:reconnectAttempts = 5"
206+
]
207+
}

0 commit comments

Comments
 (0)