knosky 0.6.3 → 0.7.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +149 -93
  2. package/CREDITS.md +14 -14
  3. package/LICENSE.md +76 -76
  4. package/LIMITATIONS.md +33 -23
  5. package/PRIVACY.md +30 -30
  6. package/README.md +170 -117
  7. package/SECURITY.md +78 -46
  8. package/action/post-comment.mjs +94 -89
  9. package/action.yml +62 -62
  10. package/bin/knosky.mjs +279 -105
  11. package/core/CONTRACT.md +70 -70
  12. package/core/append-only-checkpoint.mjs +215 -0
  13. package/core/audit-writer.mjs +317 -0
  14. package/core/benchmark-results.mjs +225 -225
  15. package/core/bundle.mjs +178 -178
  16. package/core/churn.mjs +23 -23
  17. package/core/ci.mjs +268 -268
  18. package/core/comparison.mjs +189 -189
  19. package/core/config.mjs +189 -189
  20. package/core/constants.mjs +13 -13
  21. package/core/contract.mjs +123 -123
  22. package/core/cross-repo.mjs +111 -111
  23. package/core/decision-codes.mjs +92 -0
  24. package/core/destination.mjs +161 -161
  25. package/core/district-classification.mjs +111 -0
  26. package/core/doctor-scorecard.mjs +369 -0
  27. package/core/domain-store.mjs +347 -0
  28. package/core/edges.mjs +43 -43
  29. package/core/escalate.mjs +68 -68
  30. package/core/freshness.mjs +198 -194
  31. package/core/fs-indexer.mjs +218 -218
  32. package/core/key-store.mjs +348 -348
  33. package/core/layout.mjs +46 -46
  34. package/core/ledger.mjs +176 -141
  35. package/core/local-ipc-identity.mjs +500 -0
  36. package/core/lod.mjs +155 -155
  37. package/core/mode-b.mjs +410 -0
  38. package/core/multi-model-benchmark.mjs +405 -405
  39. package/core/net-lockdown.mjs +421 -0
  40. package/core/onboarding.mjs +223 -223
  41. package/core/operator-auth.mjs +317 -0
  42. package/core/overlays.mjs +45 -45
  43. package/core/policy-lattice.mjs +142 -0
  44. package/core/pr-comment.mjs +198 -198
  45. package/core/protocol-spec.mjs +460 -460
  46. package/core/provenance.mjs +320 -0
  47. package/core/retrieve.mjs +63 -63
  48. package/core/route.mjs +304 -304
  49. package/core/schema.mjs +275 -275
  50. package/core/signing-tiers.mjs +1265 -0
  51. package/core/swarm-bench.mjs +106 -0
  52. package/core/swarm-coordinator.mjs +867 -0
  53. package/core/trust-root-rekey.mjs +410 -0
  54. package/mcp/server.mjs +264 -108
  55. package/package.json +56 -46
  56. package/renderer/art/kenney/buildingTiles_sheet.xml +130 -130
  57. package/renderer/art/kenney/cityDetails_sheet.xml +12 -12
  58. package/renderer/art/kenney/landscapeTiles_sheet.xml +129 -129
  59. package/renderer/art/kenney/sheet_allCars.xml +545 -545
  60. package/renderer/build-rich.mjs +43 -43
  61. package/renderer/city.template.html +808 -808
  62. package/ssot/decision-codes.json +133 -0
  63. package/ssot/ladder-l0-l3.md +232 -0
  64. package/ssot/tool-menu.json +130 -0
