instar 0.26.11 → 0.27.2

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 (161) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/init.d.ts +5 -0
  3. package/dist/commands/init.d.ts.map +1 -1
  4. package/dist/commands/init.js +46 -1
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/server.d.ts.map +1 -1
  7. package/dist/commands/server.js +228 -36
  8. package/dist/commands/server.js.map +1 -1
  9. package/dist/commands/slack-cli.d.ts +6 -0
  10. package/dist/commands/slack-cli.d.ts.map +1 -1
  11. package/dist/commands/slack-cli.js +99 -1
  12. package/dist/commands/slack-cli.js.map +1 -1
  13. package/dist/core/GitSync.d.ts.map +1 -1
  14. package/dist/core/GitSync.js +47 -5
  15. package/dist/core/GitSync.js.map +1 -1
  16. package/dist/core/PostUpdateMigrator.d.ts +7 -1
  17. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  18. package/dist/core/PostUpdateMigrator.js +19 -1
  19. package/dist/core/PostUpdateMigrator.js.map +1 -1
  20. package/dist/core/types.d.ts +9 -0
  21. package/dist/core/types.d.ts.map +1 -1
  22. package/dist/identity/IdentityManager.d.ts +70 -0
  23. package/dist/identity/IdentityManager.d.ts.map +1 -0
  24. package/dist/identity/IdentityManager.js +179 -0
  25. package/dist/identity/IdentityManager.js.map +1 -0
  26. package/dist/identity/KeyEncryption.d.ts +40 -0
  27. package/dist/identity/KeyEncryption.d.ts.map +1 -0
  28. package/dist/identity/KeyEncryption.js +93 -0
  29. package/dist/identity/KeyEncryption.js.map +1 -0
  30. package/dist/identity/KeyRevocation.d.ts +68 -0
  31. package/dist/identity/KeyRevocation.d.ts.map +1 -0
  32. package/dist/identity/KeyRevocation.js +171 -0
  33. package/dist/identity/KeyRevocation.js.map +1 -0
  34. package/dist/identity/KeyRotation.d.ts +43 -0
  35. package/dist/identity/KeyRotation.d.ts.map +1 -0
  36. package/dist/identity/KeyRotation.js +81 -0
  37. package/dist/identity/KeyRotation.js.map +1 -0
  38. package/dist/identity/Migration.d.ts +50 -0
  39. package/dist/identity/Migration.d.ts.map +1 -0
  40. package/dist/identity/Migration.js +125 -0
  41. package/dist/identity/Migration.js.map +1 -0
  42. package/dist/identity/RecoveryPhrase.d.ts +43 -0
  43. package/dist/identity/RecoveryPhrase.d.ts.map +1 -0
  44. package/dist/identity/RecoveryPhrase.js +93 -0
  45. package/dist/identity/RecoveryPhrase.js.map +1 -0
  46. package/dist/identity/index.d.ts +13 -0
  47. package/dist/identity/index.d.ts.map +1 -0
  48. package/dist/identity/index.js +20 -0
  49. package/dist/identity/index.js.map +1 -0
  50. package/dist/identity/types.d.ts +101 -0
  51. package/dist/identity/types.d.ts.map +1 -0
  52. package/dist/identity/types.js +55 -0
  53. package/dist/identity/types.js.map +1 -0
  54. package/dist/knowledge/TreeTriage.d.ts.map +1 -1
  55. package/dist/knowledge/TreeTriage.js +9 -0
  56. package/dist/knowledge/TreeTriage.js.map +1 -1
  57. package/dist/memory/TopicMemory.d.ts +2 -0
  58. package/dist/memory/TopicMemory.d.ts.map +1 -1
  59. package/dist/memory/TopicMemory.js +55 -0
  60. package/dist/memory/TopicMemory.js.map +1 -1
  61. package/dist/messaging/slack/SlackAdapter.d.ts +15 -4
  62. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
  63. package/dist/messaging/slack/SlackAdapter.js +131 -14
  64. package/dist/messaging/slack/SlackAdapter.js.map +1 -1
  65. package/dist/messaging/slack/SocketModeClient.d.ts +2 -0
  66. package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -1
  67. package/dist/messaging/slack/SocketModeClient.js +31 -1
  68. package/dist/messaging/slack/SocketModeClient.js.map +1 -1
  69. package/dist/moltbridge/MoltBridgeClient.d.ts +124 -0
  70. package/dist/moltbridge/MoltBridgeClient.d.ts.map +1 -0
  71. package/dist/moltbridge/MoltBridgeClient.js +321 -0
  72. package/dist/moltbridge/MoltBridgeClient.js.map +1 -0
  73. package/dist/moltbridge/ProfileCompiler.d.ts +68 -0
  74. package/dist/moltbridge/ProfileCompiler.d.ts.map +1 -0
  75. package/dist/moltbridge/ProfileCompiler.js +317 -0
  76. package/dist/moltbridge/ProfileCompiler.js.map +1 -0
  77. package/dist/moltbridge/index.d.ts +12 -0
  78. package/dist/moltbridge/index.d.ts.map +1 -0
  79. package/dist/moltbridge/index.js +11 -0
  80. package/dist/moltbridge/index.js.map +1 -0
  81. package/dist/moltbridge/routes.d.ts +21 -0
  82. package/dist/moltbridge/routes.d.ts.map +1 -0
  83. package/dist/moltbridge/routes.js +224 -0
  84. package/dist/moltbridge/routes.js.map +1 -0
  85. package/dist/moltbridge/types.d.ts +93 -0
  86. package/dist/moltbridge/types.d.ts.map +1 -0
  87. package/dist/moltbridge/types.js +20 -0
  88. package/dist/moltbridge/types.js.map +1 -0
  89. package/dist/monitoring/PresenceProxy.d.ts +3 -0
  90. package/dist/monitoring/PresenceProxy.d.ts.map +1 -1
  91. package/dist/monitoring/PresenceProxy.js +80 -3
  92. package/dist/monitoring/PresenceProxy.js.map +1 -1
  93. package/dist/monitoring/SessionMonitor.d.ts +7 -0
  94. package/dist/monitoring/SessionMonitor.d.ts.map +1 -1
  95. package/dist/monitoring/SessionMonitor.js +47 -22
  96. package/dist/monitoring/SessionMonitor.js.map +1 -1
  97. package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -1
  98. package/dist/monitoring/TriageOrchestrator.js +25 -1
  99. package/dist/monitoring/TriageOrchestrator.js.map +1 -1
  100. package/dist/scaffold/templates.d.ts.map +1 -1
  101. package/dist/scaffold/templates.js +29 -1
  102. package/dist/scaffold/templates.js.map +1 -1
  103. package/dist/server/AgentServer.d.ts +1 -0
  104. package/dist/server/AgentServer.d.ts.map +1 -1
  105. package/dist/server/AgentServer.js +1 -0
  106. package/dist/server/AgentServer.js.map +1 -1
  107. package/dist/server/routes.d.ts +2 -0
  108. package/dist/server/routes.d.ts.map +1 -1
  109. package/dist/server/routes.js +21 -0
  110. package/dist/server/routes.js.map +1 -1
  111. package/dist/threadline/AuthorizationPolicy.d.ts +110 -0
  112. package/dist/threadline/AuthorizationPolicy.d.ts.map +1 -0
  113. package/dist/threadline/AuthorizationPolicy.js +226 -0
  114. package/dist/threadline/AuthorizationPolicy.js.map +1 -0
  115. package/dist/threadline/DiscoveryWaterfall.d.ts +73 -0
  116. package/dist/threadline/DiscoveryWaterfall.d.ts.map +1 -0
  117. package/dist/threadline/DiscoveryWaterfall.js +113 -0
  118. package/dist/threadline/DiscoveryWaterfall.js.map +1 -0
  119. package/dist/threadline/ListenerSessionManager.d.ts.map +1 -1
  120. package/dist/threadline/ListenerSessionManager.js +2 -0
  121. package/dist/threadline/ListenerSessionManager.js.map +1 -1
  122. package/dist/threadline/MessageSecurity.d.ts +49 -0
  123. package/dist/threadline/MessageSecurity.d.ts.map +1 -0
  124. package/dist/threadline/MessageSecurity.js +93 -0
  125. package/dist/threadline/MessageSecurity.js.map +1 -0
  126. package/dist/threadline/SecureInvitation.d.ts +79 -0
  127. package/dist/threadline/SecureInvitation.d.ts.map +1 -0
  128. package/dist/threadline/SecureInvitation.js +164 -0
  129. package/dist/threadline/SecureInvitation.js.map +1 -0
  130. package/dist/threadline/TrustAuditLog.d.ts +49 -0
  131. package/dist/threadline/TrustAuditLog.d.ts.map +1 -0
  132. package/dist/threadline/TrustAuditLog.js +111 -0
  133. package/dist/threadline/TrustAuditLog.js.map +1 -0
  134. package/dist/threadline/TrustEvaluator.d.ts +69 -0
  135. package/dist/threadline/TrustEvaluator.d.ts.map +1 -0
  136. package/dist/threadline/TrustEvaluator.js +93 -0
  137. package/dist/threadline/TrustEvaluator.js.map +1 -0
  138. package/dist/threadline/UnifiedTrustWiring.d.ts +66 -0
  139. package/dist/threadline/UnifiedTrustWiring.d.ts.map +1 -0
  140. package/dist/threadline/UnifiedTrustWiring.js +192 -0
  141. package/dist/threadline/UnifiedTrustWiring.js.map +1 -0
  142. package/dist/threadline/client/IdentityManager.d.ts +27 -6
  143. package/dist/threadline/client/IdentityManager.d.ts.map +1 -1
  144. package/dist/threadline/client/IdentityManager.js +64 -18
  145. package/dist/threadline/client/IdentityManager.js.map +1 -1
  146. package/dist/threadline/relay/SybilProtection.d.ts +78 -0
  147. package/dist/threadline/relay/SybilProtection.d.ts.map +1 -0
  148. package/dist/threadline/relay/SybilProtection.js +187 -0
  149. package/dist/threadline/relay/SybilProtection.js.map +1 -0
  150. package/package.json +9 -3
  151. package/playbook-scripts/build-state.py +529 -0
  152. package/scripts/check-contract-evidence.js +103 -0
  153. package/scripts/pre-push-gate.js +53 -0
  154. package/scripts/run-contract-tests.js +75 -0
  155. package/src/data/builtin-manifest.json +87 -63
  156. package/src/templates/hooks/build-stop-hook.sh +79 -0
  157. package/upgrades/0.26.10.md +36 -0
  158. package/upgrades/0.27.1.md +101 -0
  159. package/upgrades/0.27.2.md +36 -0
  160. package/upgrades/NEXT.md +0 -27
  161. /package/.claude/skills/secret-setup/{SKILL.md → skill.md} +0 -0
