soulprint-core 0.1.5 → 0.1.7

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/dist/index.d.ts CHANGED
@@ -100,6 +100,6 @@ export declare function calculateScore(credentials: CredentialType[]): number;
100
100
  */
101
101
  export declare function calculateTotalScore(credentials: CredentialType[], botRep?: BotReputation): number;
102
102
  export declare function calculateLevel(credentials: CredentialType[]): TrustLevel;
103
- export { PROTOCOL, isProtocolCompatible, clampMinScore, computeTotalScoreWithFloor, withRetry, } from "./protocol-constants.js";
103
+ export { PROTOCOL, PROTOCOL_HASH, computeProtocolHash, isProtocolCompatible, isProtocolHashCompatible, clampMinScore, computeTotalScoreWithFloor, withRetry, } from "./protocol-constants.js";
104
104
  export { FARMING_RULES, checkFarming, recordApprovedGain, recordFarmingStrike, getOrCreateAudit, loadAuditStore, exportAuditStore, } from "./anti-farming.js";
105
105
  export type { SessionContext, FarmingCheckResult, DIDAuditEntry } from "./anti-farming.js";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.exportAuditStore = exports.loadAuditStore = exports.getOrCreateAudit = exports.recordFarmingStrike = exports.recordApprovedGain = exports.checkFarming = exports.FARMING_RULES = exports.withRetry = exports.computeTotalScoreWithFloor = exports.clampMinScore = exports.isProtocolCompatible = exports.PROTOCOL = void 0;
6
+ exports.exportAuditStore = exports.loadAuditStore = exports.getOrCreateAudit = exports.recordFarmingStrike = exports.recordApprovedGain = exports.checkFarming = exports.FARMING_RULES = exports.withRetry = exports.computeTotalScoreWithFloor = exports.clampMinScore = exports.isProtocolHashCompatible = exports.isProtocolCompatible = exports.computeProtocolHash = exports.PROTOCOL_HASH = exports.PROTOCOL = void 0;
7
7
  exports.generateKeypair = generateKeypair;
8
8
  exports.keypairFromPrivateKey = keypairFromPrivateKey;
9
9
  exports.deriveNullifier = deriveNullifier;