@@ -0,0 +1,106 @@
1
+ // Simple swarm benchmark harness (DEC-113 remaining — L3 foundation measure).
2
+ // Runs two agents: claim conflict + quota path; emits JSON summary. No network.
3
+
4
+ import { mkdtempSync, rmSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { tmpdir } from 'node:os';
7
+ import { createSwarmCoordinator } from './swarm-coordinator.mjs';
8
+ import { registerAgentWithLease, loadDomain } from './domain-store.mjs';
9
+
10
+ /**
11
+ * @param {object} [opts]
12
+ * @param {string} [opts.domainRoot]
13
+ * @returns {{ ok: boolean, metrics: object, events: object[] }}
14
+ */
15
+ export function runSwarmBench(opts = {}) {
16
+ const tmp = opts.domainRoot
17
+ ? null
18
+ : mkdtempSync(join(tmpdir(), 'ks-swarm-bench-'));
19
+ const domainRoot = opts.domainRoot || join(tmp, '.knosky');
20
+ const events = [];
21
+ const t0 = Date.now();
22
+
23
+ try {
24
+ const domain = loadDomain(domainRoot);
25
+ const a = registerAgentWithLease(domain, {
26
+ agentId: 'bench-a',
27
+ classes: ['public', 'internal'],
28
+ });
29
+ if (!a.ok) throw new Error('register A failed: ' + a.reason);
30
+ const b = registerAgentWithLease(domain, {
31
+ agentId: 'bench-b',
32
+ classes: ['public', 'internal'],
33
+ });
34
+ if (!b.ok) throw new Error('register B failed: ' + b.reason);
35
+ const coord = createSwarmCoordinator({
36
+ domainRoot,
37
+ domain: loadDomain(domainRoot),
38
+ quotas: {
39
+ maxClaimsPerAgent: 2,
40
+ maxActionsPerWindow: 50,
41
+ antiProbeDenyThreshold: 20,
42
+ },
43
+ });
44
+
45
+ // A claims a file
46
+ const c1 = coord.claim({
47
+ agentId: a.agentId,
48
+ leaseId: a.leaseId,
49
+ resource: 'file:src/bench.js',
50
+ kind: 'file',
51
+ });
52
+ events.push({ step: 'a_claim', ok: c1.ok, code: c1.decision_code || c1.reason });
53
+
54
+ // B conflicts
55
+ const c2 = coord.claim({
56
+ agentId: b.agentId,
57
+ leaseId: b.leaseId,
58
+ resource: 'file:src/bench.js',
59
+ kind: 'file',
60
+ });
61
+ events.push({
62
+ step: 'b_conflict',
63
+ ok: !c2.ok,
64
+ code: c2.decision_code || c2.reason,
65
+ });
66
+
67
+ // Quota pressure on A
68
+ coord.claim({
69
+ agentId: a.agentId,
70
+ leaseId: a.leaseId,
71
+ resource: 'file:src/b2.js',
72
+ kind: 'file',
73
+ });
74
+ const c3 = coord.claim({
75
+ agentId: a.agentId,
76
+ leaseId: a.leaseId,
77
+ resource: 'file:src/b3.js',
78
+ kind: 'file',
79
+ });
80
+ events.push({
81
+ step: 'a_quota',
82
+ ok: !c3.ok || c3.reason === 'quota_claims' || c3.decision_code === 'DENY',
83
+ code: c3.decision_code || c3.reason,
84
+ });
85
+
86
+ const heat = coord.writeHeatmap();
87
+ const ms = Date.now() - t0;
88
+ const metrics = {
89
+ duration_ms: ms,
90
+ conflict_detected: events.find((e) => e.step === 'b_conflict')?.ok === true,
91
+ quota_enforced: events.find((e) => e.step === 'a_quota')?.ok === true,
92
+ heatmap_written: !!heat?.ok,
93
+ agents: 2,
94
+ };
95
+ const ok = metrics.conflict_detected && metrics.quota_enforced && metrics.heatmap_written;
96
+ return { ok, metrics, events, domainRoot, heatmapPath: heat?.path };
97
+ } finally {
98
+ if (tmp) {
99
+ try {
100
+ rmSync(tmp, { recursive: true, force: true });
101
+ } catch {
102
+ /* ignore */
103
+ }
104
+ }
105
+ }
106
+ }