@lmzhen/dsh-evolution-core 0.6.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -2965,6 +2965,53 @@ function allowRowCollisions(env = process.env) {
2965
2965
  return env.DSH_EVOLUTION_ALLOW_ROW_COLLISIONS === ALLOW_ROW_COLLISIONS;
2966
2966
  }
2967
2967
  //#endregion
2968
+ //#region lib/types/errors.js
2969
+ /**
2970
+ * THE error-code table: E-301…E-316 with the exact text each one emits.
2971
+ *
2972
+ * The codes used to be spelled out at 33 call sites across two packages, so one
2973
+ * code's wording could drift between the branches that answer it and nothing could
2974
+ * see the drift. Keys name the SCENARIO rather than the code, because a code
2975
+ * legitimately carries more than one text (E-301 answers pending / approve / reject
2976
+ * with different guidance); the code still leads every string, so model- and
2977
+ * user-facing output is unchanged. Interpolations are written `%aN%` and filled by
2978
+ * `errorText` from the values the call site used to interpolate inline.
2979
+ * @module @lmzhen/dsh-evolution-core
2980
+ */
2981
+ const EVOLUTION_ERRORS = Object.freeze({
2982
+ "e-305-this-invocation-carries-no": "E-305: this invocation carries no agent — `%a1%` needs a session-backed call (run it from a session in the GUI or the CLI).",
2983
+ "e-306-this-deployment-stages-foreground": "E-306: this deployment stages foreground writes, but `/evolution %a1%` is not replayable through the skill runner — there is nothing to stage. Run it from a session whose approval policy is 'never', or set `stageForeground: false` on the evolution-approval row, then repeat the command.",
2984
+ "e-301-approval-service-not-mounted": "E-301: approval service not mounted — pending writes cannot be listed or replayed. Next: the evolution-approval row ships with evolution-host/evolution-all — run /evolution doctor to see which services are mounted.",
2985
+ "e-301-approval-service-not-mounted-2": "E-301: approval service not mounted. Next: the evolution-approval row ships with evolution-host/evolution-all — run /evolution doctor to see which services are mounted.",
2986
+ "e-304-the-mounted-approval-service": "E-304: the mounted approval service predates the release capability — reject the record instead.",
2987
+ "e-302-curator-service-not-mounted": "E-302: curator service not mounted. Next: mount the evolution-curator row (evolution-host/evolution-all) and run /evolution doctor.",
2988
+ "e-305-the-invocation-agent-exposes": "E-305: the invocation agent exposes neither `followup` nor `inject` — this learn request has no delivery channel.",
2989
+ "e-306-this-deployment-stages-foreground-2": "E-306: this deployment stages foreground writes, but this invocation carries no agent session — `/evolution restructure` would stage a record with no session attribution. Run it from a session in the GUI or the CLI, or set `stageForeground: false` on the evolution-approval row, then repeat the command.",
2990
+ "e-303-replay-service-not-mounted": "E-303: replay service not mounted. Next: mount the evolution-replay row (evolution-host/evolution-all) and run /evolution doctor.",
2991
+ "e-307-the-settings-service-could": "E-307: the settings service could not report its sections (%a1%). /evolution params needs the user layer to tell an override from a deployment value; run /evolution doctor to see which services are mounted.",
2992
+ "e-308-unknown-parameter-group-group": "E-308: unknown parameter group \"%a1%\" — known groups: %a2%.",
2993
+ "e-311-no-settings-service-is": "E-311: no settings service is mounted, so there is no user layer to write. Mount the settings row (packages/settings/settings-file) and retry; this command never edits cordis.yml — a deployment value belongs to the deployment. /evolution doctor lists the mounted services.",
2994
+ "e-312-error-instanceof-Error-error": "E-312: %a1% — /evolution params lists the canonical ids.",
2995
+ "e-313-unknown-parameter-id-evolution": "E-313: unknown parameter \"%a1%\" — /evolution params lists every registered id with its tier and user layer.",
2996
+ "e-314-id-is-a-deployment": "E-314: \"%a1%\" is a deployment parameter (tier %a2%, owner %a3%) — it is written in cordis.yml on its plugin or policy row, not from a session. /evolution params shows who may write each row.",
2997
+ "e-315-id-has-no-user": "E-315: \"%a1%\" has no user layer — owner %a2% publishes no settings namespace, so the value stays with the deployment.",
2998
+ "e-307-the-settings-service-could-2": "E-307: the settings service could not report its sections (%a1%). /evolution policy set needs the current revision to write safely; run /evolution doctor to see which services are mounted.",
2999
+ "e-316-namespace-namespace-is-not": "E-316: namespace \"%a1%\" is not registered — owner %a2% is not mounted in this composition, so its parameters cannot be written from here. /evolution params marks those rows 'unregistered'.",
3000
+ "e-309-revision-conflict-you-sent": "E-309: revision conflict — you sent %a1%, the document stands at %a2%. Re-read with /evolution params --json and retry.",
3001
+ "e-309-revision-conflict-message-Re": "E-309: revision conflict — %a1%. Re-read with /evolution params --json and retry.",
3002
+ "e-310-the-settings-service-refused": "E-310: the settings service refused the write: %a1% — the owning plugin's rule stands (a cross-field pair, or a cap that may only be tightened). /evolution params shows the current value.",
3003
+ "e-305-this-invocation-carries-no-2": "E-305: this invocation carries no agent — `%a1%` needs a session-backed call (run it from a session in the GUI or the CLI)."
3004
+ });
3005
+ /**
3006
+ * Render one table entry, substituting its interpolation slots.
3007
+ * @param id - the scenario key.
3008
+ * @param args - values for the entry's `%aN%` slots.
3009
+ * @returns the message text the call site used to spell out inline.
3010
+ */
3011
+ function errorText(id, args = {}) {
3012
+ return EVOLUTION_ERRORS[id].replace(/%a(\d+)%/g, (_match, n) => String(args["a" + n] ?? ""));
3013
+ }
3014
+ //#endregion
2968
3015
  //#region lib/types/learn-prompt.js