@@ -0,0 +1,78 @@
1
+ /**
2
+ * SybilProtection — Relay-side protection against identity flooding.
3
+ *
4
+ * Spec Section 3.12:
5
+ * - Proof-of-Work at connection (Hashcash-style, ~1s commodity hardware)
6
+ * - Dynamic difficulty (3x spike → scale up, 10x ceiling)
7
+ * - Fast-solver throttling (<100ms = suspicious)
8
+ * - Identity aging (new identities hidden from directory for 1h)
9
+ * - IP rate limiting (10 new connections/min, 50 total/IP)
10
+ * - Identity-level limits (5 identities per IP per hour)
11
+ */
12
+ /** Identity aging: new identities hidden for 1 hour */
13
+ export declare const IDENTITY_AGING_MS: number;
14
+ /** IP rate limits */
15
+ export declare const IP_LIMITS: {
16
+ readonly newConnectionsPerMinute: 10;
17
+ readonly totalConnectionsPerIP: 50;
18
+ readonly identitiesPerIPPerHour: 5;
19
+ };
20
+ export interface PoWChallenge {
21
+ epoch: string;
22
+ difficulty: number;
23
+ issuedAt: number;
24
+ }
25
+ export interface PoWSolution {
26
+ challenge: PoWChallenge;
27
+ nonce: string;
28
+ solveTimeMs: number;
29
+ }
30
+ export interface IPConnectionState {
31
+ recentConnections: number[];
32
+ identities: Set<string>;
33
+ identityTimestamps: number[];
34
+ }
35
+ /**
36
+ * Generate a PoW challenge for a connecting agent.
37
+ */
38
+ export declare function generateChallenge(clientIP: string, currentDifficulty?: number): PoWChallenge;
39
+ /**
40
+ * Verify a PoW solution.
41
+ *
42
+ * Checks:
43
+ * 1. SHA-256(epoch || clientIP || nonce) has enough leading zero bits
44
+ * 2. Epoch is current (within tolerance)
45
+ * 3. Not solved suspiciously fast
46
+ */
47
+ export declare function verifySolution(solution: PoWSolution, clientIP: string): {
48
+ valid: boolean;
49
+ suspicious: boolean;
50
+ reason?: string;
51
+ };
52
+ /**
53
+ * Solve a PoW challenge (for client-side use / testing).
54
+ */
55
+ export declare function solveChallenge(challenge: PoWChallenge, clientIP: string): PoWSolution;
56
+ /**
57
+ * Compute dynamic difficulty based on connection rate.
58
+ *
59
+ * Attack condition: >3x rolling 10-minute average = spike.
60
+ * Difficulty scales linearly from 1x to ceiling proportional to spike magnitude.
61
+ */
62
+ export declare function computeDynamicDifficulty(recentConnectionRate: number, baselineRate: number): number;
63
+ export declare class IPRateLimiter {
64
+ private ipStates;
65
+ /**
66
+ * Check if a new connection from an IP is allowed.
67
+ */
68
+ checkConnection(ip: string, fingerprint: string): {
69
+ allowed: boolean;
70
+ reason?: string;
71
+ };
72
+ /**
73
+ * Check if an identity is old enough to appear in directory.
74
+ */
75
+ isIdentityAged(firstSeenTimestamp: number, now?: number): boolean;
76
+ private getOrCreateState;
77
+ }
78
+ //# sourceMappingURL=SybilProtection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SybilProtection.d.ts","sourceRoot":"","sources":["../../../src/threadline/relay/SybilProtection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkBH,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD,qBAAqB;AACrB,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAIX,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAID;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE,MAAM,GACzB,YAAY,CAOd;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAoB1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAgBrF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,GACnB,MAAM,CAUR;AAID,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAA6C;IAE7D;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAoCvF;;OAEG;IACH,cAAc,CAAC,kBAAkB,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO;IAIjE,OAAO,CAAC,gBAAgB;CAQzB"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * SybilProtection — Relay-side protection against identity flooding.
3
+ *
4
+ * Spec Section 3.12:
5
+ * - Proof-of-Work at connection (Hashcash-style, ~1s commodity hardware)
6
+ * - Dynamic difficulty (3x spike → scale up, 10x ceiling)
7
+ * - Fast-solver throttling (<100ms = suspicious)
8
+ * - Identity aging (new identities hidden from directory for 1h)
9
+ * - IP rate limiting (10 new connections/min, 50 total/IP)
10
+ * - Identity-level limits (5 identities per IP per hour)
11
+ */
12
+ import crypto from 'node:crypto';
13
+ // ── Constants ────────────────────────────────────────────────────────
14
+ /** Default PoW difficulty: 20 leading zero bits (~1s on commodity hardware) */
15
+ const DEFAULT_DIFFICULTY = 20;
16
+ /** Max difficulty ceiling: 10x baseline = ~10s on commodity hardware */
17
+ const MAX_DIFFICULTY_BITS = DEFAULT_DIFFICULTY + 4; // ~16x baseline, capped
18
+ /** Epoch rotation interval (10 minutes) */
19
+ const EPOCH_INTERVAL_MS = 10 * 60 * 1000;
20
+ /** Fast-solver threshold: solutions under 100ms are suspicious */
21
+ const FAST_SOLVER_THRESHOLD_MS = 100;
22
+ /** Identity aging: new identities hidden for 1 hour */
23
+ export const IDENTITY_AGING_MS = 60 * 60 * 1000;
24
+ /** IP rate limits */
25
+ export const IP_LIMITS = {
26
+ newConnectionsPerMinute: 10,
27
+ totalConnectionsPerIP: 50,
28
+ identitiesPerIPPerHour: 5,
29
+ };
30
+ // ── PoW Functions ────────────────────────────────────────────────────
31
+ /**
32
+ * Generate a PoW challenge for a connecting agent.
33
+ */
34
+ export function generateChallenge(clientIP, currentDifficulty) {
35
+ const epoch = getCurrentEpoch();
36
+ return {
37
+ epoch,
38
+ difficulty: currentDifficulty ?? DEFAULT_DIFFICULTY,
39
+ issuedAt: Date.now(),
40
+ };
41
+ }
42
+ /**
43
+ * Verify a PoW solution.
44
+ *
45
+ * Checks:
46
+ * 1. SHA-256(epoch || clientIP || nonce) has enough leading zero bits
47
+ * 2. Epoch is current (within tolerance)
48
+ * 3. Not solved suspiciously fast
49
+ */
50
+ export function verifySolution(solution, clientIP) {
51
+ // Check epoch freshness (allow previous + current epoch)
52
+ const currentEpoch = getCurrentEpoch();
53
+ const previousEpoch = getEpoch(Date.now() - EPOCH_INTERVAL_MS);
54
+ if (solution.challenge.epoch !== currentEpoch && solution.challenge.epoch !== previousEpoch) {
55
+ return { valid: false, suspicious: false, reason: 'Stale epoch — challenge expired' };
56
+ }
57
+ // Verify hash
58
+ const hash = computePoWHash(solution.challenge.epoch, clientIP, solution.nonce);
59
+ const leadingZeros = countLeadingZeroBits(hash);
60
+ if (leadingZeros < solution.challenge.difficulty) {
61
+ return { valid: false, suspicious: false, reason: `Insufficient work: ${leadingZeros} < ${solution.challenge.difficulty} bits` };
62
+ }
63
+ // Fast-solver detection
64
+ const elapsedMs = Date.now() - solution.challenge.issuedAt;
65
+ const suspicious = elapsedMs < FAST_SOLVER_THRESHOLD_MS;
66
+ return { valid: true, suspicious };
67
+ }
68
+ /**
69
+ * Solve a PoW challenge (for client-side use / testing).
70
+ */
71
+ export function solveChallenge(challenge, clientIP) {
72
+ const startTime = Date.now();
73
+ let nonce = 0;
74
+ while (true) {
75
+ const nonceHex = nonce.toString(16).padStart(16, '0');
76
+ const hash = computePoWHash(challenge.epoch, clientIP, nonceHex);
77
+ if (countLeadingZeroBits(hash) >= challenge.difficulty) {
78
+ return {
79
+ challenge,
80
+ nonce: nonceHex,
81
+ solveTimeMs: Date.now() - startTime,
82
+ };
83
+ }
84
+ nonce++;
85
+ }
86
+ }
87
+ /**
88
+ * Compute dynamic difficulty based on connection rate.
89
+ *
90
+ * Attack condition: >3x rolling 10-minute average = spike.
91
+ * Difficulty scales linearly from 1x to ceiling proportional to spike magnitude.
92
+ */
93
+ export function computeDynamicDifficulty(recentConnectionRate, baselineRate) {
94
+ if (baselineRate <= 0)
95
+ return DEFAULT_DIFFICULTY;
96
+ const ratio = recentConnectionRate / baselineRate;
97
+ if (ratio <= 3)
98
+ return DEFAULT_DIFFICULTY;
99
+ // Linear scale from baseline to 10x ceiling
100
+ const scaleFactor = Math.min((ratio - 3) / 7, 1); // 0 at 3x, 1 at 10x
101
+ const extraBits = Math.floor(scaleFactor * (MAX_DIFFICULTY_BITS - DEFAULT_DIFFICULTY));
102
+ return Math.min(DEFAULT_DIFFICULTY + extraBits, MAX_DIFFICULTY_BITS);
103
+ }
104
+ // ── IP Rate Limiter ──────────────────────────────────────────────────
105
+ export class IPRateLimiter {
106
+ ipStates = new Map();
107
+ /**
108
+ * Check if a new connection from an IP is allowed.
109
+ */
110
+ checkConnection(ip, fingerprint) {
111
+ const now = Date.now();
112
+ const state = this.getOrCreateState(ip);
113
+ // Prune old entries
114
+ const oneMinuteAgo = now - 60 * 1000;
115
+ const oneHourAgo = now - 60 * 60 * 1000;
116
+ state.recentConnections = state.recentConnections.filter(t => t > oneMinuteAgo);
117
+ state.identityTimestamps = state.identityTimestamps.filter(t => t > oneHourAgo);
118
+ // Check connections per minute
119
+ if (state.recentConnections.length >= IP_LIMITS.newConnectionsPerMinute) {
120
+ return { allowed: false, reason: `IP rate limit: ${IP_LIMITS.newConnectionsPerMinute} connections/min` };
121
+ }
122
+ // Check total connections per IP
123
+ if (state.recentConnections.length >= IP_LIMITS.totalConnectionsPerIP) {
124
+ return { allowed: false, reason: `IP total limit: ${IP_LIMITS.totalConnectionsPerIP} connections` };
125
+ }
126
+ // Check identities per IP per hour
127
+ if (!state.identities.has(fingerprint) &&
128
+ state.identityTimestamps.length >= IP_LIMITS.identitiesPerIPPerHour) {
129
+ return { allowed: false, reason: `IP identity limit: ${IP_LIMITS.identitiesPerIPPerHour} identities/hour` };
130
+ }
131
+ // Record
132
+ state.recentConnections.push(now);
133
+ if (!state.identities.has(fingerprint)) {
134
+ state.identities.add(fingerprint);
135
+ state.identityTimestamps.push(now);
136
+ }
137
+ return { allowed: true };
138
+ }
139
+ /**
140
+ * Check if an identity is old enough to appear in directory.
141
+ */
142
+ isIdentityAged(firstSeenTimestamp, now) {
143
+ return ((now ?? Date.now()) - firstSeenTimestamp) >= IDENTITY_AGING_MS;
144
+ }
145
+ getOrCreateState(ip) {
146
+ let state = this.ipStates.get(ip);
147
+ if (!state) {
148
+ state = { recentConnections: [], identities: new Set(), identityTimestamps: [] };
149
+ this.ipStates.set(ip, state);
150
+ }
151
+ return state;
152
+ }
153
+ }
154
+ // ── Helpers ──────────────────────────────────────────────────────────
155
+ function getCurrentEpoch() {
156
+ return getEpoch(Date.now());
157
+ }
158
+ function getEpoch(timestamp) {
159
+ const epochNum = Math.floor(timestamp / EPOCH_INTERVAL_MS);
160
+ return epochNum.toString(16);
161
+ }
162
+ function computePoWHash(epoch, clientIP, nonce) {
163
+ return crypto.createHash('sha256')
164
+ .update(epoch)
165
+ .update(clientIP)
166
+ .update(nonce)
167
+ .digest();
168
+ }
169
+ function countLeadingZeroBits(hash) {
170
+ let bits = 0;
171
+ for (const byte of hash) {
172
+ if (byte === 0) {
173
+ bits += 8;
174
+ }
175
+ else {
176
+ // Count leading zeros in this byte
177
+ let mask = 0x80;
178
+ while (mask > 0 && (byte & mask) === 0) {
179
+ bits++;
180
+ mask >>= 1;
181
+ }
182
+ break;
183
+ }
184
+ }
185
+ return bits;
186
+ }
187
+ //# sourceMappingURL=SybilProtection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SybilProtection.js","sourceRoot":"","sources":["../../../src/threadline/relay/SybilProtection.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "0.26.11",
3
+ "version": "0.27.2",
4
4
  "description": "Persistent autonomy infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,13 +24,16 @@
