@xiciyang/rsi-contract 0.0.0-stage → 0.1.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/CONTRACT.md +240 -0
- package/LICENSE +29 -0
- package/README.md +76 -2
- package/package.json +17 -4
- package/src/contract.mjs +890 -0
- package/src/criterion.mjs +48 -0
- package/src/direction-selection.mjs +234 -0
- package/src/effect-judgment.mjs +210 -0
- package/src/goal-setting.mjs +255 -0
- package/src/index.mjs +135 -0
- package/src/risk-assessment.mjs +186 -0
- package/src/rollback-decision.mjs +248 -0
- package/src/support.mjs +198 -0
- package/src/version.mjs +20 -0
package/CONTRACT.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# @xiciyang/rsi-contract —— 契约 v0(五个「自」能力)
|
|
2
|
+
|
|
3
|
+
> **这是什么**:五个能力的**载体库** —— 目标设定 / 方向选择 / 效果判定 / 风险识别 / 回退决策。
|
|
4
|
+
> **这不是什么**:**不是循环**。本库不含编排、调度、迭代控制、重试、停止条件、预算控制、状态持久化。
|
|
5
|
+
> 每个能力都是**一次纯函数调用**:给输入、出结论、附证据、自带阻断理由。逐轮推进是调用方(编排层)的事。
|
|
6
|
+
>
|
|
7
|
+
> 人读版报告在工作区根:`RSI_SELF_CAPABILITIES.md`。
|
|
8
|
+
|
|
9
|
+
**契约版本**:`0.1.0` **能力语义版本**:`2.0.0` **包版本**:`0.0.1` **运行时依赖**:无
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 0. 导出面
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
CONTRACT_VERSION · CAPABILITY_VERSION · CAPABILITY_IDS · ERROR_CODES · VOCAB
|
|
17
|
+
CAPABILITY_MANIFEST · getCapability(id) · verifyCapabilityContract({sourceText,patterns})
|
|
18
|
+
goalSetting(input) · directionSelection(input) · effectJudgment(input)
|
|
19
|
+
riskAssessment(input) · rollbackDecision(input) · verifyRollbackDecision({decision,observed})
|
|
20
|
+
significance({improvement,se,z}) · SIGNIFICANCE_CRITERION · SELECTION_RULE
|
|
21
|
+
EFFECT_CHECK_ORDER · VERIFICATION_CRITERION · RISK_ORDER
|
|
22
|
+
canonicalJson(v) · jsonClone(v,name) · jsonSafeReport(v) · factorTable() · assertNoSafeLevel()
|
|
23
|
+
RsiLoopError · DIRECTIONS
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
跑法:`node tests/run.mjs`(或 `npm test`);等价入口 `node tests/contract.mjs`。
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. 五个能力的分配(谁负责什么,边界在哪)
|
|
31
|
+
|
|
32
|
+
| 能力 | 回答的问题 | **明确不做** |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `goalSetting` | 现在有哪几件**值得做且做得成**的事? | 不选具体手段、不评估风险、不执行 |
|
|
35
|
+
| `directionSelection` | 用哪个手段去做? | 不评估风险(只透传)、不执行、不改目标度量 |
|
|
36
|
+
| `effectJudgment` | 做完之后,Δ 是**真的**吗? | 不产出"下一步"、**不用自己产出的证据** |
|
|
37
|
+
| `riskAssessment` | 这个方向有多危险? | 不做回退决策、不执行、不替调用方降档 |
|
|
38
|
+
| `rollbackDecision` | 出事了回到哪、怎么回、**怎么证明回去了**? | 不执行回退、不触发回退(只给方案) |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2. 五条横切纪律(对所有能力成立,且有测试举证)
|
|
43
|
+
|
|
44
|
+
| # | 纪律 | 具体形态 | 举证 |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| 1 | **产物自带证据** | 每个产物带 `evidenceRefs` / `evidence`,第三方可重算;`jsonSafeReport` 全绿 | `determinism.spec`:JSON 卫生 + 反向对照(函数/NaN/循环会被报出) |
|
|
47
|
+
| 2 | **确定性** | 同输入同输出;无时钟/无随机/无环境变量;所有排序是**全序**(带唯一 tiebreak);产物无时间字段 | `determinism.spec`(同输入两次逐字节相同 + 源码扫描);`rollback-decision.spec`(改 `verifiedAt` 不改变目标) |
|
|
48
|
+
| 3 | **fail-closed** | 缺输入就拒绝;**没有兜底默认值**这条路径;阈值/离散度/z 一律由调用方给出 | 各 spec 的"缺 X ⇒ refused"断言;`manifest.spec` 断言 schema 里**没有 `default`** |
|
|
49
|
+
| 4 | **不自证** | 能力不得消费自己的产物当验证 | `effect-judgment.spec`(`producedBy=effectJudgment` ⇒ 拒绝);`rollback-decision.spec`(同上) |
|
|
50
|
+
| 5 | **声明即可枚举** | `CAPABILITY_MANIFEST` 给出 id/version/两个 schema/失败模式;`falsifiedBy` 指向**真实存在**的 spec | `manifest.spec`:逐条去磁盘确认该 spec 文件存在且含断言 |
|
|
51
|
+
|
|
52
|
+
**零运行时依赖**是可检查事实,不是注释:`determinism.spec` 断言 `src/**.mjs` 里没有
|
|
53
|
+
`from 'node:*'`、没有 `from '@xiciyang/*'`、没有 `from '../…'`。
|
|
54
|
+
需要文件系统/网络时由调用方在库外取好数据、以参数注入(沿用 `@xiciyang/state-core` 的
|
|
55
|
+
`parseFile(fs, path)` 式方言约定)。
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 3. 逐能力契约
|
|
60
|
+
|
|
61
|
+
### 3.1 `goalSetting` —— 目标设定
|
|
62
|
+
|
|
63
|
+
**输入**:`{ state: { metrics, lineage?, history?, constraints? }, means?, options? }`
|
|
64
|
+
- `metrics`: `{ [metricId]: { value, direction, evidenceRefs?, expectedDelta?, atBound?, unit? } }`
|
|
65
|
+
- `means?`: **可选**,只用于可达性分析(`[{id, targets}]`);手段菜单的完整契约在 `directionSelection`。
|
|
66
|
+
|
|
67
|
+
**输出**:`{ capability, version, goals[], refused, code, reasons[], evidenceRefs[] }`
|
|
68
|
+
每条 `goal`:`{ goalId, statement, targetMetric, direction, expectedDelta, rationale, evidenceRefs[], priority, priorityBasis, blocked? }`
|
|
69
|
+
|
|
70
|
+
**语义**
|
|
71
|
+
- 期望增量只有两个来源,且都要能在**本次输入内**复核:① 度量自带 `expectedDelta`(并要求该度量带可解析的 `evidenceRefs`);② 既往**成功**轮次 `delta` 的**中位数**(证据引用=那些轮次 id)。两者都没有 ⇒ 阻断。
|
|
72
|
+
- `priority = |expectedDelta| / |当前值|`(无量纲相对量);当前值为 0 ⇒ `priority: null` + `priorityBasis: 'unavailable'`(不是 0)。
|
|
73
|
+
- 排序是**全序**:未阻断在前 → `priority` 降序(null 在后)→ `goalId` 升序。
|
|
74
|
+
|
|
75
|
+
**失败模式**
|
|
76
|
+
|
|
77
|
+
| code | 名称 | 检出条件 |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `E_GOAL_UNREACHABLE` | 目标不可达 | `expectedDelta ≤ 0` / `atBound=true` / 声明的 `means` 中无任何手段覆盖该度量 |
|
|
80
|
+
| `E_GOAL_CONFLICT` | 目标冲突 | 两候选度量出现在**已声明**的 `tradeoff` / `mutually-exclusive` 关系里 ⇒ **双方**都 blocked 并互相点名(`conflictsWith`);不静默替调用方选边 |
|
|
81
|
+
| `E_GOAL_MEANINGLESS` | 目标无意义 | 无 `direction` / 无证据引用 / 引用在输入内无法解析 / 期望增量无来源 |
|
|
82
|
+
| `E_METRICS_ABSENT` | 度量缺失 | `state.metrics` 缺失或为空 ⇒ `refused` + `goals: []`。**绝不发明度量** |
|
|
83
|
+
|
|
84
|
+
**被阻断的候选不伪造值**:`direction: null`、`expectedDelta: null`(不是占位方向、不是 0)。
|
|
85
|
+
|
|
86
|
+
### 3.2 `directionSelection` —— 方向选择
|
|
87
|
+
|
|
88
|
+
**输入**:`{ goal: {goalId,targetMetric,direction,expectedDelta?,evidenceRefs?}, means[], constraints?, preferredMeansId? }`
|
|
89
|
+
`means[i] = { id, targets[], expectedGain, risk, irreversible?, evidenceRefs? }`
|
|
90
|
+
(`risk` = **`riskAssessment` 的产物**,本能力只透传。)
|
|
91
|
+
|
|
92
|
+
**输出**:`{ chosen, rationale, expectedGain, risk, alternativesConsidered[], refused, code, reasons[], evidenceRefs[], selectionRule }`
|
|
93
|
+
|
|
94
|
+
**选择规则**(写进产物 `selectionRule`):在"菜单内 ∧ 打在目标度量上 ∧ 满足全部声明约束 ∧ 已附带风险结论 ∧ 增益可测"的手段中,取 `expectedGain` 最大者;同值按 `meansId` 升序(全序)。
|
|
95
|
+
|
|
96
|
+
**失败模式**
|
|
97
|
+
|
|
98
|
+
| code | 名称 | 检出条件 |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| `E_MEANS_NOT_IN_MENU` | 不可行(不在菜单内) | `preferredMeansId` 不在 `means` 里 ⇒ 整体 refused |
|
|
101
|
+
| `E_DIRECTION_MISMATCH` | 方向错误 | 手段 `targets` 不含 `goal.targetMetric` ⇒ 不可采纳;被强制指定时整体拒绝 |
|
|
102
|
+
| `E_CONSTRAINT_VIOLATION` | 与约束冲突 | `forbid-means` / `forbid-irreversible` / `require-target` 三类。**`forbid-irreversible`(v2.0.0 起)把 `inPlace === true` 也算不可逆**(与 `riskAssessment` 的自动注入对齐);旧语义经 `options.legacyForbidIrreversible=true` 保留,产物用 `constraintSemantics` 自述用了哪一版 |
|
|
103
|
+
| `E_RISK_MISSING` | 风险未透传 | 手段缺 `risk`,或 `risk.level` 不在词表内 ⇒ 不可采纳 |
|
|
104
|
+
| `E_MEANS_UNMEASURABLE` | 手段增益不可测 | `expectedGain` 不是有限数 |
|
|
105
|
+
| `E_NO_MEANS` / `E_NO_ADMISSIBLE_MEANS` | 无可选方向 | 菜单为空 / 菜单内全部被拒 |
|
|
106
|
+
|
|
107
|
+
`risk` 是**深拷贝**透传:调用方之后修改输入对象不会改变已产出的产物。
|
|
108
|
+
|
|
109
|
+
### 3.3 `effectJudgment` —— 效果判定(最重要)
|
|
110
|
+
|
|
111
|
+
**输入**:`{ before:{metric,value,datasetHash,evidenceRefs?}, after:{…}, integrity:{attempted,succeeded,failed,partial,producedBy?,evidenceRefs?}, direction, threshold:{minDelta}, noise:{se,z} }`
|
|
112
|
+
|
|
113
|
+
**输出**:`{ verdict:'success'|'failure'|'measurement-invalid', refused, code, inconclusive?, evidence, reasons[], evidenceRefs[] }`
|
|
114
|
+
|
|
115
|
+
**判定顺序**(全部有效性检查都跑完、`reasons[]` 列全部失败项;`code` 取固定优先级第一条 ⇒ 产物确定且病因可区分):
|
|
116
|
+
|
|
117
|
+
| 序 | code | 条件 | 结论 |
|
|
118
|
+
|---|---|---|---|
|
|
119
|
+
| 1 | `E_INTEGRITY_MISSING` | 缺 `attempted/succeeded/failed/partial`,或 `succeeded > attempted` | measurement-invalid |
|
|
120
|
+
| 2 | `E_MEASUREMENT_INCOMPLETE` | `failed > 0` 或 `partial === true` | measurement-invalid(**不完整的测量不是测量**) |
|
|
121
|
+
| 3 | `E_NO_SAMPLES` | `succeeded ≤ 0` 或 `attempted ≤ 0` | measurement-invalid |
|
|
122
|
+
| 4 | `E_METRIC_MISMATCH` | `before.metric ≠ after.metric` | measurement-invalid |
|
|
123
|
+
| 5 | `E_METRIC_VALUE_MISSING` | 任一 `value` 不是有限数 | measurement-invalid(缺值不得当 0) |
|
|
124
|
+
| 6 | `E_DATASET_IDENTITY_MISSING` | 缺 `datasetHash` | measurement-invalid(未知 ≠ 已知完整) |
|
|
125
|
+
| 7 | `E_DATASET_MISMATCH` | 两侧 `datasetHash` 不同 | measurement-invalid(`eval-contract` §7.1) |
|
|
126
|
+
| 8 | `E_SELF_JUDGING` | `integrity.producedBy === 'effectJudgment'` | measurement-invalid |
|
|
127
|
+
| 9 | `E_THRESHOLD_NOT_PROVIDED` | `minDelta` / `se` / `z` 缺失、非有限或为负 | refused(**不发明判据**:本库没有 1.96 这样的默认值) |
|
|
128
|
+
|
|
129
|
+
有效性全过之后才谈数值:
|
|
130
|
+
- `improvement > z·SE` 不成立 ⇒ `failure` + `inconclusive: true`,code `E_WITHIN_NOISE`;
|
|
131
|
+
- 显著但 `improvement < minDelta` ⇒ `failure`,code `E_BELOW_THRESHOLD`;
|
|
132
|
+
- 否则 ⇒ `success`。
|
|
133
|
+
|
|
134
|
+
`improvement` 的定义:`direction='lower-is-better' ? before − after : after − before`(正数 = 变好)。
|
|
135
|
+
判据形式 `improvement > z·SE` 与冻结参考实现 `inference-training/checks/overfit-criterion.mjs`
|
|
136
|
+
的 O2 判据**逐字一致**,并由 `effect-judgment.spec` 做**跨实现一致性**断言(不可 import 时显式 skip,不计入断言数)。
|
|
137
|
+
`refused === true` ⟺ `verdict === 'measurement-invalid'`。
|
|
138
|
+
|
|
139
|
+
### 3.4 `riskAssessment` —— 风险识别
|
|
140
|
+
|
|
141
|
+
**输入**:`{ direction: { id, kind?, targetMetric?, factors[]?, irreversible?, inPlace?, declaredLevel?, evidenceRefs? }, state? }`
|
|
142
|
+
|
|
143
|
+
**输出**:`{ level, mitigations[], requiresHumanConfirmation, reasons[], factorLevels[], calibration, refused, code, evidenceRefs[] }`
|
|
144
|
+
|
|
145
|
+
**词表**:`level ∈ {low, medium, high, critical}` —— **没有 `none` / `safe` 这一档**(`assertNoSafeLevel()` 在测试里守着)。
|
|
146
|
+
档位 = 各因子档位的**上界(max)**,不取平均(平均会把 critical 摊薄成 medium)。
|
|
147
|
+
|
|
148
|
+
**因子对照表**(冻结,表外一切皆为"未识别"):
|
|
149
|
+
|
|
150
|
+
| 因子 | 档位 |
|
|
151
|
+
|---|---|
|
|
152
|
+
| `read-only-observation` · `reversible-local` · `resource-consuming` | low |
|
|
153
|
+
| `shared-state` · `external-side-effect` · `artifact-overwrite` | medium |
|
|
154
|
+
| `irreversible-in-place`(**独立风险档**) · `irreproducible` · `affects-eval-data` · `user-visible-position` | high |
|
|
155
|
+
| 表外因子 / 一个因子都没声明 | **critical** |
|
|
156
|
+
|
|
157
|
+
`irreversible === true` 或 `inPlace === true` ⇒ **自动注入** `irreversible-in-place`(产物标 `injected: true`)。
|
|
158
|
+
"调用方漏写"被结构事实补上,而不是被判为安全。`requiresHumanConfirmation = level ∈ {high, critical}`。
|
|
159
|
+
|
|
160
|
+
**失败模式**
|
|
161
|
+
|
|
162
|
+
| code | 名称 | 检出条件 |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| `E_RISK_UNCLASSIFIED` | 风险未识别 | 未声明任何因子,或出现词表外的因子 ⇒ 升到 `critical` + 需人工确认(**never safe**) |
|
|
165
|
+
| `E_RISK_UNDERESTIMATE` | 低估风险 | `declaredLevel` 低于计算档位 ⇒ **采用计算档位** |
|
|
166
|
+
| `E_RISK_OVERESTIMATE` | 高估风险 | `declaredLevel` 高于计算档位 ⇒ 报出但**保留调用方的更高档位**(把人的谨慎降下来是另一种错)。另有**校准对照**:已完全归类且良性可逆的方向必须落在 `low` |
|
|
167
|
+
|
|
168
|
+
### 3.5 `rollbackDecision` —— 回退决策
|
|
169
|
+
|
|
170
|
+
**输入**:`{ failure: {stateId, artifacts:[{name,sha256}]}, history: [{stateId, seq?, artifacts[], verifiedGood, verifiedBy?, verifiedAt?, evidenceRefs?}], proposedVerification? }`
|
|
171
|
+
|
|
172
|
+
**输出**:`{ target, path, verification, refused, code, reasons[], evidence, evidenceRefs[] }`
|
|
173
|
+
|
|
174
|
+
**可信候选的三个条件**(缺一不可):`verifiedGood === true` ∧ `verifiedBy` 非空 ∧ 产物全部带 `sha256:<64hex>`。
|
|
175
|
+
候选还必须**覆盖故障态的全部产物**,且不得与故障态**逐产物全等**(那就是空操作)。
|
|
176
|
+
排序只按 `seq`(缺失则按输入下标并在 `orderingBasis` 里标明);**时间戳不参与决策**。
|
|
177
|
+
|
|
178
|
+
**核验**(`verification`):`kind='artifact-content-hash'`、`comparator='sha256-equal'`,
|
|
179
|
+
每条 check 带 `expectSha256` 与 `notBeforeSha256`。`verifyRollbackDecision({decision, observed})`
|
|
180
|
+
把**别处产出的**现场观测与之比对。
|
|
181
|
+
|
|
182
|
+
**失败模式**
|
|
183
|
+
|
|
184
|
+
| code | 名称 | 检出条件 |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| `E_NO_ROLLBACK_TARGET` | 回退失败(无可信目标) | 无任何满足三条件的候选 ⇒ refused(**不猜最近的那个**) |
|
|
187
|
+
| `E_TARGET_NOT_VERIFIED_GOOD` | 把未验证状态当可信目标 | `verifiedGood !== true` 或缺 `verifiedBy` |
|
|
188
|
+
| `E_ARTIFACT_SET_MISMATCH` | 回退不彻底(决策期) | 候选未覆盖故障态全部产物 / 产物缺合法哈希 / 故障态本身无哈希 |
|
|
189
|
+
| `E_ROLLBACK_NOOP` | 回退失败(空操作) | 候选与故障态哈希全等 ⇒ 排除;核验期 `observed === notBeforeSha256` ⇒ 判失败 |
|
|
190
|
+
| `E_ROLLBACK_WRONG_VERSION` | 回退到错误版本 | 核验期 `observed` 哈希能归属到**别的**历史状态 ⇒ **指名**是哪一个 |
|
|
191
|
+
| `E_ROLLBACK_INCOMPLETE` | 回退不彻底(核验期) | `observed` 缺某个必需产物的哈希 |
|
|
192
|
+
| `E_PROCESS_ONLY_VERIFICATION` | 只断言过程 | `proposedVerification` 不是产物级;或 `observed` 只有退出码/日志没有哈希 |
|
|
193
|
+
| `E_SELF_JUDGING` | 自证回退生效 | `observed.producedBy === 'rollbackDecision'` |
|
|
194
|
+
|
|
195
|
+
> **本仓库原则**:"只断言过程抓不到空操作,必须断言权重。"
|
|
196
|
+
> `exitCode === 0` + 哈希未变 ⇒ 判 `E_ROLLBACK_NOOP`(过程看起来完全成功)。
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 4. 词表
|
|
201
|
+
|
|
202
|
+
- `direction`:`higher-is-better` / `lower-is-better`
|
|
203
|
+
- `verdict`:`success` / `failure` / `measurement-invalid`
|
|
204
|
+
- `riskLevel`:`low` / `medium` / `high` / `critical`(**无 `none` / `safe`**)
|
|
205
|
+
- `historyOutcome`:`success` / `failure` / `blocked` / `measurement-invalid`
|
|
206
|
+
- 内容哈希:只认 `sha256:<64 位小写十六进制>`
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 5. 版本与解冻
|
|
211
|
+
|
|
212
|
+
**minor**(允许追加):新增可选输入字段、新增失败模式 code、新增缓解措施文案、追加导出。
|
|
213
|
+
**major**(须暂停报告):改任一能力的判定顺序/判据形式、改"缺输入即拒绝"的语义、
|
|
214
|
+
改 `verdict` / `riskLevel` 值域、改 `CAPABILITY_VERSION` 的含义、让本库获得循环控制流。
|
|
215
|
+
|
|
216
|
+
### 5.1 已发生的 major 变更
|
|
217
|
+
|
|
218
|
+
| 版本 | 变更 | 授权 | 旧行为 |
|
|
219
|
+
|---|---|---|---|
|
|
220
|
+
| **`1.0.0 → 2.0.0`** | `directionSelection` 的 `forbid-irreversible` **纳入 `inPlace === true`** | 用户显式授权(第二轮任务书"走 major 契约变更") | ✅ **完整保留**:`options.legacyForbidIrreversible = true` 恢复 v1.x 语义(只看 `means.irreversible`);产物用 `constraintSemantics` 自述用了哪一版 |
|
|
221
|
+
|
|
222
|
+
> **为什么必须改**:v1.x 下,一个 `inPlace: true` 的手段**能通过** `forbid-irreversible`,
|
|
223
|
+
> 而 `riskAssessment` 认为 `inPlace === true ⇒ 自动注入 irreversible-in-place`(high)。
|
|
224
|
+
> 两个能力对"什么算不可逆"**理解不一致** ⇒ 实测复现:两手段只差 `inPlace`、增益高 `0.001` 时,
|
|
225
|
+
> **声明了禁止不可逆仍然选中就地变更的那个**。
|
|
226
|
+
> 旧语义**不删除**:本仓库硬纪律是"变更判据时保留旧判据作对照"。这里方向是**收紧**而非放宽,
|
|
227
|
+
> 但保留对照同样必要 —— 否则无法证明"改的确实是这一条判据"。
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 6. 已知边界(如实记录)
|
|
232
|
+
|
|
233
|
+
1. **本库尚未登记进 `inference-training/shared/run-all.mjs` 的 `LIBS`** —— 那个文件在本任务范围之外。
|
|
234
|
+
在登记前,`inference-contracts/checks/run-all.mjs` 的 C11 组**不会**自动跑到本库契约;
|
|
235
|
+
`tests/contract.mjs` 就是届时接线的落点(`NAME` + `run(t)` 形态,与六库同款)。
|
|
236
|
+
2. `E_RISK_OVERESTIMATE` 的判定依赖调用方**可选**给出的 `declaredLevel`;不给就只能靠
|
|
237
|
+
`risk-assessment.spec` 的**校准对照**(良性且已归类 ⇒ 必须 low)来守住"不高估"。
|
|
238
|
+
3. `effectJudgment` 的噪声判据只做**单侧**显著性;多重比较校正不在本库职责内(属实验设计)。
|
|
239
|
+
4. 本库**不**校验 `datasetHash` 是否真的是那份数据集的哈希 —— 那是 `eval-contract` §7.3 与
|
|
240
|
+
`EVAL_SET_IDENTITY.json` 的职责;本库只要求"两侧同一个哈希,且哈希在场"。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, xiciyang
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,77 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @xiciyang/rsi-contract
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**五个自改进决策原语**——目标设定、方向选择、效果判定、风险识别、回退决策。
|
|
4
|
+
每个都是一次纯函数调用:给输入、出结论、附证据、自带阻断理由。
|
|
5
|
+
|
|
6
|
+
## 这不是什么(先说清楚)
|
|
7
|
+
|
|
8
|
+
**这不是一个 RSI 循环。** 本库不含:
|
|
9
|
+
|
|
10
|
+
- 编排、调度、迭代控制
|
|
11
|
+
- 重试、停止条件、预算控制
|
|
12
|
+
- 状态持久化、人工晋级闸门
|
|
13
|
+
- 任何"自我进化"的执行体
|
|
14
|
+
|
|
15
|
+
逐轮推进是调用方的事。这里只把"一次决策该怎么判"固化成可测试的契约——因为自改进系统最容易骗自己的地方不是执行,而是**判定**:
|
|
16
|
+
|
|
17
|
+
- 目标设定时把"想做"当成"值得做且做得成"
|
|
18
|
+
- 方向选择时把"能跑通"当成"该走这条路"
|
|
19
|
+
- 效果判定时用自己产出的证据证明自己有效
|
|
20
|
+
- 风险识别时默认"往好处走"
|
|
21
|
+
- 回退决策时给不出"怎么证明真的回去了"
|
|
22
|
+
|
|
23
|
+
五个能力各自回答一个问题,并明确写出**不做什么**(见 `CONTRACT.md` 的分配表)。
|
|
24
|
+
|
|
25
|
+
## 五个能力
|
|
26
|
+
|
|
27
|
+
| 能力 | 回答的问题 | 明确不做 |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `goalSetting` | 现在有哪几件值得做且做得成的事? | 不选手段、不评风险、不执行 |
|
|
30
|
+
| `directionSelection` | 用哪个手段去做? | 不评风险、不执行、不改目标度量 |
|
|
31
|
+
| `effectJudgment` | 做完之后,Δ 是真的吗? | 不产出下一步、不用自己产出的证据 |
|
|
32
|
+
| `riskAssessment` | 这个方向有多危险? | 不做回退决策、不执行、不替调用方降档 |
|
|
33
|
+
| `rollbackDecision` | 出事了回到哪、怎么回、怎么证明回去了? | 不执行回退、不触发回退(只给方案) |
|
|
34
|
+
|
|
35
|
+
另外提供:`significance()`(改进量与显著性判据)、`verifyRollbackDecision()`(回退是否真的发生)、
|
|
36
|
+
`canonicalJson()`、`factorTable()`、`assertNoSafeLevel()`。
|
|
37
|
+
|
|
38
|
+
## 安装
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm i @xiciyang/rsi-contract
|
|
42
|
+
# 或直接把 src/ 拷进你的项目(零运行时依赖,只用 node: 内置模块)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
要求:Node.js >= 20。没有网络、文件系统或 GPU 依赖——需要数据时由调用方在外面取好、以参数注入。
|
|
46
|
+
|
|
47
|
+
## 用法
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import { goalSetting, effectJudgment, rollbackDecision, significance } from '@xiciyang/rsi-contract'
|
|
51
|
+
|
|
52
|
+
const goals = goalSetting({ /* 候选、预算、可验证性 … */ })
|
|
53
|
+
const verdict = effectJudgment({ /* before/after、噪声模型、证据来源 … */ })
|
|
54
|
+
const plan = rollbackDecision({ /* 变更、可达回退点 … */ })
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
每个返回值都带 `ok` / `blocked` / 判据与证据字段;被拒绝时**给出理由**,不是静默返回 false。
|
|
58
|
+
字段与错误码以 `CONTRACT.md` 为准(契约版本 `0.1.0`,能力语义版本 `2.0.0`)。
|
|
59
|
+
|
|
60
|
+
## 测试
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
node tests/run.mjs
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
7 个 spec、616 条断言,覆盖:五个能力的正常/阻断路径、判据自检、确定性(同输入同输出)、
|
|
67
|
+
契约导出面一致性。全部是纯逻辑,任何机器上都应全绿。
|
|
68
|
+
|
|
69
|
+
## 为什么会有人需要它
|
|
70
|
+
|
|
71
|
+
自改进/自动调优系统最常见的事故不是"改错了",而是**判定层坏了却没人发现**:效果判定用了自己刚写下的日志、显著性判据在噪声上做优化、回退方案从未被验证过。把判定抽成纯函数、让每个判定带反例与阻断理由,是这类系统能被外部审查的前提。
|
|
72
|
+
|
|
73
|
+
本库只提供这一层;怎么用、要不要真的自动执行,是调用方的风险决定。
|
|
74
|
+
|
|
75
|
+
## 许可
|
|
76
|
+
|
|
77
|
+
BSD-3-Clause。见 `LICENSE`。
|
package/package.json
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiciyang/rsi-contract",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "五个自改进决策原语(目标设定/方向选择/效果判定/风险识别/回退决策)—— 纯函数库,明确不是循环",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.mjs",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": { "default": "./src/index.mjs" },
|
|
9
|
+
"./package.json": "./package.json"
|
|
10
|
+
},
|
|
11
|
+
"files": ["src", "CONTRACT.md"],
|
|
12
|
+
"license": "BSD-3-Clause",
|
|
13
|
+
"engines": { "node": ">=20" },
|
|
14
|
+
"dependencies": {},
|
|
15
|
+
"scripts": { "test": "node tests/run.mjs" },
|
|
16
|
+
"repository": { "type": "git", "url": "git+https://github.com/xiciyang/rsi-contract.git" },
|
|
17
|
+
"homepage": "https://github.com/xiciyang/rsi-contract#readme",
|
|
18
|
+
"keywords": ["ai-infra", "self-improvement", "decision-primitives", "contract-tests", "dsh"]
|
|
19
|
+
}
|