@steve02081504/fount-p2p 0.0.31 → 0.0.32

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.
Files changed (60) hide show
  1. package/AGENTS.md +79 -0
  2. package/docs/evfs.md +32 -0
  3. package/docs/infra.md +25 -0
  4. package/docs/mesh.md +67 -0
  5. package/docs/reputation.md +22 -0
  6. package/docs/runtime.md +62 -0
  7. package/docs/signaling.md +23 -0
  8. package/docs/transports.md +92 -0
  9. package/docs/wire.md +21 -0
  10. package/package.json +2 -9
  11. package/sim/AGENTS.md +29 -0
  12. package/sim/admission.mjs +56 -0
  13. package/sim/anomaly.mjs +39 -0
  14. package/sim/apply.mjs +77 -0
  15. package/sim/attack_space.mjs +113 -0
  16. package/sim/attacks.mjs +614 -0
  17. package/sim/behavior.mjs +78 -0
  18. package/sim/cli.mjs +282 -0
  19. package/sim/coevolution.mjs +245 -0
  20. package/sim/cold_start.md +13 -0
  21. package/sim/constants.mjs +44 -0
  22. package/sim/discovery.mjs +259 -0
  23. package/sim/duration.mjs +64 -0
  24. package/sim/graph_adj.mjs +28 -0
  25. package/sim/integrity.mjs +58 -0
  26. package/sim/metrics.mjs +423 -0
  27. package/sim/model.mjs +1176 -0
  28. package/sim/optimizer.mjs +250 -0
  29. package/sim/propagation.mjs +57 -0
  30. package/sim/report.mjs +176 -0
  31. package/sim/reputation_social.tunables.json +6 -0
  32. package/sim/rng.mjs +62 -0
  33. package/sim/scenarios.mjs +345 -0
  34. package/sim/sim_pool.mjs +169 -0
  35. package/sim/sim_worker.mjs +31 -0
  36. package/sim/social_reputation.mjs +30 -0
  37. package/sim/space.mjs +312 -0
  38. package/sim/test/admission.test.mjs +25 -0
  39. package/sim/test/attack_space.test.mjs +39 -0
  40. package/sim/test/behavior_vector.test.mjs +37 -0
  41. package/sim/test/coevolution.test.mjs +32 -0
  42. package/sim/test/cold_start.test.mjs +46 -0
  43. package/sim/test/defense.test.mjs +320 -0
  44. package/sim/test/discovery.test.mjs +68 -0
  45. package/sim/test/duration.test.mjs +20 -0
  46. package/sim/test/fidelity.test.mjs +151 -0
  47. package/sim/test/integrity.test.mjs +56 -0
  48. package/sim/test/optimizer.test.mjs +24 -0
  49. package/sim/test/propagation.test.mjs +29 -0
  50. package/sim/test/sim_model_regressions.test.mjs +110 -0
  51. package/sim/test/slow_drip.test.mjs +28 -0
  52. package/sim/test/smoke.test.mjs +52 -0
  53. package/sim/test/transport.test.mjs +55 -0
  54. package/sim/test/tunables_apply.test.mjs +64 -0
  55. package/sim/test/tunables_param_space.test.mjs +74 -0
  56. package/sim/test/vulnerability.test.mjs +127 -0
  57. package/sim/transport.mjs +135 -0
  58. package/sim/tunables_bundle.mjs +71 -0
  59. package/sim/vulnerability.mjs +532 -0
  60. package/deno.json +0 -7
