@hardkas/core 0.8.20-alpha → 0.9.1-alpha

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.md CHANGED
@@ -1,48 +1,56 @@
1
- # `@hardkas/core`
2
-
3
- The Core package provides the foundational safety rails, filesystem abstractions, and atomic persistence primitives for the entire HardKAS ecosystem.
4
-
5
- ## 1. Atomic Persistence Variants
6
-
7
- All state mutation in HardKAS relies on strict atomic persistence to prevent corruption during unexpected crashes or power loss. The standard flow follows the `temp + rename + fsync` pattern.
8
-
9
- ### Flow: Standard Atomic Write
10
- 1. Data is written to a temporary file (`.hardkas/tmp/<uuid>.json`).
11
- 2. `fs.fsyncSync()` is called on the temporary file to flush buffers to disk.
12
- 3. The temporary file is atomically renamed over the target file (e.g., `state.json`).
13
- 4. `fs.fsyncSync()` is called on the **parent directory** (`.hardkas/`) to ensure the directory entry is durably linked.
14
-
15
- ### Variant: Fallback Write
16
- If the filesystem does not support directory `fsync` (e.g., certain Windows/WSL configurations), the engine catches `EINVAL` or `EISDIR` and gracefully degrades to a standard atomic rename without the parent directory flush, logging a warning to the telemetry stream.
17
-
18
- ## 2. Workspace Lock Mechanisms
19
-
20
- To prevent concurrent modifications to the developer workspace, `@hardkas/core` uses a conservative file-based locking strategy (`.hardkas/locks/<domain>.lock`).
21
-
22
- ### Flow: Lock Acquisition
23
- 1. Process attempts to create a lock file using `fs.openSync(path, 'wx')` (exclusive write).
24
- 2. If successful, the process PID and timestamp are written.
25
- 3. If `EEXIST` is thrown, the process enters a **spin-wait loop** with exponential backoff (up to 30 seconds).
26
-
27
- ### Variant: Stale Lock Detection & Recovery (LockHell Defense)
28
- If a lock cannot be acquired after 30 seconds, the engine checks if the holding process is still alive.
29
- - **Dead Process:** If `process.kill(pid, 0)` fails (indicating the PID no longer exists), the lock is deemed **stale**. The engine atomically overrides the lock and logs a `STALE_LOCK_RECOVERY` telemetry event.
30
- - **Live Process:** If the PID is active, HardKAS strictly aborts with `HARDKAS_LOCK_CONTENTION`. It will *never* violently break a lock held by a live process.
31
- - **Zero-Byte Locks:** If a system crash occurs precisely when the `wx` descriptor is created but before the PID is written (a TOCTOU scenario), HardKAS considers any 0-byte lock older than 10 seconds as implicitly stale.
32
-
33
- ## 3. AppendCoordinator (Event Ledger)
34
-
35
- The `events.jsonl` ledger is the source of truth for the workspace. It is strictly append-only.
36
-
37
- ### Flow: Ledger Append
38
- 1. Acquire the exclusive `events` lock.
39
- 2. Read the tail of the stream to determine the last `eventId`.
40
- 3. Append the new JSON payload with a trailing newline.
41
- 4. `fs.fsyncSync()` the file descriptor.
42
-
43
- ### Variant: Tail Corruption Repair
44
- If the chaos engine (or a crash) leaves a partial JSON object at the tail of `events.jsonl` (e.g., `{"eventId": 142, "domain": "tx"` missing the closing brace):
45
- 1. The `AppendCoordinator` detects `Unexpected end of JSON input` during tail-read.
46
- 2. It explicitly scans backward to find the last valid newline boundary.
47
- 3. The corrupted tail is truncated automatically.
48
- 4. A `CORRUPT_TAIL_RECOVERY` event is dispatched to `telemetry.jsonl`.
1
+ # `@hardkas/core`
2
+
3
+ The Core package provides the foundational safety rails, filesystem abstractions, and atomic persistence primitives for the entire HardKAS ecosystem.
4
+
5
+ ## 1. Atomic Persistence Variants
6
+
7
+ All state mutation in HardKAS relies on strict atomic persistence to prevent corruption during unexpected crashes or power loss. The standard flow follows the `temp + rename + fsync` pattern.
8
+
9
+ ### Flow: Standard Atomic Write
10
+
11
+ 1. Data is written to a temporary file (`.hardkas/tmp/<uuid>.json`).
12
+ 2. `fs.fsyncSync()` is called on the temporary file to flush buffers to disk.
13
+ 3. The temporary file is atomically renamed over the target file (e.g., `state.json`).
14
+ 4. `fs.fsyncSync()` is called on the **parent directory** (`.hardkas/`) to ensure the directory entry is durably linked.
15
+
16
+ ### Variant: Fallback Write
17
+
18
+ If the filesystem does not support directory `fsync` (e.g., certain Windows/WSL configurations), the engine catches `EINVAL` or `EISDIR` and gracefully degrades to a standard atomic rename without the parent directory flush, logging a warning to the telemetry stream.
19
+
20
+ ## 2. Workspace Lock Mechanisms
21
+
22
+ To prevent concurrent modifications to the developer workspace, `@hardkas/core` uses a conservative file-based locking strategy (`.hardkas/locks/<domain>.lock`).
23
+
24
+ ### Flow: Lock Acquisition
25
+
26
+ 1. Process attempts to create a lock file using `fs.openSync(path, 'wx')` (exclusive write).
27
+ 2. If successful, the process PID and timestamp are written.
28
+ 3. If `EEXIST` is thrown, the process enters a **spin-wait loop** with exponential backoff (up to 30 seconds).
29
+
30
+ ### Variant: Stale Lock Detection & Recovery (LockHell Defense)
31
+
32
+ If a lock cannot be acquired after 30 seconds, the engine checks if the holding process is still alive.
33
+
34
+ - **Dead Process:** If `process.kill(pid, 0)` fails (indicating the PID no longer exists), the lock is deemed **stale**. The engine atomically overrides the lock and logs a `STALE_LOCK_RECOVERY` telemetry event.
35
+ - **Live Process:** If the PID is active, HardKAS strictly aborts with `HARDKAS_LOCK_CONTENTION`. It will _never_ violently break a lock held by a live process.
36
+ - **Zero-Byte Locks:** If a system crash occurs precisely when the `wx` descriptor is created but before the PID is written (a TOCTOU scenario), HardKAS considers any 0-byte lock older than 10 seconds as implicitly stale.
37
+
38
+ ## 3. AppendCoordinator (Event Ledger)
39
+
40
+ The `events.jsonl` ledger is the source of truth for the workspace. It is strictly append-only.
41
+
42
+ ### Flow: Ledger Append
43
+
44
+ 1. Acquire the exclusive `events` lock.
45
+ 2. Read the tail of the stream to determine the last `eventId`.
46
+ 3. Append the new JSON payload with a trailing newline.
47
+ 4. `fs.fsyncSync()` the file descriptor.
48
+
49
+ ### Variant: Tail Corruption Repair
50
+
51
+ If the chaos engine (or a crash) leaves a partial JSON object at the tail of `events.jsonl` (e.g., `{"eventId": 142, "domain": "tx"` missing the closing brace):
52
+
53
+ 1. The `AppendCoordinator` detects `Unexpected end of JSON input` during tail-read.
54
+ 2. It explicitly scans backward to find the last valid newline boundary.
55
+ 3. The corrupted tail is truncated automatically.
56
+ 4. A `CORRUPT_TAIL_RECOVERY` event is dispatched to `telemetry.jsonl`.
package/dist/index.d.ts CHANGED
@@ -75,6 +75,268 @@ declare const asNetworkId: <T extends string>(id: T) => Brand<T, "NetworkId">;
75
75
  declare const asEventSequence: (seq: number) => EventSequence;
76
76
  declare const asDaaScore: (score: number | bigint) => DaaScore;
77
77
 