24
24
  "test:watch": "vitest",
25
25
  "test:integration": "vitest run --config vitest.integration.config.ts",
26
26
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
27
+ "test:contract": "node scripts/run-contract-tests.js",
28
+ "test:contract:raw": "vitest run --config vitest.contract.config.ts",
27
29
  "test:all": "vitest run && vitest run --config vitest.integration.config.ts && vitest run --config vitest.e2e.config.ts",
28
30
  "lint": "tsc --noEmit",
29
31
  "clean": "rm -rf dist",
30
32
  "check:upgrade-guide": "node scripts/check-upgrade-guide.js",
31
33
  "check:pre-push-gate": "node scripts/pre-push-gate.js",
32
34
  "check:release": "node scripts/analyze-release.js",
33
- "prepublishOnly": "npm run build && npm run check:upgrade-guide",
35
+ "check:contract-evidence": "node scripts/check-contract-evidence.js",
36
+ "prepublishOnly": "npm run build && npm run check:upgrade-guide && npm run check:contract-evidence",
34
37
  "postinstall": "node scripts/fix-better-sqlite3.cjs",
35
38
  "prepare": "husky"
36
39
  },
@@ -83,12 +86,15 @@
83
86
  "@inquirer/prompts": "^8.2.1",
84
87
  "@modelcontextprotocol/sdk": "^1.27.1",
85
88
  "@noble/ciphers": "^2.1.1",
89
+ "@noble/hashes": "^2.0.1",
90
+ "@scure/bip39": "^2.0.1",
86
91
  "better-sqlite3": "^12.8.0",
87
92
  "cloudflared": "^0.7.1",
88
93
  "commander": "^12.0.0",
89
94
  "croner": "^8.0.0",
90
95
  "express": "^4.18.0",
91
96
  "marked": "^17.0.5",
97
+ "moltbridge": "^0.1.6",
92
98
  "picocolors": "^1.0.0",
93
99
  "proper-lockfile": "^4.1.2",
94
100
  "ws": "^8.19.0",
@@ -108,6 +114,6 @@
108
114
  "husky": "^9.1.7",
109
115
  "supertest": "^7.2.2",
110
116
  "typescript": "^5.9.3",
111
- "vitest": "^2.0.0"
117
+ "vitest": "^2.1.9"
112
118
  }
113
119
  }