dsh-vibe-math 2.7.1 → 2.7.3
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/README.en.md +682 -690
- package/README.md +19 -27
- package/cordis.patch.yml +112 -16
- package/docs/AUDIT-CHECKLIST.md +744 -518
- package/docs/COMPAT-AUDIT-ROUND2.md +35 -9
- package/docs/COMPAT-AUDIT-ROUND3.md +154 -154
- package/docs/final-paper.md +172 -172
- package/docs/formal-verification.md +588 -588
- package/docs/math-computation.md +194 -163
- package/docs/parameter-schema.md +37 -0
- package/docs/release-notes/README.en.md +49 -0
- package/docs/release-notes/README.md +48 -0
- package/docs/release-notes/RELEASE-NOTES-2.7.2.en.md +72 -0
- package/docs/release-notes/RELEASE-NOTES-2.7.2.md +72 -0
- package/docs/release-notes/RELEASE-NOTES-2.7.3.en.md +67 -0
- package/docs/release-notes/RELEASE-NOTES-2.7.3.md +67 -0
- package/docs/release-notes/TEMPLATE.md +126 -0
- package/docs/status-report-fields.md +167 -0
- package/docs/test-timing.md +157 -154
- package/installer.js +27 -17
- package/package.json +55 -3
- package/prompt-corpus-persona/persona-corpus.json +9 -9
- package/prompt-corpus-persona/persona-corpus.md +225 -33
- package/prompt-corpus-v2/formal-verify-v2.json +305 -113
- package/prompt-corpus-v2/formal-verify-v2.md +2399 -279
- package/prompt-corpus-v3/formal-verify-v3.json +134 -110
- package/prompt-corpus-v3/formal-verify-v3.md +409 -141
- package/prompt-corpus-v4/formal-verify-v4.json +18 -18
- package/prompt-corpus-v4/formal-verify-v4.md +49 -44
- package/prompt-corpus-v5/prompt-corpus-v5.json +82 -82
- package/prompt-corpus-v5/prompt-corpus-v5.md +513 -259
- package/scripts/update-doc-counts.mjs +71 -0
- package/tests/audit-artifact-docs.mjs +72 -0
- package/tests/audit-artifact-docs.mutants.mjs +58 -0
- package/tests/audit-installer-assertions.mutants.mjs +63 -0
- package/tests/audit-installer-compat.test.mjs +52 -4
- package/tests/audit-installer-policy.test.mjs +41 -8
- package/tests/audit-math-computation-contract.mjs +107 -9
- package/tests/audit-math-computation-contract.mutants.mjs +106 -0
- package/tests/audit-math-computation-parity.mjs +164 -3
- package/tests/audit-math-computation-sensitivity.mjs +6 -4
- package/tests/audit-package-membership.mjs +57 -0
- package/tests/audit-package-membership.mutants.mjs +28 -0
- package/tests/audit-participant-set-parity.mjs +160 -0
- package/tests/audit-path-discipline.mjs +83 -0
- package/tests/audit-path-discipline.mutants.mjs +51 -0
- package/tests/audit-persona-sensitivity.mjs +14 -0
- package/tests/audit-persona-surface.mutants.mjs +69 -0
- package/tests/audit-persona-surface.test.mjs +63 -22
- package/tests/audit-prompt-duplication.mjs +143 -0
- package/tests/audit-prompt-duplication.mutants.mjs +50 -0
- package/tests/audit-prompt-invariants.mjs +43 -5
- package/tests/audit-readme-bilingual.test.mjs +152 -0
- package/tests/audit-readme-counts.mjs +95 -0
- package/tests/audit-readme-counts.mutants.mjs +52 -0
- package/tests/audit-registration.mjs +78 -0
- package/tests/audit-status-report-fields.mjs +172 -0
- package/tests/audit-status-report-fields.mutants.mjs +64 -0
- package/tests/audit-v3-registration-parity.mjs +156 -0
- package/tests/audit-v5-integrity.mjs +300 -13
- package/tests/audit-v5-lean-abstention.mjs +392 -0
- package/tests/audit-v5-lean-abstention.mutants.mjs +106 -0
- package/tests/audit-v5-prompt-duplication.mjs +88 -0
- package/tests/audit-v5-prompt-duplication.mutants.mjs +34 -0
- package/tests/audit-v5-sensitivity.mjs +15 -8
- package/tests/e2e-identity-a6.mutants.mjs +65 -0
- package/tests/e2e-v5-round2.test.mjs +566 -12
- package/tests/formal-verify-v2.test.mjs +91 -5
- package/tests/formal-verify-v3.mutants.mjs +117 -0
- package/tests/formal-verify-v3.test.mjs +85 -6
- package/tests/formal-verify-v4.mutants.mjs +152 -0
- package/tests/formal-verify-v4.test.mjs +628 -9
- package/tests/formal-verify-v5.test.mjs +68 -9
- package/tests/helpers/doc-counts-format.mjs +41 -0
- package/tests/helpers/math-computation-fake-seam.mjs +4 -0
- package/tests/math-computation-a1.mutants.mjs +72 -0
- package/tests/math-computation-archive-rerun.mutants.mjs +65 -0
- package/tests/math-computation-discovery.mutants.mjs +76 -0
- package/tests/math-computation-shared.test.mjs +396 -2
- package/tests/math-computation-v2.test.mjs +767 -0
- package/tests/math-computation-v3.test.mjs +759 -0
- package/tests/math-computation-v4.mutants.mjs +133 -0
- package/tests/math-computation-v4.test.mjs +739 -0
- package/tests/prompt-v5-integrity.test.mjs +13 -2
- package/tests/run-tests.mjs +139 -9
- package/tests/run-tests.mutants.mjs +70 -0
- package/tests/selfdrive-v5.mjs +53 -1
- package/tests/selfdrive-v5.mutants.mjs +132 -0
- package/tests/v2-fix-probes.mutants.mjs +100 -0
- package/tests/v2-fix-probes.test.mjs +1039 -0
- package/tests/v2-list-agents-and-next-step.mutants.mjs +106 -0
- package/tests/v3-fix-probes.mutants.mjs +95 -0
- package/tests/v3-fix-probes.test.mjs +891 -0
- package/tests/v5-institute-fixes.mutants.mjs +190 -0
- package/vibe-math-v2/agent.cordis.yml +62 -6
- package/vibe-math-v2/math-computation.js +229 -29
- package/vibe-math-v2/math-engines.js +12 -12
- package/vibe-math-v2/vibe-math-v2.js +458 -119
- package/vibe-math-v2//345/256/236/347/216/260/346/226/271/346/241/210.md +5 -1
- package/vibe-math-v3/agent.cordis.yml +72 -6
- package/vibe-math-v3/math-computation.js +229 -29
- package/vibe-math-v3/math-engines.js +12 -12
- package/vibe-math-v3/vibe-math-v3.js +482 -139
- package/vibe-math-v4/agent.cordis.yml +44 -8
- package/vibe-math-v4/math-computation.js +229 -29
- package/vibe-math-v4/math-engines.js +12 -12
- package/vibe-math-v4/vibe-math-v4.js +245 -52
- package/vibe-math-v4//345/256/236/347/216/260/346/226/271/346/241/210.md +2 -0
- package/vibe-math-v5/agent.cordis.yml +46 -12
- package/vibe-math-v5/math-computation.js +229 -29
- package/vibe-math-v5/math-engines.js +12 -12
- package/vibe-math-v5/vibe-math-v5.js +1307 -243
- package/vibe-math-v5//345/256/236/347/216/260/346/226/271/346/241/210.md +1728 -1655
- package/vibe-math-v5//346/236/266/346/236/204/345/233/276.md +693 -693
|
@@ -68,7 +68,9 @@ const probes = [
|
|
|
68
68
|
name: 'quorum-forced-to-one',
|
|
69
69
|
ref: 'selfdrive-v5.mjs',
|
|
70
70
|
guarantee: '④ only >= m boolean votes may verify (m must be min(quorumCap, |voters|))',
|
|
71
|
-
|
|
71
|
+
// The floor moved into `quorumMFrom(vc)` when the quorum became single-sourced (defect B of
|
|
72
|
+
// the 3rd self-test); the anchor follows the implementation, it is not relaxed.
|
|
73
|
+
from: " return Math.max(1, Math.min(cap, vc))",
|
|
72
74
|
to: " return 1",
|
|
73
75
|
},
|
|
74
76
|
{
|
|
@@ -134,7 +136,9 @@ const probes = [
|
|
|
134
136
|
name: 'solve-vote-not-unanimous',
|
|
135
137
|
ref: 'selfdrive-v5.mjs',
|
|
136
138
|
guarantee: '⑥ the institute must not stop unless EVERY voter agrees',
|
|
137
|
-
|
|
139
|
+
// Anchor follows the HIGH-3 fix (the tally moved from an in-memory Map to durable state); the
|
|
140
|
+
// guarantee is unchanged — the unanimity test itself is what the mutation removes.
|
|
141
|
+
from: " const sv = solveVotesOf()\n if (!vs.every((id) => sv[id] === true)) return false",
|
|
138
142
|
to: " if (false) return false",
|
|
139
143
|
},
|
|
140
144
|
// ── probes added after the round-2 audit found these defects ──────────────
|
|
@@ -152,8 +156,8 @@ const probes = [
|
|
|
152
156
|
// The anchor must include the CALL. An `if (false)` inserted before the comment would
|
|
153
157
|
// leave the real `await checkSolved()` below it untouched — an inert mutation that
|
|
154
158
|
// would masquerade as a blind spot.
|
|
155
|
-
from: "
|
|
156
|
-
to: "
|
|
159
|
+
from: " await putSolve({ member: memberId, value: val === true })\n // Evaluate the stop condition on EVERY solve vote, not only when a meeting\n // finalizes. A vote that lands after the meeting closed — a late reply, or an\n // ordinary round carrying vote_solved — would otherwise be recorded and never\n // read, leaving a unanimously-concluded institute running forever.\n await checkSolved()",
|
|
160
|
+
to: " await putSolve({ member: memberId, value: val === true })",
|
|
157
161
|
},
|
|
158
162
|
{
|
|
159
163
|
name: 'proposal-only-kicks-scheduler',
|
|
@@ -203,8 +207,8 @@ const probes = [
|
|
|
203
207
|
name: 'brief-names-the-last-woken-member',
|
|
204
208
|
ref: 'prompt-v5-integrity.test.mjs',
|
|
205
209
|
guarantee: '⑳ a prompt\'s [状态] block must name the member it is sent to (the exact field bug: briefs named the previous member)',
|
|
206
|
-
from: " function stateBlock(member) {\n return briefBlock(member)\n }",
|
|
207
|
-
to: " function stateBlock(member) {\n return briefBlock(memberById(currentMember) || activeMembers()[0] || member)\n }",
|
|
210
|
+
from: " function stateBlock(member, roundNo) {\n return briefBlock(member, roundNo)\n }",
|
|
211
|
+
to: " function stateBlock(member, roundNo) {\n return briefBlock(memberById(currentMember) || activeMembers()[0] || member, roundNo)\n }",
|
|
208
212
|
},
|
|
209
213
|
{
|
|
210
214
|
name: 'joiner-absent-from-own-roster',
|
|
@@ -217,8 +221,11 @@ const probes = [
|
|
|
217
221
|
name: 'inbox-message-delivered-twice',
|
|
218
222
|
ref: 'prompt-v5-integrity.test.mjs',
|
|
219
223
|
guarantee: '㉑ one prompt must not deliver the same message twice',
|
|
220
|
-
|
|
221
|
-
|
|
224
|
+
// G1 moved the ack AFTER the wake, so the duplicate can no longer be produced by the ack order:
|
|
225
|
+
// it now comes from prepending the inbox while `briefBlock` ALSO embeds the same pending mail.
|
|
226
|
+
// Suppressing the base block while a block IS prepended is what keeps exactly one inbox section.
|
|
227
|
+
from: " const pending = inboxSuppressed.has(member.id) ? [] : pendingFor(member.id)",
|
|
228
|
+
to: " const pending = pendingFor(member.id)",
|
|
222
229
|
},
|
|
223
230
|
{
|
|
224
231
|
name: 'charter-rewritten-on-resume',
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Registered mutant harness for the A6 name-set snapshots (tests/e2e-multisession.test.mjs / tests/e2e-v3.test.mjs).
|
|
2
|
+
// A same-count tool rename must redden the identity assertion (counting alone would pass). One family per preset.
|
|
3
|
+
// Exit criterion: every family reddens BY NAME; any skipped family prints, is counted, and forces exit 1.
|
|
4
|
+
// Run: node tests/e2e-identity-a6.mutants.mjs
|
|
5
|
+
import { readFileSync, writeFileSync, mkdirSync, copyFileSync, rmSync, readdirSync } from 'node:fs'
|
|
6
|
+
import { execFileSync } from 'node:child_process'
|
|
7
|
+
import { dirname, join } from 'node:path'
|
|
8
|
+
import { tmpdir } from 'node:os'
|
|
9
|
+
import { fileURLToPath } from 'node:url'
|
|
10
|
+
|
|
11
|
+
// Bound every child run: run-tests has no per-suite timeout, so an unbounded child hangs the gate.
|
|
12
|
+
// A timeout is reported as HANG, counts as a failure for that family, and is listed in hangs=[].
|
|
13
|
+
const CHILD_TIMEOUT_MS = Number(process.env.MUTANT_CHILD_TIMEOUT_MS || 120000)
|
|
14
|
+
const TIMES = []
|
|
15
|
+
const hangs = []
|
|
16
|
+
let lastHang = false
|
|
17
|
+
const HERE = dirname(fileURLToPath(import.meta.url))
|
|
18
|
+
const REPO = join(HERE, '..')
|
|
19
|
+
function copyGraph(preset, file, dest) {
|
|
20
|
+
const src = join(REPO, preset, file)
|
|
21
|
+
copyFileSync(src, join(dest, file))
|
|
22
|
+
for (const m of readFileSync(src, 'utf8').matchAll(/from\s+'(\.\/[A-Za-z0-9_.-]+\.js)'/g)) {
|
|
23
|
+
const dep = m[1].slice(2)
|
|
24
|
+
if (!readdirSync(dest).includes(dep)) copyGraph(preset, dep, dest)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const skipped = []
|
|
28
|
+
function runFamily(f) {
|
|
29
|
+
const dest = join(tmpdir(), 'a6-mut-' + Math.random().toString(36).slice(2, 10))
|
|
30
|
+
mkdirSync(dest, { recursive: true })
|
|
31
|
+
copyGraph(f.preset, f.preset + '.js', dest)
|
|
32
|
+
const target = join(dest, f.preset + '.js')
|
|
33
|
+
const before = readFileSync(target, 'utf8')
|
|
34
|
+
const n = before.split(f.from).length - 1
|
|
35
|
+
if (n < 1) { skipped.push(f.name + ' (anchor x' + n + ')'); console.error(' SKIP - ' + f.name + ' (anchor x' + n + ')'); rmSync(dest, { recursive: true, force: true }); return false }
|
|
36
|
+
writeFileSync(target, before.split(f.from).join(f.to), 'utf8') // all occurrences: the two registration layers must stay identical
|
|
37
|
+
try { execFileSync(process.execPath, ['--check', target], { stdio: 'pipe' }) }
|
|
38
|
+
catch (e) { writeFileSync(target, before, 'utf8'); skipped.push(f.name + ' (mutation did not compile)'); console.error(' SKIP - ' + f.name + ' (mutation did not compile; restored)'); rmSync(dest, { recursive: true, force: true }); return false }
|
|
39
|
+
let out = ''
|
|
40
|
+
let code = 0
|
|
41
|
+
try { out = execFileSync(process.execPath, [f.suite], { cwd: REPO, encoding: 'utf8', timeout: CHILD_TIMEOUT_MS, killSignal: 'SIGKILL', env: Object.assign({}, process.env, { [f.env]: join(dest, f.preset + '.js') }) }) }
|
|
42
|
+
catch (e) { if (e && (e.killed || e.signal === 'SIGKILL')) lastHang = true; code = (e && e.status) || 1; out = String((e && e.stdout) || '') + String((e && e.stderr) || '') }
|
|
43
|
+
const named = out.split(/\r?\n/).filter((l) => /^\s*(FAIL - | {2}- )/.test(l) && f.expect.test(l)).map((l) => l.trim())
|
|
44
|
+
const ok = code !== 0 && named.length > 0
|
|
45
|
+
console.log((ok ? ' ok - ' : ' FAIL - ') + f.name + (named.length ? ' :: ' + named[0].slice(0, 135) : ' :: no named red (exit=' + code + ')'))
|
|
46
|
+
rmSync(dest, { recursive: true, force: true })
|
|
47
|
+
return ok
|
|
48
|
+
}
|
|
49
|
+
const FROM = "registerTool('vibe_math_template'"
|
|
50
|
+
const TO = "registerTool('vibe_math_templateX'"
|
|
51
|
+
const FAMILIES = [
|
|
52
|
+
{ name: 'A6-v2 (tool renamed, count unchanged)', preset: 'vibe-math-v2', suite: 'tests/e2e-multisession.test.mjs', env: 'MC_V2_PLUGIN', from: FROM, to: TO,
|
|
53
|
+
expect: /A6:注册的工具\*\*名字集合\*\*与快照逐个匹配/ },
|
|
54
|
+
{ name: 'A6-v3 (tool renamed, count unchanged)', preset: 'vibe-math-v3', suite: 'tests/e2e-v3.test.mjs', env: 'MC_V3_PLUGIN', from: FROM, to: TO,
|
|
55
|
+
expect: /A6:注册的工具\*\*名字集合\*\*与快照逐个匹配/ },
|
|
56
|
+
]
|
|
57
|
+
let red = 0
|
|
58
|
+
for (const f of FAMILIES) { const t0 = Date.now(); lastHang = false; const ok = runFamily(f); const ms = Date.now() - t0; TIMES.push([f.name, ms]); if (lastHang) hangs.push(f.name + "(" + Math.round(ms / 1000) + "s)"); if (ok) red++ }
|
|
59
|
+
console.log('')
|
|
60
|
+
console.log('mutant families reddening the A6 identity assertion by name: ' + red + '/' + FAMILIES.length)
|
|
61
|
+
console.log('skipped=[' + skipped.join(' | ') + ']')
|
|
62
|
+
console.log('timings: ' + TIMES.map((t) => String(t[0]).split(':')[0] + '=' + t[1] + 'ms').join(' '))
|
|
63
|
+
console.log('hangs=[' + hangs.join(' | ') + ']')
|
|
64
|
+
if (red !== FAMILIES.length || skipped.length || hangs.length) process.exit(1)
|
|
65
|
+
console.log('ALL MUTANTS RED AS REQUIRED')
|