package/sim/apply.mjs ADDED
@@ -0,0 +1,77 @@
1
+ /**
2
+ * 按模块写回 tunables JSON。
3
+ */
4
+ import { writeFile } from 'node:fs/promises'
5
+ import path from 'node:path'
6
+ import { fileURLToPath } from 'node:url'
7
+
8
+ import { normalizeBundle, sanitizeBundle } from './space.mjs'
9
+
10
+ /** @typedef {import('./tunables_bundle.mjs').TunablesBundle} TunablesBundle */
11
+
12
+ /** @type {Record<Exclude<keyof TunablesBundle, 'social'>, URL>} */
13
+ const PACKAGE_MODULE_URLS = {
14
+ reputation: new URL('../reputation/tunables.json', import.meta.url),
15
+ trustGraph: new URL('../trust_graph/tunables.json', import.meta.url),
16
+ mailbox: new URL('../mailbox/tunables.json', import.meta.url),
17
+ archive: new URL('../dag/tunables.json', import.meta.url),
18
+ admission: new URL('../governance/tunables.json', import.meta.url),
19
+ }
20
+
21
+ /**
22
+ * @param {TunablesBundle} bundle 完整 tunables
23
+ * @returns {TunablesBundle} 写盘前规整后的 bundle
24
+ */
25
+ export function prepareBundleForApply(bundle) {
26
+ return sanitizeBundle(normalizeBundle(bundle))
27
+ }
28
+
29
+ /**
30
+ * @param {string} socialTunablesPath 外部 social shell 的 reputation_social.tunables.json 绝对或相对路径
31
+ * @returns {string} 规范化绝对路径
32
+ */
33
+ export function resolveSocialTunablesPath(socialTunablesPath) {
34
+ const raw = String(socialTunablesPath ?? '').trim()
35
+ if (!raw) throw new Error('socialTunablesPath required to write social tunables')
36
+ return path.resolve(raw)
37
+ }
38
+
39
+ /**
40
+ * @param {keyof TunablesBundle} module 模块键
41
+ * @param {Record<string, unknown>} data JSON 内容
42
+ * @param {string} [socialTunablesPath] social 模块写入路径(module === 'social' 时必填)
43
+ * @returns {Promise<string>} 写入路径
44
+ */
45
+ export async function writeModuleTunables(module, data, socialTunablesPath) {
46
+ const filePath = module === 'social'
47
+ ? resolveSocialTunablesPath(socialTunablesPath)
48
+ : fileURLToPath(PACKAGE_MODULE_URLS[module])
49
+ await writeFile(filePath, `${JSON.stringify(data, null, '\t')}\n`, 'utf8')
50
+ return filePath
51
+ }
52
+
53
+ /**
54
+ * @param {TunablesBundle} bundle 完整 tunables
55
+ * @param {{ socialTunablesPath: string }} paths 外部模块路径(social 写回 shell 侧 JSON)
56
+ * @returns {Promise<string[]>} 各模块 JSON 写入路径
57
+ */
58
+ export async function applyTunablesBundle(bundle, paths) {
59
+ const socialPath = resolveSocialTunablesPath(paths?.socialTunablesPath)
60
+ const ready = prepareBundleForApply(bundle)
61
+ const written = []
62
+ written.push(await writeModuleTunables('reputation', ready.reputation))
63
+ written.push(await writeModuleTunables('trustGraph', ready.trustGraph))
64
+ written.push(await writeModuleTunables('social', ready.social, socialPath))
65
+ written.push(await writeModuleTunables('mailbox', ready.mailbox))
66
+ written.push(await writeModuleTunables('archive', ready.archive))
67
+ written.push(await writeModuleTunables('admission', ready.admission))
68
+ return written
69
+ }
70
+
71
+ /**
72
+ * @param {string} [dir] sim 目录(默认本模块目录)
73
+ * @returns {string} results 子目录绝对路径
74
+ */
75
+ export function resultsDirFromSim(dir = path.dirname(fileURLToPath(import.meta.url))) {
76
+ return path.join(dir, 'results')
77
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * 攻击者可进化基因(与 space.mjs 采样器共用 latent 语义)。
3
+ */
4
+ import { createRng } from './rng.mjs'
5
+ import { normalizeParam, sampleParam } from './space.mjs'
6
+ import { loadDefaultTunables } from './tunables_bundle.mjs'
7
+
8
+ /** @typedef {import('./attacks.mjs').AttackKind} AttackKind */
9
+
10
+ /**
11
+ * @typedef {{
12
+ * global: { activationRate: number, burstSize: number, targetBiasHighRep: number, eclipseFocus: number },
13
+ * byAttack: Partial<Record<AttackKind, { activationRate?: number, burstSize?: number, collusionAllyRate?: number, sleeperTurnFrac?: number, hintWeightMul?: number }>>,
14
+ * }} AttackGenome
15
+ */
16
+
17
+ /** @type {import('./space.mjs').ParamSpec[]} */
18
+ const GLOBAL_ATTACK_SPECS = [
19
+ { module: 'reputation', key: 'relayRepBump', kind: 'unit' }, // reuse kind; values remapped below
20
+ ]
21
+
22
+ const DEFAULT_GENOME = Object.freeze({
23
+ global: {
24
+ activationRate: 0.55,
25
+ burstSize: 4,
26
+ targetBiasHighRep: 0.35,
27
+ eclipseFocus: 0.65,
28
+ },
29
+ byAttack: {},
30
+ })
31
+
32
+ /**
33
+ * @param {() => number} rng 随机源
34
+ * @returns {AttackGenome} 随机攻击基因组
35
+ */
36
+ export function randomAttackGenome(rng) {
37
+ return {
38
+ global: {
39
+ activationRate: 0.2 + rng() * 0.75,
40
+ burstSize: 1 + Math.floor(rng() * 8),
41
+ targetBiasHighRep: rng() * 0.9,
42
+ eclipseFocus: 0.3 + rng() * 0.65,
43
+ },
44
+ byAttack: {},
45
+ }
46
+ }
47
+
48
+ /**
49
+ * @param {AttackGenome} parent 父代
50
+ * @param {number} seed 种子
51
+ * @returns {AttackGenome} 变异子代
52
+ */
53
+ export function mutateAttackGenome(parent, seed) {
54
+ const rng = createRng(seed)
55
+ const child = structuredClone(parent)
56
+ if (rng() < 0.4) child.global.activationRate = Math.max(0.05, Math.min(0.98, child.global.activationRate + (rng() - 0.5) * 0.2))
57
+ if (rng() < 0.35) child.global.burstSize = Math.max(1, Math.min(12, child.global.burstSize + Math.floor((rng() - 0.5) * 4)))
58
+ if (rng() < 0.3) child.global.targetBiasHighRep = Math.max(0, Math.min(1, child.global.targetBiasHighRep + (rng() - 0.5) * 0.25))
59
+ if (rng() < 0.3) child.global.eclipseFocus = Math.max(0.1, Math.min(1, child.global.eclipseFocus + (rng() - 0.5) * 0.25))
60
+ return child
61
+ }
62
+
63
+ /**
64
+ * @param {AttackKind} attack 攻击类型
65
+ * @param {AttackGenome} genome 基因组
66
+ * @returns {{ activationRate: number, burstSize: number, targetBiasHighRep: number, eclipseFocus: number, collusionAllyRate: number, sleeperTurnFrac: number, hintWeightMul: number }} 有效参数
67
+ */
68
+ export function resolveAttackParams(attack, genome) {
69
+ const g = genome.global
70
+ const row = genome.byAttack[attack] ?? {}
71
+ return {
72
+ activationRate: row.activationRate ?? g.activationRate,
73
+ burstSize: Math.max(1, Math.floor(row.burstSize ?? g.burstSize)),
74
+ targetBiasHighRep: g.targetBiasHighRep,
75
+ eclipseFocus: g.eclipseFocus,
76
+ collusionAllyRate: row.collusionAllyRate ?? 0.25,
77
+ sleeperTurnFrac: row.sleeperTurnFrac ?? 0.35,
78
+ hintWeightMul: row.hintWeightMul ?? 3,
79
+ }
80
+ }
81
+
82
+ /**
83
+ * @param {AttackGenome | undefined} genome 基因组
84
+ * @returns {AttackGenome} 默认补齐
85
+ */
86
+ export function normalizeAttackGenome(genome) {
87
+ if (!genome) return structuredClone(DEFAULT_GENOME)
88
+ return {
89
+ global: { ...DEFAULT_GENOME.global, ...genome.global },
90
+ byAttack: { ...genome.byAttack },
91
+ }
92
+ }
93
+
94
+ /** 名人堂容量 */
95
+ export const ATTACK_HOF_SIZE = 6
96
+
97
+ /**
98
+ * @param {Array<{ genome: AttackGenome, fitness: number }>} hall 名人堂
99
+ * @param {AttackGenome} genome 候选
100
+ * @param {number} fitness 适应度
101
+ * @returns {Array<{ genome: AttackGenome, fitness: number }>} 更新后名人堂
102
+ */
103
+ export function updateAttackHallOfFame(hall, genome, fitness) {
104
+ const next = [...hall, { genome: structuredClone(genome), fitness }]
105
+ next.sort((a, b) => b.fitness - a.fitness)
106
+ return next.slice(0, ATTACK_HOF_SIZE)
107
+ }
108
+
109
+ // silence unused import warning from eslint if any
110
+ void GLOBAL_ATTACK_SPECS
111
+ void loadDefaultTunables
112
+ void normalizeParam
113
+ void sampleParam