@@ -207,7 +207,10 @@ function calculateLevel(credentials) {
207
207
  // ── Protocol Constants (re-export) ────────────────────────────────────────────
208
208
  var protocol_constants_js_1 = require("./protocol-constants.js");
209
209
  Object.defineProperty(exports, "PROTOCOL", { enumerable: true, get: function () { return protocol_constants_js_1.PROTOCOL; } });
210
+ Object.defineProperty(exports, "PROTOCOL_HASH", { enumerable: true, get: function () { return protocol_constants_js_1.PROTOCOL_HASH; } });
211
+ Object.defineProperty(exports, "computeProtocolHash", { enumerable: true, get: function () { return protocol_constants_js_1.computeProtocolHash; } });
210
212
  Object.defineProperty(exports, "isProtocolCompatible", { enumerable: true, get: function () { return protocol_constants_js_1.isProtocolCompatible; } });
213
+ Object.defineProperty(exports, "isProtocolHashCompatible", { enumerable: true, get: function () { return protocol_constants_js_1.isProtocolHashCompatible; } });
211
214
  Object.defineProperty(exports, "clampMinScore", { enumerable: true, get: function () { return protocol_constants_js_1.clampMinScore; } });
212
215
  Object.defineProperty(exports, "computeTotalScoreWithFloor", { enumerable: true, get: function () { return protocol_constants_js_1.computeTotalScoreWithFloor; } });
213
216
  Object.defineProperty(exports, "withRetry", { enumerable: true, get: function () { return protocol_constants_js_1.withRetry; } });
@@ -7,6 +7,15 @@
7
7
  * y una actualización de versión de protocolo.
8
8
  *
9
9
  * Object.freeze() garantiza que no se modifiquen en runtime.
10
+ *
11
+ * ─── POR QUÉ Object.freeze() NO ES SUFICIENTE ─────────────────────────────
12
+ * Un AI o developer con acceso al código podría modificar los valores y
13
+ * correr su propio nodo con constantes distintas, rompiendo el protocolo.
14
+ *
15
+ * LA VERDADERA INMUTABILIDAD LA DA LA RED P2P:
16
+ * Cada nodo computa PROTOCOL_HASH al arrancar.
17
+ * Si el hash no coincide con los peers → el nodo es rechazado de la red.
18
+ * No hay forma de participar en la red con constantes modificadas.
10
19
  */
11
20
  export declare const PROTOCOL: Readonly<{
12
21
  /** Versión del protocolo SIP. Nodos con versiones distintas se rechazan. */
@@ -60,8 +69,63 @@ export declare const PROTOCOL: Readonly<{
60
69
  readonly RATE_LIMIT_MAX: 100;
61
70
  /** Ventana de tiempo del rate limiter (ms). */
62
71
  readonly RATE_LIMIT_WINDOW_MS: 60000;
72
+ /**
73
+ * Similitud mínima para verificación DOCUMENTO vs SELFIE.
74
+ * Fotos de documentos son más antiguas/pequeñas que selfies en vivo.
75
+ * Validado con cédula CO real: similitud 0.365 → VERIFICADO.
76
+ * Una persona diferente obtiene < 0.15 con el mismo modelo.
77
+ *
78
+ * NO MODIFICAR en runtime. Cambiar requiere nuevo SIP + bump de versión.
79
+ */
80
+ readonly FACE_SIM_DOC_SELFIE: 0.35;
81
+ /**
82
+ * Similitud mínima para verificación SELFIE vs SELFIE (re-verificación,
83
+ * liveness check, o comparación entre sesiones del mismo usuario).
84
+ * Umbral más estricto porque ambas fotos son recientes y de alta calidad.
85
+ */
86
+ readonly FACE_SIM_SELFIE_SELFIE: 0.65;
87
+ /**
88
+ * Número de dimensiones del embedding usadas para derivar el face_key.
89
+ * Las primeras 32 dims capturan suficiente identidad y son más robustas
90
+ * ante variaciones de iluminación/ángulo.
91
+ */
92
+ readonly FACE_KEY_DIMS: 32;
93
+ /**
94
+ * Decimales de precisión al redondear las dimensiones del embedding.
95
+ * 1 decimal absorbe el ruido natural de InsightFace (±0.01).
96
+ * Garantiza que la misma cara → mismo face_key aunque la foto varíe levemente.
97
+ */
98
+ readonly FACE_KEY_PRECISION: 1;
63
99
  }>;
64
100
  export type ProtocolConstants = typeof PROTOCOL;
101
+ /**
102
+ * Hash canónico de todos los valores de PROTOCOL.
103
+ * Se computa deterministicamente: JSON con claves ordenadas → SHA-256.
104
+ *
105
+ * PROPÓSITO:
106
+ * Este hash es la "identidad del protocolo" en la red P2P.
107
+ * Dos nodos solo pueden interactuar si sus PROTOCOL_HASH coinciden.
108
+ * Si alguien modifica cualquier constante (aunque sea 0.35 → 0.34),
109
+ * el hash cambia y el nodo queda aislado de toda la red.
110
+ *
111
+ * NO SE PUEDE FALSIFICAR: el hash se re-computa de los valores reales
112
+ * en memoria. Si PROTOCOL fue modificado antes de importar este módulo,
113
+ * el hash resultante no coincidirá con el de ningún nodo honesto.
114
+ *
115
+ * Valor esperado para SIP v0.1 con biometric constants:
116
+ * dfe1ccca1270ec86f93308dc4b981bab1d6bd74bdcc334059f4380b407ca07ca
117
+ */
118
+ export declare function computeProtocolHash(): string;
119
+ /**
120
+ * Hash oficial del protocolo SIP v0.1 (biometric constants incluidas).
121
+ * Cualquier nodo con un hash diferente no es compatible con esta red.
122
+ */
123
+ export declare const PROTOCOL_HASH: string;
124
+ /**
125
+ * Verifica que el hash de protocolo de un peer remoto coincide con el local.
126
+ * Retorna true si el peer es compatible, false si debe ser rechazado.
127
+ */
128
+ export declare function isProtocolHashCompatible(remoteHash: string): boolean;
65
129
  /**
66
130
  * Verifica que este nodo es compatible con la versión de protocolo recibida.
67
131
  * Retorna true si son compatibles, false si hay que rechazar la conexión.
@@ -8,13 +8,25 @@
8
8
  * y una actualización de versión de protocolo.
9
9
  *
10
10
  * Object.freeze() garantiza que no se modifiquen en runtime.
11
+ *
12
+ * ─── POR QUÉ Object.freeze() NO ES SUFICIENTE ─────────────────────────────
13
+ * Un AI o developer con acceso al código podría modificar los valores y
14
+ * correr su propio nodo con constantes distintas, rompiendo el protocolo.
15
+ *
16
+ * LA VERDADERA INMUTABILIDAD LA DA LA RED P2P:
17
+ * Cada nodo computa PROTOCOL_HASH al arrancar.
18
+ * Si el hash no coincide con los peers → el nodo es rechazado de la red.
19
+ * No hay forma de participar en la red con constantes modificadas.
11
20
  */
12
21
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.PROTOCOL = void 0;
22
+ exports.PROTOCOL_HASH = exports.PROTOCOL = void 0;
23
+ exports.computeProtocolHash = computeProtocolHash;
24
+ exports.isProtocolHashCompatible = isProtocolHashCompatible;
14
25
  exports.isProtocolCompatible = isProtocolCompatible;
15
26
  exports.clampMinScore = clampMinScore;
16
27
  exports.computeTotalScoreWithFloor = computeTotalScoreWithFloor;
17
28
  exports.withRetry = withRetry;
29
+ const node_crypto_1 = require("node:crypto");
18
30
  exports.PROTOCOL = Object.freeze({
19
31
  // ── Versión del protocolo ──────────────────────────────────────────────────
20
32
  /** Versión del protocolo SIP. Nodos con versiones distintas se rechazan. */
@@ -74,7 +86,69 @@ exports.PROTOCOL = Object.freeze({
74
86
  RATE_LIMIT_MAX: 100,
75
87
  /** Ventana de tiempo del rate limiter (ms). */
76
88
  RATE_LIMIT_WINDOW_MS: 60_000,
89
+ // ── Biometric thresholds (INAMOVIBLES) ─────────────────────────────────────
90
+ /**
91
+ * Similitud mínima para verificación DOCUMENTO vs SELFIE.
92
+ * Fotos de documentos son más antiguas/pequeñas que selfies en vivo.
93
+ * Validado con cédula CO real: similitud 0.365 → VERIFICADO.
94
+ * Una persona diferente obtiene < 0.15 con el mismo modelo.
95
+ *
96
+ * NO MODIFICAR en runtime. Cambiar requiere nuevo SIP + bump de versión.
97
+ */
98
+ FACE_SIM_DOC_SELFIE: 0.35,
99
+ /**
100
+ * Similitud mínima para verificación SELFIE vs SELFIE (re-verificación,
101
+ * liveness check, o comparación entre sesiones del mismo usuario).
102
+ * Umbral más estricto porque ambas fotos son recientes y de alta calidad.
103
+ */
104
+ FACE_SIM_SELFIE_SELFIE: 0.65,
105
+ /**
106
+ * Número de dimensiones del embedding usadas para derivar el face_key.
107
+ * Las primeras 32 dims capturan suficiente identidad y son más robustas
108
+ * ante variaciones de iluminación/ángulo.
109
+ */
110
+ FACE_KEY_DIMS: 32,
111
+ /**
112
+ * Decimales de precisión al redondear las dimensiones del embedding.
113
+ * 1 decimal absorbe el ruido natural de InsightFace (±0.01).
114
+ * Garantiza que la misma cara → mismo face_key aunque la foto varíe levemente.
115
+ */
116
+ FACE_KEY_PRECISION: 1,
77
117
  });
118
+ // ── Protocol Hash ─────────────────────────────────────────────────────────────
119
+ /**
120
+ * Hash canónico de todos los valores de PROTOCOL.
121
+ * Se computa deterministicamente: JSON con claves ordenadas → SHA-256.
122
+ *
123
+ * PROPÓSITO:
124
+ * Este hash es la "identidad del protocolo" en la red P2P.
125
+ * Dos nodos solo pueden interactuar si sus PROTOCOL_HASH coinciden.
126
+ * Si alguien modifica cualquier constante (aunque sea 0.35 → 0.34),
127
+ * el hash cambia y el nodo queda aislado de toda la red.
128
+ *
129
+ * NO SE PUEDE FALSIFICAR: el hash se re-computa de los valores reales
130
+ * en memoria. Si PROTOCOL fue modificado antes de importar este módulo,
131
+ * el hash resultante no coincidirá con el de ningún nodo honesto.
132
+ *
133
+ * Valor esperado para SIP v0.1 con biometric constants:
134
+ * dfe1ccca1270ec86f93308dc4b981bab1d6bd74bdcc334059f4380b407ca07ca
135
+ */
136
+ function computeProtocolHash() {
137
+ const canonical = JSON.stringify(Object.fromEntries(Object.entries(exports.PROTOCOL).sort(([a], [b]) => a.localeCompare(b))));
138
+ return (0, node_crypto_1.createHash)("sha256").update(canonical).digest("hex");
139
+ }
140
+ /**
141
+ * Hash oficial del protocolo SIP v0.1 (biometric constants incluidas).
142
+ * Cualquier nodo con un hash diferente no es compatible con esta red.
143
+ */
144
+ exports.PROTOCOL_HASH = computeProtocolHash();
145
+ /**
146
+ * Verifica que el hash de protocolo de un peer remoto coincide con el local.
147
+ * Retorna true si el peer es compatible, false si debe ser rechazado.
148
+ */
149
+ function isProtocolHashCompatible(remoteHash) {
150
+ return remoteHash === exports.PROTOCOL_HASH;
151
+ }
78
152
  /**
79
153
  * Verifica que este nodo es compatible con la versión de protocolo recibida.
80
154
  * Retorna true si son compatibles, false si hay que rechazar la conexión.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soulprint-core",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Soulprint core — DID keypairs, SPT tokens, Ed25519 signatures, trust scoring",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",