From 3cb1f75fff6342205d69d34739ac6f33e86b1c10 Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Wed, 11 Mar 2026 17:30:18 +0100 Subject: [PATCH 01/12] adding missing nocolor tests --- tests/rt/neg/ifc/blockdeclto_leak.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/blockdownto_leak.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/blockendorseto_leak.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/declassifyType.nocolor.golden | 11 +++++++++++ .../ifc/declassify_blocking.authority.nocolor.golden | 11 +++++++++++ .../rt/neg/ifc/declassify_blocking.to.nocolor.golden | 11 +++++++++++ .../declassify_blocking.value_level.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/downgradeType.nocolor.golden | 11 +++++++++++ .../ifc/downgrade_blocking.authority.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/downgrade_blocking.to.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/endorseType.nocolor.golden | 11 +++++++++++ .../neg/ifc/endorse_blocking.authority.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/endorse_blocking.to.nocolor.golden | 11 +++++++++++ tests/rt/neg/ifc/pinipushto_leak.nocolor.golden | 10 ++++++++++ tests/rt/pos/ifc/declassifyType.nocolor.golden | 2 ++ tests/rt/pos/ifc/downgradeType.nocolor.golden | 2 ++ tests/rt/pos/ifc/endorseType.nocolor.golden | 2 ++ 17 files changed, 159 insertions(+) create mode 100644 tests/rt/neg/ifc/blockdeclto_leak.nocolor.golden create mode 100644 tests/rt/neg/ifc/blockdownto_leak.nocolor.golden create mode 100644 tests/rt/neg/ifc/blockendorseto_leak.nocolor.golden create mode 100644 tests/rt/neg/ifc/declassifyType.nocolor.golden create mode 100644 tests/rt/neg/ifc/declassify_blocking.authority.nocolor.golden create mode 100644 tests/rt/neg/ifc/declassify_blocking.to.nocolor.golden create mode 100644 tests/rt/neg/ifc/declassify_blocking.value_level.nocolor.golden create mode 100644 tests/rt/neg/ifc/downgradeType.nocolor.golden create mode 100644 tests/rt/neg/ifc/downgrade_blocking.authority.nocolor.golden create mode 100644 tests/rt/neg/ifc/downgrade_blocking.to.nocolor.golden create mode 100644 tests/rt/neg/ifc/endorseType.nocolor.golden create mode 100644 tests/rt/neg/ifc/endorse_blocking.authority.nocolor.golden create mode 100644 tests/rt/neg/ifc/endorse_blocking.to.nocolor.golden create mode 100644 tests/rt/neg/ifc/pinipushto_leak.nocolor.golden create mode 100644 tests/rt/pos/ifc/declassifyType.nocolor.golden create mode 100644 tests/rt/pos/ifc/downgradeType.nocolor.golden create mode 100644 tests/rt/pos/ifc/endorseType.nocolor.golden diff --git a/tests/rt/neg/ifc/blockdeclto_leak.nocolor.golden b/tests/rt/neg/ifc/blockdeclto_leak.nocolor.golden new file mode 100644 index 00000000..966dbd3b --- /dev/null +++ b/tests/rt/neg/ifc/blockdeclto_leak.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:42.123Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread a78fc27c-27c8-47ec-b735-d603107edeb3@{}%{} + + 20 | val _ = blockdeclto (aliceAuth, target) + | ^ + +>> Not enough authority for blocking level declassification + | from level of the blocking level: + | level of the authority: + | to level of the blocking level: {} +>> at tests/rt/neg/ifc/blockdeclto_leak.trp:20:13 diff --git a/tests/rt/neg/ifc/blockdownto_leak.nocolor.golden b/tests/rt/neg/ifc/blockdownto_leak.nocolor.golden new file mode 100644 index 00000000..e5368103 --- /dev/null +++ b/tests/rt/neg/ifc/blockdownto_leak.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:45.637Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread 708baebb-c69e-413e-8545-7b8185c46236@{}%{} + + 20 | val _ = blockdownto (aliceAuth, target) + | ^ + +>> Not enough authority for blocking level downgrade + | from level of the blocking level: + | level of the authority: {alice} + | to level of the blocking level: {} +>> at tests/rt/neg/ifc/blockdownto_leak.trp:20:13 diff --git a/tests/rt/neg/ifc/blockendorseto_leak.nocolor.golden b/tests/rt/neg/ifc/blockendorseto_leak.nocolor.golden new file mode 100644 index 00000000..54053173 --- /dev/null +++ b/tests/rt/neg/ifc/blockendorseto_leak.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:44.203Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread 07dc6946-984c-4699-9170-951408975ec7@{}%{} + + 20 | val _ = blockendorseto (intAliceAuth, target) + | ^ + +>> Not enough authority for blocking level integrity + | from level of the blocking level: <#null-confidentiality;bob> + | level of the authority: <#null-confidentiality;alice> + | to level of the blocking level: {} +>> at tests/rt/neg/ifc/blockendorseto_leak.trp:20:13 diff --git a/tests/rt/neg/ifc/declassifyType.nocolor.golden b/tests/rt/neg/ifc/declassifyType.nocolor.golden new file mode 100644 index 00000000..319675b2 --- /dev/null +++ b/tests/rt/neg/ifc/declassifyType.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:44.506Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread 1b93eeb5-175c-4675-a4d3-701e45720c04@{}%{} + + 5 | val x' = declassifyType (x, attenuate (authority, `{bob}`), `{}`) + | ^ + +>> Not enough authority for declassification + | level of the data: + | level of the authority: {bob} + | target level of the declassification: {} +>> at tests/rt/neg/ifc/declassifyType.trp:5:14 diff --git a/tests/rt/neg/ifc/declassify_blocking.authority.nocolor.golden b/tests/rt/neg/ifc/declassify_blocking.authority.nocolor.golden new file mode 100644 index 00000000..72645372 --- /dev/null +++ b/tests/rt/neg/ifc/declassify_blocking.authority.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:44.268Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread 3ea4c408-11cb-4296-9ee0-d63b46124a42@{}%{} + + 15 | in adv () + | ^ + +>> Illegal flow in adv function: + | pc: {} + | block: + | value: ()@{}%{} +>> at tests/rt/neg/ifc/declassify_blocking.authority.trp:15:4 diff --git a/tests/rt/neg/ifc/declassify_blocking.to.nocolor.golden b/tests/rt/neg/ifc/declassify_blocking.to.nocolor.golden new file mode 100644 index 00000000..ec414af2 --- /dev/null +++ b/tests/rt/neg/ifc/declassify_blocking.to.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:45.220Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread c371653d-7fef-421c-88da-be5f1dbe4af5@{}%{} + + 19 | in adv () + | ^ + +>> Illegal flow in adv function: + | pc: {} + | block: + | value: ()@{}%{} +>> at tests/rt/neg/ifc/declassify_blocking.to.trp:19:4 diff --git a/tests/rt/neg/ifc/declassify_blocking.value_level.nocolor.golden b/tests/rt/neg/ifc/declassify_blocking.value_level.nocolor.golden new file mode 100644 index 00000000..c9c0ed32 --- /dev/null +++ b/tests/rt/neg/ifc/declassify_blocking.value_level.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:42.565Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread b925ad24-a040-46a1-ab09-98d05d7d9853@{}%{} + + 22 | in adv () + | ^ + +>> Illegal flow in adv function: + | pc: {} + | block: + | value: ()@{}%{} +>> at tests/rt/neg/ifc/declassify_blocking.value_level.trp:22:4 diff --git a/tests/rt/neg/ifc/downgradeType.nocolor.golden b/tests/rt/neg/ifc/downgradeType.nocolor.golden new file mode 100644 index 00000000..b67538a4 --- /dev/null +++ b/tests/rt/neg/ifc/downgradeType.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:44.223Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread 952f5c93-c87e-4854-b055-bfde8ee9c4aa@{}%{} + + 5 | val x' = downgradeType (x, attenuate (authority, `{bob}`), `{}`) + | ^ + +>> Not enough authority for downgrade + | level of the data: {alice} + | level of the authority: {bob} + | target level of the downgrade: {} +>> at tests/rt/neg/ifc/downgradeType.trp:5:14 diff --git a/tests/rt/neg/ifc/downgrade_blocking.authority.nocolor.golden b/tests/rt/neg/ifc/downgrade_blocking.authority.nocolor.golden new file mode 100644 index 00000000..e60596b3 --- /dev/null +++ b/tests/rt/neg/ifc/downgrade_blocking.authority.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:42.588Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread 4fe033b0-253d-41e2-a40f-a3cf754dee24@{}%{} + + 19 | in adv () + | ^ + +>> Illegal flow in adv function: + | pc: {} + | block: + | value: ()@{}%{} +>> at tests/rt/neg/ifc/downgrade_blocking.authority.trp:19:4 diff --git a/tests/rt/neg/ifc/downgrade_blocking.to.nocolor.golden b/tests/rt/neg/ifc/downgrade_blocking.to.nocolor.golden new file mode 100644 index 00000000..2b50a41f --- /dev/null +++ b/tests/rt/neg/ifc/downgrade_blocking.to.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:42.573Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread 53a5823b-7464-4d99-aa42-36cbd7375410@{}%{} + + 19 | in adv () + | ^ + +>> Illegal flow in adv function: + | pc: {} + | block: + | value: ()@{}%{} +>> at tests/rt/neg/ifc/downgrade_blocking.to.trp:19:4 diff --git a/tests/rt/neg/ifc/endorseType.nocolor.golden b/tests/rt/neg/ifc/endorseType.nocolor.golden new file mode 100644 index 00000000..0963f0d3 --- /dev/null +++ b/tests/rt/neg/ifc/endorseType.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:42.830Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread d1bbdcc8-00ee-4dce-9fa0-d6582b323253@{}%{} + + 5 | val x' = endorseType (x, attenuate (authority, `{bob}`), ``) + | ^ + +>> Not enough authority for endorsement + | level of the data: {alice} + | level of the authority: {bob} + | target level of the endorsement: +>> at tests/rt/neg/ifc/endorseType.trp:5:14 diff --git a/tests/rt/neg/ifc/endorse_blocking.authority.nocolor.golden b/tests/rt/neg/ifc/endorse_blocking.authority.nocolor.golden new file mode 100644 index 00000000..b9d41aa9 --- /dev/null +++ b/tests/rt/neg/ifc/endorse_blocking.authority.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:44.494Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread a9b27294-76cd-4d04-8642-58f5d8b3b609@{}%{} + + 22 | in cert () + | ^ + +>> Illegal flow in cert function: + | pc: {} + | block: <#null-confidentiality;(alice|bob)&(bob|charlie)> + | value: ()@{}%{} +>> at tests/rt/neg/ifc/endorse_blocking.authority.trp:22:4 diff --git a/tests/rt/neg/ifc/endorse_blocking.to.nocolor.golden b/tests/rt/neg/ifc/endorse_blocking.to.nocolor.golden new file mode 100644 index 00000000..90d18b57 --- /dev/null +++ b/tests/rt/neg/ifc/endorse_blocking.to.nocolor.golden @@ -0,0 +1,11 @@ +2026-03-11T16:28:42.840Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread b22e513a-2fea-49c9-9781-a913f34d3a90@{}%{} + + 25 | in adv () + | ^ + +>> Illegal flow in adv function: + | pc: {} + | block: + | value: ()@{}%{} +>> at tests/rt/neg/ifc/endorse_blocking.to.trp:25:4 diff --git a/tests/rt/neg/ifc/pinipushto_leak.nocolor.golden b/tests/rt/neg/ifc/pinipushto_leak.nocolor.golden new file mode 100644 index 00000000..2fabbe53 --- /dev/null +++ b/tests/rt/neg/ifc/pinipushto_leak.nocolor.golden @@ -0,0 +1,10 @@ +2026-03-11T16:28:44.508Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +Runtime error in thread bff20588-f8de-47b5-b304-0cc8727cd6bb@{}%{} + + 16 | val cap = pinipushto (aliceAuth, target) + | ^ + +>> level argument of pinipushto operation must flow to the current blocking level +| the blocking level: +| the level argument: {}@%{} +>> at tests/rt/neg/ifc/pinipushto_leak.trp:16:15 diff --git a/tests/rt/pos/ifc/declassifyType.nocolor.golden b/tests/rt/pos/ifc/declassifyType.nocolor.golden new file mode 100644 index 00000000..8b7df290 --- /dev/null +++ b/tests/rt/pos/ifc/declassifyType.nocolor.golden @@ -0,0 +1,2 @@ +2026-03-11T16:28:36.281Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +>>> Main thread finished with value: (42@%, 42@%{})@{}%{} diff --git a/tests/rt/pos/ifc/downgradeType.nocolor.golden b/tests/rt/pos/ifc/downgradeType.nocolor.golden new file mode 100644 index 00000000..82da788f --- /dev/null +++ b/tests/rt/pos/ifc/downgradeType.nocolor.golden @@ -0,0 +1,2 @@ +2026-03-11T16:28:35.000Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +>>> Main thread finished with value: (42@{alice}%{alice}, 42@{alice}%{})@{}%{} diff --git a/tests/rt/pos/ifc/endorseType.nocolor.golden b/tests/rt/pos/ifc/endorseType.nocolor.golden new file mode 100644 index 00000000..8ae571f6 --- /dev/null +++ b/tests/rt/pos/ifc/endorseType.nocolor.golden @@ -0,0 +1,2 @@ +2026-03-11T16:28:32.633Z [RTM] info: Skipping network creation. Observe that all external IO operations will yield a runtime error. +>>> Main thread finished with value: (42@{alice}%{alice}, 42@{alice}%)@{}%{} From 4ab4132658dcc2ead8cc5e3338d34cbbcb534bbf Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 27 Apr 2026 14:37:16 +0200 Subject: [PATCH 02/12] ts6 configuration --- .gitignore | 5 +++++ p2p-tools/tsconfig.json | 2 ++ rt/tsconfig.json | 2 ++ 3 files changed, 9 insertions(+) diff --git a/.gitignore b/.gitignore index 731e3bff..b9792cd4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ TAGS # NPM node_modules +################################################## +# TypeScript incremental build cache +*.tsbuildinfo + ################################################## # Haskell @@ -72,3 +76,4 @@ compiler/src/Parser.info _claude_planning/ _troupe_notebook_planning .notebook-storage +.claude/ diff --git a/p2p-tools/tsconfig.json b/p2p-tools/tsconfig.json index c2c30e78..6d4239f4 100644 --- a/p2p-tools/tsconfig.json +++ b/p2p-tools/tsconfig.json @@ -9,6 +9,8 @@ "skipLibCheck": true, "incremental": true, "lib": ["ESNext"], + "strict": false, + "types": ["node"] }, "include": [ "./*.ts", diff --git a/rt/tsconfig.json b/rt/tsconfig.json index 1eaa160f..9d9e2fd5 100644 --- a/rt/tsconfig.json +++ b/rt/tsconfig.json @@ -1,6 +1,8 @@ { "compilerOptions": { "outDir": "./built", + "rootDir": "./src", + "strict": false, "allowJs": true, "moduleResolution": "node16", "module": "Node16", From 52c5cc3178e4bfc0db184b8f4c8f86663f2fa0e0 Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 27 Apr 2026 14:55:43 +0200 Subject: [PATCH 03/12] upgrade tsc config --- p2p-tools/relay/tsconfig.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/p2p-tools/relay/tsconfig.json b/p2p-tools/relay/tsconfig.json index 6f4bcadc..da640e0b 100644 --- a/p2p-tools/relay/tsconfig.json +++ b/p2p-tools/relay/tsconfig.json @@ -8,7 +8,9 @@ "esModuleInterop": true, "incremental": false, "lib": ["ESNext"], - "skipLibCheck": true + "skipLibCheck": true, + "strict": false, + "types": ["node"] }, "include": ["./relay.mts"], "exclude": [] From 03e465e5f4ef1d3c6c577ca153f5b3f5bb8a2784 Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Sun, 31 May 2026 19:14:12 +0200 Subject: [PATCH 04/12] docs: update whats-next planning notes Mark quarantining outline + implementation done, update label-format option to --label-format v1|v2|v2-full, and note declassification consolidation status (PR #151). Co-Authored-By: Claude Opus 4.8 (1M context) --- .experiments/whats-next.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.experiments/whats-next.md b/.experiments/whats-next.md index 040bc5ac..1d66bf00 100644 --- a/.experiments/whats-next.md +++ b/.experiments/whats-next.md @@ -30,9 +30,6 @@ └──────────────────────────┘ ``` -## Applications - - ## Integrity - [x] Integrity of blocking and mailboxes @@ -47,8 +44,8 @@ ## Quarantining -- [ ] Outline of the quarantining in the security model (done) -- [ ] Implementation +- [x] Outline of the quarantining in the security model +- [x] Implementation (quarantine builtins, multinode tests, `--no-quarantine` CLI opt-out) ## NMIFC evaluation @@ -96,12 +93,10 @@ ### Other improvements -#### Frontend - #### Backend - [x] Provide a runtime option to NOT use V1 compatible pretty printing - (done: `--no-v1-labels` / `--v1-labels` runtime options) + (done: `--label-format v1|v2|v2-full` runtime option) ## Refactoring @@ -109,6 +104,8 @@ ### Runtime - [+ongoing+] Consolidate error handling of downgrading + (declassification rework merged via PR #151; verify whether further + consolidation is still needed or this can be closed) - [x] Get rid of lubs in the runtime codebase, because it is redundant, now that we have a multi-arg lub From 103b1826022e0e1cc92651d3fb20d4390f743c6c Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Sun, 31 May 2026 19:23:38 +0200 Subject: [PATCH 05/12] fix: downgrade no longer raises the integrity (type) level (#159) A value downgrade computed the result's integrity level as the tainted target level, which incorrectly *raised* it. Per the agreed fix in #159, the integrity of a downgraded value is now glb(data.tlev, taintedLevTo), so e.g. `pdowngrade(x raisedTo {alice,bob}, authority, {alice})` yields `%{}` instead of `%{alice}`. - downgrading.mts: pass glb(data.tlev, taintedLevTo) as the LCopyVal tlev. - Lval.mts: expose LCopyVal's third (integrity) arg; make posInfo and the nullable constructor params explicitly `| null` for stricter typing. - tests/lib/IfcUtil.golden: regenerate declassifyDeep/downgradeDeep section to reflect the corrected integrity (%{}). Co-Authored-By: Claude Opus 4.8 (1M context) --- rt/src/Lval.mts | 6 +++--- rt/src/downgrading.mts | 4 ++-- tests/lib/IfcUtil.golden | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rt/src/Lval.mts b/rt/src/Lval.mts index 4bf25313..1195ac1e 100644 --- a/rt/src/Lval.mts +++ b/rt/src/Lval.mts @@ -8,7 +8,7 @@ export class LVal implements TroupeRawValue{ lev: Level; tlev: Level; dlev: Level; - posInfo: string; + posInfo: string | null; /* 2020-06-06: AA @@ -21,7 +21,7 @@ export class LVal implements TroupeRawValue{ */ __troupeType : Ty.TroupeType - constructor(v:any, l:Level, tlev:Level = null, posInfo:string = null) { + constructor(v:any, l:Level, tlev:Level | null = null, posInfo:string | null = null) { this.val = v; this.lev = l; this.tlev = tlev == null?l:tlev; @@ -95,7 +95,7 @@ export class LValCopyAt extends LVal { } export class LCopyVal extends LVal { - constructor (x:LVal, l1:Level, l2:Level = null) { + constructor (x:LVal, l1:Level, l2:Level | null = null) { super (x.val, l1, l2); } } diff --git a/rt/src/downgrading.mts b/rt/src/downgrading.mts index 6441cfb9..0c5c353e 100644 --- a/rt/src/downgrading.mts +++ b/rt/src/downgrading.mts @@ -1,7 +1,7 @@ import { LCopyVal, LVal } from './Lval.mjs'; import { assertIsNTuple, assertIsAuthority, assertIsLevel } from './Asserts.mjs' import { __unit } from './UnitVal.mjs'; -import { lub, flowsTo, okToDeclassify, okToEndorse, okToCrossDimensionalDowngrade} from './Level.mjs' +import { lub, glb, okToDeclassify, okToEndorse, okToCrossDimensionalDowngrade} from './Level.mjs' import { DowngradeResult, DowngradeDimension, DowngradeErrorReason, DowngradeKind, ValueDowngradeGranularity } from './DowngradeEnums.mjs'; import { formatIntegrityMismatchMsg, @@ -84,7 +84,7 @@ export function downgrader (runtime: RuntimeInterface, const taintedLevTo = lub(lev_to, pc, arg.lev, auth.lev); const r = typeOnly ? new LCopyVal(data, lub(data.lev, taintedLevTo), taintedLevTo) - : new LCopyVal(data, taintedLevTo); + : new LCopyVal(data, taintedLevTo, glb(data.tlev, taintedLevTo) ); return runtime.ret(r) } else { let errorMessage = ""; diff --git a/tests/lib/IfcUtil.golden b/tests/lib/IfcUtil.golden index 5e0cdce7..62c6375e 100644 --- a/tests/lib/IfcUtil.golden +++ b/tests/lib/IfcUtil.golden @@ -44,10 +44,10 @@ invokeAtLevel, invokeAtLevel declassifyDeep, endorseDeep, downgradeDeep ============================================================ -1@% +1@%{} 1@{}%{} 1@{}%{} -"secret!"@% +"secret!"@%{} "secret!"@{}%{} "secret!"@{}%{} (1@%, 2@%)@% From 2f8ee94feb375f520b3ac39f16769aaf2798209a Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 1 Jun 2026 08:27:08 +0200 Subject: [PATCH 06/12] docs: require AI commits to be verified, never untested Add a "Commit quality" policy to CLAUDE.md: AI-generated commits must be verified before committing; changes that cannot be verified (e.g. their exercising tool hangs/is unavailable) must be held in the working tree and surfaced, not committed on faith; verified changes must not be bundled with unverified ones. Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index f94a49f6..54cd9364 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -382,6 +382,17 @@ When choosing between the obviosuly clean but laborious approach and a quick easy but partial solution, in this code base we almost always want to do the clean thing that is _right_! +## Commit quality — no unverified or untested changes + +AI-generated commits must be held to the highest quality bar. **Never commit a change that has not been verified.** + +- Every committed change must be verified *before* it is committed: code changes by the relevant tests passing (`make test` / `bin/golden`), behavioral changes by observing the new behavior directly, and documentation by review. A change that merely builds or type-checks is **not** verified. +- If a change cannot be verified — e.g. the tool that exercises it hangs, is broken, or is unavailable — **do not commit it**. Leave it in the working tree and surface the situation to the user; never commit on faith. +- Do not bundle unverified changes together with verified ones to slip them in. Commit only what is verified and hold the rest in separate, clearly-scoped commits. +- When a behavior or a golden output changes, first confirm the new result is *correct* (not merely *different*) — understand why it changed — before regenerating goldens or committing. +- Prefer several small, individually-verified commits over one large commit whose parts have not all been checked. + + ## Note on backticks in the labels. Beware of the backticks in the syntax of the info flow labels that can have unfortunate From 391a2f3dcddceec2c004e21ccda99b18ab97255e Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 1 Jun 2026 08:39:18 +0200 Subject: [PATCH 07/12] fix: disable rollup tree-shaking to stop bundle build from hanging Rollup's tree-shaking pass hangs indefinitely (observed 5+ CPU-hours) on the compiled runtime's circular module graph (runtimeMonitored <-> MailboxProcessor <-> QuarantineUtils <-> deserialize, and <-> UserRuntime <-> exit). The hang is entirely in tree-shaking: isolation showed plain `rollup` with zero plugins hangs, while the full pipeline (resolve+commonjs+json+terser) with `treeshake: false` produces a valid 148 KB minified bundle in ~1s. Dead-code elimination is unnecessary here since terser still minifies, so disable tree-shaking. Co-Authored-By: Claude Opus 4.8 (1M context) --- rollup.config.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rollup.config.js b/rollup.config.js index 782b8b0b..eea25143 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -18,6 +18,13 @@ export default { format: 'cjs' }, + // The compiled runtime in rt/built has circular dependencies (e.g. + // runtimeMonitored <-> MailboxProcessor <-> QuarantineUtils <-> deserialize), + // which make Rollup's tree-shaking pass hang indefinitely on this graph. + // We don't need dead-code elimination here (terser still minifies the + // output), so disable tree-shaking to keep the bundle build fast. + treeshake: false, + plugins: [ resolve(), commonjs({ From ead66754195631a451fca1f303e3d813b0e33cd0 Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 1 Jun 2026 08:44:02 +0200 Subject: [PATCH 08/12] =?UTF-8?q?chore:=20npm=20audit=20fix=20=E2=80=94=20?= =?UTF-8?q?resolve=20dependency=20advisories?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply `npm audit fix` across the runtime and notebook trees. Notably bumps @rollup/plugin-terser 0.4 -> 1.0 (fixes a high-severity serialize-javascript RCE advisory) and dedupes libp2p transitive deps (multiformats, uint8arrays, protons-runtime). Verified: full `make test` green (890/890, multinode included) on the updated tree; the rollup bundle builds and minifies correctly under plugin-terser 1.0 (148 KB, valid JS). Co-Authored-By: Claude Opus 4.8 (1M context) --- notebook/package-lock.json | 65 ++-- package-lock.json | 676 +++++++++++++++++++++++++------------ package.json | 2 +- 3 files changed, 495 insertions(+), 248 deletions(-) diff --git a/notebook/package-lock.json b/notebook/package-lock.json index dd89fffd..b0d22fb6 100644 --- a/notebook/package-lock.json +++ b/notebook/package-lock.json @@ -759,9 +759,9 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -772,7 +772,7 @@ "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", - "qs": "~6.14.0", + "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" @@ -906,13 +906,10 @@ } }, "node_modules/dompurify": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.2.tgz", - "integrity": "sha512-6obghkliLdmKa56xdbLOpUZ43pAR6xFy1uOrxBaIDjT+yaRuuybLjGS9eVBoSR/UPU5fq3OXClEHLJNGvbxKpQ==", + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.7.tgz", + "integrity": "sha512-2jBxDJY4RR06tQNy4w5FlFH7kfxsQZlufd0sbv+chfHCxeJwrFw2baUDsSwvBISD4K4RDbd0PTfy3uNXsR6siA==", "license": "(MPL-2.0 OR Apache-2.0)", - "engines": { - "node": ">=20" - }, "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -965,9 +962,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -1034,14 +1031,14 @@ } }, "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "~1.20.3", + "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", @@ -1060,7 +1057,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "~6.14.0", + "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", @@ -1186,9 +1183,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -1374,9 +1371,9 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", "license": "MIT" }, "node_modules/proxy-addr": { @@ -1393,9 +1390,9 @@ } }, "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -1528,13 +1525,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -1672,9 +1669,9 @@ "license": "MIT" }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package-lock.json b/package-lock.json index cf82ba53..2be8db18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", - "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-terser": "^1.0.0", "@types/archy": "^0.0.36", "@types/ws": "^8.18.1", "@types/yargs": "^17.0.33", @@ -226,20 +226,61 @@ } }, "node_modules/@libp2p/crypto": { - "version": "5.1.13", - "resolved": "https://registry.npmjs.org/@libp2p/crypto/-/crypto-5.1.13.tgz", - "integrity": "sha512-8NN9cQP3jDn+p9+QE9ByiEoZ2lemDFf/unTgiKmS3JF93ph240EUVdbCyyEgOMfykzb0okTM4gzvwfx9osJebQ==", + "version": "5.1.19", + "resolved": "https://registry.npmjs.org/@libp2p/crypto/-/crypto-5.1.19.tgz", + "integrity": "sha512-hYNeHQpUSwLPopWCgDf6OklOvVwJPS/vYZOiBG3VXPIzx5AkONBOfdkgVwB4YsIBH2V6z+TMgMH0yXUZsMurPA==", "license": "Apache-2.0 OR MIT", "dependencies": { - "@libp2p/interface": "^3.1.0", + "@libp2p/interface": "^3.2.3", "@noble/curves": "^2.0.1", "@noble/hashes": "^2.0.1", - "multiformats": "^13.4.0", - "protons-runtime": "^5.6.0", + "multiformats": "^14.0.0", + "protons-runtime": "^6.0.1", + "uint8arraylist": "^2.4.8", + "uint8arrays": "^6.1.1" + } + }, + "node_modules/@libp2p/crypto/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@libp2p/crypto/node_modules/protons-runtime": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-6.0.2.tgz", + "integrity": "sha512-hiyjyANwGcgmzc+tXc1/ZcSZhKnl5MDjaVNWkISHBgadaU0sjTgKIKZMZ62d9J9zlSTyKHCs/osPkQ/3Z+7yeA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "uint8-varint": "^2.0.4", "uint8arraylist": "^2.4.8", "uint8arrays": "^5.1.0" } }, + "node_modules/@libp2p/crypto/node_modules/protons-runtime/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@libp2p/crypto/node_modules/protons-runtime/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@libp2p/crypto/node_modules/uint8arrays": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-6.1.1.tgz", + "integrity": "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^14.0.0" + } + }, "node_modules/@libp2p/identify": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/@libp2p/identify/-/identify-4.0.9.tgz", @@ -263,47 +304,53 @@ } }, "node_modules/@libp2p/interface": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@libp2p/interface/-/interface-3.1.0.tgz", - "integrity": "sha512-RE7/XyvC47fQBe1cHxhMvepYKa5bFCUyFrrpj8PuM0E7JtzxU7F+Du5j4VXbg2yLDcToe0+j8mB7jvwE2AThYw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@libp2p/interface/-/interface-3.2.3.tgz", + "integrity": "sha512-OKZFrY+x8IYl4Fr/YWjh4s6+uks5zQBIAdg2cl+zaRUpPORfk1ELI4r+eB+fUlXR9mHDsQylSSzmAqi0drDfiA==", "license": "Apache-2.0 OR MIT", "dependencies": { "@multiformats/dns": "^1.0.6", - "@multiformats/multiaddr": "^13.0.1", + "@multiformats/multiaddr": "^13.0.3", "main-event": "^1.0.1", - "multiformats": "^13.4.0", - "progress-events": "^1.0.1", + "multiformats": "^14.0.0", + "progress-events": "^1.1.0", "uint8arraylist": "^2.4.8" } }, "node_modules/@libp2p/interface-internal": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@libp2p/interface-internal/-/interface-internal-3.0.9.tgz", - "integrity": "sha512-g6hqsrorej945uh/iwA4MY4n7vAFq5mtuMXOf1vo4CS2v8Zl3RMOl0mQZIhUpHLq8XV2aZ3C5rSe4+KsOmZM5A==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@libp2p/interface-internal/-/interface-internal-3.1.6.tgz", + "integrity": "sha512-604qCe56YVdNlKktwXatMnkHp8lKjXGuuYc/kVrvACm5+euD8AoObir+Xg5Z+Q57D+im4Mg+tvnn/lrM2Cxyxg==", "license": "Apache-2.0 OR MIT", "dependencies": { - "@libp2p/interface": "^3.1.0", - "@libp2p/peer-collections": "^7.0.9", - "@multiformats/multiaddr": "^13.0.1", + "@libp2p/interface": "^3.2.3", + "@libp2p/peer-collections": "^7.0.21", + "@multiformats/multiaddr": "^13.0.3", "progress-events": "^1.0.1" } }, + "node_modules/@libp2p/interface/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, "node_modules/@libp2p/kad-dht": { - "version": "16.1.2", - "resolved": "https://registry.npmjs.org/@libp2p/kad-dht/-/kad-dht-16.1.2.tgz", - "integrity": "sha512-s/S859NPnF2DaLcV7ynPhFHvW2wGhaHdKQbOI6yziICe/A6/eJtTM4hjjHHCoqo+hG7Duj8Tnk/GYsrfG6Qdrg==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@libp2p/kad-dht/-/kad-dht-16.3.1.tgz", + "integrity": "sha512-b/kBUvYMcYIs64VL0sbiTRTOQ9GAFpmdmamJk1jJ/oFiuzw+EvuYns31/SrkXwzeg5gZwcu81Tyyfq2DvYv9Ow==", "license": "Apache-2.0 OR MIT", "dependencies": { - "@libp2p/crypto": "^5.1.13", - "@libp2p/interface": "^3.1.0", - "@libp2p/interface-internal": "^3.0.9", - "@libp2p/peer-collections": "^7.0.9", - "@libp2p/peer-id": "^6.0.4", - "@libp2p/ping": "^3.0.9", - "@libp2p/record": "^4.0.8", - "@libp2p/utils": "^7.0.9", - "@multiformats/multiaddr": "^13.0.1", - "@multiformats/multiaddr-matcher": "^3.0.1", + "@libp2p/crypto": "^5.1.19", + "@libp2p/interface": "^3.2.3", + "@libp2p/interface-internal": "^3.1.6", + "@libp2p/peer-collections": "^7.0.21", + "@libp2p/peer-id": "^6.0.10", + "@libp2p/ping": "^3.1.6", + "@libp2p/record": "^4.0.13", + "@libp2p/utils": "^7.2.2", + "@multiformats/multiaddr": "^13.0.3", + "@multiformats/multiaddr-matcher": "^3.0.2", "any-signal": "^4.1.1", "interface-datastore": "^9.0.1", "it-all": "^3.0.9", @@ -316,30 +363,77 @@ "it-pushable": "^3.2.3", "it-take": "^3.0.9", "main-event": "^1.0.1", - "multiformats": "^13.4.0", + "multiformats": "^14.0.0", "p-defer": "^4.0.1", "p-event": "^7.0.0", "progress-events": "^1.0.1", - "protons-runtime": "^5.6.0", + "protons-runtime": "^6.0.1", "race-signal": "^2.0.0", + "uint8-varint": "^2.0.4", + "uint8arraylist": "^2.4.8", + "uint8arrays": "^6.1.1" + } + }, + "node_modules/@libp2p/kad-dht/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@libp2p/kad-dht/node_modules/protons-runtime": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-6.0.2.tgz", + "integrity": "sha512-hiyjyANwGcgmzc+tXc1/ZcSZhKnl5MDjaVNWkISHBgadaU0sjTgKIKZMZ62d9J9zlSTyKHCs/osPkQ/3Z+7yeA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { "uint8-varint": "^2.0.4", "uint8arraylist": "^2.4.8", "uint8arrays": "^5.1.0" } }, + "node_modules/@libp2p/kad-dht/node_modules/protons-runtime/node_modules/multiformats": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.4.2.tgz", + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@libp2p/kad-dht/node_modules/protons-runtime/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@libp2p/kad-dht/node_modules/uint8arrays": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-6.1.1.tgz", + "integrity": "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^14.0.0" + } + }, "node_modules/@libp2p/logger": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/@libp2p/logger/-/logger-6.2.2.tgz", - "integrity": "sha512-XtanXDT+TuMuZoCK760HGV1AmJsZbwAw5AiRUxWDbsZPwAroYq64nb41AHRu9Gyc0TK9YD+p72+5+FIxbw0hzw==", + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/@libp2p/logger/-/logger-6.2.8.tgz", + "integrity": "sha512-oPTkWJhYvhk8fjInH1ySyUDC/LLuqHsVqpNprtImd/64lnRHInV0EbwpRYwjdPNXAxYXDU/eQJzyqMWUNnN4+A==", "license": "Apache-2.0 OR MIT", "dependencies": { - "@libp2p/interface": "^3.1.0", - "@multiformats/multiaddr": "^13.0.1", + "@libp2p/interface": "^3.2.3", + "@multiformats/multiaddr": "^13.0.3", "interface-datastore": "^9.0.1", - "multiformats": "^13.4.0", + "multiformats": "^14.0.0", "weald": "^1.1.0" } }, + "node_modules/@libp2p/logger/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, "node_modules/@libp2p/mdns": { "version": "12.0.10", "resolved": "https://registry.npmjs.org/@libp2p/mdns/-/mdns-12.0.10.tgz", @@ -385,27 +479,48 @@ } }, "node_modules/@libp2p/peer-collections": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@libp2p/peer-collections/-/peer-collections-7.0.9.tgz", - "integrity": "sha512-pAMRxmT5V31V0gy2MfwVE1TMAcTnbyBYFOv60OWnkKth4hD+HvQ9DLW1z+opYDqRNON5sIWjcnDsIQDm2VUS7A==", + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/@libp2p/peer-collections/-/peer-collections-7.0.21.tgz", + "integrity": "sha512-kZFxzT+JE7TPo6Ygbu4/REds9QrSNpWP2eXHXSF2aImSw/AGvegXRD+p5/nALoz7D8Um2GIms/uTATqd+aD5Uw==", "license": "Apache-2.0 OR MIT", "dependencies": { - "@libp2p/interface": "^3.1.0", - "@libp2p/peer-id": "^6.0.4", - "@libp2p/utils": "^7.0.9", - "multiformats": "^13.4.0" + "@libp2p/interface": "^3.2.3", + "@libp2p/peer-id": "^6.0.10", + "@libp2p/utils": "^7.2.2", + "multiformats": "^14.0.0" } }, + "node_modules/@libp2p/peer-collections/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, "node_modules/@libp2p/peer-id": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@libp2p/peer-id/-/peer-id-6.0.4.tgz", - "integrity": "sha512-Z3xK0lwwKn4bPg3ozEpPr1HxsRi2CxZdghOL+MXoFah/8uhJJHxHFA8A/jxtKn4BB8xkk6F8R5vKNIS05yaCYw==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/@libp2p/peer-id/-/peer-id-6.0.10.tgz", + "integrity": "sha512-FgXeraxl932zim/K+vipCkscjLNMsyNVBh1NpGcJ+y8DQi/jgFXV4YZ0M2JuWM20GTcVCqDT5P10A0DJHRjecg==", "license": "Apache-2.0 OR MIT", "dependencies": { - "@libp2p/crypto": "^5.1.13", - "@libp2p/interface": "^3.1.0", - "multiformats": "^13.4.0", - "uint8arrays": "^5.1.0" + "@libp2p/crypto": "^5.1.19", + "@libp2p/interface": "^3.2.3", + "multiformats": "^14.0.0", + "uint8arrays": "^6.1.1" + } + }, + "node_modules/@libp2p/peer-id/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@libp2p/peer-id/node_modules/uint8arrays": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-6.1.1.tgz", + "integrity": "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^14.0.0" } }, "node_modules/@libp2p/peer-record": { @@ -448,32 +563,81 @@ } }, "node_modules/@libp2p/ping": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@libp2p/ping/-/ping-3.0.9.tgz", - "integrity": "sha512-PeOH3jH+f4cjczxNMKsAf67x/ai3/YQIAc8rq+fkhRWzIuYKjSG8omgiIJJ9sGbaI0b7Ap8vFVbVflvb52qEDg==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@libp2p/ping/-/ping-3.1.6.tgz", + "integrity": "sha512-scLY3/lC4xu6wq835JmeT2Q+sN2L1R/lexTICZuvoMW36f9hN8oAXwP+zf+eQpz20r628X4j6KWznfOc2cYE+A==", "license": "Apache-2.0 OR MIT", "dependencies": { - "@libp2p/crypto": "^5.1.13", - "@libp2p/interface": "^3.1.0", - "@libp2p/interface-internal": "^3.0.9", - "@multiformats/multiaddr": "^13.0.1", + "@libp2p/crypto": "^5.1.19", + "@libp2p/interface": "^3.2.3", + "@libp2p/interface-internal": "^3.1.6", "p-event": "^7.0.0", "race-signal": "^2.0.0", "uint8arraylist": "^2.4.8", - "uint8arrays": "^5.1.0" + "uint8arrays": "^6.1.1" + } + }, + "node_modules/@libp2p/ping/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@libp2p/ping/node_modules/uint8arrays": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-6.1.1.tgz", + "integrity": "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^14.0.0" } }, "node_modules/@libp2p/record": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@libp2p/record/-/record-4.0.8.tgz", - "integrity": "sha512-ZsGKBA1zuzqiwNPO2q0PHFhZzAJi/p+YLDtYdkwLYW0FbIgeMb5FX7cmopDk5Aa8mM9UbINb+nK5xz4+Bz8ShQ==", + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@libp2p/record/-/record-4.0.13.tgz", + "integrity": "sha512-f3kUWL09E7mNdIDOqClOimEURQFwYP9Zo8Ozpstk4BDCGf+8IJOe9X6s/Fs+eQMXrCo1PiS/kHT0xs65YR2OHg==", "license": "Apache-2.0 OR MIT", "dependencies": { - "protons-runtime": "^5.6.0", + "protons-runtime": "^6.0.1", + "uint8arraylist": "^2.4.8", + "uint8arrays": "^6.1.1" + } + }, + "node_modules/@libp2p/record/node_modules/protons-runtime": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-6.0.2.tgz", + "integrity": "sha512-hiyjyANwGcgmzc+tXc1/ZcSZhKnl5MDjaVNWkISHBgadaU0sjTgKIKZMZ62d9J9zlSTyKHCs/osPkQ/3Z+7yeA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "uint8-varint": "^2.0.4", "uint8arraylist": "^2.4.8", "uint8arrays": "^5.1.0" } }, + "node_modules/@libp2p/record/node_modules/protons-runtime/node_modules/uint8arrays": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.1.tgz", + "integrity": "sha512-9muQwa4wZG4dKi9gMAIBtnk2Pw87SRpvWTH6lOGm19V2Uqxr4uomUf2PGqPnWc+qs06sN8owUU4jfcoWOcfwVQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^13.0.0" + } + }, + "node_modules/@libp2p/record/node_modules/uint8arrays": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-6.1.1.tgz", + "integrity": "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^14.0.0" + } + }, + "node_modules/@libp2p/record/node_modules/uint8arrays/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, "node_modules/@libp2p/tcp": { "version": "11.0.9", "resolved": "https://registry.npmjs.org/@libp2p/tcp/-/tcp-11.0.9.tgz", @@ -492,20 +656,21 @@ } }, "node_modules/@libp2p/utils": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@libp2p/utils/-/utils-7.0.9.tgz", - "integrity": "sha512-2wYhsgfbFXfh5ui0ME9MNHc7uUIuZwpeZ/yagKmDSjIP7B+L3/9mj+vVXO14AhmjfwnKx2xUDQvzGZeq5to4ow==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@libp2p/utils/-/utils-7.2.2.tgz", + "integrity": "sha512-EEF/S3nYnR6+Ii0o2XL8RATEb8d+IhPCUNVVZ46u9L0wB+8cxL856pPi5tlzz+vK+Aix0ARGK4tbpROyXQst5Q==", "license": "Apache-2.0 OR MIT", "dependencies": { "@chainsafe/is-ip": "^2.1.0", "@chainsafe/netmask": "^2.0.0", - "@libp2p/crypto": "^5.1.13", - "@libp2p/interface": "^3.1.0", - "@libp2p/logger": "^6.2.2", - "@multiformats/multiaddr": "^13.0.1", + "@libp2p/crypto": "^5.1.19", + "@libp2p/interface": "^3.2.3", + "@libp2p/logger": "^6.2.8", + "@multiformats/multiaddr": "^13.0.3", + "@multiformats/multiaddr-matcher": "^3.0.2", "@sindresorhus/fnv1a": "^3.1.0", "any-signal": "^4.1.1", - "cborg": "^4.2.14", + "cborg": "^5.1.0", "delay": "^7.0.0", "is-loopback-addr": "^2.0.2", "it-length-prefixed": "^10.0.1", @@ -516,10 +681,26 @@ "netmask": "^2.0.2", "p-defer": "^4.0.1", "p-event": "^7.0.0", + "progress-events": "^1.1.0", "race-signal": "^2.0.0", "uint8-varint": "^2.0.4", "uint8arraylist": "^2.4.8", - "uint8arrays": "^5.1.0" + "uint8arrays": "^6.1.1" + } + }, + "node_modules/@libp2p/utils/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@libp2p/utils/node_modules/uint8arrays": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-6.1.1.tgz", + "integrity": "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^14.0.0" } }, "node_modules/@libp2p/websockets": { @@ -556,21 +737,21 @@ } }, "node_modules/@multiformats/multiaddr": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/@multiformats/multiaddr/-/multiaddr-13.0.1.tgz", - "integrity": "sha512-XToN915cnfr6Lr9EdGWakGJbPT0ghpg/850HvdC+zFX8XvpLZElwa8synCiwa8TuvKNnny6m8j8NVBNCxhIO3g==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@multiformats/multiaddr/-/multiaddr-13.0.3.tgz", + "integrity": "sha512-mEqqJ4r3a/uuFMTpRkU316wGNIDQNhuVWpm+ebKTQeYsfv9jXbPONWM6VVnj3KGUrwfsX7GZOyp4TFqEA2SPCw==", "license": "Apache-2.0 OR MIT", "dependencies": { "@chainsafe/is-ip": "^2.0.1", - "multiformats": "^13.0.0", - "uint8-varint": "^2.0.1", - "uint8arrays": "^5.0.0" + "multiformats": "^14.0.0", + "uint8-varint": "^3.0.0", + "uint8arrays": "^6.1.1" } }, "node_modules/@multiformats/multiaddr-matcher": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@multiformats/multiaddr-matcher/-/multiaddr-matcher-3.0.1.tgz", - "integrity": "sha512-jvjwzCPysVTQ53F4KqwmcqZw73BqHMk0UUZrMP9P4OtJ/YHrfs122ikTqhVA2upe0P/Qz9l8HVlhEifVYB2q9A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@multiformats/multiaddr-matcher/-/multiaddr-matcher-3.0.2.tgz", + "integrity": "sha512-iphGQJliZxe2yKu57bdRDgeS+3znc5uXtMybDO1Wau3rIjas4zjrjlyxmFz3wqyUL9f3VDQwas/ZqA7N4QeSfw==", "license": "Apache-2.0 OR MIT", "dependencies": { "@multiformats/multiaddr": "^13.0.0" @@ -585,6 +766,40 @@ "@multiformats/multiaddr": "^13.0.0" } }, + "node_modules/@multiformats/multiaddr/node_modules/multiformats": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-14.0.0.tgz", + "integrity": "sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==", + "license": "Apache-2.0 OR MIT" + }, + "node_modules/@multiformats/multiaddr/node_modules/uint8-varint": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/uint8-varint/-/uint8-varint-3.0.0.tgz", + "integrity": "sha512-S4DdpXBaLwKcFo7f0bWzWfHjbZ/i3QhM842qn+ZvHjxqFCfUcEB9SQNcmI69S+zMlcmIcKxsk9Iyw77S2Kxv6Q==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "uint8arraylist": "^3.0.1", + "uint8arrays": "^6.1.0" + } + }, + "node_modules/@multiformats/multiaddr/node_modules/uint8arraylist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/uint8arraylist/-/uint8arraylist-3.0.2.tgz", + "integrity": "sha512-LDVoq9BQaGJzGDUovEnoX6rpKCvnY/Jbtws4ikwnBzjRbq5qBAFpBZevUEbSmMM87aO0Sp+wOZy2ZXf5yODmXQ==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "uint8arrays": "^6.0.0" + } + }, + "node_modules/@multiformats/multiaddr/node_modules/uint8arrays": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-6.1.1.tgz", + "integrity": "sha512-iz7JN0XCSZYA111lhFG2Ui9EhFvTNekqSRHw3lvMHq+dzwWy1OQftxFQREEh4rffU0oSoXdQHsk2TiHKVm4fsA==", + "license": "Apache-2.0 OR MIT", + "dependencies": { + "multiformats": "^14.0.0" + } + }, "node_modules/@noble/ciphers": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.1.1.tgz", @@ -731,18 +946,18 @@ "license": "MIT" }, "node_modules/@rollup/plugin-terser": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", - "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-1.0.0.tgz", + "integrity": "sha512-FnCxhTBx6bMOYQrar6C8h3scPt8/JwIzw3+AJ2K++6guogH5fYaIFia+zZuhqv0eo1RN7W1Pz630SyvLbDjhtQ==", "dev": true, "license": "MIT", "dependencies": { - "serialize-javascript": "^6.0.1", + "serialize-javascript": "^7.0.3", "smob": "^1.0.0", "terser": "^5.17.4" }, "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" }, "peerDependencies": { "rollup": "^2.0.0||^3.0.0||^4.0.0" @@ -784,9 +999,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz", - "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.4.tgz", + "integrity": "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==", "cpu": [ "arm" ], @@ -798,9 +1013,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz", - "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.4.tgz", + "integrity": "sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==", "cpu": [ "arm64" ], @@ -812,9 +1027,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz", - "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.4.tgz", + "integrity": "sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==", "cpu": [ "arm64" ], @@ -826,9 +1041,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz", - "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.4.tgz", + "integrity": "sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==", "cpu": [ "x64" ], @@ -840,9 +1055,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz", - "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.4.tgz", + "integrity": "sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==", "cpu": [ "arm64" ], @@ -854,9 +1069,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz", - "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.4.tgz", + "integrity": "sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==", "cpu": [ "x64" ], @@ -868,9 +1083,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz", - "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.4.tgz", + "integrity": "sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==", "cpu": [ "arm" ], @@ -882,9 +1097,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz", - "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.4.tgz", + "integrity": "sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==", "cpu": [ "arm" ], @@ -896,9 +1111,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz", - "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.4.tgz", + "integrity": "sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==", "cpu": [ "arm64" ], @@ -910,9 +1125,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz", - "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.4.tgz", + "integrity": "sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==", "cpu": [ "arm64" ], @@ -924,9 +1139,23 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz", - "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.4.tgz", + "integrity": "sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.4.tgz", + "integrity": "sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==", "cpu": [ "loong64" ], @@ -938,9 +1167,23 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz", - "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.4.tgz", + "integrity": "sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.4.tgz", + "integrity": "sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==", "cpu": [ "ppc64" ], @@ -952,9 +1195,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz", - "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.4.tgz", + "integrity": "sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==", "cpu": [ "riscv64" ], @@ -966,9 +1209,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz", - "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.4.tgz", + "integrity": "sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==", "cpu": [ "riscv64" ], @@ -980,9 +1223,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz", - "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.4.tgz", + "integrity": "sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==", "cpu": [ "s390x" ], @@ -994,9 +1237,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz", - "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.4.tgz", + "integrity": "sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==", "cpu": [ "x64" ], @@ -1008,9 +1251,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz", - "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.4.tgz", + "integrity": "sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==", "cpu": [ "x64" ], @@ -1021,10 +1264,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.4.tgz", + "integrity": "sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz", - "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.4.tgz", + "integrity": "sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==", "cpu": [ "arm64" ], @@ -1036,9 +1293,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz", - "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.4.tgz", + "integrity": "sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==", "cpu": [ "arm64" ], @@ -1050,9 +1307,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz", - "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.4.tgz", + "integrity": "sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==", "cpu": [ "ia32" ], @@ -1064,9 +1321,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz", - "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.4.tgz", + "integrity": "sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==", "cpu": [ "x64" ], @@ -1078,9 +1335,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz", - "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.4.tgz", + "integrity": "sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==", "cpu": [ "x64" ], @@ -1336,9 +1593,9 @@ "license": "MIT" }, "node_modules/cborg": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.3.2.tgz", - "integrity": "sha512-l+QzebEAG0vb09YKkaOrMi2zmm80UNjmbvocMIeW5hO7JOXWdrQ/H49yOKfYX0MBgrj/KWgatBnEgRXyNyKD+A==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.1.tgz", + "integrity": "sha512-BDbSRIp6XrQXkTc7g+DN0RB9RrDPTUfals2ecWUlt3juPLjbAvy/V72mJcXY0Ehu0Dq/3WpNCOCT68HUTbW+lw==", "license": "Apache-2.0", "bin": { "cborg": "lib/bin.js" @@ -2041,9 +2298,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/logform": { @@ -2231,9 +2488,9 @@ "license": "MIT" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -2253,9 +2510,9 @@ } }, "node_modules/progress-events": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.1.tgz", - "integrity": "sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.1.0.tgz", + "integrity": "sha512-82DVc5tI36neVB3IjdXR11ztwGuoBc98em9ijzubeZKxI47OlV2Znq6mlPqE5xPDzO2Uw98GHiQSjj2favBCRQ==", "license": "Apache-2.0 OR MIT" }, "node_modules/protons-runtime": { @@ -2296,16 +2553,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -2348,9 +2595,9 @@ "license": "Apache-2.0 OR MIT" }, "node_modules/rollup": { - "version": "4.54.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz", - "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==", + "version": "4.60.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.4.tgz", + "integrity": "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==", "dev": true, "license": "MIT", "dependencies": { @@ -2364,28 +2611,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.54.0", - "@rollup/rollup-android-arm64": "4.54.0", - "@rollup/rollup-darwin-arm64": "4.54.0", - "@rollup/rollup-darwin-x64": "4.54.0", - "@rollup/rollup-freebsd-arm64": "4.54.0", - "@rollup/rollup-freebsd-x64": "4.54.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.54.0", - "@rollup/rollup-linux-arm-musleabihf": "4.54.0", - "@rollup/rollup-linux-arm64-gnu": "4.54.0", - "@rollup/rollup-linux-arm64-musl": "4.54.0", - "@rollup/rollup-linux-loong64-gnu": "4.54.0", - "@rollup/rollup-linux-ppc64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-gnu": "4.54.0", - "@rollup/rollup-linux-riscv64-musl": "4.54.0", - "@rollup/rollup-linux-s390x-gnu": "4.54.0", - "@rollup/rollup-linux-x64-gnu": "4.54.0", - "@rollup/rollup-linux-x64-musl": "4.54.0", - "@rollup/rollup-openharmony-arm64": "4.54.0", - "@rollup/rollup-win32-arm64-msvc": "4.54.0", - "@rollup/rollup-win32-ia32-msvc": "4.54.0", - "@rollup/rollup-win32-x64-gnu": "4.54.0", - "@rollup/rollup-win32-x64-msvc": "4.54.0", + "@rollup/rollup-android-arm-eabi": "4.60.4", + "@rollup/rollup-android-arm64": "4.60.4", + "@rollup/rollup-darwin-arm64": "4.60.4", + "@rollup/rollup-darwin-x64": "4.60.4", + "@rollup/rollup-freebsd-arm64": "4.60.4", + "@rollup/rollup-freebsd-x64": "4.60.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", + "@rollup/rollup-linux-arm-musleabihf": "4.60.4", + "@rollup/rollup-linux-arm64-gnu": "4.60.4", + "@rollup/rollup-linux-arm64-musl": "4.60.4", + "@rollup/rollup-linux-loong64-gnu": "4.60.4", + "@rollup/rollup-linux-loong64-musl": "4.60.4", + "@rollup/rollup-linux-ppc64-gnu": "4.60.4", + "@rollup/rollup-linux-ppc64-musl": "4.60.4", + "@rollup/rollup-linux-riscv64-gnu": "4.60.4", + "@rollup/rollup-linux-riscv64-musl": "4.60.4", + "@rollup/rollup-linux-s390x-gnu": "4.60.4", + "@rollup/rollup-linux-x64-gnu": "4.60.4", + "@rollup/rollup-linux-x64-musl": "4.60.4", + "@rollup/rollup-openbsd-x64": "4.60.4", + "@rollup/rollup-openharmony-arm64": "4.60.4", + "@rollup/rollup-win32-arm64-msvc": "4.60.4", + "@rollup/rollup-win32-ia32-msvc": "4.60.4", + "@rollup/rollup-win32-x64-gnu": "4.60.4", + "@rollup/rollup-win32-x64-msvc": "4.60.4", "fsevents": "~2.3.2" } }, @@ -2419,13 +2669,13 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", "dev": true, "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" + "engines": { + "node": ">=20.0.0" } }, "node_modules/smob": { @@ -2648,9 +2898,9 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", - "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.2.tgz", + "integrity": "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -2746,9 +2996,9 @@ } }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/package.json b/package.json index 2d217618..78e189f4 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.3", - "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-terser": "^1.0.0", "@types/archy": "^0.0.36", "@types/ws": "^8.18.1", "@types/yargs": "^17.0.33", From 0a901d89d8ff2b449bde23e95e44321f6a46e51f Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 1 Jun 2026 08:50:32 +0200 Subject: [PATCH 09/12] chore: gitignore dist build output, make rt clean wipe tsc cache - .gitignore: ignore the /build/ distribution bundle produced by `make dist` / `rollup -c` (was previously untracked-but-unignored). - rt/Makefile: `clean` now also removes tsconfig.tsbuildinfo. Removing only built/ left tsc's incremental cache behind, so a subsequent build emitted nothing (or regenerated stale layouts). This is what left the obsolete rt/built/src/ duplicate tree around after the rootDir change. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 4 ++++ rt/Makefile | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b9792cd4..ffc42b4e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ TAGS # NPM node_modules +################################################## +# Distribution bundle output (`make dist` / `rollup -c`) +/build/ + ################################################## # TypeScript incremental build cache *.tsbuildinfo diff --git a/rt/Makefile b/rt/Makefile index ba32b88a..693725a2 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -2,4 +2,4 @@ all: tsc clean: - rm -rf built + rm -rf built tsconfig.tsbuildinfo From 4cdedb9d888906cd2a3632afd640c26e46d8a6c5 Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 1 Jun 2026 08:54:18 +0200 Subject: [PATCH 10/12] docs: soften rollup treeshake comment to not overclaim cause The hang is confirmed (5+ CPU-hours; ~1s with treeshake off) but its exact trigger is not. Reword the comment to present the circular dependencies as present-but-unconfirmed rather than the established cause, and reference the known Rollup tree-shaking pathology class (rollup/rollup#5729). Co-Authored-By: Claude Opus 4.8 (1M context) --- rollup.config.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index eea25143..336a5c1d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -18,11 +18,14 @@ export default { format: 'cjs' }, - // The compiled runtime in rt/built has circular dependencies (e.g. - // runtimeMonitored <-> MailboxProcessor <-> QuarantineUtils <-> deserialize), - // which make Rollup's tree-shaking pass hang indefinitely on this graph. - // We don't need dead-code elimination here (terser still minifies the - // output), so disable tree-shaking to keep the bundle build fast. + // Rollup's tree-shaking pass hangs indefinitely (observed 5+ CPU-hours) on + // the compiled runtime in rt/built; with treeshake disabled the same bundle + // builds in ~1s. The exact trigger is unconfirmed -- it is a known class of + // Rollup tree-shaking performance pathology (cf. rollup/rollup#5729), and + // this graph does have circular dependencies (e.g. runtimeMonitored <-> + // MailboxProcessor <-> QuarantineUtils <-> deserialize), but those have not + // been confirmed as the cause. We don't need dead-code elimination here + // (terser still minifies the output), so disable tree-shaking. treeshake: false, plugins: [ From 92e6ec2ae9cfd0e044efd303b2f270688bbb9091 Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 1 Jun 2026 10:19:51 +0200 Subject: [PATCH 11/12] docs: split human-facing docs into docs/, keep CLAUDE.md agent-only Move all human-relevant reference material out of CLAUDE.md so it holds only agent-specific directives. README.md becomes a thin landing page; installation, development, architecture, contributing, and networking reference move into docs/. - CLAUDE.md: agent directives only; add "Writing documentation" rule against editorializing; link to the new docs. - README.md: intro, components, repository layout, quick start, docs index. - docs/INSTALL.md, DEVELOPMENT.md, ARCHITECTURE.md, CONTRIBUTING.md, NETWORKING.md: split reference material, each with a scope blurb. - NETWORKING.md: replace stale websocket-star node-discovery section with the mechanisms actually used (bootstrap, mDNS, kad-DHT; circuit relay v2 for NAT), verified against rt/src/p2p/p2p.mts. - De-editorialize inherited prose. Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 546 +++++++++++-------------------------------- README.md | 289 +++-------------------- docs/ARCHITECTURE.md | 68 ++++++ docs/CONTRIBUTING.md | 82 +++++++ docs/DEVELOPMENT.md | 154 ++++++++++++ docs/INSTALL.md | 84 +++++++ docs/NETWORKING.md | 60 +++++ 7 files changed, 612 insertions(+), 671 deletions(-) create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/CONTRIBUTING.md create mode 100644 docs/DEVELOPMENT.md create mode 100644 docs/INSTALL.md create mode 100644 docs/NETWORKING.md diff --git a/CLAUDE.md b/CLAUDE.md index 54cd9364..ba487cd4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,441 +1,155 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Overview - -Troupe is an actor-based programming language with dynamic information flow control. The codebase consists of three main components: - -1. **Compiler** (`/compiler/`) - Haskell-based compiler that transforms Troupe code to JavaScript -2. **Runtime** (`/rt/`) - TypeScript/JavaScript runtime implementing the actor model and information flow control. Note that the folder (`/rt/built`) is used as target for the generated code; it should be ignored for source code analysis. -3. **Standard Library** (`/lib/`) - Built-in libraries written in Troupe - -### Additional tools - -In addition to the core language runtime and the compiler, the codebase includes a few tools. - -1. **P2P** tools (`/p2p-tools`). - - 1. **Libp2p relay** (`relay/`) - TypeScript/JavaScript implementation of a libp2p relay. In multinode deployments we want to offer to our users at least one relay in order to allow communicating with Troupe nodes behind NAT. - - - -## Folders with executables - -- Executable binaries (`/bin`). Contains compiled binaries. Important to not add any scripts or other version-controllable artifacts in here, because this folder is to be ignored by version control. - -- Executiable scripts (`/scripts`). Contains useful executable scripts that are version controlled. - - -## Essential Commands - -### Building the Project - -```bash -# Build everything (recommended for significant changes) -make all - -# Build individual components -make compiler # Build the compiler -make rt # Build the runtime -make libs # Compile standard libraries -make service # Compile service module -``` - -### When to Rebuild - -Before running Troupe programs or tests, check for stale builds: - -**Compiler needs rebuilding if:** -- Any `.hs` file in `compiler/src/` was modified -- `bin/troupec` doesn't exist or isn't executable -- Error: "troupec: command not found" or parse errors in valid code - -**Runtime needs rebuilding if:** -- Any `.mts` file in `rt/src/` was modified -- `rt/built/troupe.mjs` doesn't exist -- Error: "Cannot find module" for runtime files - -**Libraries need rebuilding if:** -- Compiler was rebuilt -- Any `.trp` file in `lib/` was modified -- Error: "Cannot find module" for library files - -| Changed | Command | -|---------------------------|------------------| -| Haskell (`compiler/`) | `make compiler` | -| TypeScript (`rt/src/`) | `make rt` | -| Troupe libraries (`lib/`) | `make lib` | -| Everything | `make all` | - -**After git operations:** Always run `make all` after `git pull`, `git checkout`, or `git merge`. - -### Running Tests - -```bash -# Run full test suite -make test - -# Run golden tests with options -bin/golden - -# Run a test with specific pattern. Beware that slashes are not allowed in the patterns. -bin/golden -p - -# Quick mode: skip unoptimized pass for faster iteration -bin/golden --quick -bin/golden -p --quick -``` - -### Running Troupe Programs -There are two convenient scripts for running Troupe programs. They are in the root folder, and should remain there because of how frequently they are accessed. - - -```bash -# Local execution (no P2P networking, faster startup) -./local.sh myprogram.trp - -# Network execution (with P2P support) -./network.sh myprogram.trp - -# With debugging -./local.sh myprogram.trp --debug -``` - -### Development Commands - -```bash -# Clean build artifacts -make clear-built-rt - -# Interactive Haskell REPL for compiler development -cd compiler && make ghci-troupec - -# Check parser info -cd compiler && make parser-info -``` - -## Architecture Overview - -### Compilation Pipeline - -The Troupe compiler transforms source code through multiple stages: - -1. **Parsing** (`Parser.y`, `Lexer.x`) - Parse `.trp` files into AST -2. **Core Transformations**: - - Pattern elimination (`DirectWOPats.hs`) - - Function/let lowering - - Alpha renaming - - CPS transformation (`RetCPS.hs`, `RetDFCPS.hs`) - - CPS optimization (`CPSOpt.hs`) - - Closure conversion (`ClosureConv.hs`) -3. **Code Generation**: - - IR → Raw (`IR2Raw.hs`) - - Raw → Stack (`Raw2Stack.hs`) - - Stack → JavaScript (`Stack2JS.hs`) - -### Runtime Architecture - -The runtime implements: - -- **Actor System**: Process spawning, message passing, mailbox management -- **Information Flow Control**: Security levels, label tracking, declassification -- **P2P Networking**: libp2p integration for distributed actors -- **Built-in Functions**: Located in `/rt/src/builtins/` -- **Level System**: Various label implementations in `/rt/src/levels/` - -### Key Runtime Components - -- `troupe.mts` - Main entry point -- `runtimeMonitored.mts` - Gluing point for most of the runtime -- `Scheduler.mts` - Scheduler -- `MailboxProcessor.mts` - Message handling -- `TrustManager.mts` - Trust and security management -- `p2p/p2p.mts` - P2P networking layer -- `builtins` - Many language built-ins. - -## Testing Strategy - - -Tests are organized in `/tests/`, with the following subfolders - -- `cmp` - Negative compiler tests. -- `rt` - Runtime tests - - `pos/` - Positive tests (should succeed) - - `core/` - Core language features - - `ifc/` - Information flow control - - `sandbox/` - Sandboxing tests - - `neg/` - Negative tests (should fail) - - `timeout/` - Tests with timeouts - - `warn/` - Tests that should produce warnings - - `multinode/` - Multinode (networking) tests - - -## Creating new tests - -Do not put tests into the folders with existing .golden files, without explicit permission! - -### Testing non-networking functionality - -Non-network tests have a `.trp` source file and a `.golden` file with expected output. The comparison of the expected output is handled using the golden utility. This is needed because outputs often include timestamped value and that utility invokes the special diff that discards the timestamps. - - -### Multinode tests - -Multinode tests do not use the `golden` functionality. They should instead use the functionality described in -`tests/rt/multinode-tests/README.md` using the scripts in the `scripts` folder. - -When creating new multinode tests, do not create any ids or aliases or trustmaps. Instead, this needs to be coordinated using the corresponding `config.json`. - -### Guidelines for creating new tests - -- Use Troupe syntax (unless working specifically on negative parsing tests)! Please consult both the existing positive test corpus for examples of Troupe programs and the user-guide referenced in this document for how to write Troupe programs. - -- The easiest way to list all the built-ins is by inspecting the `compiler/src/IR.hs` where they are included in a long list. - -- Remember that there is Troupe standard library that may have useful functionality. - -- Troupe compiler `troupec` can be used to test tests for syntactic validity. - -- Local tests can be executed directly using `local.sh` script. - -#### Golden files for new tests - -When creating new tests, do not create `.golden` files manually. They are auto-generated by the `bin/golden` utility upon detection of a missing `.golden` file, for the non-network tests; and are not required at all for the multinode tests. - - - - -## Information Flow Control - -Troupe implements dynamic information flow control with: - -- **Security Levels**: High/Low, DC labels, custom lattices -- **PC (Program Counter) Label**: Tracks implicit flows -- **Declassification**: Controlled information release -- **Sandboxing**: Isolated execution with label constraints - - -## File Extensions - -- `.trp` - Troupe source files -- `.picox`, `.pico`, `.femto`, `.atto` - Test file variants -- `.golden` - Expected test outputs -- `.exports` - Library export definitions - -## Troupe language user guide - -Troupe language user guide is available at https://troupelang.github.io/troupe-user-guide-jb/. The guide currently uses the V1 label syntax `` `{alice}` ``, which the present Troupe runtime interprets as DC Labels corresponding to `` `` ``. - - -## Development Tips - -1. Use `./local.sh` for quick testing without P2P overhead -2. The compiler must be rebuilt after changes to Haskell code -3. Runtime changes require `make rt` to recompile TypeScript -4. Library changes require `make libs` to recompile -5. VSCode with Haskell and TypeScript extensions provides good IDE support -6. Set `TROUPE` environment variable to the repository root - -### Adding New Built-in Functions - -To add a new built-in function to Troupe, you need to make changes in both the compiler and runtime: - -#### 1. Compiler Registration -Add the function name to the built-in list in `/compiler/src/IR.hs` (around lines 262-337): -```haskell -wfir (Base fname) = - if fname `elem`[ - -- existing built-ins... - , "yourNewFunction" -- Add your function name here - ] -``` - -#### 2. Runtime Implementation -Create a new file `/rt/src/builtins/yourFunction.mts`: -```typescript -'use strict' -import { UserRuntimeZero, Constructor, mkBase } from './UserRuntimeZero.mjs' -import { LVal } from '../Lval.mjs'; - -export function BuiltinYourFunction>(Base: TBase) { - return class extends Base { - yourNewFunction = mkBase((larg) => { - // Your implementation here - // Use assertIsX functions for type checking - // Use lub() for security level calculations - return this.runtime.ret(new LVal(result, resultLevel)); - }, "yourNewFunction") - } -} -``` - -#### 3. Runtime Registration -Update `/rt/src/UserRuntime.mts`: -1. Import your new built-in: - ```typescript - import { BuiltinYourFunction } from './builtins/yourFunction.mjs' - ``` -2. Add it to the composition chain (order matters for dependencies): - ```typescript - export const UserRuntime = - BuiltinYourFunction ( - // ... rest of the existing chain - ``` - -#### 4. Build and Test -```bash -make compiler # Rebuild compiler -make rt # Rebuild runtime -make test # Run tests -``` - -#### Notes: -- Built-in functions must handle Troupe's information flow control using `lub()` for security levels -- Use appropriate `assertIsX` functions from `Asserts.mjs` for type safety -- The function name in IR.hs must exactly match the runtime function name -- Consider adding tests in `/tests/rt/pos/core/` for your new built-in - - - - -### Temporary test generation - -For temporary test generation, please use the folder `tests/_unautomated/claude`. - -### Testing the compiler-generated output. - -The compiler binary `troupec` has an option for verbose output `-v`, and the generated files are written into the `/out` folder, named with different stages of the compilation. - - -#### Turning off raw optimizations - -Some bugs may be further caught by turning off the raw ouptimizations. There is a flag `--no-rawopt` that disables Raw optimizations. It can be helpful for some corner compiler-related bugs. - -#### Troupe parser implementation. - -There should be no shift/reduce or reduce/reduce conflicts in the Troupe parser. - -#### Avoid unnecessary beautification - -Do not introduce cosmetic changes to the code as part of another goal, e.g., removing trailing spaces, etc. That -will unnecessary clutter the diffs. - - -### Troupe programs - -#### Syntax - -See the user guide for the exact language syntax, that is useful when creating tests. - -#### Syntax highlighting - -Troupe programs use Standard ML - style syntax, and that can be used for syntax highlighting. - -## Markdown Formatting - -When creating markdown tables, align columns for readability in raw view: +Agent-specific directives for working in this repository. This file contains **only** directives +for how to work here. For human-facing reference material, see: + +- [README.md](README.md) — overview, project components, repository layout +- [docs/INSTALL.md](docs/INSTALL.md) — dependencies and installation +- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) — build/test commands, running programs, source maps +- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — compilation pipeline, runtime, IFC, file extensions +- [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) — test-suite layout, adding a built-in +- [docs/NETWORKING.md](docs/NETWORKING.md) — P2P runtime + +## Build before running + +Before running Troupe programs or tests, check for stale builds and rebuild what changed. Build +commands are documented in [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) ("Building and running"). + +| Changed | Command | Symptom of a stale build | +|---------------------------|-----------------|-------------------------------------------| +| Haskell (`compiler/src/`) | `make compiler` | `troupec: command not found`, parse errors in valid code | +| TypeScript (`rt/src/`) | `make rt` | `Cannot find module` for runtime files | +| Troupe libraries (`lib/`) | `make libs` | `Cannot find module` for library files | +| Everything | `make all` | — | + +- Libraries also need rebuilding (`make libs`) after the compiler is rebuilt. +- After any `git pull`, `git checkout`, or `git merge`, run `make all`. +- `rt/built/` holds generated code — ignore it for source-code analysis. + +## Make + +Always invoke `/usr/bin/make` instead of `make`, to avoid a zsh function conflict. + +## Running tests + +- Running the suite takes time. Run it once, redirect output to a temp file, and read that file + for failures and status instead of re-running from scratch. +- When a golden test `t.trp` fails, run `./local.sh t.trp` to see the actual output before + drawing any conclusions. +- When a golden output changes, first confirm the new result is *correct* (understand **why** it + changed) before regenerating goldens. + +## Creating tests + +- Do **not** put new tests into folders that already contain `.golden` files without explicit + permission. +- Do **not** create `.golden` files by hand — `bin/golden` auto-generates them on first run for + non-network tests (multinode tests need none). +- For multinode tests, do not create ids, aliases, or trustmaps; coordinate them through the + corresponding `config.json`. Follow `tests/rt/multinode-tests/README.md` and the scripts in + `scripts/`. +- Put temporary/throwaway tests in `tests/_unautomated/claude`. +- A test that reads stdin may require a corresponding `.input` file. Golden tests are sensitive to + output formatting. +- When adding a new language primitive, add one or more brief tests demonstrating syntax, expected + behavior, and error messages; propose where in the corpus they belong. +- Write tests in real Troupe syntax (consult the user guide and the existing positive test corpus). + `troupec` can be used to check a test for syntactic validity. Remember the standard library may + already provide useful functionality. + +## Information flow claims + +Do not make untested claims about IFC relationships between levels. Use `debugpc()` to inspect the +current pc and blocking labels for correct information. + +## Compiler work + +- `troupec -v` writes per-stage generated files into `/out`; inspect these to debug codegen. +- `--no-rawopt` disables Raw optimizations and can surface corner-case compiler bugs. +- The Troupe parser must have no shift/reduce or reduce/reduce conflicts. +- For changes that span the whole compiler pipeline, prefer approaches that keep the compiler + working at each changed phase, so changes can be tested modularly. + +## Code and commit quality + +AI-generated commits must be held to the highest quality bar. + +- **Never commit an unverified change.** Verify code changes by the relevant tests passing + (`make test` / `bin/golden`), behavioral changes by observing the new behavior directly, and + documentation by review. A change that merely builds or type-checks is **not** verified. +- If a change cannot be verified — the tool that exercises it hangs, is broken, or is unavailable — + **do not commit it.** Leave it in the working tree and surface the situation; never commit on + faith. +- Do not bundle unverified changes together with verified ones to slip them in. Prefer several + small, individually-verified commits over one large commit whose parts have not all been checked. +- Do not introduce cosmetic changes (trailing-space removal, reformatting) as part of an unrelated + goal — it clutters diffs. +- When choosing between a clean-but-laborious approach and a quick partial one, in this codebase we + almost always do the clean thing that is *right*. + +## Conventions + +- Use absolute paths in runtime code. +- Backticks in info-flow label syntax interact badly with the shell; save example programs that use + backticks to files rather than creating them via `echo`. +- Use `--localonly` for local testing to skip slow p2p initialization. + +### Markdown tables + +Align columns for readability in raw view: ```markdown -| Column One | Column Two | Column Three | -|---------------------------|--------------|------------------------------| -| `short` | `value` | Description here | -| `longer_entry` | `val` | Another description | +| Column One | Column Two | Column Three | +|----------------|------------|---------------------| +| `short` | `value` | Description here | +| `longer_entry` | `val` | Another description | ``` -## Common Pitfalls - -- Remember to rebuild both compiler and runtime after pulling changes -- Use absolute paths in the runtime code -- P2P initialization can be slow; use `--localonly` for local testing. -- Test files may require specific `.input` files for stdin -- Golden tests are sensitive to output formatting -- Always use `/usr/bin/make` instead of `make` to avoid zsh function conflicts - - -## What to do when a golden test fails - -In most cases the right thing to do is to locally run the file, i.e., -if the test `t.trp` fails, run `./local.sh t.trp` to see what the output is. - -Be careful making untested claims about information flow relationships between levels; -do use `debugpc()` functionality to see the present values of the pc and blocking labels -for correct information. - - -## Working on changes that affect the whole compiler pipeline - -When working on changes that affect the whole compiler, consider approaches that -would maintain a working compiler at each changed phase, so that changes can be -modularly tested. - +## Writing documentation -## Estimates +- Write factually. State what something is and how to use it; do not editorialize. +- Avoid value judgments and color the reader did not ask for: words like *convenient*, *useful*, + *powerful*, *simply*, *just*, *easy*, *nice*, *day-to-day*; hedging like *hopefully* or *should be + fine*; and hype. +- Drop self-justifying asides about why a choice was made unless the rationale is actionable for the + reader. +- Prefer a fact to an opinion: "skips p2p initialization" over "a convenient script that skips p2p + initialization." -All estimates should be given in the degree of autonomy (as opposed to weeks that make little sense -for the agent-assisted development) +## Estimates +Give estimates as **degree of autonomy**, not weeks (which make little sense for agent-assisted +development). -## Choosing between the cleanest and the partial easy solutions. - -When choosing between the obviosuly clean but laborious approach and -a quick easy but partial solution, in this code base we almost always want to do the clean thing that is _right_! - - -## Commit quality — no unverified or untested changes - -AI-generated commits must be held to the highest quality bar. **Never commit a change that has not been verified.** - -- Every committed change must be verified *before* it is committed: code changes by the relevant tests passing (`make test` / `bin/golden`), behavioral changes by observing the new behavior directly, and documentation by review. A change that merely builds or type-checks is **not** verified. -- If a change cannot be verified — e.g. the tool that exercises it hangs, is broken, or is unavailable — **do not commit it**. Leave it in the working tree and surface the situation to the user; never commit on faith. -- Do not bundle unverified changes together with verified ones to slip them in. Commit only what is verified and hold the rest in separate, clearly-scoped commits. -- When a behavior or a golden output changes, first confirm the new result is *correct* (not merely *different*) — understand why it changed — before regenerating goldens or committing. -- Prefer several small, individually-verified commits over one large commit whose parts have not all been checked. - - -## Note on backticks in the labels. - -Beware of the backticks in the syntax of the info flow labels that can have unfortunate -interactions with the shell. Example programs that use bacticks should probably not be -created via echo, but saved in files. - -## Executing tests - -Running tests takes time; to save on running them, run them and save the results in a temp file and read that file for failures and status (instead of re-running them from scratch) - - -## New primitives should have tests - -When adding new primitives into the language, make sure to create one or more tests that would demonstrate the syntax, the expected behavior, expected error messages, etc. Keep these demo tests brief and down to the chase; propose to add them to the appropriate place in the test corpus. - - -## Auto-structuring Large Plans +## Auto-structuring large plans Before finalizing any implementation plan, assess its complexity and structure accordingly: -| Complexity | Criteria | Structure | -|------------|-------------------------------------|------------------------------------------------| -| Small | <3 tasks, single focus | Inline in conversation | -| Medium | 3-4 tasks, 2-3 areas | Single plan file with sections | -| Large | 4+ tasks, multiple areas/phases | Multi-file structure in `_claude_planning/` | +| Complexity | Criteria | Structure | +|------------|---------------------------------|---------------------------------------------| +| Small | <3 tasks, single focus | Inline in conversation | +| Medium | 3-4 tasks, 2-3 areas | Single plan file with sections | +| Large | 4+ tasks, multiple areas/phases | Multi-file structure in `_claude_planning/` | **For large plans**, automatically create the following structure without being asked: ``` _claude_planning// - index.md # Overview, progress tracking, step links - step-1-.md # Self-contained step file + index.md # Overview, progress tracking, step links + step-1-.md # Self-contained step file step-2-.md ... ``` **Requirements for multi-file plans:** -1. **index.md**: Progress table with status indicators, links to all steps, decision log -2. **Step files**: Each must be self-contained with enough context to execute in a fresh session -3. **Progress tracking**: Use checkboxes and status indicators (Pending/In Progress/Complete/Blocked) -**Templates are available at:** `_claude_planning/_template/` -- `index.md` - Index file template -- `step-N-template.md` - Step file template +1. **index.md**: progress table with status indicators, links to all steps, decision log. +2. **Step files**: each must be self-contained with enough context to execute in a fresh session. +3. **Progress tracking**: use checkboxes and status indicators (Pending/In Progress/Complete/Blocked). + +**Templates are available at** `_claude_planning/_template/`: + +- `index.md` — index file template +- `step-N-template.md` — step file template -When creating a new large plan, copy and adapt these templates. \ No newline at end of file +When creating a new large plan, copy and adapt these templates. diff --git a/README.md b/README.md index 859e200b..163e1772 100644 --- a/README.md +++ b/README.md @@ -3,275 +3,54 @@ Troupe is a programming language based on the actor model for concurrent and distributed programming that provides dynamic information flow control. -## Troupe development container +## Project components -If you want to try out Troupe without manual installation (e.g., for a class exercise or just checking the system), please check out the VSCode development container available through the [Troupe/example-project](https://github.com/TroupeLang/example-project) repository. +Troupe consists of three main components: -## Installation +1. **Compiler** (`compiler/`) — Haskell-based compiler that transforms Troupe code to JavaScript. +2. **Runtime** (`rt/`) — TypeScript/JavaScript runtime implementing the actor model and information flow control. The `rt/built/` folder is the build target for generated code. +3. **Standard library** (`lib/`) — built-in libraries written in Troupe. -Once all dependencies have been installed, the whole project can be built and Troupe installed to the `bin` directory with `make all`. The following shows step-by-step which dependencies are needed for which parts and how to install them. +### Additional tools -### Step 1. Install JS runtime -1. Install NodeJS (e.g. `sudo apt-get install nodejs`) -2. Install js dependencies via `npm install` -3. Set the `TROUPE` environment variable to point to the folder that contains this README. In bash this is done by adding the following lines to a file such as `~/.bashrc` or `~/.bash_profile`: - ``` - TROUPE= - export TROUPE= - ``` - Read [here](https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux-vps") for more info on environment variables. -6. Install [TypeScript](https://www.typescriptlang.org/): `npm install -g typescript` - - To install to the home directory without root, first run `npm config set prefix ~/.npm` and add `~/.npm/bin` to your PATH -7. Compile Troupe runtime by typing `make rt` +- **P2P tools** (`p2p-tools/`) — utilities for the distributed runtime, including a [libp2p](https://libp2p.io/) **relay** (`p2p-tools/relay/`). In multinode deployments the relay lets users communicate with Troupe nodes behind NAT. -### Step 2. Install Troupe compiler +### Repository layout -1. Get [Haskell stack](https://www.haskellstack.org). -2. Change to the `compiler` directory and run `make` +| Path | Contents | +|--------------|-------------------------------------------------------------------------| +| `compiler/` | Haskell compiler sources (`troupec`) | +| `rt/` | TypeScript runtime; `rt/built/` is the generated build output | +| `lib/` | Troupe standard library (`.trp` sources) | +| `bin/` | Compiled binaries — **not** version-controlled; do not add scripts here | +| `scripts/` | Version-controlled executable scripts | +| `tests/` | Test corpus (see [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md#test-suite-layout)) | +| `p2p-tools/` | P2P utilities and relay | -The above make script copies the binary of the compiler into the -bin folder of the project under name `troupec`. That name is then used -by the runtime module. +## Quick start - -### Step 3. Install Troupe top-level scripts - -Type `make compiler` (in the repository's root) to compile Troupe's bin scripts - -### Step 4. Install Troupe standard library - -Type - -- `make libs` to compile Troupe's built-in libraries, and -- `make service` to compile the service module placeholder. - - -### Step 5. Running the test suite - -#### OS X specific utilities for testing - -On OS X, make sure to have `gtimeout`, `greadlink`, and GNU `diff` utilities. - -- `gtimeout` and `greadlink` can be installed via `brew install coreutils` -- GNU `diff` can be installed via `brew install diffutils` - -The GNU diff is required because Troupe's test suite relies on specific diff features not available in the default macOS diff. After installation, verify that GNU diff is available: +With all [dependencies installed](docs/INSTALL.md), build everything and run a program: ```bash -diff --version +make all # build compiler, runtime, libraries, and service +./local.sh myprogram.trp # run a program locally (no P2P) ``` -Expected output: -``` -diff (GNU diffutils) 3.10 -Copyright (C) 2023 Free Software Foundation, Inc. -License GPLv3+: GNU GPL version 3 or later . -This is free software: you are free to change and redistribute it. -There is NO WARRANTY, to the extent permitted by law. - -Written by Paul Eggert, Mike Haertel, David Hayes, -Richard Stallman, and Len Tower. -``` - -#### Checking the installation - -Check that the installation works by running the local test suite: `$TROUPE/bin/golden` -(alternatively `make test` in this directory). - -#### Multinode tests - -Multinode tests are located in `tests/rt/multinode-tests/` and can be run using the script: -`scripts/run-multinode-tests.sh` - - -## Setting up a development environment - -### Using VSCode - -#### Setting up remote development on a Linux remote machine (optional) -This will allow to develop on a remote machine, using VSCode on a local machine to access the project. Compilation and tools such as the Haskell Language Server will run on the remote machine. - +To try Troupe without a manual install, use the VSCode development container in the +[Troupe/example-project](https://github.com/TroupeLang/example-project) repository. -##### On the remote machine +## Documentation -- Setup ssh -- Install [ghcup](https://www.haskell.org/ghcup/install/#how-to-install): `curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh` - - The installation script will ask whether to install stack and the Haskell Language Server, say yes both - - Make sure that PATH is updated as suggested -- Reboot remote (or make sure that the newly installed environment variables are on PATH and available everywhere) - - -##### On the local machine - -- Install Visual Studio Code -- Install the [Remote Development extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) - - NOTE: ssh connections might not work with the open source builds of VS Code (where the ssh extensions have to be manually downloaded and installed, or open source alternatives have to be used) -- Now you should be able to connect to the remote machine (use the green button in the bottom-left, or F1 -> "Remote-SSH: Connect to Host"). If the remote machine is added in `.ssh/config`, it should show up. You'll be asked to enter the password for the ssh key. - - On first connect, the VSCode server will automatically be installed on the remote machine. - - -#### Setting up Haskell support - -- Install the [Haskell](https://marketplace.visualstudio.com/items?itemName=haskell.haskell) and [Haskell Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=justusadam.language-haskell) extensions (on the remote if applicable) - - The Haskell extension will at some point ask which way to use to manage HLS, choose GHCup - - In the description of the Haskell extension is a table with supported GHC versions. Make sure that the project's stack resolver in `compiler/stack.yaml` is set to a version with a supported GHC version (see [stackage.org](https://www.stackage.org/)). -- Open the `compiler` folder. VSCode should start setting up the Haskell Language Server and might ask whether to download some specific versions of HLS/stack/ghc. - - In case of a failure, it might help to reload the window, so that VSCode tries again. - -Now, when having opened the `compiler` folder, the Haskell Language Server should highlight errors and hints, support "Go to definition" and more. - - -#### Syntax support for Troupe files - -As Troupe syntax is similar to SML, installing the [SML Environment](https://marketplace.visualstudio.com/items?itemName=vrjuliao.sml-environment) extension is useful. It adds syntax highlighting, some identation support and support for commenting with editor commands. - -Use `Ctrl-k m` ("Change language mode") to set the current file's language mode to SML. The suggestions will also allow to generally associate `.trp` files with SML mode. - - -#### Building and running - -- **Building the compiler:** When having opened the `compiler` folder, there is a task "Build all", which is set as the default build task, so running "Run build task" (Ctrl-F9) should execute it. -- **Running a Troupe file locally:** When having the Troupe root folder opened, there is a task "Run local" which runs `local.sh` with the currently focused file. It is set to the default test task, so "Run Test Task" should execute it. You may want to set a keybinding. -- Tasks are defined in the respective `.vscode/tasks.json` file, where further tasks can be added easily. - - - - - +| Document | Contents | +|----------------------------------------------|-----------------------------------------------------------------------| +| [docs/INSTALL.md](docs/INSTALL.md) | Dependencies and step-by-step installation, including OS X setup | +| [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) | Editor setup, build/test commands, running programs, source maps | +| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Compilation pipeline, runtime architecture, IFC, file extensions | +| [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) | Test-suite layout and how to add a built-in function | +| [docs/NETWORKING.md](docs/NETWORKING.md) | P2P runtime, libp2p, node discovery, relays | ## User guide -The current user guide is accessible [here](https://troupe.cs.au.dk/userguide.pdf). - -### Note on DC Labels - -All DC label tags are normalized to lowercase. For example, `` `` `` is equivalent to `` `` ``. This normalization is applied both at compile time (by the lexer) and at runtime. - -## Building and running -### Building - -The following commands build specific parts of the project and install the results to the `bin`, `rt/built` and `lib` directories. - -- `make all`: build everything (use this whenever significant changes have been made to the project, to be sure that everything is up-to-date) -- `make` / `make compiler`: build the compiler -- `make rt`: build the runtime (into the `rt/built` directory) -- `make libs`: compile Troupe's built-in libraries (into the `lib` directory) -- `make service` compile the service module placeholder - -### Tests - -- `make test` to run all tests -- `bin/golden` to run the test suite with options - -### Running examples that do not require network - -For programs that do not require network access, there is a convenient script -`local.sh` that prompts the Troupe runtime to skip initialization of the p2p -infrastructure or key generation (which otherwise takes a few seconds). - -### Passing command-line arguments to Troupe programs - -To pass arguments to a Troupe program, use `--` to separate runtime options from program arguments: - -```bash -./local.sh myprogram.trp -- arg1 arg2 arg3 -./network.sh myprogram.trp -- arg1 "argument with spaces" arg3 -``` - -Arguments after `--` are accessible in the Troupe program using the `getCliArgs` built-in function, which requires root authority: - -```sml -let val args = getCliArgs authority -in print args (* ["arg1", "arg2", "arg3"] *) -end -``` - -Note: CLI arguments are treated as sensitive data and are labeled at the highest security level (ROOT). Only code with root authority can access them. - -### Building and naming the snapshot - -Script `dev-utils/build.sh` runs `make` and copies the executables to `../bin/`. -This is useful when wanting to compile some snapshots to compare how different versions behave. - -## Source Maps - -The Troupe compiler can generate source maps to help with debugging by mapping generated JavaScript code back to the original Troupe source. - -### Generating Source Maps - -Use the `-m` or `--source-map` flag when compiling: - -```bash -bin/troupec -m myprogram.trp -o myprogram.js -``` - -This generates both `myprogram.js` and `myprogram.js.map`. - -### Inspecting Source Maps - -A tool is provided for inspecting generated source maps: - -```bash -npx ts-node rt/src/tools/inspect-sourcemap.ts -``` - -This displays: -- Source map metadata (file, sources, version) -- All decoded mappings grouped by source file -- Line/column mappings from generated to original code - -## Networking - -When the program starts, once the keys are loaded (or generated), the runtime starts by connecting to -a number of nodes to bootstrap its discovery. This takes an observable amount of time. - - -### Local only mode -To skip network connection, one can provide `--localonly` flag to the runtime, but -observe that in this case all external I/O will result -in a runtime error. - - -### Generating new persistent IDs -See [p2p-tools/mkid.mts](p2p-tools/mkid.mts). - -### Auto-created IDs - -If the id file is omitted, a new id (via a fresh key/pair) is generated upon -start. Observe that this induces a bigger runtime overhead than loading a key pair -from a file. - -### Stability issues and patches. - -Libp2p is a fast-moving project, and there are stability issues. We -apply local patches to work around these issues (hence the patch application in the installation of JS runtime), but this should be used on a temporary -basis only and removed once the actual bugs are fixed (either in the official - packages or in our codebase). - - -### Notes on the p2p runtime - -The p2p runtime is implemented using [libp2p](https://libp2p.io/) library (part of IPFS project). This -means that nodes at runtime are now libp2p nodes (this is good for functionality -and terrible for anonymity). We inherit from libp2p that every node has an -associated pair of public/private keys, and an id of the node is the hash of its -public key. - -We use libp2p's functionality of relaying messages. This means that programs or -processes running behind NAT (e.g., something running on a developer laptop) are -accessible from the outside. Hopefully, this should facilitate development of -more examples (this is the main reason for trying out this networking -transport). - - -### Navigating the code base - -The main p2p runtime module is in [rt/src/p2p/p2p.ts](rt/src/p2p/p2p.ts). - - -## References - -### How node discovery works. -See [this ](https://github.com/libp2p/js-libp2p/tree/master/examples/discovery-mechanisms) and [this](https://github.com/libp2p/js-libp2p/tree/master/examples/peer-and-content-routing) examples for how the discovery works. We also make use of websocket-star transport/discovery, which -proxies the connections in case one of the machines is behind NAT. We currently use one of the third-party default websocket-star-rendezvous servers for convenience, but in the future we can set up our own rendezvous server running -using [this package](https://github.com/libp2p/js-libp2p-websocket-star-rendezvous). +The current user guide is accessible [here](https://troupe.cs.au.dk/userguide.pdf). A +[Jupyter-book version](https://troupelang.github.io/troupe-user-guide-jb/) is also available. +See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md#note-on-dc-labels) for a note on DC label syntax. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 00000000..35349064 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,68 @@ +# Architecture + +> **Scope:** how Troupe is structured internally — the compilation pipeline, the runtime, the +> information-flow-control model, and file extensions. For making changes (e.g. adding a built-in) +> see [CONTRIBUTING.md](CONTRIBUTING.md); for the networking layer see [NETWORKING.md](NETWORKING.md). + +## Compilation pipeline + +The compiler transforms source through several stages: + +1. **Parsing** (`Parser.y`, `Lexer.x`) — parse `.trp` files into an AST. +2. **Core transformations:** + - Pattern elimination (`DirectWOPats.hs`) + - Function/let lowering + - Alpha renaming + - CPS transformation (`RetCPS.hs`, `RetDFCPS.hs`) + - CPS optimization (`CPSOpt.hs`) + - Closure conversion (`ClosureConv.hs`) +3. **Code generation:** + - IR → Raw (`IR2Raw.hs`) + - Raw → Stack (`Raw2Stack.hs`) + - Stack → JavaScript (`Stack2JS.hs`) + +## Runtime architecture + +The runtime implements: + +- **Actor system** — process spawning, message passing, mailbox management +- **Information flow control** — security levels, label tracking, declassification +- **P2P networking** — libp2p integration for distributed actors +- **Built-in functions** — `rt/src/builtins/` +- **Level system** — label implementations in `rt/src/levels/` + +Key components: + +| File | Role | +|------------------------|--------------------------------------| +| `troupe.mts` | Main entry point | +| `runtimeMonitored.mts` | Gluing point for most of the runtime | +| `Scheduler.mts` | Scheduler | +| `MailboxProcessor.mts` | Message handling | +| `TrustManager.mts` | Trust and security management | +| `p2p/p2p.mts` | P2P networking layer | +| `builtins/` | Language built-ins | + +## Information flow control + +Troupe implements dynamic information flow control with: + +- **Security levels** — High/Low, DC labels, custom lattices +- **PC (program counter) label** — tracks implicit flows +- **Declassification** — controlled information release +- **Sandboxing** — isolated execution with label constraints + +### Note on DC Labels + +All DC label tags are normalized to lowercase. For example, `` `` `` is equivalent to `` `` ``. This normalization is applied both at compile time (by the lexer) and at runtime. + +The user guide currently uses the V1 label syntax `` `{alice}` ``, which the present Troupe runtime interprets as a DC Label corresponding to `` `` ``. + +## File extensions + +| Extension | Meaning | +|--------------------------------------|----------------------------| +| `.trp` | Troupe source files | +| `.picox`, `.pico`, `.femto`, `.atto` | Test file variants | +| `.golden` | Expected test outputs | +| `.exports` | Library export definitions | diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 00000000..ce4036e8 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,82 @@ +# Contributing + +> **Scope:** conventions for changing the codebase — the test-suite layout and a worked example of +> adding a built-in function. For background on how the system is structured see +> [ARCHITECTURE.md](ARCHITECTURE.md); for build/test commands see [DEVELOPMENT.md](DEVELOPMENT.md). + +## Test suite layout + +Tests live in `tests/`: + +- `cmp/` — negative compiler tests +- `rt/` — runtime tests + - `pos/` — positive tests (should succeed): `core/`, `ifc/`, `sandbox/` + - `neg/` — negative tests (should fail) + - `timeout/` — tests with timeouts + - `warn/` — tests that should produce warnings + - `multinode/` — multinode (networking) tests + +Non-networking tests pair a `.trp` source with a `.golden` expected-output file; the `bin/golden` utility compares output using a diff that discards timestamped values. Multinode tests do not use golden files — see `tests/rt/multinode-tests/README.md`. + +## Adding a built-in function + +Adding a built-in requires changes in both the compiler and the runtime. The easiest way to +list all existing built-ins is to inspect `compiler/src/IR.hs`. + +### 1. Compiler registration + +Add the function name to the built-in list in `compiler/src/IR.hs`: + +```haskell +wfir (Base fname) = + if fname `elem`[ + -- existing built-ins... + , "yourNewFunction" -- add your function name here + ] +``` + +### 2. Runtime implementation + +Create `rt/src/builtins/yourFunction.mts`: + +```typescript +'use strict' +import { UserRuntimeZero, Constructor, mkBase } from './UserRuntimeZero.mjs' +import { LVal } from '../Lval.mjs'; + +export function BuiltinYourFunction>(Base: TBase) { + return class extends Base { + yourNewFunction = mkBase((larg) => { + // Implementation. Use assertIsX functions for type checking + // and lub() for security-level calculations. + return this.runtime.ret(new LVal(result, resultLevel)); + }, "yourNewFunction") + } +} +``` + +### 3. Runtime registration + +In `rt/src/UserRuntime.mts`, import the built-in and add it to the composition chain (order matters for dependencies): + +```typescript +import { BuiltinYourFunction } from './builtins/yourFunction.mjs' + +export const UserRuntime = + BuiltinYourFunction ( + // ... rest of the existing chain +``` + +### 4. Build and test + +```bash +make compiler # rebuild compiler +make rt # rebuild runtime +make test # run tests +``` + +Notes: + +- Built-ins must handle information flow control using `lub()` for security levels. +- Use the `assertIsX` helpers from `Asserts.mjs` for type safety. +- The name in `IR.hs` must exactly match the runtime function name. diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md new file mode 100644 index 00000000..04330ffc --- /dev/null +++ b/docs/DEVELOPMENT.md @@ -0,0 +1,154 @@ +# Development + +> **Scope:** editor setup, build/test commands, running programs, and source maps. For first-time +> installation see [INSTALL.md](INSTALL.md); for how the system is put together see +> [ARCHITECTURE.md](ARCHITECTURE.md). + +## Setting up a development environment + +### Using VSCode + +#### Setting up remote development on a Linux remote machine (optional) +This will allow to develop on a remote machine, using VSCode on a local machine to access the project. Compilation and tools such as the Haskell Language Server will run on the remote machine. + + +##### On the remote machine + +- Setup ssh +- Install [ghcup](https://www.haskell.org/ghcup/install/#how-to-install): `curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh` + - The installation script will ask whether to install stack and the Haskell Language Server, say yes both + - Make sure that PATH is updated as suggested +- Reboot remote (or make sure that the newly installed environment variables are on PATH and available everywhere) + + +##### On the local machine + +- Install Visual Studio Code +- Install the [Remote Development extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) + - NOTE: ssh connections might not work with the open source builds of VS Code (where the ssh extensions have to be manually downloaded and installed, or open source alternatives have to be used) +- Now you should be able to connect to the remote machine (use the green button in the bottom-left, or F1 -> "Remote-SSH: Connect to Host"). If the remote machine is added in `.ssh/config`, it should show up. You'll be asked to enter the password for the ssh key. + - On first connect, the VSCode server will automatically be installed on the remote machine. + + +#### Setting up Haskell support + +- Install the [Haskell](https://marketplace.visualstudio.com/items?itemName=haskell.haskell) and [Haskell Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=justusadam.language-haskell) extensions (on the remote if applicable) + - The Haskell extension will at some point ask which way to use to manage HLS, choose GHCup + - In the description of the Haskell extension is a table with supported GHC versions. Make sure that the project's stack resolver in `compiler/stack.yaml` is set to a version with a supported GHC version (see [stackage.org](https://www.stackage.org/)). +- Open the `compiler` folder. VSCode should start setting up the Haskell Language Server and might ask whether to download some specific versions of HLS/stack/ghc. + - In case of a failure, it might help to reload the window, so that VSCode tries again. + +Now, when having opened the `compiler` folder, the Haskell Language Server should highlight errors and hints and support "Go to definition". + + +#### Syntax support for Troupe files + +Troupe syntax is similar to SML; the [SML Environment](https://marketplace.visualstudio.com/items?itemName=vrjuliao.sml-environment) extension adds syntax highlighting, some indentation support, and commenting with editor commands. + +Use `Ctrl-k m` ("Change language mode") to set the current file's language mode to SML. The suggestions will also allow to generally associate `.trp` files with SML mode. + + +#### Building and running + +- **Building the compiler:** When having opened the `compiler` folder, there is a task "Build all", which is set as the default build task, so running "Run build task" (Ctrl-F9) should execute it. +- **Running a Troupe file locally:** When having the Troupe root folder opened, there is a task "Run local" which runs `local.sh` with the currently focused file. It is set to the default test task, so "Run Test Task" should execute it. +- Tasks are defined in the respective `.vscode/tasks.json` file, where further tasks can be added. + + + + + + +## Building and running + +### Building + +The following commands build specific parts of the project and install the results to the `bin`, `rt/built` and `lib` directories. + +- `make all`: build everything (compiler, runtime, libraries, and service) +- `make` / `make compiler`: build the compiler +- `make rt`: build the runtime (into the `rt/built` directory) +- `make libs`: compile Troupe's built-in libraries (into the `lib` directory) +- `make service` compile the service module placeholder + +### Tests + +- `make test` to run all tests +- `bin/golden` to run the test suite with options +- `bin/golden -p ` to run tests matching a pattern (slashes are not allowed in patterns) +- `bin/golden --quick` to skip the unoptimized pass for faster iteration + +For the test-suite layout and conventions, see [CONTRIBUTING.md](CONTRIBUTING.md#test-suite-layout). + +### Running Troupe programs + +```bash +./local.sh myprogram.trp # local execution (no P2P, faster startup) +./network.sh myprogram.trp # network execution (with P2P support) +./local.sh myprogram.trp --debug # with debugging +``` + +### Development commands + +```bash +make clear-built-rt # clean runtime build artifacts +cd compiler && make ghci-troupec # interactive Haskell REPL for compiler development +cd compiler && make parser-info # parser info +``` + +### Running examples that do not require network + +For programs that do not require network access, there is a utility script +`local.sh` that prompts the Troupe runtime to skip initialization of the p2p +infrastructure or key generation (which otherwise takes a few seconds). + +### Passing command-line arguments to Troupe programs + +To pass arguments to a Troupe program, use `--` to separate runtime options from program arguments: + +```bash +./local.sh myprogram.trp -- arg1 arg2 arg3 +./network.sh myprogram.trp -- arg1 "argument with spaces" arg3 +``` + +Arguments after `--` are accessible in the Troupe program using the `getCliArgs` built-in function, which requires root authority: + +```sml +let val args = getCliArgs authority +in print args (* ["arg1", "arg2", "arg3"] *) +end +``` + +Note: CLI arguments are treated as sensitive data and are labeled at the highest security level (ROOT). Only code with root authority can access them. + +### Building and naming the snapshot + +Script `dev-utils/build.sh` runs `make` and copies the executables to `../bin/`, +so snapshots from different versions can be compared. + +## Source Maps + +The Troupe compiler can generate source maps to help with debugging by mapping generated JavaScript code back to the original Troupe source. + +### Generating Source Maps + +Use the `-m` or `--source-map` flag when compiling: + +```bash +bin/troupec -m myprogram.trp -o myprogram.js +``` + +This generates both `myprogram.js` and `myprogram.js.map`. + +### Inspecting Source Maps + +A tool is provided for inspecting generated source maps: + +```bash +npx ts-node rt/src/tools/inspect-sourcemap.ts +``` + +This displays: +- Source map metadata (file, sources, version) +- All decoded mappings grouped by source file +- Line/column mappings from generated to original code diff --git a/docs/INSTALL.md b/docs/INSTALL.md new file mode 100644 index 00000000..1a2f1f72 --- /dev/null +++ b/docs/INSTALL.md @@ -0,0 +1,84 @@ +# Installing Troupe + +> **Scope:** how to obtain dependencies and build Troupe for the first time. For build, test, and +> run commands once installed, see [DEVELOPMENT.md](DEVELOPMENT.md). + +## Troupe development container + +If you want to try out Troupe without manual installation (e.g., for a class exercise or just checking the system), check out the VSCode development container available through the [Troupe/example-project](https://github.com/TroupeLang/example-project) repository. + +## Installation + +Once all dependencies have been installed, the whole project can be built and Troupe installed to the `bin` directory with `make all`. The following shows step-by-step which dependencies are needed for which parts and how to install them. + +### Step 1. Install JS runtime +1. Install NodeJS (e.g. `sudo apt-get install nodejs`) +2. Install js dependencies via `npm install` +3. Set the `TROUPE` environment variable to point to the folder that contains the main README. In bash this is done by adding the following lines to a file such as `~/.bashrc` or `~/.bash_profile`: + ``` + TROUPE= + export TROUPE= + ``` + Read [here](https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux-vps") for more info on environment variables. +6. Install [TypeScript](https://www.typescriptlang.org/): `npm install -g typescript` + - To install to the home directory without root, first run `npm config set prefix ~/.npm` and add `~/.npm/bin` to your PATH +7. Compile Troupe runtime by typing `make rt` + +### Step 2. Install Troupe compiler + +1. Get [Haskell stack](https://www.haskellstack.org). +2. Change to the `compiler` directory and run `make` + +The above make script copies the binary of the compiler into the +bin folder of the project under name `troupec`. That name is then used +by the runtime module. + + +### Step 3. Install Troupe top-level scripts + +Type `make compiler` (in the repository's root) to compile Troupe's bin scripts + +### Step 4. Install Troupe standard library + +Type + +- `make libs` to compile Troupe's built-in libraries, and +- `make service` to compile the service module placeholder. + + +### Step 5. Running the test suite + +#### OS X specific utilities for testing + +On OS X, make sure to have `gtimeout`, `greadlink`, and GNU `diff` utilities. + +- `gtimeout` and `greadlink` can be installed via `brew install coreutils` +- GNU `diff` can be installed via `brew install diffutils` + +The GNU diff is required because Troupe's test suite relies on specific diff features not available in the default macOS diff. After installation, verify that GNU diff is available: + +```bash +diff --version +``` + +Expected output: +``` +diff (GNU diffutils) 3.10 +Copyright (C) 2023 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later . +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Written by Paul Eggert, Mike Haertel, David Hayes, +Richard Stallman, and Len Tower. +``` + +#### Checking the installation + +Check that the installation works by running the local test suite: `$TROUPE/bin/golden` +(alternatively `make test` in this directory). + +#### Multinode tests + +Multinode tests are located in `tests/rt/multinode-tests/` and can be run using the script: +`scripts/run-multinode-tests.sh` diff --git a/docs/NETWORKING.md b/docs/NETWORKING.md new file mode 100644 index 00000000..8dbf2b6d --- /dev/null +++ b/docs/NETWORKING.md @@ -0,0 +1,60 @@ +# Networking + +> **Scope:** the P2P runtime — how nodes connect, identity and IDs, libp2p relaying, node discovery, +> and known stability caveats. For running programs locally without networking see +> [DEVELOPMENT.md](DEVELOPMENT.md); for the runtime architecture see [ARCHITECTURE.md](ARCHITECTURE.md). + +When the program starts, once the keys are loaded (or generated), the runtime starts by connecting to +a number of nodes to bootstrap its discovery. Note that this process takes a human-observable time. + + +## Local only mode +To skip network connection, one can provide `--localonly` flag to the runtime, but +observe that in this case all external I/O will result +in a runtime error. + + +## Generating new persistent IDs +See [p2p-tools/mkid.mts](../p2p-tools/mkid.mts). + +## Auto-created IDs + +If the id file is omitted, a new id (via a fresh key/pair) is generated upon +start. Observe that this induces a bigger runtime overhead than loading a key pair +from a file. + +## Stability issues and patches. + +Libp2p is a fast-moving project, and there are stability issues. We +apply local patches to work around these issues (hence the patch application in the installation of JS runtime), but this should be used on a temporary +basis only and removed once the actual bugs are fixed (either in the official + packages or in our codebase). + + +## Notes on the p2p runtime + +The p2p runtime is implemented using [libp2p](https://libp2p.io/) library (part of IPFS project). This +means that nodes at runtime are now libp2p nodes. We inherit from libp2p that every node has an +associated pair of public/private keys, and an id of the node is the hash of its +public key. + +We use libp2p's functionality of relaying messages. This means that programs or +processes running behind NAT (e.g., something running on a developer laptop) are +accessible from the outside. + + +## Navigating the code base + +The main p2p runtime module is in [rt/src/p2p/p2p.ts](../rt/src/p2p/p2p.ts). + + +## How node discovery works + +Peer discovery uses three mechanisms (`rt/src/p2p/p2p.mts`): + +- **bootstrap** — connecting to the public libp2p bootstrap nodes listed in `p2p.mts` +- **mDNS** — discovering peers on the local network +- **kad-DHT** — the Kademlia distributed hash table + +All three are disabled in relay-only mode. NAT traversal is handled by circuit relay v2 +(`@libp2p/circuit-relay-v2`): a node behind NAT is reachable through a relay. From 06ea8b6f230955f22694424658123b342ffe48de Mon Sep 17 00:00:00 2001 From: Aslan Askarov Date: Mon, 1 Jun 2026 10:39:54 +0200 Subject: [PATCH 12/12] chore: migrate to TypeScript 6.0 Bump typescript ^5.8.3 -> ^6.0.3 in root and notebook. Add explicit rootDir to notebook/tsconfig.json (TS6 now requires it for emit, TS5011). Config-only; no source changes. rt/p2p-tools/relay build clean, notebook builds clean, all 890 golden tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) --- notebook/package-lock.json | 8 ++++---- notebook/package.json | 2 +- notebook/tsconfig.json | 1 + package-lock.json | 8 ++++---- package.json | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/notebook/package-lock.json b/notebook/package-lock.json index b0d22fb6..0f4160c6 100644 --- a/notebook/package-lock.json +++ b/notebook/package-lock.json @@ -22,7 +22,7 @@ "@types/express": "^4.17.21", "@types/ws": "^8.18.1", "esbuild": "^0.27.3", - "typescript": "^5.8.3" + "typescript": "^6.0.3" } }, "node_modules/@codemirror/autocomplete": { @@ -1615,9 +1615,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/notebook/package.json b/notebook/package.json index a0384a4d..5908245e 100644 --- a/notebook/package.json +++ b/notebook/package.json @@ -22,6 +22,6 @@ "@types/express": "^4.17.21", "@types/ws": "^8.18.1", "esbuild": "^0.27.3", - "typescript": "^5.8.3" + "typescript": "^6.0.3" } } diff --git a/notebook/tsconfig.json b/notebook/tsconfig.json index dc66b268..b724d846 100644 --- a/notebook/tsconfig.json +++ b/notebook/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "outDir": "./built", + "rootDir": "./src", "moduleResolution": "node16", "module": "Node16", "target": "ES2022", diff --git a/package-lock.json b/package-lock.json index 2be8db18..42560402 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@types/yargs": "^17.0.33", "rollup": "^4.41.0", "source-map": "^0.7.6", - "typescript": "^5.8.3" + "typescript": "^6.0.3" } }, "node_modules/@chainsafe/as-chacha20poly1305": { @@ -2832,9 +2832,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 78e189f4..1b8d799e 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,6 @@ "@types/yargs": "^17.0.33", "rollup": "^4.41.0", "source-map": "^0.7.6", - "typescript": "^5.8.3" + "typescript": "^6.0.3" } }