2969
3016
  /**
2970
3017
  * Open-ended `/evolution learn` prompt builder.
@@ -8923,7 +8970,12 @@ const PARAM_EXPOSURE = Object.freeze([
8923
8970
  owner: "evolution-review",
8924
8971
  applies: "live",
8925
8972
  docAnchor: "PARAMETERS.md#review",
8926
- summary: "Activity units between skill-review injections."
8973
+ summary: "Activity units between skill-review injections.",
8974
+ label: "技能审查间隔",
8975
+ hint: "每多少活动单位触发一次技能审查注入。",
8976
+ control: "number",
8977
+ unit: "次",
8978
+ values: ""
8927
8979
  },
8928
8980
  {
8929
8981
  id: "reviewMemoryInterval",
@@ -8933,7 +8985,12 @@ const PARAM_EXPOSURE = Object.freeze([
8933
8985
  owner: "evolution-review",
8934
8986
  applies: "live",
8935
8987
  docAnchor: "PARAMETERS.md#review",
8936
- summary: "Activity units between memory-review injections."
8988
+ summary: "Activity units between memory-review injections.",
8989
+ label: "记忆审查间隔",
8990
+ hint: "每多少活动单位触发一次记忆审查注入。",
8991
+ control: "number",
8992
+ unit: "次",
8993
+ values: ""
8937
8994
  },
8938
8995
  {
8939
8996
  id: "skillReviewTrigger",
@@ -8943,7 +9000,12 @@ const PARAM_EXPOSURE = Object.freeze([
8943
9000
  owner: "evolution-review",
8944
9001
  applies: "live",
8945
9002
  docAnchor: "PARAMETERS.md#review",
8946
- summary: "Which channel may inject a skill review (cadence, completion, both)."
9003
+ summary: "Which channel may inject a skill review (cadence, completion, both).",
9004
+ label: "审查触发通道",
9005
+ hint: "哪个通道可以注入技能审查:cadence=按间隔、completion=按完成、both=两者。",
9006
+ control: "select",
9007
+ unit: "",
9008
+ values: "cadence|completion|both"
8947
9009
  },
8948
9010
  {
8949
9011
  id: "skillReviewCompletionMinToolCalls",
@@ -8953,7 +9015,12 @@ const PARAM_EXPOSURE = Object.freeze([
8953
9015
  owner: "evolution-review",
8954
9016
  applies: "live",
8955
9017
  docAnchor: "PARAMETERS.md#review",
8956
- summary: "Tool calls a task needs before the completion channel injects."
9018
+ summary: "Tool calls a task needs before the completion channel injects.",
9019
+ label: "完成通道最少工具调用",
9020
+ hint: "走完成通道时,任务至少经过多少次工具调用才注入。",
9021
+ control: "number",
9022
+ unit: "次",
9023
+ values: ""
8957
9024
  },
8958
9025
  {
8959
9026
  id: "reviewEnabled",
@@ -8963,7 +9030,12 @@ const PARAM_EXPOSURE = Object.freeze([
8963
9030
  owner: "evolution-review",
8964
9031
  applies: "live",
8965
9032
  docAnchor: "PARAMETERS.md#review",
8966
- summary: "Master switch for the review plugin."
9033
+ summary: "Master switch for the review plugin.",
9034
+ label: "启用审查插件",
9035
+ hint: "审查插件的总开关。",
9036
+ control: "switch",
9037
+ unit: "",
9038
+ values: ""
8967
9039
  },
8968
9040
  {
8969
9041
  id: "reviewMode",
@@ -8973,7 +9045,12 @@ const PARAM_EXPOSURE = Object.freeze([
8973
9045
  owner: "evolution-review",
8974
9046
  applies: "live",
8975
9047
  docAnchor: "PARAMETERS.md#review",
8976
- summary: "Run the review in the parent session (inject) or on a subagent."
9048
+ summary: "Run the review in the parent session (inject) or on a subagent.",
9049
+ label: "审查运行方式",
9050
+ hint: "inject=在父会话内注入,subagent=交给子代理运行。",
9051
+ control: "select",
9052
+ unit: "",
9053
+ values: "subagent|inject"
8977
9054
  },
8978
9055
  {
8979
9056
  id: "reviewWakeInject",
@@ -8983,7 +9060,12 @@ const PARAM_EXPOSURE = Object.freeze([
8983
9060
  owner: "evolution-review",
8984
9061
  applies: "live",
8985
9062
  docAnchor: "PARAMETERS.md#review",
8986
- summary: "Deliver the deferred review as a waking follow-up message."
9063
+ summary: "Deliver the deferred review as a waking follow-up message.",
9064
+ label: "审查后续唤醒注入",
9065
+ hint: "把延后的审查作为唤醒消息投递。",
9066
+ control: "switch",
9067
+ unit: "",
9068
+ values: ""
8987
9069
  },
8988
9070
  {
8989
9071
  id: "reviewProvider",
@@ -9053,7 +9135,12 @@ const PARAM_EXPOSURE = Object.freeze([
9053
9135
  owner: "tool-skill-manage",
9054
9136
  applies: "live",
9055
9137
  docAnchor: "PARAMETERS.md#write-caps",
9056
- summary: "Character cap on a SKILL.md body (tighten-only)."
9138
+ summary: "Character cap on a SKILL.md body (tighten-only).",
9139
+ label: "SKILL.md 正文字符上限",
9140
+ hint: "SKILL.md 正文的字符上限(只许收紧)。",
9141
+ control: "number",
9142
+ unit: "字符",
9143
+ values: ""
9057
9144
  },
9058
9145
  {
9059
9146
  id: "maxSkillFileBytes",
@@ -9063,7 +9150,12 @@ const PARAM_EXPOSURE = Object.freeze([
9063
9150
  owner: "tool-skill-manage",
9064
9151
  applies: "live",
9065
9152
  docAnchor: "PARAMETERS.md#write-caps",
9066
- summary: "Byte cap on one support file (tighten-only)."
9153
+ summary: "Byte cap on one support file (tighten-only).",
9154
+ label: "支持文件字节上限",
9155
+ hint: "单个支持文件的字节上限(只许收紧)。",
9156
+ control: "number",
9157
+ unit: "字节",
9158
+ values: ""
9067
9159
  },
9068
9160
  {
9069
9161
  id: "maxSkillNameLength",
@@ -9073,7 +9165,12 @@ const PARAM_EXPOSURE = Object.freeze([
9073
9165
  owner: "tool-skill-manage",
9074
9166
  applies: "live",
9075
9167
  docAnchor: "PARAMETERS.md#write-caps",
9076
- summary: "Character cap on a skill name (tighten-only)."
9168
+ summary: "Character cap on a skill name (tighten-only).",
9169
+ label: "技能名字符上限",
9170
+ hint: "技能名的字符上限(只许收紧)。",
9171
+ control: "number",
9172
+ unit: "字符",
9173
+ values: ""
9077
9174
  },
9078
9175
  {
9079
9176
  id: "maxDescriptionLength",
@@ -9083,7 +9180,12 @@ const PARAM_EXPOSURE = Object.freeze([
9083
9180
  owner: "tool-skill-manage",
9084
9181
  applies: "live",
9085
9182
  docAnchor: "PARAMETERS.md#write-caps",
9086
- summary: "Character cap on a skill description (tighten-only)."
9183
+ summary: "Character cap on a skill description (tighten-only).",
9184
+ label: "技能描述字符上限",
9185
+ hint: "技能描述的字符上限(只许收紧)。",
9186
+ control: "number",
9187
+ unit: "字符",
9188
+ values: ""
9087
9189
  },
9088
9190
  {
9089
9191
  id: "descriptionStrict",
@@ -9093,7 +9195,12 @@ const PARAM_EXPOSURE = Object.freeze([
9093
9195
  owner: "tool-skill-manage",
9094
9196
  applies: "live",
9095
9197
  docAnchor: "PARAMETERS.md#write-caps",
9096
- summary: "Refuse a description over the authoring bar instead of advising."
9198
+ summary: "Refuse a description over the authoring bar instead of advising.",
9199
+ label: "描述严格档",
9200
+ hint: "描述超过写作门槛时拒绝写入,而不是只提示。",
9201
+ control: "switch",
9202
+ unit: "",
9203
+ values: ""
9097
9204
  },
9098
9205
  {
9099
9206
  id: "strictCrossSource",
@@ -9103,7 +9210,12 @@ const PARAM_EXPOSURE = Object.freeze([
9103
9210
  owner: "tool-skill-manage",
9104
9211
  applies: "live",
9105
9212
  docAnchor: "PARAMETERS.md#write-caps",
9106
- summary: "Refuse writes whose catalog entry resolves outside the family."
9213
+ summary: "Refuse writes whose catalog entry resolves outside the family.",
9214
+ label: "跨源严格档",
9215
+ hint: "目录项解析到家族之外时拒绝写入。",
9216
+ control: "switch",
9217
+ unit: "",
9218
+ values: ""
9107
9219
  },
9108
9220
  {
9109
9221
  id: "citationPolicy",
@@ -9113,7 +9225,12 @@ const PARAM_EXPOSURE = Object.freeze([
9113
9225
  owner: "tool-skill-manage",
9114
9226
  applies: "live",
9115
9227
  docAnchor: "PARAMETERS.md#write-caps",
9116
- summary: "Refuse a move that would leave a dangling reference, or verify it."
9228
+ summary: "Refuse a move that would leave a dangling reference, or verify it.",
9229
+ label: "引用校验档",
9230
+ hint: "移动或合并时对引用的处置:verify=校验、refuse=直接拒绝。",
9231
+ control: "select",
9232
+ unit: "",
9233
+ values: "verify|refuse"
9117
9234
  },
9118
9235
  {
9119
9236
  id: "referenceRewrite",
@@ -9143,7 +9260,12 @@ const PARAM_EXPOSURE = Object.freeze([
9143
9260
  owner: "tool-skill-manage",
9144
9261
  applies: "live",
9145
9262
  docAnchor: "PARAMETERS.md#write-caps",
9146
- summary: "Warn about an oversize support file, or refuse the write."
9263
+ summary: "Warn about an oversize support file, or refuse the write.",
9264
+ label: "支持文件超限档",
9265
+ hint: "支持文件超出字符上限时:report=只报告、enforce=拒写。",
9266
+ control: "select",
9267
+ unit: "",
9268
+ values: "report|enforce"
9147
9269
  },
9148
9270
  {
9149
9271
  id: "memoryChars",
@@ -9153,7 +9275,12 @@ const PARAM_EXPOSURE = Object.freeze([
9153
9275
  owner: "memory-files",
9154
9276
  applies: "live",
9155
9277
  docAnchor: "PARAMETERS.md#memory",
9156
- summary: "Character budget the memory store enforces for MEMORY.md."
9278
+ summary: "Character budget the memory store enforces for MEMORY.md.",
9279
+ label: "MEMORY.md 字符预算",
9280
+ hint: "memory 存储对 MEMORY.md 的字符上限。",
9281
+ control: "number",
9282
+ unit: "字符",
9283
+ values: ""
9157
9284
  },
9158
9285
  {
9159
9286
  id: "userChars",
@@ -9163,7 +9290,12 @@ const PARAM_EXPOSURE = Object.freeze([
9163
9290
  owner: "memory-files",
9164
9291
  applies: "live",
9165
9292
  docAnchor: "PARAMETERS.md#memory",
9166
- summary: "Character budget the memory store enforces for USER.md."
9293
+ summary: "Character budget the memory store enforces for USER.md.",
9294
+ label: "USER.md 字符预算",
9295
+ hint: "memory 存储对 USER.md 的字符上限。",
9296
+ control: "number",
9297
+ unit: "字符",
9298
+ values: ""
9167
9299
  },
9168
9300
  {
9169
9301
  id: "memoryEnabled",
@@ -9183,7 +9315,12 @@ const PARAM_EXPOSURE = Object.freeze([
9183
9315
  owner: "tool-memory",
9184
9316
  applies: "live",
9185
9317
  docAnchor: "PARAMETERS.md#memory",
9186
- summary: "Characters of one memory entry shown in a tool result preview."
9318
+ summary: "Characters of one memory entry shown in a tool result preview.",
9319
+ label: "条目预览字符数",
9320
+ hint: "单条记忆预览保留多少字符。",
9321
+ control: "number",
9322
+ unit: "字符",
9323
+ values: ""
9187
9324
  },
9188
9325
  {
9189
9326
  id: "addDatePrefix",
@@ -9193,7 +9330,12 @@ const PARAM_EXPOSURE = Object.freeze([
9193
9330
  owner: "memory-files",
9194
9331
  applies: "live",
9195
9332
  docAnchor: "PARAMETERS.md#memory",
9196
- summary: "Prefix stored memory entries with their date heading."
9333
+ summary: "Prefix stored memory entries with their date heading.",
9334
+ label: "记忆条目加日期前缀",
9335
+ hint: "写入记忆时为条目加上日期标题。",
9336
+ control: "switch",
9337
+ unit: "",
9338
+ values: ""
9197
9339
  },
9198
9340
  {
9199
9341
  id: "maxConsolidationFailures",
@@ -9203,7 +9345,12 @@ const PARAM_EXPOSURE = Object.freeze([
9203
9345
  owner: "memory-files",
9204
9346
  applies: "live",
9205
9347
  docAnchor: "PARAMETERS.md#memory",
9206
- summary: "Consolidation failures one turn tolerates before the tool gives up."
9348
+ summary: "Consolidation failures one turn tolerates before the tool gives up.",
9349
+ label: "合并失败容忍次数",
9350
+ hint: "一轮内合并失败多少次后工具放弃。",
9351
+ control: "number",
9352
+ unit: "次",
9353
+ values: ""
9207
9354
  },
9208
9355
  {
9209
9356
  id: "curatorIntervalHours",
@@ -9213,7 +9360,12 @@ const PARAM_EXPOSURE = Object.freeze([
9213
9360
  owner: "evolution-curator",
9214
9361
  applies: "live",
9215
9362
  docAnchor: "PARAMETERS.md#curator",
9216
- summary: "Minimum hours between deterministic curation passes."
9363
+ summary: "Minimum hours between deterministic curation passes.",
9364
+ label: "策展间隔",
9365
+ hint: "两次确定性策展之间至少间隔多少小时。",
9366
+ control: "number",
9367
+ unit: "小时",
9368
+ values: ""
9217
9369
  },
9218
9370
  {
9219
9371
  id: "staleAfterDays",
@@ -9223,7 +9375,12 @@ const PARAM_EXPOSURE = Object.freeze([
9223
9375
  owner: "evolution-curator",
9224
9376
  applies: "live",
9225
9377
  docAnchor: "PARAMETERS.md#curator",
9226
- summary: "Inactive days before a skill counts as stale."
9378
+ summary: "Inactive days before a skill counts as stale.",
9379
+ label: "判为陈旧的天数",
9380
+ hint: "技能多少天没被使用即算陈旧。",
9381
+ control: "number",
9382
+ unit: "天",
9383
+ values: ""
9227
9384
  },
9228
9385
  {
9229
9386
  id: "archiveAfterDays",
@@ -9233,7 +9390,12 @@ const PARAM_EXPOSURE = Object.freeze([
9233
9390
  owner: "evolution-curator",
9234
9391
  applies: "live",
9235
9392
  docAnchor: "PARAMETERS.md#curator",
9236
- summary: "Inactive days before a stale skill is archived (must be >= staleAfterDays)."
9393
+ summary: "Inactive days before a stale skill is archived (must be >= staleAfterDays).",
9394
+ label: "归档天数",
9395
+ hint: "陈旧技能再过多少天归档(须 ≥ 判为陈旧的天数)。",
9396
+ control: "number",
9397
+ unit: "天",
9398
+ values: ""
9237
9399
  },
9238
9400
  {
9239
9401
  id: "qualityWarnStaleAfterDays",
@@ -9243,7 +9405,12 @@ const PARAM_EXPOSURE = Object.freeze([
9243
9405
  owner: "evolution-curator",
9244
9406
  applies: "live",
9245
9407
  docAnchor: "PARAMETERS.md#curator",
9246
- summary: "Age at which a low quality score starts warning."
9408
+ summary: "Age at which a low quality score starts warning.",
9409
+ label: "低质量告警天数",
9410
+ hint: "质量分偏低时从多少天开始告警。",
9411
+ control: "number",
9412
+ unit: "天",
9413
+ values: ""
9247
9414
  },
9248
9415
  {
9249
9416
  id: "minIdleHours",
@@ -9253,7 +9420,12 @@ const PARAM_EXPOSURE = Object.freeze([
9253
9420
  owner: "evolution-curator",
9254
9421
  applies: "live",
9255
9422
  docAnchor: "PARAMETERS.md#curator",
9256
- summary: "Idle hours required before an automatic curation pass runs."
9423
+ summary: "Idle hours required before an automatic curation pass runs.",
9424
+ label: "空闲门槛",
9425
+ hint: "至少空闲多少小时才跑自动策展。",
9426
+ control: "number",
9427
+ unit: "小时",
9428
+ values: ""
9257
9429
  },
9258
9430
  {
9259
9431
  id: "minIdleFailOpen",
@@ -9263,7 +9435,12 @@ const PARAM_EXPOSURE = Object.freeze([
9263
9435
  owner: "evolution-curator",
9264
9436
  applies: "live",
9265
9437
  docAnchor: "PARAMETERS.md#curator",
9266
- summary: "Let the idle gate open when the activity probe is unavailable."
9438
+ summary: "Let the idle gate open when the activity probe is unavailable.",
9439
+ label: "空闲探针失败时放行",
9440
+ hint: "活动探针不可用时,是否让空闲门槛直接放行。",
9441
+ control: "switch",
9442
+ unit: "",
9443
+ values: ""
9267
9444
  },
9268
9445
  {
9269
9446
  id: "llmReview",
@@ -9273,7 +9450,12 @@ const PARAM_EXPOSURE = Object.freeze([
9273
9450
  owner: "evolution-curator",
9274
9451
  applies: "live",
9275
9452
  docAnchor: "PARAMETERS.md#curator",
9276
- summary: "Enable the LLM nomination pass on top of the deterministic lifecycle."
9453
+ summary: "Enable the LLM nomination pass on top of the deterministic lifecycle.",
9454
+ label: "启用 LLM 提名",
9455
+ hint: "在确定性生命周期之上再跑一遍 LLM 提名。",
9456
+ control: "switch",
9457
+ unit: "",
9458
+ values: ""
9277
9459
  },
9278
9460
  {
9279
9461
  id: "curatorReviewMaxTokens",
@@ -9283,7 +9465,12 @@ const PARAM_EXPOSURE = Object.freeze([
9283
9465
  owner: "evolution-curator",
9284
9466
  applies: "live",
9285
9467
  docAnchor: "PARAMETERS.md#curator",
9286
- summary: "Token budget of the curator LLM review."
9468
+ summary: "Token budget of the curator LLM review.",
9469
+ label: "策展 LLM token 预算",
9470
+ hint: "策展 LLM 审查可用的 token 预算。",
9471
+ control: "number",
9472
+ unit: "token",
9473
+ values: ""
9287
9474
  },
9288
9475
  {
9289
9476
  id: "curatorReviewTimeoutMs",
@@ -9293,7 +9480,12 @@ const PARAM_EXPOSURE = Object.freeze([
9293
9480
  owner: "evolution-curator",
9294
9481
  applies: "live",
9295
9482
  docAnchor: "PARAMETERS.md#curator",
9296
- summary: "Wall-clock bound of the curator LLM review."
9483
+ summary: "Wall-clock bound of the curator LLM review.",
9484
+ label: "策展 LLM 超时",
9485
+ hint: "策展 LLM 审查的墙钟上限。",
9486
+ control: "number",
9487
+ unit: "毫秒",
9488
+ values: ""
9297
9489
  },
9298
9490
  {
9299
9491
  id: "healthSoftBodyChars",
@@ -9303,7 +9495,12 @@ const PARAM_EXPOSURE = Object.freeze([
9303
9495
  owner: "evolution-curator",
9304
9496
  applies: "live",
9305
9497
  docAnchor: "PARAMETERS.md#curator",
9306
- summary: "Body character line the health view judges against."
9498
+ summary: "Body character line the health view judges against.",
9499
+ label: "正文软带",
9500
+ hint: "健康视图判定正文长度的软带。",
9501
+ control: "number",
9502
+ unit: "字符",
9503
+ values: ""
9307
9504
  },
9308
9505
  {
9309
9506
  id: "healthStampDensityPerKb",
@@ -9313,7 +9510,12 @@ const PARAM_EXPOSURE = Object.freeze([
9313
9510
  owner: "evolution-curator",
9314
9511
  applies: "live",
9315
9512
  docAnchor: "PARAMETERS.md#curator",
9316
- summary: "Stamp density per KB that flags log-like content in a body."
9513
+ summary: "Stamp density per KB that flags log-like content in a body.",
9514
+ label: "标记密度阈值",
9515
+ hint: "每 KB 出现多少个时间标记就算「像日志」。",
9516
+ control: "number",
9517
+ unit: "处/KB",
9518
+ values: ""
9317
9519
  },
9318
9520
  {
9319
9521
  id: "healthChurnMinPatches",
@@ -9323,7 +9525,12 @@ const PARAM_EXPOSURE = Object.freeze([
9323
9525
  owner: "evolution-curator",
9324
9526
  applies: "live",
9325
9527
  docAnchor: "PARAMETERS.md#curator",
9326
- summary: "Patches without a read that flag a write-ghost skill."
9528
+ summary: "Patches without a read that flag a write-ghost skill.",
9529
+ label: "空写判定补丁数",
9530
+ hint: "多少次改动都没有任何读取,即判为「写幽灵」。",
9531
+ control: "number",
9532
+ unit: "处",
9533
+ values: ""
9327
9534
  },
9328
9535
  {
9329
9536
  id: "evolution-curator.enabled",
@@ -9881,6 +10088,20 @@ const PARAM_NAMESPACES = Object.freeze({
9881
10088
  "tool-skill-manage": "evolution-skills"
9882
10089
  });
9883
10090
  /**
10091
+ * The settings namespace one owner package registers. The registry's map is the only
10092
+ * place a namespace is spelled: a package without an entry has no user layer, so a
10093
+ * missing entry must fail loud here instead of letting a package fall back to a
10094
+ * private constant that the registry never sees.
10095
+ * @param owner - owner package directory name (the map's key).
10096
+ * @returns the namespace that owner registers.
10097
+ * @throws when the owner has no entry in {@link PARAM_NAMESPACES}.
10098
+ */
10099
+ function paramNamespace(owner) {
10100
+ const namespace = PARAM_NAMESPACES[owner];
10101
+ if (namespace === void 0) throw new Error("no settings namespace registered for owner `" + owner + "` (add it to PARAM_NAMESPACES)");
10102
+ return namespace;
10103
+ }
10104
+ /**
9884
10105
  * G3: expose one parameter section to the user layer.
9885
10106
  *
9886
10107
  * Precedence stays 'user > deployment > default': the caller keeps reading its
@@ -10079,4 +10300,4 @@ function sessionAudited(ctx, sessionId, sessionScoped) {
10079
10300
  return false;
10080
10301
  }
10081
10302
  //#endregion
10082
- export { ALIVE_LOCK_TAKEOVER_MS, AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEAD_LOCK_TAKEOVER_MS, DEDUP_MAX_PAIR_COMPARISONS, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, EMPTY_LOCK_TAKEOVER_MS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, HEALTH_STAMP_RE, HOOK_LINE_RE, INSTANCE_KEYS, KEEP_LINE_RE, LOCK_BODY_RE, LOCK_SUFFIX, LOCK_TEAR_TAKEOVER_MS, LOW_QUALITY_THRESHOLD, LostWriteLock, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MUTATIONS_FILE_VERSION, MemoryStore, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, RESTRUCTURE_TARGET_RE, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UPSTREAM_LIMIT_CHARS_PER_TOKEN, advanceReview, allowRowCollisions, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyReferenceRewrite, assertDispatchPayload, assertSkillsRootAliasRetired, assessStructureHealth, authoringFeedback, bodyCost, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, canonicalWriteId, claimInstance, clampedNumber, clearReviewChannel, collectReadSkillNames, composePresetComposition, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, countDispatches, createGateSet, daysSinceIso, decideTakeover, describeReferenceRewrite, duplicateHeadings, emptyRecord, evaluateThreat, eventsFile, evolutionEventPayloadIssue, evolutionHome, evolutionIoAdapter, evolutionRoot, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurn, frontmatterBlock, frontmatterCatalogInvalid, getRecord, idleDays, installParamSection, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, latestActivityAt, lifecycleCandidate, listEventArchives, loadMutations, loadRowOverrides, loadSuppressedNames, loadUsage, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, neutralizePromptVariables, newSkillLibrary, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, observeEvent, overlongLines, paramSectionOverrides, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseLockBody, pendingSelfCleanup, persistedWriteSite, persistedWriteSites, planReferenceRewrite, planRehoming, policyStageLimits, probeAbsent, probeList, probeMtime, probePresent, probeReason, probeUnknown, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readNumberParam, readParam, recordMutation, redactSecrets, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, retainEventArchives, retirementReport, reviewPrompt, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopedProbeReport, sessionAudited, sessionSeesFamilyTools, skillReadNameOf, skillsRoot, supportFileReadOf, suppressedFile, sweepReviewChannelSessions, tokenLineFor, transactIo, transactTaskGuard, unhookedSupportPointers, updateSuppressedNames, usageFile, usageObserved, validateFrontmatter, validateRestructureTarget, valueOr, verifyPromptBundle, writeDurableTmp, yamlPlainScalarNeedsQuotes };
10303
+ export { ALIVE_LOCK_TAKEOVER_MS, AUTHORING_DESCRIPTION_BAR, AUTHORING_SPLIT_LINE_CHARS, CITATION_SUPPORT_DIRS, COMBINED_REVIEW_PLAN_PROMPT, COMBINED_REVIEW_PROMPT, COMPLETION_SKILL_REVIEW_PROMPT, CONTENT_SPLIT_HINT, COST_ASCII_TOKEN_HIGH, COST_ASCII_TOKEN_LOW, COST_CJK_TOKEN_HIGH, COST_CJK_TOKEN_LOW, CURATOR_DRY_RUN_BANNER, CURATOR_PROMPT, DEAD_LOCK_TAKEOVER_MS, DEDUP_MAX_PAIR_COMPARISONS, DEFAULT_ARCHIVE_AFTER_DAYS, DEFAULT_ARCHIVE_RETENTION_POLICY, DEFAULT_CITATION_POLICY, DEFAULT_CITATION_REF_BUDGET, DEFAULT_CONSOLIDATION_FAILURES, DEFAULT_CURATOR_BOOT_GRACE_SECONDS, DEFAULT_CURATOR_INTERVAL_HOURS, DEFAULT_CURATOR_MODEL, DEFAULT_CURATOR_REVIEW_MAX_TOKENS, DEFAULT_HEALTH_THRESHOLDS, DEFAULT_MAX_OPS_PER_PLAN, DEFAULT_MEMORY_CHAR_LIMIT, DEFAULT_MEMORY_REVIEW_MODEL, DEFAULT_MIN_IDLE_HOURS, DEFAULT_MUTATION_CAP, DEFAULT_REFERENCE_REWRITE_POLICY, DEFAULT_REVIEW_CONTEXT_MESSAGES, DEFAULT_REVIEW_MEMORY_INTERVAL, DEFAULT_REVIEW_MESSAGE_CHARS, DEFAULT_REVIEW_SKILL_INTERVAL, DEFAULT_REVIEW_TIMEOUT_MS, DEFAULT_SKILL_CONTENT_CHARS, DEFAULT_SKILL_LIMITS, DEFAULT_SKILL_REVIEW_COMPLETION_MIN_TOOL_CALLS, DEFAULT_SKILL_REVIEW_MODEL, DEFAULT_SKILL_REVIEW_TRIGGER, DEFAULT_STALE_AFTER_DAYS, DEFAULT_SUBSTANTIVE_MIN_AGENT_CHARS, DEFAULT_SUBSTANTIVE_MIN_TOOL_CALLS, DEFAULT_SUBSTANTIVE_MIN_USER_CHARS, DEFAULT_SUPPORT_FILE_CHAR_POLICY, DEFAULT_SUPPORT_READ_TOOL_NAMES, DEFAULT_THREAT_MAX_SCAN_CHARS, DEFAULT_USER_CHAR_LIMIT, DISPATCH_EVENT_TYPES, DRIFT_MAX_LINE_CHARS, DRIFT_SIGNALS_VERSION, DRIFT_SIGNAL_NOUNS, DSH_AUTHORING_STANDARDS, EMPTY_LOCK_TAKEOVER_MS, ENTRY_DELIMITER, EVENT_ARCHIVE_PREFIX, EVENT_LOG_RETAIN_ARCHIVES, EVENT_LOG_ROTATE_AT, EVENT_LOG_VERSION, EVOLUTION_ERRORS, EVOLUTION_WRITE_TOOLS, EvolutionGateSet, FAMILY_SESSION_TOOL_NAMES, FORBIDDEN_CONTROL_KEYS, HEALTH_STAMP_RE, HOOK_LINE_RE, INSTANCE_KEYS, KEEP_LINE_RE, LOCK_BODY_RE, LOCK_SUFFIX, LOCK_TEAR_TAKEOVER_MS, LOW_QUALITY_THRESHOLD, LostWriteLock, MAINTAIN_OUTPUT_INSTRUCTION, MAINTAIN_PROMPT, MAX_DESCRIPTION_LENGTH, MAX_RESTRUCTURE_MOVES, MAX_SKILL_CONTENT_CHARS, MAX_SKILL_FILE_BYTES, MAX_SKILL_NAME_LENGTH, MAX_SUPPORT_READ_PATHS, MAX_TIMER_DELAY_MS, MEMORY_GUIDANCE_SECTION_ORDER, MEMORY_REVIEW_PROMPT, MIN_STAMP_BODY_CHARS, MUTATIONS_FILE_VERSION, MemoryStore, NATIVE_CALL_EVENT, NATIVE_RESULT_EVENT, PARAM_ALIASES, PARAM_EXPOSURE, PARAM_NAMESPACES, PATTERN_OVERLAP, PLATFORM_ESTIMATE_CHARS_PER_TOKEN, POLICY_STAGE_DEFAULTS, PROMPT_BUNDLE, PROMPT_BUNDLE_ID, PROMPT_BUNDLE_VERSION, PROTECTED_BUILTIN_SKILLS, PTC_DISPATCH_EVENT, PTC_DISPATCH_START_EVENT, QUALITY_WEIGHTS, RESTRUCTURE_TARGET_RE, SKILLS_GUIDANCE, SKILLS_GUIDANCE_SECTION_ORDER, SKILL_ACTION_REQUIRED_FIELDS, SKILL_NAME_RE, SKILL_REVIEW_PLAN_PROMPT, SKILL_REVIEW_PROMPT, SNAPSHOT_EXTRA_NAME_RE, SUPPORT_DIRS, SUPPRESSED_FILE_VERSION, SkillLibrary, THREAT_EXEMPTION_HINT, TOKEN_ASCII_WEIGHT, TOKEN_CJK_WEIGHT, ToolDispatchNormalizer, ToolDispatchPayloadError, UPSTREAM_LIMIT_CHARS_PER_TOKEN, advanceReview, allowRowCollisions, appendEvolutionEvent, applyCuratorLifecycleFields, applyCuratorMetaFields, applyReferenceRewrite, assertDispatchPayload, assertSkillsRootAliasRetired, assessStructureHealth, authoringFeedback, bodyCost, buildCuratorRunReport, buildLearnPrompt, bumpPatch, bumpSupportRead, bumpUse, bumpView, callingScope, canonicalWriteId, claimInstance, clampedNumber, clearReviewChannel, collectReadSkillNames, composePresetComposition, computeDedupGroups, computeDriftSignals, computeLifecycleTransitions, computePrefixClusters, computeQualityScores, computeScopeView, contentHash, countDispatches, createGateSet, daysSinceIso, decideTakeover, describeReferenceRewrite, duplicateHeadings, emptyRecord, errorText, evaluateThreat, eventsFile, evolutionEventPayloadIssue, evolutionHome, evolutionIoAdapter, evolutionRoot, findDriftSignal, foldCuratorFields, foldToolDispatches, foldTurn, frontmatterBlock, frontmatterCatalogInvalid, getRecord, idleDays, installParamSection, instanceClaimKey, instanceClaimedWriteSites, instanceHolder, isAbsent, isCommittedWarning, isDeprecatedParamId, isFileShapedPath, isMissingPath, isPresent, isProcessAlive, isProgramToolName, isReviewChannelSession, isSkillReadToolName, isSkillToolName, isUnknown, latestActivityAt, lifecycleCandidate, listEventArchives, loadMutations, loadRowOverrides, loadSuppressedNames, loadUsage, makeSerialQueue, mapProbe, markAgentCreated, markReviewChannel, markerEntryName, memoryRoot, missingSupportPointers, mutateUsage, mutationsFile, narrowNameMatches, neutralizePromptVariables, newSkillLibrary, nodeEvolutionIo, normalizeFrontmatter, normalizeUsageRecord, observeEvent, overlongLines, paramNamespace, paramSectionOverrides, parseCuratorNominations, parseEvolutionEvents, parseFrontmatter, parseLockBody, pendingSelfCleanup, persistedWriteSite, persistedWriteSites, planReferenceRewrite, planRehoming, policyStageLimits, probeAbsent, probeList, probeMtime, probePresent, probeReason, probeUnknown, readDispatchSignal, readEvolutionEvents, readEvolutionTimeline, readNumberParam, readParam, recordMutation, redactSecrets, relatedSkillNames, releaseInstance, renameWithRetry, renderCuratorReportMarkdown, resolveCitations, resolveExecOrigins, resolveOrigins, resolveParamId, resolveRootConfig, resolveSkillsRoot, retainEventArchives, retirementReport, reviewPrompt, saveSuppressedNames, saveUsage, scanBodyHooks, scanContentThreats, scanMemoryThreats, scanThreats, scopedProbeReport, sessionAudited, sessionSeesFamilyTools, skillReadNameOf, skillsRoot, supportFileReadOf, suppressedFile, sweepReviewChannelSessions, tokenLineFor, transactIo, transactTaskGuard, unhookedSupportPointers, updateSuppressedNames, usageFile, usageObserved, validateFrontmatter, validateRestructureTarget, valueOr, verifyPromptBundle, writeDurableTmp, yamlPlainScalarNeedsQuotes };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * THE error-code table: E-301…E-316 with the exact text each one emits.
3
+ *
4
+ * The codes used to be spelled out at 33 call sites across two packages, so one
5
+ * code's wording could drift between the branches that answer it and nothing could
6
+ * see the drift. Keys name the SCENARIO rather than the code, because a code
7
+ * legitimately carries more than one text (E-301 answers pending / approve / reject
8
+ * with different guidance); the code still leads every string, so model- and
9
+ * user-facing output is unchanged. Interpolations are written `%aN%` and filled by
10
+ * `errorText` from the values the call site used to interpolate inline.
11
+ * @module @lmzhen/dsh-evolution-core
12
+ */
13
+ export declare const EVOLUTION_ERRORS: Readonly<{
14
+ readonly 'e-305-this-invocation-carries-no': "E-305: this invocation carries no agent — `%a1%` needs a session-backed call (run it from a session in the GUI or the CLI).";
15
+ readonly 'e-306-this-deployment-stages-foreground': "E-306: this deployment stages foreground writes, but `/evolution %a1%` is not replayable through the skill runner — there is nothing to stage. Run it from a session whose approval policy is 'never', or set `stageForeground: false` on the evolution-approval row, then repeat the command.";
16
+ readonly 'e-301-approval-service-not-mounted': "E-301: approval service not mounted — pending writes cannot be listed or replayed. Next: the evolution-approval row ships with evolution-host/evolution-all — run /evolution doctor to see which services are mounted.";
17
+ readonly 'e-301-approval-service-not-mounted-2': "E-301: approval service not mounted. Next: the evolution-approval row ships with evolution-host/evolution-all — run /evolution doctor to see which services are mounted.";
18
+ readonly 'e-304-the-mounted-approval-service': "E-304: the mounted approval service predates the release capability — reject the record instead.";
19
+ readonly 'e-302-curator-service-not-mounted': "E-302: curator service not mounted. Next: mount the evolution-curator row (evolution-host/evolution-all) and run /evolution doctor.";
20
+ readonly 'e-305-the-invocation-agent-exposes': "E-305: the invocation agent exposes neither `followup` nor `inject` — this learn request has no delivery channel.";
21
+ readonly 'e-306-this-deployment-stages-foreground-2': "E-306: this deployment stages foreground writes, but this invocation carries no agent session — `/evolution restructure` would stage a record with no session attribution. Run it from a session in the GUI or the CLI, or set `stageForeground: false` on the evolution-approval row, then repeat the command.";
22
+ readonly 'e-303-replay-service-not-mounted': "E-303: replay service not mounted. Next: mount the evolution-replay row (evolution-host/evolution-all) and run /evolution doctor.";
23
+ readonly 'e-307-the-settings-service-could': "E-307: the settings service could not report its sections (%a1%). /evolution params needs the user layer to tell an override from a deployment value; run /evolution doctor to see which services are mounted.";
24
+ readonly 'e-308-unknown-parameter-group-group': "E-308: unknown parameter group \"%a1%\" — known groups: %a2%.";
25
+ readonly 'e-311-no-settings-service-is': "E-311: no settings service is mounted, so there is no user layer to write. Mount the settings row (packages/settings/settings-file) and retry; this command never edits cordis.yml — a deployment value belongs to the deployment. /evolution doctor lists the mounted services.";
26
+ readonly 'e-312-error-instanceof-Error-error': "E-312: %a1% — /evolution params lists the canonical ids.";
27
+ readonly 'e-313-unknown-parameter-id-evolution': "E-313: unknown parameter \"%a1%\" — /evolution params lists every registered id with its tier and user layer.";
28
+ readonly 'e-314-id-is-a-deployment': "E-314: \"%a1%\" is a deployment parameter (tier %a2%, owner %a3%) — it is written in cordis.yml on its plugin or policy row, not from a session. /evolution params shows who may write each row.";
29
+ readonly 'e-315-id-has-no-user': "E-315: \"%a1%\" has no user layer — owner %a2% publishes no settings namespace, so the value stays with the deployment.";
30
+ readonly 'e-307-the-settings-service-could-2': "E-307: the settings service could not report its sections (%a1%). /evolution policy set needs the current revision to write safely; run /evolution doctor to see which services are mounted.";
31
+ readonly 'e-316-namespace-namespace-is-not': "E-316: namespace \"%a1%\" is not registered — owner %a2% is not mounted in this composition, so its parameters cannot be written from here. /evolution params marks those rows 'unregistered'.";
32
+ readonly 'e-309-revision-conflict-you-sent': "E-309: revision conflict — you sent %a1%, the document stands at %a2%. Re-read with /evolution params --json and retry.";
33
+ readonly 'e-309-revision-conflict-message-Re': "E-309: revision conflict — %a1%. Re-read with /evolution params --json and retry.";
34
+ readonly 'e-310-the-settings-service-refused': "E-310: the settings service refused the write: %a1% — the owning plugin's rule stands (a cross-field pair, or a cap that may only be tightened). /evolution params shows the current value.";
35
+ readonly 'e-305-this-invocation-carries-no-2': "E-305: this invocation carries no agent — `%a1%` needs a session-backed call (run it from a session in the GUI or the CLI).";
36
+ }>;
37
+ /** One table key. */
38
+ export type EvolutionErrorId = keyof typeof EVOLUTION_ERRORS;
39
+ /**
40
+ * Render one table entry, substituting its interpolation slots.
41
+ * @param id - the scenario key.
42
+ * @param args - values for the entry's `%aN%` slots.
43
+ * @returns the message text the call site used to spell out inline.
44
+ */
45
+ export declare function errorText(id: EvolutionErrorId, args?: Record<string, string | number>): string;
46
+ //# sourceMappingURL=errors.d.ts.map
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * - **Cross-cutting basics** — `state-store.ts` (env roots — the single
16
16
  * source of DSH-home semantics), `serial.ts`, `numeric.ts`, `constants.ts`,