78
+ /**
79
+ * Parses a KAS decimal string (e.g. "1.234") into Sompi (bigint).
80
+ * If a bigint is provided, it is assumed to be an already-parsed sompi amount.
81
+ *
82
+ * Rules:
83
+ * - string input = decimal KAS
84
+ * - bigint input = already sompi
85
+ * - format input = sompi
86
+ * - no floats
87
+ * - no Number decimal
88
+ * - no silent rounding
89
+ *
90
+ * @param input The KAS amount as a decimal string, or sompi as a bigint.
91
+ * @returns The sompi amount as a bigint.
92
+ */
93
+ declare function parseKasToSompi(input: string | bigint | number): bigint;
94
+ /**
95
+ * Formats a sompi amount into a KAS decimal string.
96
+ * @param sompi The sompi amount as a bigint or string representation of a bigint.
97
+ * @returns The KAS amount as a string.
98
+ */
99
+ declare function formatSompiToKas(sompi: bigint | string): string;
100
+ /**
101
+ * Formats a signed sompi amount into a KAS decimal string.
102
+ * This is meant ONLY for reporting deltas, audit statements, or rendering logic.
103
+ * It is NOT intended for validating spendable balances or user input amounts.
104
+ * @param sompi The sompi amount as a signed bigint or string representation of a bigint.
105
+ * @returns The KAS amount as a string (with a leading '-' if negative).
106
+ */
107
+ declare function formatSignedSompiToKas(sompi: bigint | string): string;
108
+
109
+ interface SchemaMetadata {
110
+ type: string;
111
+ domain: "tx" | "silver" | "zk" | "vprogs" | "programmability" | "corpus" | "infra" | "cli" | "audit";
112
+ version: "v1" | "v2" | "legacy" | string;
113
+ stability: "stable" | "stable-local" | "experimental" | "fixture-coherence" | "inspect-only" | "report";
114
+ legacy?: boolean;
115
+ }
116
+ declare const HardkasSchemas: {
117
+ readonly Event: "hardkas.event";
118
+ readonly WorkflowIntent: "hardkas.workflow.intent";
119
+ readonly TxPlan: "hardkas.txPlan";
120
+ readonly TxPlanV1: "hardkas.txPlan.v1";
121
+ readonly TxPlanV2: "hardkas.txPlan.v2";
122
+ readonly SignedTx: "hardkas.signedTx";
123
+ readonly SignedTxV1: "hardkas.signedTx.v1";
124
+ readonly TxReceipt: "hardkas.txReceipt";
125
+ readonly TxReceiptV1: "hardkas.txReceipt.v1";
126
+ readonly TxTrace: "hardkas.txTrace";
127
+ readonly TxTraceV1: "hardkas.txTrace.v1";
128
+ readonly Snapshot: "hardkas.snapshot";
129
+ readonly SnapshotV1: "hardkas.snapshot.v1";
130
+ readonly WorkflowV1: "hardkas.workflow.v1";
131
+ readonly PolicyV1: "hardkas.policy.v1";
132
+ readonly AssumptionV1: "hardkas.assumption.v1";
133
+ readonly NetworkProfileV1: "hardkas.networkProfile.v1";
134
+ readonly MigrationReceiptV1: "hardkas.migrationReceipt.v1";
135
+ readonly ErrorV1: "hardkas.error.v1";
136
+ readonly ReplayV1: "hardkas.replay.v1";
137
+ readonly ReplayDiffV1: "hardkas.replayDiff.v1";
138
+ readonly ReplayReportV1: "hardkas.replayReport.v1";
139
+ readonly ReplayVerifyV1: "hardkas.replayVerify.v1";
140
+ readonly LocalnetStateV1: "hardkas.localnetState.v1";
141
+ readonly LocalnetStatusV1: "hardkas.localnetStatus.v1";
142
+ readonly LocalnetControlV1: "hardkas.localnetControl.v1";
143
+ readonly LocalnetFundingV1: "hardkas.localnetFunding.v1";
144
+ readonly RealAccountStoreV1: "hardkas.realAccountStore.v1";
145
+ readonly EncryptedKeystoreV2: "hardkas.encryptedKeystore.v2";
146
+ readonly NodeStatusV1: "hardkas.nodeStatus.v1";
147
+ readonly DeploymentV1: "hardkas.deployment.v1";
148
+ readonly DeploymentIndexV1: "hardkas.deploymentIndex.v1";
149
+ readonly IgraTxPlan: "hardkas.igraTxPlan";
150
+ readonly IgraTxPlanV1: "hardkas.igraTxPlan.v1";
151
+ readonly IgraSignedTxV1: "hardkas.igraSignedTx.v1";
152
+ readonly IgraTxReceipt: "hardkas.igraTxReceipt";
153
+ readonly IgraTxReceiptV1: "hardkas.igraTxReceipt.v1";
154
+ readonly L2ProfileV1: "hardkas.l2Profile.v1";
155
+ readonly L2BridgeAssumptionsV1: "hardkas.l2BridgeAssumptions.v1";
156
+ readonly SilverCompile: "hardkas.silver.compile";
157
+ readonly SilverTest: "hardkas.silver.test";
158
+ readonly SilverDeployPlan: "hardkas.silver.deployPlan";
159
+ readonly SilverDeploy: "hardkas.silver.deploy";
160
+ readonly SilverSpendPlan: "hardkas.silver.spendPlan";
161
+ readonly SilverSpendReceipt: "hardkas.silver.spendReceipt";
162
+ readonly SilverDeploySimulation: "hardkas.silver.deploySimulation";
163
+ readonly SilverSpendSimulation: "hardkas.silver.spendSimulation";
164
+ readonly SilverSimulationStateV1: "hardkas.silver.simulationState.v1";
165
+ readonly ProgrammabilityCapabilitiesV1: "hardkas.programmability.capabilities.v1";
166
+ readonly ProgrammabilityInspectV1: "hardkas.programmability.inspect.v1";
167
+ readonly ProgrammabilityVerifyV1: "hardkas.programmability.verify.v1";
168
+ readonly ProgrammabilityCorpusReportV1: "hardkas.programmability.corpusReport.v1";
169
+ readonly ProgrammabilityAppPlanV1: "hardkas.programmability.appPlan.v1";
170
+ readonly ProgrammabilitySurfaceCheckV1: "hardkas.programmability.surfaceCheck.v1";
171
+ readonly ProgrammabilityExamplesCheckV1: "hardkas.programmability.examplesCheck.v1";
172
+ readonly ProgrammabilityTemplatesCheckV1: "hardkas.programmability.templatesCheck.v1";
173
+ readonly ZkCapabilitiesV1: "hardkas.zkCapabilities.v1";
174
+ readonly ZkCorpusV1: "hardkas.zkCorpus.v1";
175
+ readonly ZkProofInspectV1: "hardkas.zkProofInspect.v1";
176
+ readonly ZkProofVerificationV1: "hardkas.zkProofVerification.v1";
177
+ readonly ZkCorpusVerificationV1: "hardkas.zkCorpusVerification.v1";
178
+ readonly ZkGroth16FixtureV1: "hardkas.zkGroth16Fixture.v1";
179
+ readonly ZkRisc0FixtureV1: "hardkas.zkRisc0Fixture.v1";
180
+ readonly ZkGroth16ProofV1: "hardkas.zk.groth16.proof.v1";
181
+ readonly ZkGroth16PublicInputsV1: "hardkas.zk.groth16.publicInputs.v1";
182
+ readonly ZkGroth16VerificationKeyV1: "hardkas.zk.groth16.verificationKey.v1";
183
+ readonly ZkGroth16VerifierMetadataV1: "hardkas.zk.groth16.verifierMetadata.v1";
184
+ readonly ZkGroth16VerifyReportV1: "hardkas.zk.groth16.verifyReport.v1";
185
+ readonly ZkRisc0ImageIdV1: "hardkas.zk.risc0.imageId.v1";
186
+ readonly ZkRisc0JournalV1: "hardkas.zk.risc0.journal.v1";
187
+ readonly ZkRisc0ReceiptV1: "hardkas.zk.risc0.receipt.v1";
188
+ readonly ZkRisc0VerifyReportV1: "hardkas.zk.risc0.verifyReport.v1";
189
+ readonly VProgsCapabilitiesV1: "hardkas.vprogsCapabilities.v1";
190
+ readonly VProgsInspectV1: "hardkas.vprogsInspect.v1";
191
+ readonly VProgsStatusV1: "hardkas.vprogsStatus.v1";
192
+ readonly VProgsInspectFixtureV1: "hardkas.vprogs.inspectFixture.v1";
193
+ readonly ToccataProgrammabilityCorpusV1: "hardkas.toccataProgrammabilityCorpus.v1";
194
+ readonly ToccataGauntletV1: "hardkas.toccataGauntlet.v1";
195
+ readonly ToccataCorpusV1: "hardkas.toccataCorpus.v1";
196
+ readonly ToccataGoldenCompareV1: "hardkas.toccataGoldenCompare.v1";
197
+ readonly ToccataGoldenFailureCaseV1: "hardkas.toccataGoldenFailureCase.v1";
198
+ readonly ToccataGoldenManifestV1: "hardkas.toccataGoldenManifest.v1";
199
+ readonly ToccataGoldenFailureManifestV1: "hardkas.toccataGoldenFailureManifest.v1";
200
+ readonly PostReleaseProbe: "hardkas.postReleaseProbe";
201
+ readonly CliReferenceV1: "hardkas.cliReference.v1";
202
+ readonly ArtifactV1: "hardkas.artifact.v1";
203
+ readonly ArtifactInspectV1: "hardkas.artifactInspect.v1";
204
+ readonly AuditV1: "hardkas.audit.v1";
205
+ readonly PostReleaseBreakGauntletV1: "hardkas.postReleaseBreakGauntlet.v1";
206
+ readonly KaspaDoctorV1: "hardkas.kaspaDoctor.v1";
207
+ readonly DevDoctorV1: "hardkas.devDoctor.v1";
208
+ readonly DevServerV1: "hardkas.devServer.v1";
209
+ readonly LocalWizardV1: "hardkas.localWizard.v1";
210
+ readonly QueryRebuildV1: "hardkas.queryRebuild.v1";
211
+ readonly QueryVerifyV1: "hardkas.queryVerify.v1";
212
+ readonly SemanticBundleV1: "hardkas.semantic-bundle.v1";
213
+ readonly SessionV1: "hardkas.session.v1";
214
+ readonly SessionV0: "hardkas.session.v0";
215
+ readonly TelemetryV1: "hardkas.telemetry.v1";
216
+ readonly TortureReportV1: "hardkas.tortureReport.v1";
217
+ readonly PruneReportV1: "hardkas.pruneReport.v1";
218
+ readonly LockV1: "hardkas.lock.v1";
219
+ readonly BridgeLocalPlanV1: "hardkas.bridge.localPlan.v1";
220
+ readonly BridgeLocalSimulationV1: "hardkas.bridge.localSimulation.v1";
221
+ readonly KaswareLocalV1: "hardkas.kaswareLocal.v1";
222
+ readonly MetamaskLocalV1: "hardkas.metamaskLocal.v1";
223
+ readonly ExampleDocumentAnchorV1: "hardkas.example.documentAnchor.v1";
224
+ };
225
+ type HardkasSchema = typeof HardkasSchemas[keyof typeof HardkasSchemas];
226
+ /** Alias for compatibility */
227
+ declare const ArtifactTypes: {
228
+ readonly Event: "hardkas.event";
229
+ readonly WorkflowIntent: "hardkas.workflow.intent";
230
+ readonly TxPlan: "hardkas.txPlan";
231
+ readonly TxPlanV1: "hardkas.txPlan.v1";
232
+ readonly TxPlanV2: "hardkas.txPlan.v2";
233
+ readonly SignedTx: "hardkas.signedTx";
234
+ readonly SignedTxV1: "hardkas.signedTx.v1";
235
+ readonly TxReceipt: "hardkas.txReceipt";
236
+ readonly TxReceiptV1: "hardkas.txReceipt.v1";
237
+ readonly TxTrace: "hardkas.txTrace";
238
+ readonly TxTraceV1: "hardkas.txTrace.v1";
239
+ readonly Snapshot: "hardkas.snapshot";
240
+ readonly SnapshotV1: "hardkas.snapshot.v1";
241
+ readonly WorkflowV1: "hardkas.workflow.v1";
242
+ readonly PolicyV1: "hardkas.policy.v1";
243
+ readonly AssumptionV1: "hardkas.assumption.v1";
244
+ readonly NetworkProfileV1: "hardkas.networkProfile.v1";
245
+ readonly MigrationReceiptV1: "hardkas.migrationReceipt.v1";
246
+ readonly ErrorV1: "hardkas.error.v1";
247
+ readonly ReplayV1: "hardkas.replay.v1";
248
+ readonly ReplayDiffV1: "hardkas.replayDiff.v1";
249
+ readonly ReplayReportV1: "hardkas.replayReport.v1";
250
+ readonly ReplayVerifyV1: "hardkas.replayVerify.v1";
251
+ readonly LocalnetStateV1: "hardkas.localnetState.v1";
252
+ readonly LocalnetStatusV1: "hardkas.localnetStatus.v1";
253
+ readonly LocalnetControlV1: "hardkas.localnetControl.v1";
254
+ readonly LocalnetFundingV1: "hardkas.localnetFunding.v1";
255
+ readonly RealAccountStoreV1: "hardkas.realAccountStore.v1";
256
+ readonly EncryptedKeystoreV2: "hardkas.encryptedKeystore.v2";
257
+ readonly NodeStatusV1: "hardkas.nodeStatus.v1";
258
+ readonly DeploymentV1: "hardkas.deployment.v1";
259
+ readonly DeploymentIndexV1: "hardkas.deploymentIndex.v1";
260
+ readonly IgraTxPlan: "hardkas.igraTxPlan";
261
+ readonly IgraTxPlanV1: "hardkas.igraTxPlan.v1";
262
+ readonly IgraSignedTxV1: "hardkas.igraSignedTx.v1";
263
+ readonly IgraTxReceipt: "hardkas.igraTxReceipt";
264
+ readonly IgraTxReceiptV1: "hardkas.igraTxReceipt.v1";
265
+ readonly L2ProfileV1: "hardkas.l2Profile.v1";
266
+ readonly L2BridgeAssumptionsV1: "hardkas.l2BridgeAssumptions.v1";
267
+ readonly SilverCompile: "hardkas.silver.compile";
268
+ readonly SilverTest: "hardkas.silver.test";
269
+ readonly SilverDeployPlan: "hardkas.silver.deployPlan";
270
+ readonly SilverDeploy: "hardkas.silver.deploy";
271
+ readonly SilverSpendPlan: "hardkas.silver.spendPlan";
272
+ readonly SilverSpendReceipt: "hardkas.silver.spendReceipt";
273
+ readonly SilverDeploySimulation: "hardkas.silver.deploySimulation";
274
+ readonly SilverSpendSimulation: "hardkas.silver.spendSimulation";
275
+ readonly SilverSimulationStateV1: "hardkas.silver.simulationState.v1";
276
+ readonly ProgrammabilityCapabilitiesV1: "hardkas.programmability.capabilities.v1";
277
+ readonly ProgrammabilityInspectV1: "hardkas.programmability.inspect.v1";
278
+ readonly ProgrammabilityVerifyV1: "hardkas.programmability.verify.v1";
279
+ readonly ProgrammabilityCorpusReportV1: "hardkas.programmability.corpusReport.v1";
280
+ readonly ProgrammabilityAppPlanV1: "hardkas.programmability.appPlan.v1";
281
+ readonly ProgrammabilitySurfaceCheckV1: "hardkas.programmability.surfaceCheck.v1";
282
+ readonly ProgrammabilityExamplesCheckV1: "hardkas.programmability.examplesCheck.v1";
283
+ readonly ProgrammabilityTemplatesCheckV1: "hardkas.programmability.templatesCheck.v1";
284
+ readonly ZkCapabilitiesV1: "hardkas.zkCapabilities.v1";
285
+ readonly ZkCorpusV1: "hardkas.zkCorpus.v1";
286
+ readonly ZkProofInspectV1: "hardkas.zkProofInspect.v1";
287
+ readonly ZkProofVerificationV1: "hardkas.zkProofVerification.v1";
288
+ readonly ZkCorpusVerificationV1: "hardkas.zkCorpusVerification.v1";
289
+ readonly ZkGroth16FixtureV1: "hardkas.zkGroth16Fixture.v1";
290
+ readonly ZkRisc0FixtureV1: "hardkas.zkRisc0Fixture.v1";
291
+ readonly ZkGroth16ProofV1: "hardkas.zk.groth16.proof.v1";
292
+ readonly ZkGroth16PublicInputsV1: "hardkas.zk.groth16.publicInputs.v1";
293
+ readonly ZkGroth16VerificationKeyV1: "hardkas.zk.groth16.verificationKey.v1";
294
+ readonly ZkGroth16VerifierMetadataV1: "hardkas.zk.groth16.verifierMetadata.v1";
295
+ readonly ZkGroth16VerifyReportV1: "hardkas.zk.groth16.verifyReport.v1";
296
+ readonly ZkRisc0ImageIdV1: "hardkas.zk.risc0.imageId.v1";
297
+ readonly ZkRisc0JournalV1: "hardkas.zk.risc0.journal.v1";
298
+ readonly ZkRisc0ReceiptV1: "hardkas.zk.risc0.receipt.v1";
299
+ readonly ZkRisc0VerifyReportV1: "hardkas.zk.risc0.verifyReport.v1";
300
+ readonly VProgsCapabilitiesV1: "hardkas.vprogsCapabilities.v1";
301
+ readonly VProgsInspectV1: "hardkas.vprogsInspect.v1";
302
+ readonly VProgsStatusV1: "hardkas.vprogsStatus.v1";
303
+ readonly VProgsInspectFixtureV1: "hardkas.vprogs.inspectFixture.v1";
304
+ readonly ToccataProgrammabilityCorpusV1: "hardkas.toccataProgrammabilityCorpus.v1";
305
+ readonly ToccataGauntletV1: "hardkas.toccataGauntlet.v1";
306
+ readonly ToccataCorpusV1: "hardkas.toccataCorpus.v1";
307
+ readonly ToccataGoldenCompareV1: "hardkas.toccataGoldenCompare.v1";
308
+ readonly ToccataGoldenFailureCaseV1: "hardkas.toccataGoldenFailureCase.v1";
309
+ readonly ToccataGoldenManifestV1: "hardkas.toccataGoldenManifest.v1";
310
+ readonly ToccataGoldenFailureManifestV1: "hardkas.toccataGoldenFailureManifest.v1";
311
+ readonly PostReleaseProbe: "hardkas.postReleaseProbe";
312
+ readonly CliReferenceV1: "hardkas.cliReference.v1";
313
+ readonly ArtifactV1: "hardkas.artifact.v1";
314
+ readonly ArtifactInspectV1: "hardkas.artifactInspect.v1";
315
+ readonly AuditV1: "hardkas.audit.v1";
316
+ readonly PostReleaseBreakGauntletV1: "hardkas.postReleaseBreakGauntlet.v1";
317
+ readonly KaspaDoctorV1: "hardkas.kaspaDoctor.v1";
318
+ readonly DevDoctorV1: "hardkas.devDoctor.v1";
319
+ readonly DevServerV1: "hardkas.devServer.v1";
320
+ readonly LocalWizardV1: "hardkas.localWizard.v1";
321
+ readonly QueryRebuildV1: "hardkas.queryRebuild.v1";
322
+ readonly QueryVerifyV1: "hardkas.queryVerify.v1";
323
+ readonly SemanticBundleV1: "hardkas.semantic-bundle.v1";
324
+ readonly SessionV1: "hardkas.session.v1";
325
+ readonly SessionV0: "hardkas.session.v0";
326
+ readonly TelemetryV1: "hardkas.telemetry.v1";
327
+ readonly TortureReportV1: "hardkas.tortureReport.v1";
328
+ readonly PruneReportV1: "hardkas.pruneReport.v1";
329
+ readonly LockV1: "hardkas.lock.v1";
330
+ readonly BridgeLocalPlanV1: "hardkas.bridge.localPlan.v1";
331
+ readonly BridgeLocalSimulationV1: "hardkas.bridge.localSimulation.v1";
332
+ readonly KaswareLocalV1: "hardkas.kaswareLocal.v1";
333
+ readonly MetamaskLocalV1: "hardkas.metamaskLocal.v1";
334
+ readonly ExampleDocumentAnchorV1: "hardkas.example.documentAnchor.v1";
335
+ };
336
+ declare function isKnownArtifactType(type: string): type is HardkasSchema;
337
+ declare function assertKnownArtifactType(type: string): HardkasSchema;
338
+ declare function describeArtifactType(type: HardkasSchema): SchemaMetadata;
339
+
78
340
  /**
79
341
  * HardKAS Core Event Domains.
80
342
  */
@@ -254,7 +516,7 @@ interface EventPayloadByKind {
254
516
  * Standardizes how events are captured and tracked across the system.
255
517
  */
256
518
  interface EventEnvelope<K extends EventKind = EventKind> {
257
- schema: "hardkas.event";
519
+ schema: typeof HardkasSchemas.Event;
258
520
  version: "1.0.0";
259
521
  eventId: EventId;
260
522
  domain: EventDomain;
@@ -434,7 +696,7 @@ interface StateProvenance {
434
696
  * HardKAS Lock Metadata schema v1
435
697
  */
436
698
  interface LockMetadata {
437
- schema: "hardkas.lock.v1";
699
+ schema: typeof HardkasSchemas.LockV1;
438
700
  name: string;
439
701
  pid: number;
440
702
  command: string;
@@ -527,7 +789,7 @@ interface RuntimeNoiseDiff {
527
789
  metadataDrift: string[];
528
790
  }
529
791
  interface LayeredReplayDiff {
530
- schema: "hardkas.replayDiff.v1";
792
+ schema: typeof HardkasSchemas.ReplayDiffV1;
531
793
  structural: StructuralDiff;
532
794
  deterministic: DeterministicDiff;
533
795
  observational: RuntimeNoiseDiff;
@@ -793,7 +1055,7 @@ declare class AppendCoordinator {
793
1055
  };
794
1056
  }
795
1057
 
796
- declare const CURRENT_RUNTIME_VERSION = "0.8.20-alpha";
1058
+ declare const CURRENT_RUNTIME_VERSION = "0.9.1-alpha";
797
1059
  declare const MIN_SUPPORTED_VERSION = "0.5.0-alpha";
798
1060
  interface MigrationStatus {
799
1061
  needsMigration: boolean;
@@ -808,16 +1070,47 @@ declare class MigrationManager {
808
1070
  private static compareSemver;
809
1071
  }
810
1072
 
1073
+ /**
1074
+ * Calculates the Blake2b 32-byte hash of the raw redeem script bytes.
1075
+ * This MUST ONLY be the raw bytes, never the artifact JSON or wrapper hex.
1076
+ *
1077
+ * @param scriptHexOrBytes The compiled script hex string or Buffer
1078
+ * @returns 32-byte hash as hex string
1079
+ */
1080
+ declare function createRedeemScriptHash(scriptHexOrBytes: string | Buffer | Uint8Array): string;
1081
+ /**
1082
+ * Creates a Kaspa standard P2SH locking script (BIP16-like but with Blake2b).
1083
+ * Version is always 0 for standard script hashes in Kaspa currently,
1084
+ * although future VM versions might use 8.
1085
+ *
1086
+ * @param scriptHexOrBytes The compiled script hex string or Buffer
1087
+ */
1088
+ declare function createKaspaP2shBlake2bLock(scriptHexOrBytes: string | Buffer | Uint8Array): {
1089
+ scriptPublicKeyVersion: number;
1090
+ lockingScriptHex: string;
1091
+ redeemScriptHash: string;
1092
+ redeemScriptHex: string;
1093
+ };
1094
+ /**
1095
+ * Creates a valid Kaspa v2.0.0 signature script for a P2SH UTXO.
1096
+ * The signature script must be push-only. It pushes any arguments,
1097
+ * followed by the raw redeem script itself.
1098
+ *
1099
+ * @param args Array of hex strings representing the arguments to push
1100
+ * @param redeemScriptHex The compiled script hex string
1101
+ */
1102
+ declare function createPushOnlySignatureScript(args: string[], redeemScriptHex: string): string;
1103
+
811
1104
  declare const SOMPI_PER_KAS = 100000000n;
812
1105
  declare const kaspaNetworkIdSchema: z.ZodEnum<["mainnet", "testnet-10", "testnet-11", "testnet-12", "simnet", "simnet-1", "devnet", "simulated", "igra"]>;
813
1106
  type NetworkId = Brand<z.infer<typeof kaspaNetworkIdSchema>, "NetworkId">;
814
1107
  declare const executionModeSchema: z.ZodEnum<["simulated", "real", "readonly"]>;
815
1108
  type ExecutionMode = z.infer<typeof executionModeSchema>;
816
- declare const artifactTypeSchema: z.ZodEnum<["txPlan", "signedTx", "txReceipt", "txTrace", "snapshot", "workflow.v1", "policy.v1", "networkProfile.v1", "assumption.v1", "migrationReceipt.v1"]>;
1109
+ declare const artifactTypeSchema: z.ZodEnum<["txPlan", "signedTx", "txReceipt", "txTrace", "snapshot", "workflow.v1", "policy.v1", "networkProfile.v1", "assumption.v1", "migrationReceipt.v1", "silver.compile", "silver.test", "silver.spendPlan", "silver.deployPlan", "silver.deploy", "silver.spendReceipt", "silver.deploySimulation", "silver.spendSimulation"]>;
817
1110
  type ArtifactType = z.infer<typeof artifactTypeSchema>;
818
1111
  declare const NetworkIdSchema: z.ZodEnum<["mainnet", "testnet-10", "testnet-11", "testnet-12", "simnet", "simnet-1", "devnet", "simulated", "igra"]>;
819
1112
  declare const ExecutionModeSchema: z.ZodEnum<["simulated", "real", "readonly"]>;
820
- declare const ArtifactTypeSchema: z.ZodEnum<["txPlan", "signedTx", "txReceipt", "txTrace", "snapshot", "workflow.v1", "policy.v1", "networkProfile.v1", "assumption.v1", "migrationReceipt.v1"]>;
1113
+ declare const ArtifactTypeSchema: z.ZodEnum<["txPlan", "signedTx", "txReceipt", "txTrace", "snapshot", "workflow.v1", "policy.v1", "networkProfile.v1", "assumption.v1", "migrationReceipt.v1", "silver.compile", "silver.test", "silver.spendPlan", "silver.deployPlan", "silver.deploy", "silver.spendReceipt", "silver.deploySimulation", "silver.spendSimulation"]>;
821
1114
  declare const hardkasConfigSchema: z.ZodObject<{
822
1115
  project: z.ZodObject<{
823
1116
  name: z.ZodString;
@@ -895,7 +1188,5 @@ declare class InvariantViolationError extends HardkasError {
895
1188
  });
896
1189
  }
897
1190
  declare function parseHardkasConfig(input: unknown): HardkasConfig;
898
- declare function parseKasToSompi(input: string): bigint;
899
- declare function formatSompi(amountSompi: bigint): string;
900
1191
 
901
- export { type AcquireLockArgs, type AnomalyEvent, type AnomalyType, AppendCoordinator, type ArtifactId, type ArtifactStatus, type ArtifactType, ArtifactTypeSchema, type Brand, type Branded, CURRENT_RUNTIME_VERSION, type ContentHash, type CoreEvent, type CoreEventListener, type CorrelationId, type CorruptionCode, type CorruptionIssue, type CorruptionSeverity, type CreateSnapshotOptions, type DaaScore, type DeterministicClock, type DeterministicDiff, type DeterministicRandom, EnvironmentTelemetry, type EventDomain, type EventEnvelope, type EventId, type EventKind, type EventPayloadByKind, type EventSequence, type ExecutionMode, ExecutionModeSchema, type HardkasConfig, HardkasError, type IdProvider, type IntegrityStatus, type InvariantDomain, type InvariantSeverity, InvariantViolationError, type KaspaAddress, LOCK_ORDER, type LayeredReplayDiff, type LineageId, type LockHandle, type LockMetadata, MIN_SUPPORTED_VERSION, MigrationManager, type MigrationResult, type MigrationStatus, type NetworkId, NetworkIdSchema, type ReplayContext, type RotationResult, type RpcEndpointId, type RuntimeContext, type RuntimeNoiseDiff, SOMPI_PER_KAS, type SchemaVersion, type SemanticDriftReport, type SemanticIdentity, type Severity, type SnapshotManifest, type StampedEvent, type StateProvenance, type StructuralDiff, TelemetryManager, TelemetryRotator, type TelemetrySubsystem, type TxId, type UnknownEventPayload, type WorkflowId, type WriteFileAtomicOptions, acquireLock, artifactTypeSchema, asArtifactId, asContentHash, asCorrelationId, asDaaScore, asEventId, asEventSequence, asKaspaAddress, asLineageId, asNetworkId, asRpcEndpointId, asTxId, asWorkflowId, assertNoSemanticDrift, attachLedgerAppender, classifyArtifactStatus, clearLock, comparePrePostMigrationLineage, coreEvents, createEventEnvelope, createSnapshot, detectSemanticDrift, deterministicCompare, diffReplays, executionModeSchema, formatCorruptionIssue, formatSompi, getTelemetry, globalTelemetry, hardkasConfigSchema, isProcessAlive, kaspaNetworkIdSchema, listLocks, maskSecrets, migrateArtifact, parseHardkasConfig, parseKasToSompi, readSnapshotManifest, redactSecret, resolveCanonicalArtifact, resolveLineage, systemRuntimeContext, telemetryContextStorage, validateEventEnvelope, validateStatusTransition, verifyArtifactIntegrity, verifyCapabilityBoundary, verifyMigrationIntegrity, verifyProjectionFreshness, verifyReplay, withLock, withLocks, writeFileAtomic, writeFileAtomicSync };
1192
+ export { type AcquireLockArgs, type AnomalyEvent, type AnomalyType, AppendCoordinator, type ArtifactId, type ArtifactStatus, type ArtifactType, ArtifactTypeSchema, ArtifactTypes, type Brand, type Branded, CURRENT_RUNTIME_VERSION, type ContentHash, type CoreEvent, type CoreEventListener, type CorrelationId, type CorruptionCode, type CorruptionIssue, type CorruptionSeverity, type CreateSnapshotOptions, type DaaScore, type DeterministicClock, type DeterministicDiff, type DeterministicRandom, EnvironmentTelemetry, type EventDomain, type EventEnvelope, type EventId, type EventKind, type EventPayloadByKind, type EventSequence, type ExecutionMode, ExecutionModeSchema, type HardkasConfig, HardkasError, type HardkasSchema, HardkasSchemas, type IdProvider, type IntegrityStatus, type InvariantDomain, type InvariantSeverity, InvariantViolationError, type KaspaAddress, LOCK_ORDER, type LayeredReplayDiff, type LineageId, type LockHandle, type LockMetadata, MIN_SUPPORTED_VERSION, MigrationManager, type MigrationResult, type MigrationStatus, type NetworkId, NetworkIdSchema, type ReplayContext, type RotationResult, type RpcEndpointId, type RuntimeContext, type RuntimeNoiseDiff, SOMPI_PER_KAS, type SchemaMetadata, type SchemaVersion, type SemanticDriftReport, type SemanticIdentity, type Severity, type SnapshotManifest, type StampedEvent, type StateProvenance, type StructuralDiff, TelemetryManager, TelemetryRotator, type TelemetrySubsystem, type TxId, type UnknownEventPayload, type WorkflowId, type WriteFileAtomicOptions, acquireLock, artifactTypeSchema, asArtifactId, asContentHash, asCorrelationId, asDaaScore, asEventId, asEventSequence, asKaspaAddress, asLineageId, asNetworkId, asRpcEndpointId, asTxId, asWorkflowId, assertKnownArtifactType, assertNoSemanticDrift, attachLedgerAppender, classifyArtifactStatus, clearLock, comparePrePostMigrationLineage, coreEvents, createEventEnvelope, createKaspaP2shBlake2bLock, createPushOnlySignatureScript, createRedeemScriptHash, createSnapshot, describeArtifactType, detectSemanticDrift, deterministicCompare, diffReplays, executionModeSchema, formatCorruptionIssue, formatSignedSompiToKas, formatSompiToKas, getTelemetry, globalTelemetry, hardkasConfigSchema, isKnownArtifactType, isProcessAlive, kaspaNetworkIdSchema, listLocks, maskSecrets, migrateArtifact, parseHardkasConfig, parseKasToSompi, readSnapshotManifest, redactSecret, resolveCanonicalArtifact, resolveLineage, systemRuntimeContext, telemetryContextStorage, validateEventEnvelope, validateStatusTransition, verifyArtifactIntegrity, verifyCapabilityBoundary, verifyMigrationIntegrity, verifyProjectionFreshness, verifyReplay, withLock, withLocks, writeFileAtomic, writeFileAtomicSync };
package/dist/index.js CHANGED
@@ -1,6 +1,249 @@
1
1
  // src/index.ts
2
2
  import { z } from "zod";
3
3
 
4
+ // src/money.ts
5
+ function parseKasToSompi(input) {
6
+ if (typeof input === "bigint") {
7
+ if (input < 0n) {
8
+ throw new Error("KAS_AMOUNT_NEGATIVE: negative money not allowed");
9
+ }
10
+ return input;
11
+ }
12
+ if (typeof input === "number") {
13
+ if (!Number.isSafeInteger(input)) {
14
+ throw new Error(
15
+ "KAS_AMOUNT_UNSAFE_NUMBER: floats or unsafe numbers are forbidden for monetary paths. Pass a string for KAS or bigint for Sompi."
16
+ );
17
+ }
18
+ if (input < 0) {
19
+ throw new Error("KAS_AMOUNT_NEGATIVE: negative money not allowed");
20
+ }
21
+ return BigInt(input);
22
+ }
23
+ if (typeof input !== "string") {
24
+ throw new Error("INVALID_KAS_AMOUNT: amount must be a string or bigint");
25
+ }
26
+ let cleaned = input.trim();
27
+ if (cleaned.startsWith("-")) {
28
+ throw new Error("KAS_AMOUNT_NEGATIVE: negative money not allowed");
29
+ }
30
+ if (cleaned.startsWith("+")) {
31
+ throw new Error("INVALID_KAS_AMOUNT: explicit positive sign not supported");
32
+ }
33
+ if (cleaned.toLowerCase().includes("e")) {
34
+ throw new Error(
35
+ "KAS_AMOUNT_SCIENTIFIC_NOTATION_UNSUPPORTED: scientific notation is not supported"
36
+ );
37
+ }
38
+ if (cleaned.toUpperCase().endsWith("KAS")) {
39
+ cleaned = cleaned.slice(0, -3).trim();
40
+ }
41
+ if (!/^[0-9]+(\.[0-9]+)?$/.test(cleaned)) {
42
+ throw new Error(`INVALID_KAS_AMOUNT: invalid characters or format in '${input}'`);
43
+ }
44
+ const parts = cleaned.split(".");
45
+ const integerPart = parts[0];
46
+ let fractionalPart = parts[1] || "";
47
+ if (fractionalPart.length > 8) {
48
+ throw new Error(
49
+ `KAS_AMOUNT_TOO_MANY_DECIMALS: too many decimal places in '${input}'`
50
+ );
51
+ }
52
+ fractionalPart = fractionalPart.padEnd(8, "0");
53
+ return BigInt(integerPart + fractionalPart);
54
+ }
55
+ function formatSompiToKas(sompi) {
56
+ let s;
57
+ try {
58
+ s = BigInt(sompi);
59
+ } catch (e) {
60
+ throw new Error("INVALID_KAS_AMOUNT: invalid sompi format");
61
+ }
62
+ if (s < 0n) {
63
+ throw new Error("SOMPI_AMOUNT_NEGATIVE: negative sompi amounts are not supported");
64
+ }
65
+ const str = s.toString().padStart(9, "0");
66
+ const intPart = str.slice(0, -8);
67
+ let fracPart = str.slice(-8);
68
+ fracPart = fracPart.replace(/0+$/, "");
69
+ if (fracPart.length > 0) {
70
+ return `${intPart}.${fracPart}`;
71
+ }
72
+ return intPart;
73
+ }
74
+ function formatSignedSompiToKas(sompi) {
75
+ let s;
76
+ try {
77
+ s = BigInt(sompi);
78
+ } catch (e) {
79
+ throw new Error("INVALID_KAS_AMOUNT: invalid sompi format");
80
+ }
81
+ if (s < 0n) {
82
+ return `-${formatSompiToKas(-s)}`;
83
+ }
84
+ return formatSompiToKas(s);
85
+ }
86
+
87
+ // src/registry.ts
88
+ var HardkasSchemas = {
89
+ // --- Tx & Core ---
90
+ Event: "hardkas.event",
91
+ WorkflowIntent: "hardkas.workflow.intent",
92
+ TxPlan: "hardkas.txPlan",
93
+ TxPlanV1: "hardkas.txPlan.v1",
94
+ TxPlanV2: "hardkas.txPlan.v2",
95
+ SignedTx: "hardkas.signedTx",
96
+ SignedTxV1: "hardkas.signedTx.v1",
97
+ TxReceipt: "hardkas.txReceipt",
98
+ TxReceiptV1: "hardkas.txReceipt.v1",
99
+ TxTrace: "hardkas.txTrace",
100
+ TxTraceV1: "hardkas.txTrace.v1",
101
+ Snapshot: "hardkas.snapshot",
102
+ SnapshotV1: "hardkas.snapshot.v1",
103
+ WorkflowV1: "hardkas.workflow.v1",
104
+ PolicyV1: "hardkas.policy.v1",
105
+ AssumptionV1: "hardkas.assumption.v1",
106
+ NetworkProfileV1: "hardkas.networkProfile.v1",
107
+ MigrationReceiptV1: "hardkas.migrationReceipt.v1",
108
+ ErrorV1: "hardkas.error.v1",
109
+ ReplayV1: "hardkas.replay.v1",
110
+ ReplayDiffV1: "hardkas.replayDiff.v1",
111
+ ReplayReportV1: "hardkas.replayReport.v1",
112
+ ReplayVerifyV1: "hardkas.replayVerify.v1",
113
+ // --- Localnet & Realnet Infra ---
114
+ LocalnetStateV1: "hardkas.localnetState.v1",
115
+ LocalnetStatusV1: "hardkas.localnetStatus.v1",
116
+ LocalnetControlV1: "hardkas.localnetControl.v1",
117
+ LocalnetFundingV1: "hardkas.localnetFunding.v1",
118
+ RealAccountStoreV1: "hardkas.realAccountStore.v1",
119
+ EncryptedKeystoreV2: "hardkas.encryptedKeystore.v2",
120
+ NodeStatusV1: "hardkas.nodeStatus.v1",
121
+ // --- Deployment ---
122
+ DeploymentV1: "hardkas.deployment.v1",
123
+ DeploymentIndexV1: "hardkas.deploymentIndex.v1",
124
+ // --- L2 & Igra ---
125
+ IgraTxPlan: "hardkas.igraTxPlan",
126
+ IgraTxPlanV1: "hardkas.igraTxPlan.v1",
127
+ IgraSignedTxV1: "hardkas.igraSignedTx.v1",
128
+ IgraTxReceipt: "hardkas.igraTxReceipt",
129
+ IgraTxReceiptV1: "hardkas.igraTxReceipt.v1",
130
+ L2ProfileV1: "hardkas.l2Profile.v1",
131
+ L2BridgeAssumptionsV1: "hardkas.l2BridgeAssumptions.v1",
132
+ // --- SilverScript ---
133
+ SilverCompile: "hardkas.silver.compile",
134
+ SilverTest: "hardkas.silver.test",
135
+ SilverDeployPlan: "hardkas.silver.deployPlan",
136
+ SilverDeploy: "hardkas.silver.deploy",
137
+ SilverSpendPlan: "hardkas.silver.spendPlan",
138
+ SilverSpendReceipt: "hardkas.silver.spendReceipt",
139
+ SilverDeploySimulation: "hardkas.silver.deploySimulation",
140
+ SilverSpendSimulation: "hardkas.silver.spendSimulation",
141
+ SilverSimulationStateV1: "hardkas.silver.simulationState.v1",
142
+ // --- Programmability Surface ---
143
+ ProgrammabilityCapabilitiesV1: "hardkas.programmability.capabilities.v1",
144
+ ProgrammabilityInspectV1: "hardkas.programmability.inspect.v1",
145
+ ProgrammabilityVerifyV1: "hardkas.programmability.verify.v1",
146
+ ProgrammabilityCorpusReportV1: "hardkas.programmability.corpusReport.v1",
147
+ ProgrammabilityAppPlanV1: "hardkas.programmability.appPlan.v1",
148
+ ProgrammabilitySurfaceCheckV1: "hardkas.programmability.surfaceCheck.v1",
149
+ ProgrammabilityExamplesCheckV1: "hardkas.programmability.examplesCheck.v1",
150
+ ProgrammabilityTemplatesCheckV1: "hardkas.programmability.templatesCheck.v1",
151
+ // --- ZK & vProgs ---
152
+ ZkCapabilitiesV1: "hardkas.zkCapabilities.v1",
153
+ ZkCorpusV1: "hardkas.zkCorpus.v1",
154
+ ZkProofInspectV1: "hardkas.zkProofInspect.v1",
155
+ ZkProofVerificationV1: "hardkas.zkProofVerification.v1",
156
+ ZkCorpusVerificationV1: "hardkas.zkCorpusVerification.v1",
157
+ ZkGroth16FixtureV1: "hardkas.zkGroth16Fixture.v1",
158
+ ZkRisc0FixtureV1: "hardkas.zkRisc0Fixture.v1",
159
+ ZkGroth16ProofV1: "hardkas.zk.groth16.proof.v1",
160
+ ZkGroth16PublicInputsV1: "hardkas.zk.groth16.publicInputs.v1",
161
+ ZkGroth16VerificationKeyV1: "hardkas.zk.groth16.verificationKey.v1",
162
+ ZkGroth16VerifierMetadataV1: "hardkas.zk.groth16.verifierMetadata.v1",
163
+ ZkGroth16VerifyReportV1: "hardkas.zk.groth16.verifyReport.v1",
164
+ ZkRisc0ImageIdV1: "hardkas.zk.risc0.imageId.v1",
165
+ ZkRisc0JournalV1: "hardkas.zk.risc0.journal.v1",
166
+ ZkRisc0ReceiptV1: "hardkas.zk.risc0.receipt.v1",
167
+ ZkRisc0VerifyReportV1: "hardkas.zk.risc0.verifyReport.v1",
168
+ VProgsCapabilitiesV1: "hardkas.vprogsCapabilities.v1",
169
+ VProgsInspectV1: "hardkas.vprogsInspect.v1",
170
+ VProgsStatusV1: "hardkas.vprogsStatus.v1",
171
+ VProgsInspectFixtureV1: "hardkas.vprogs.inspectFixture.v1",
172
+ // --- Corpus & Testing ---
173
+ ToccataProgrammabilityCorpusV1: "hardkas.toccataProgrammabilityCorpus.v1",
174
+ ToccataGauntletV1: "hardkas.toccataGauntlet.v1",
175
+ ToccataCorpusV1: "hardkas.toccataCorpus.v1",
176
+ ToccataGoldenCompareV1: "hardkas.toccataGoldenCompare.v1",
177
+ ToccataGoldenFailureCaseV1: "hardkas.toccataGoldenFailureCase.v1",
178
+ ToccataGoldenManifestV1: "hardkas.toccataGoldenManifest.v1",
179
+ ToccataGoldenFailureManifestV1: "hardkas.toccataGoldenFailureManifest.v1",
180
+ // --- CLI / Runners / Audits / Reports ---
181
+ PostReleaseProbe: "hardkas.postReleaseProbe",
182
+ CliReferenceV1: "hardkas.cliReference.v1",
183
+ ArtifactV1: "hardkas.artifact.v1",
184
+ ArtifactInspectV1: "hardkas.artifactInspect.v1",
185
+ AuditV1: "hardkas.audit.v1",
186
+ PostReleaseBreakGauntletV1: "hardkas.postReleaseBreakGauntlet.v1",
187
+ KaspaDoctorV1: "hardkas.kaspaDoctor.v1",
188
+ DevDoctorV1: "hardkas.devDoctor.v1",
189
+ DevServerV1: "hardkas.devServer.v1",
190
+ LocalWizardV1: "hardkas.localWizard.v1",
191
+ QueryRebuildV1: "hardkas.queryRebuild.v1",
192
+ QueryVerifyV1: "hardkas.queryVerify.v1",
193
+ SemanticBundleV1: "hardkas.semantic-bundle.v1",
194
+ SessionV1: "hardkas.session.v1",
195
+ SessionV0: "hardkas.session.v0",
196
+ TelemetryV1: "hardkas.telemetry.v1",
197
+ TortureReportV1: "hardkas.tortureReport.v1",
198
+ PruneReportV1: "hardkas.pruneReport.v1",
199
+ LockV1: "hardkas.lock.v1",
200
+ BridgeLocalPlanV1: "hardkas.bridge.localPlan.v1",
201
+ BridgeLocalSimulationV1: "hardkas.bridge.localSimulation.v1",
202
+ KaswareLocalV1: "hardkas.kaswareLocal.v1",
203
+ MetamaskLocalV1: "hardkas.metamaskLocal.v1",
204
+ // Miscellaneous used in docs / examples
205
+ ExampleDocumentAnchorV1: "hardkas.example.documentAnchor.v1"
206
+ };
207
+ var ArtifactTypes = HardkasSchemas;
208
+ var registryValues = new Set(Object.values(HardkasSchemas));
209
+ function isKnownArtifactType(type) {
210
+ return registryValues.has(type);
211
+ }
212
+ function assertKnownArtifactType(type) {
213
+ if (!isKnownArtifactType(type)) {
214
+ throw new Error(`Unknown HardKAS artifact type or schema: ${type}`);
215
+ }
216
+ return type;
217
+ }
218
+ function describeArtifactType(type) {
219
+ assertKnownArtifactType(type);
220
+ const isLegacy = !type.includes(".v") && !type.endsWith("V1");
221
+ return {
222
+ type,
223
+ domain: inferDomain(type),
224
+ version: isLegacy ? "legacy" : type.split(".").pop() || "unknown",
225
+ stability: inferStability(type),
226
+ legacy: isLegacy
227
+ };
228
+ }
229
+ function inferDomain(type) {
230
+ if (type.includes("silver")) return "silver";
231
+ if (type.includes("zk") || type.includes("groth16") || type.includes("risc0")) return "zk";
232
+ if (type.includes("vprog")) return "vprogs";
233
+ if (type.includes("programmability")) return "programmability";
234
+ if (type.includes("corpus") || type.includes("toccata") || type.includes("toccataGolden") || type.includes("Fixture")) return "corpus";
235
+ if (type.includes("cli") || type.includes("Runner") || type.includes("report") || type.includes("audit") || type.includes("Doctor")) return "audit";
236
+ if (type.includes("tx") || type.includes("snapshot") || type.includes("receipt") || type.includes("policy")) return "tx";
237
+ return "infra";
238
+ }
239
+ function inferStability(type) {
240
+ if (type.includes("toccataGolden") || type.includes("Fixture")) return "fixture-coherence";
241
+ if (type.includes("Inspect") || type.includes("inspect")) return "inspect-only";
242
+ if (type.includes("Report") || type.includes("report") || type.includes("Audit") || type.includes("audit")) return "report";
243
+ if (type.includes("v1")) return "stable";
244
+ return "stable-local";
245
+ }
246
+
4
247
  // src/append-coordinator.ts
5
248
  import fs from "fs";
6
249
  import path2 from "path";
@@ -54,7 +297,7 @@ var TelemetryManager = class {
54
297
  const eventIdRaw = `${eventHash}-${nowStr}`;
55
298
  const eventId = crypto2.createHash("sha256").update(eventIdRaw).digest("hex").slice(0, 32);
56
299
  const event = {
57
- schemaVersion: "hardkas.telemetry.v1",
300
+ schemaVersion: HardkasSchemas.TelemetryV1,
58
301
  eventId,
59
302
  eventHash,
60
303
  timestamp: nowStr,
@@ -355,7 +598,7 @@ var coreEvents = new CoreEventBus();
355
598
  function createEventEnvelope(params) {
356
599
  const timestamp = (/* @__PURE__ */ new Date()).toISOString();
357
600
  return {
358
- schema: "hardkas.event",
601
+ schema: HardkasSchemas.Event,
359
602
  version: "1.0.0",
360
603
  eventId: params.eventId || crypto.randomUUID(),
361
604
  domain: params.domain,
@@ -376,7 +619,7 @@ function createEventEnvelope(params) {
376
619
  }
377
620
  function validateEventEnvelope(event) {
378
621
  if (!event || typeof event !== "object") return false;
379
- if (event.schema !== "hardkas.event") return false;
622
+ if (event.schema !== HardkasSchemas.Event) return false;
380
623
  if (!event.eventId || !event.domain || !event.kind) return false;
381
624
  if (!event.workflowId || !event.correlationId || !event.networkId) return false;
382
625
  if (typeof event.payload !== "object") return false;
@@ -634,7 +877,7 @@ async function acquireLock(args) {
634
877
  while (true) {
635
878
  try {
636
879
  const metadata = {
637
- schema: "hardkas.lock.v1",
880
+ schema: HardkasSchemas.LockV1,
638
881
  name: args.name,
639
882
  pid: process.pid,
640
883
  command: args.command || process.argv.join(" "),
@@ -853,7 +1096,7 @@ function clearLock(rootDir, name, options = {}) {
853
1096
  // src/replay.ts
854
1097
  function diffReplays(replayA, replayB) {
855
1098
  const diff = {
856
- schema: "hardkas.replayDiff.v1",
1099
+ schema: HardkasSchemas.ReplayDiffV1,
857
1100
  structural: {
858
1101
  missingArtifacts: [],
859
1102
  excludedArtifacts: [],
@@ -956,7 +1199,7 @@ async function createSnapshot(options) {
956
1199
  const manifest = {
957
1200
  snapshotVersion: 1,
958
1201
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
959
- hardkasVersion: "0.8.20-alpha",
1202
+ hardkasVersion: "0.9.1-alpha",
960
1203
  stateAuthority: "filesystem",
961
1204
  projectionAuthority: "sqlite",
962
1205
  deterministicScope,
@@ -1205,7 +1448,7 @@ Resolution Command: ${report.exactReplayCommand}`
1205
1448
  // src/migrations.ts
1206
1449
  import fs6 from "fs";
1207
1450
  import path8 from "path";
1208
- var CURRENT_RUNTIME_VERSION = "0.8.20-alpha";
1451
+ var CURRENT_RUNTIME_VERSION = "0.9.1-alpha";
1209
1452
  var MIN_SUPPORTED_VERSION = "0.5.0-alpha";
1210
1453
  var MigrationManager = class {
1211
1454
  static checkVersion(rootDir) {
@@ -1252,7 +1495,10 @@ var MigrationManager = class {
1252
1495
  }
1253
1496
  if (!status.needsMigration) return;
1254
1497
  if (dryRun) {
1255
- console.log(
1498
+ getTelemetry().logAnomaly(
1499
+ "EXTERNAL_MUTATION",
1500
+ "low",
1501
+ "projection",
1256
1502
  `[DRY-RUN] Would migrate workspace from ${status.currentVersion} to ${CURRENT_RUNTIME_VERSION}`
1257
1503
  );
1258
1504
  return;
@@ -1299,6 +1545,92 @@ var MigrationManager = class {
1299
1545
  }
1300
1546
  };
1301
1547
 
1548
+ // src/silver.ts
1549
+ import { blake2b } from "@noble/hashes/blake2.js";
1550
+ function normalizeScriptBytes(scriptHexOrBytes) {
1551
+ if (Buffer.isBuffer(scriptHexOrBytes)) return scriptHexOrBytes;
1552
+ if (scriptHexOrBytes instanceof Uint8Array) return Buffer.from(scriptHexOrBytes);
1553
+ if (typeof scriptHexOrBytes !== "string") {
1554
+ throw new HardkasError("SILVERSCRIPT_INVALID_REDEEM_SCRIPT", "Must be hex string or buffer");
1555
+ }
1556
+ const hex = scriptHexOrBytes.trim();
1557
+ if (hex === "") {
1558
+ throw new HardkasError("SILVERSCRIPT_INVALID_REDEEM_SCRIPT", "Redeem script cannot be empty");
1559
+ }
1560
+ if (!/^[0-9a-fA-F]*$/.test(hex) || hex.length % 2 !== 0) {
1561
+ throw new HardkasError("SILVERSCRIPT_INVALID_REDEEM_SCRIPT", "Redeem script must be valid even-length hex");
1562
+ }
1563
+ return Buffer.from(hex, "hex");
1564
+ }
1565
+ function createRedeemScriptHash(scriptHexOrBytes) {
1566
+ const scriptBytes = normalizeScriptBytes(scriptHexOrBytes);
1567
+ const redeemScriptHashBytes = blake2b(scriptBytes, { dkLen: 32 });
1568
+ return Buffer.from(redeemScriptHashBytes).toString("hex");
1569
+ }
1570
+ function createKaspaP2shBlake2bLock(scriptHexOrBytes) {
1571
+ const redeemScriptHash = createRedeemScriptHash(scriptHexOrBytes);
1572
+ const lockingScriptHex = `aa20${redeemScriptHash}87`;
1573
+ const redeemScriptHex = normalizeScriptBytes(scriptHexOrBytes).toString("hex");
1574
+ return {
1575
+ scriptPublicKeyVersion: 0,
1576
+ lockingScriptHex,
1577
+ redeemScriptHash,
1578
+ redeemScriptHex
1579
+ };
1580
+ }
1581
+ function getPushDataPrefix(byteCount) {
1582
+ if (byteCount < 0) {
1583
+ throw new HardkasError("SILVERSCRIPT_INVALID_PUSHDATA", "Negative byte count");
1584
+ }
1585
+ if (byteCount === 0) {
1586
+ return "00";
1587
+ }
1588
+ if (byteCount <= 75) {
1589
+ return byteCount.toString(16).padStart(2, "0");
1590
+ }
1591
+ if (byteCount <= 255) {
1592
+ return `4c${byteCount.toString(16).padStart(2, "0")}`;
1593
+ }
1594
+ if (byteCount <= 65535) {
1595
+ const hex2 = byteCount.toString(16).padStart(4, "0");
1596
+ const le2 = hex2.substring(2, 4) + hex2.substring(0, 2);
1597
+ return `4d${le2}`;
1598
+ }
1599
+ const hex = byteCount.toString(16).padStart(8, "0");
1600
+ const le = hex.substring(6, 8) + hex.substring(4, 6) + hex.substring(2, 4) + hex.substring(0, 2);
1601
+ return `4e${le}`;
1602
+ }
1603
+ function createPushOnlySignatureScript(args, redeemScriptHex) {
1604
+ if (!redeemScriptHex || redeemScriptHex.trim() === "") {
1605
+ throw new HardkasError(
1606
+ "SILVERSCRIPT_INVALID_REDEEM_SCRIPT",
1607
+ "Redeem script cannot be empty"
1608
+ );
1609
+ }
1610
+ if (!/^[0-9a-fA-F]*$/.test(redeemScriptHex) || redeemScriptHex.length % 2 !== 0) {
1611
+ throw new HardkasError(
1612
+ "SILVERSCRIPT_INVALID_REDEEM_SCRIPT",
1613
+ "Redeem script must be valid hex"
1614
+ );
1615
+ }
1616
+ let signatureScript = "";
1617
+ for (const argHex of args) {
1618
+ if (!/^[0-9a-fA-F]*$/.test(argHex) || argHex.length % 2 !== 0) {
1619
+ throw new HardkasError(
1620
+ "SILVERSCRIPT_SIGNATURE_SCRIPT_NOT_PUSH_ONLY",
1621
+ `Argument must be valid hex: ${argHex}`
1622
+ );
1623
+ }
1624
+ const byteCount = argHex.length / 2;
1625
+ const prefix = getPushDataPrefix(byteCount);
1626
+ signatureScript += prefix + argHex;
1627
+ }
1628
+ const redeemScriptByteCount = redeemScriptHex.length / 2;
1629
+ const redeemPrefix = getPushDataPrefix(redeemScriptByteCount);
1630
+ signatureScript += redeemPrefix + redeemScriptHex;
1631
+ return signatureScript;
1632
+ }
1633
+
1302
1634
  // src/index.ts
1303
1635
  var SOMPI_PER_KAS = 100000000n;
1304
1636
  var kaspaNetworkIdSchema = z.enum([
@@ -1323,7 +1655,15 @@ var artifactTypeSchema = z.enum([
1323
1655
  "policy.v1",
1324
1656
  "networkProfile.v1",
1325
1657
  "assumption.v1",
1326
- "migrationReceipt.v1"
1658
+ "migrationReceipt.v1",
1659
+ "silver.compile",
1660
+ "silver.test",
1661
+ "silver.spendPlan",
1662
+ "silver.deployPlan",
1663
+ "silver.deploy",
1664
+ "silver.spendReceipt",
1665
+ "silver.deploySimulation",
1666
+ "silver.spendSimulation"
1327
1667
  ]);
1328
1668
  var NetworkIdSchema = kaspaNetworkIdSchema;
1329
1669
  var ExecutionModeSchema = executionModeSchema;
@@ -1375,31 +1715,15 @@ function parseHardkasConfig(input) {
1375
1715
  }
1376
1716
  return result.data;
1377
1717
  }
1378
- function parseKasToSompi(input) {
1379
- const trimmed = input.trim();
1380
- if (!/^\d+(\.\d{1,8})?$/.test(trimmed)) {
1381
- throw new HardkasError("AMOUNT_INVALID", `Invalid KAS amount: ${input}`);
1382
- }
1383
- const [whole, fractional = ""] = trimmed.split(".");
1384
- if (whole === void 0) {
1385
- throw new HardkasError("AMOUNT_INVALID", `Invalid KAS amount: ${input}`);
1386
- }
1387
- return BigInt(whole) * SOMPI_PER_KAS + BigInt(fractional.padEnd(8, "0"));
1388
- }
1389
- function formatSompi(amountSompi) {
1390
- const sign = amountSompi < 0n ? "-" : "";
1391
- const absolute = amountSompi < 0n ? -amountSompi : amountSompi;
1392
- const whole = absolute / SOMPI_PER_KAS;
1393
- const fractional = absolute % SOMPI_PER_KAS;
1394
- return `${sign}${whole}.${fractional.toString().padStart(8, "0")} KAS`;
1395
- }
1396
1718
  export {
1397
1719
  AppendCoordinator,
1398
1720
  ArtifactTypeSchema,
1721
+ ArtifactTypes,
1399
1722
  CURRENT_RUNTIME_VERSION,
1400
1723
  EnvironmentTelemetry,
1401
1724
  ExecutionModeSchema,
1402
1725
  HardkasError,
1726
+ HardkasSchemas,
1403
1727
  InvariantViolationError,
1404
1728
  LOCK_ORDER,
1405
1729
  MIN_SUPPORTED_VERSION,
@@ -1422,6 +1746,7 @@ export {
1422
1746
  asRpcEndpointId,
1423
1747
  asTxId,
1424
1748
  asWorkflowId,
1749
+ assertKnownArtifactType,
1425
1750
  assertNoSemanticDrift,
1426
1751
  attachLedgerAppender,
1427
1752
  classifyArtifactStatus,
@@ -1429,16 +1754,22 @@ export {
1429
1754
  comparePrePostMigrationLineage,
1430
1755
  coreEvents,
1431
1756
  createEventEnvelope,
1757
+ createKaspaP2shBlake2bLock,
1758
+ createPushOnlySignatureScript,
1759
+ createRedeemScriptHash,
1432
1760
  createSnapshot,
1761
+ describeArtifactType,
1433
1762
  detectSemanticDrift,
1434
1763
  deterministicCompare,
1435
1764
  diffReplays,
1436
1765
  executionModeSchema,
1437
1766
  formatCorruptionIssue,
1438
- formatSompi,
1767
+ formatSignedSompiToKas,
1768
+ formatSompiToKas,
1439
1769
  getTelemetry,
1440
1770
  globalTelemetry,
1441
1771
  hardkasConfigSchema,
1772
+ isKnownArtifactType,
1442
1773
  isProcessAlive,
1443
1774
  kaspaNetworkIdSchema,
1444
1775
  listLocks,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardkas/core",
3
- "version": "0.8.20-alpha",
3
+ "version": "0.9.1-alpha",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -12,6 +12,7 @@
12
12
  }
13
13
  },
14
14
  "dependencies": {
15
+ "@noble/hashes": "^2.2.0",
15
16
  "pino": "^9.5.0",
16
17
  "zod": "^3.24.1"
17
18
  },