17
- * `mutations.ts`, `events.ts`, `gates.ts`.
17
+ * `mutations.ts`, `events.ts`, `gates.ts`, `errors.ts` (the error-code table).
18
18
  * - **Security primitives** — `threats.ts` (content threat scanner),
19
19
  * `redact.ts` (credential masking at model boundaries). Consumers:
20
20
  * evolution-policy/threat, both stores, review, maintenance.
@@ -33,6 +33,7 @@ export * from './evolution-events.ts';
33
33
  export * from './gates.ts';
34
34
  export * from './events.ts';
35
35
  export * from './env.ts';
36
+ export * from './errors.ts';
36
37
  export * from './io.ts';
37
38
  export * from './learn-prompt.ts';
38
39
  export * from './memory-store.ts';
@@ -60,6 +60,15 @@ export type ParamAuthority = 'code' | 'cordis' | 'install';
60
60
  * `applies` is the SETTINGS-side timing: 'none' means the parameter is not
61
61
  * writable through the user layer (a cordis.yml change still follows the
62
62
  * deployment's patch-reload policy).
63
+ *
64
+ * UI METADATA (0.7.0): every E3 row carries the optional tail
65
+ * `label, hint, control, unit, values` — in that order, directly after
66
+ * `summary`, still one entry per line. E3 is the only tier the settings cards
67
+ * render, so the card's Chinese name, help text, control kind, unit suffix and
68
+ * value domain come from THIS registry and nowhere else; the browser half is
69
+ * generated from this text (`gen-param-client-view.mjs`). Non-E3 rows must NOT
70
+ * carry the tail (there is no UI surface for them), and `control: 'select'`
71
+ * requires a non-empty pipe-joined `values`.
63
72
  */
64
73
  export interface ParamExposure {
65
74
  id: string;
@@ -70,6 +79,16 @@ export interface ParamExposure {
70
79
  applies: 'live' | 'restart' | 'none';
71
80
  docAnchor: string;
72
81
  summary: string;
82
+ /** Card label (Chinese, short). Required on E3 rows. */
83
+ label?: string;
84
+ /** Card help text (Chinese, one sentence). Required on E3 rows. */
85
+ hint?: string;
86
+ /** Which control the card renders for this field. Required on E3 rows. */
87
+ control?: 'number' | 'switch' | 'select' | 'text';
88
+ /** Unit suffix shown next to a number (empty when it carries none). */
89
+ unit?: string;
90
+ /** Pipe-joined allowed values; non-empty exactly when control is 'select'. */
91
+ values?: string;
73
92
  }
74
93
  /**
75
94
  * The parameter registry. G1/S1.1 seeds it with the review group (G-C); the
@@ -85,6 +104,16 @@ export declare const PARAM_EXPOSURE: readonly ParamExposure[];
85
104
  * tool-memory, each owning its own section. A package without an entry has no
86
105
  * user layer (its knobs stay deployment-only). */
87
106
  export declare const PARAM_NAMESPACES: Readonly<Record<string, string>>;
107
+ /**
108
+ * The settings namespace one owner package registers. The registry's map is the only
109
+ * place a namespace is spelled: a package without an entry has no user layer, so a
110
+ * missing entry must fail loud here instead of letting a package fall back to a
111
+ * private constant that the registry never sees.
112
+ * @param owner - owner package directory name (the map's key).
113
+ * @returns the namespace that owner registers.
114
+ * @throws when the owner has no entry in {@link PARAM_NAMESPACES}.
115
+ */
116
+ export declare function paramNamespace(owner: string): string;
88
117
  /** Structural view of one registered settings scope (platform Service Definition).
89
118
  * Declared locally so this module keeps its zero-import, zero-dependency shape. */
90
119
  interface SettingsScopeLike {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-core",
3
3
  "description": "Shared stores, prompts, signals and lifecycle logic for the dsh-evolution plugin family (community build)",
4
- "version": "0.6.1",
4
+ "version": "0.8.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },