@noopolis/daimon 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +307 -45
- package/dist/contracts/attentionContract.d.ts +117 -0
- package/dist/contracts/attentionContract.d.ts.map +1 -0
- package/dist/contracts/attentionContract.js +14 -0
- package/dist/contracts/canonicalJson.d.ts +3 -0
- package/dist/contracts/canonicalJson.d.ts.map +1 -0
- package/dist/contracts/canonicalJson.js +54 -0
- package/dist/contracts/grokWorkerContract.d.ts +74 -0
- package/dist/contracts/grokWorkerContract.d.ts.map +1 -0
- package/dist/contracts/grokWorkerContract.js +88 -0
- package/dist/contracts/organizationRuntimeContract.d.ts +765 -0
- package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -0
- package/dist/contracts/organizationRuntimeContract.js +121 -0
- package/dist/contracts/runtimeContractManifest.d.ts +1615 -0
- package/dist/contracts/runtimeContractManifest.d.ts.map +1 -0
- package/dist/contracts/runtimeContractManifest.js +181 -0
- package/dist/core/credentialRedaction.d.ts +4 -0
- package/dist/core/credentialRedaction.d.ts.map +1 -0
- package/dist/core/credentialRedaction.js +28 -0
- package/dist/core/siblingBuildFreshness.d.ts +21 -0
- package/dist/core/siblingBuildFreshness.d.ts.map +1 -0
- package/dist/core/siblingBuildFreshness.js +25 -0
- package/dist/core/types.d.ts +10 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/examples/exampleCausalId.d.ts +3 -0
- package/dist/examples/exampleCausalId.d.ts.map +1 -0
- package/dist/examples/exampleCausalId.js +8 -0
- package/dist/examples/jungian-play-org.js +3 -2
- package/dist/examples/jungian-triad-org.js +3 -2
- package/dist/examples/jungianPlayAgent.d.ts +1 -1
- package/dist/examples/jungianPlayAgent.d.ts.map +1 -1
- package/dist/examples/jungianPlayAgent.js +1 -1
- package/dist/examples/jungianProfiles.d.ts +1 -1
- package/dist/examples/jungianProfiles.d.ts.map +1 -1
- package/dist/examples/jungianTriadProfiles.d.ts +1 -1
- package/dist/examples/jungianTriadProfiles.d.ts.map +1 -1
- package/dist/examples/pi-agent.js +3 -2
- package/dist/examples/pi-memory-org.js +6 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/mcp/toolServer.d.ts +31 -0
- package/dist/mcp/toolServer.d.ts.map +1 -0
- package/dist/mcp/toolServer.js +145 -0
- package/dist/observability/causalEvents.d.ts +118 -0
- package/dist/observability/causalEvents.d.ts.map +1 -0
- package/dist/observability/causalEvents.js +223 -0
- package/dist/observability/controlCausal.d.ts +117 -0
- package/dist/observability/controlCausal.d.ts.map +1 -0
- package/dist/observability/controlCausal.js +107 -0
- package/dist/observability/emitCausalFixture.d.ts +25 -0
- package/dist/observability/emitCausalFixture.d.ts.map +1 -0
- package/dist/observability/emitCausalFixture.js +98 -0
- package/dist/observability/index.d.ts +2 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +2 -0
- package/dist/observability/orgObserver.d.ts.map +1 -1
- package/dist/observability/orgObserver.js +3 -3
- package/dist/pi/agyHeadlessResult.d.ts +60 -0
- package/dist/pi/agyHeadlessResult.d.ts.map +1 -0
- package/dist/pi/agyHeadlessResult.js +95 -0
- package/dist/pi/cliChildOutput.d.ts +67 -0
- package/dist/pi/cliChildOutput.d.ts.map +1 -0
- package/dist/pi/cliChildOutput.js +269 -0
- package/dist/pi/cliEngineRun.d.ts +16 -0
- package/dist/pi/cliEngineRun.d.ts.map +1 -0
- package/dist/pi/cliEngineRun.js +27 -0
- package/dist/pi/cliEngineSpawn.d.ts +55 -0
- package/dist/pi/cliEngineSpawn.d.ts.map +1 -0
- package/dist/pi/cliEngineSpawn.js +164 -0
- package/dist/pi/cliEnvironment.d.ts +12 -0
- package/dist/pi/cliEnvironment.d.ts.map +1 -0
- package/dist/pi/cliEnvironment.js +32 -0
- package/dist/pi/cliMcpRegistration.d.ts +61 -0
- package/dist/pi/cliMcpRegistration.d.ts.map +1 -0
- package/dist/pi/cliMcpRegistration.js +75 -0
- package/dist/pi/cliProcess.d.ts +7 -0
- package/dist/pi/cliProcess.d.ts.map +1 -0
- package/dist/pi/cliProcess.js +132 -0
- package/dist/pi/cliSession.d.ts +106 -0
- package/dist/pi/cliSession.d.ts.map +1 -0
- package/dist/pi/cliSession.js +379 -0
- package/dist/pi/cliTurnMetering.d.ts +60 -0
- package/dist/pi/cliTurnMetering.d.ts.map +1 -0
- package/dist/pi/cliTurnMetering.js +60 -0
- package/dist/pi/codexFilesystemRules.d.ts +3 -0
- package/dist/pi/codexFilesystemRules.d.ts.map +1 -0
- package/dist/pi/codexFilesystemRules.js +28 -0
- package/dist/pi/codexHeadlessResult.d.ts +68 -0
- package/dist/pi/codexHeadlessResult.d.ts.map +1 -0
- package/dist/pi/codexHeadlessResult.js +122 -0
- package/dist/pi/codexRolloutUsage.d.ts +95 -0
- package/dist/pi/codexRolloutUsage.d.ts.map +1 -0
- package/dist/pi/codexRolloutUsage.js +221 -0
- package/dist/pi/engineWakeLimits.d.ts +39 -0
- package/dist/pi/engineWakeLimits.d.ts.map +1 -0
- package/dist/pi/engineWakeLimits.js +55 -0
- package/dist/pi/grokHeadlessResult.d.ts +36 -0
- package/dist/pi/grokHeadlessResult.d.ts.map +1 -0
- package/dist/pi/grokHeadlessResult.js +118 -0
- package/dist/pi/grokHomeMcpRegistration.d.ts +21 -0
- package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -0
- package/dist/pi/grokHomeMcpRegistration.js +57 -0
- package/dist/pi/grokSandbox.d.ts +11 -0
- package/dist/pi/grokSandbox.d.ts.map +1 -0
- package/dist/pi/grokSandbox.js +216 -0
- package/dist/pi/grokStreamUsage.d.ts +31 -0
- package/dist/pi/grokStreamUsage.d.ts.map +1 -0
- package/dist/pi/grokStreamUsage.js +51 -0
- package/dist/pi/index.d.ts +5 -0
- package/dist/pi/index.d.ts.map +1 -1
- package/dist/pi/index.js +5 -0
- package/dist/pi/memoryTools.d.ts +55 -1
- package/dist/pi/memoryTools.d.ts.map +1 -1
- package/dist/pi/memoryTools.js +144 -24
- package/dist/pi/modelRegistry.d.ts +13 -0
- package/dist/pi/modelRegistry.d.ts.map +1 -0
- package/dist/pi/modelRegistry.js +19 -0
- package/dist/pi/piAgentHandle.d.ts +46 -0
- package/dist/pi/piAgentHandle.d.ts.map +1 -0
- package/dist/pi/piAgentHandle.js +351 -0
- package/dist/pi/piAgentWakeSupport.d.ts +103 -0
- package/dist/pi/piAgentWakeSupport.d.ts.map +1 -0
- package/dist/pi/piAgentWakeSupport.js +151 -0
- package/dist/pi/piHarness.d.ts +40 -5
- package/dist/pi/piHarness.d.ts.map +1 -1
- package/dist/pi/piHarness.js +151 -256
- package/dist/pi/prompts.d.ts +10 -0
- package/dist/pi/prompts.d.ts.map +1 -0
- package/dist/pi/prompts.js +63 -0
- package/dist/pi/rawTrainingCapture.d.ts +59 -0
- package/dist/pi/rawTrainingCapture.d.ts.map +1 -0
- package/dist/pi/rawTrainingCapture.js +175 -0
- package/dist/pi/turnCausal.d.ts +73 -0
- package/dist/pi/turnCausal.d.ts.map +1 -0
- package/dist/pi/turnCausal.js +75 -0
- package/dist/pi/turnTrace.d.ts +128 -0
- package/dist/pi/turnTrace.d.ts.map +1 -0
- package/dist/pi/turnTrace.js +138 -0
- package/dist/pi/wakeAcceptance.d.ts +49 -0
- package/dist/pi/wakeAcceptance.d.ts.map +1 -0
- package/dist/pi/wakeAcceptance.js +281 -0
- package/dist/pi/wakeAcceptanceFs.d.ts +44 -0
- package/dist/pi/wakeAcceptanceFs.d.ts.map +1 -0
- package/dist/pi/wakeAcceptanceFs.js +318 -0
- package/dist/pi/wakeAcceptanceSchema.d.ts +75 -0
- package/dist/pi/wakeAcceptanceSchema.d.ts.map +1 -0
- package/dist/pi/wakeAcceptanceSchema.js +265 -0
- package/dist/pi/wakeModes.d.ts +9 -0
- package/dist/pi/wakeModes.d.ts.map +1 -0
- package/dist/pi/wakeModes.js +19 -0
- package/dist/pi/worldNudge.d.ts +22 -0
- package/dist/pi/worldNudge.d.ts.map +1 -0
- package/dist/pi/worldNudge.js +62 -0
- package/dist/pi/worldToolProtocol.d.ts +13 -0
- package/dist/pi/worldToolProtocol.d.ts.map +1 -0
- package/dist/pi/worldToolProtocol.js +49 -0
- package/dist/pi/worldTools.d.ts +32 -0
- package/dist/pi/worldTools.d.ts.map +1 -0
- package/dist/pi/worldTools.js +373 -0
- package/dist/pi/worldTrajectory.d.ts +52 -0
- package/dist/pi/worldTrajectory.d.ts.map +1 -0
- package/dist/pi/worldTrajectory.js +131 -0
- package/dist/runtime/agySubscriptionBootstrap.d.ts +16 -0
- package/dist/runtime/agySubscriptionBootstrap.d.ts.map +1 -0
- package/dist/runtime/agySubscriptionBootstrap.js +80 -0
- package/dist/runtime/agySubscriptionRealm.d.ts +38 -0
- package/dist/runtime/agySubscriptionRealm.d.ts.map +1 -0
- package/dist/runtime/agySubscriptionRealm.js +242 -0
- package/dist/runtime/attention.d.ts +21 -0
- package/dist/runtime/attention.d.ts.map +1 -0
- package/dist/runtime/attention.js +36 -0
- package/dist/runtime/attentionDispatcher.d.ts +66 -0
- package/dist/runtime/attentionDispatcher.d.ts.map +1 -0
- package/dist/runtime/attentionDispatcher.js +271 -0
- package/dist/runtime/cli.d.ts +7 -0
- package/dist/runtime/cli.d.ts.map +1 -0
- package/dist/runtime/cli.js +251 -0
- package/dist/runtime/codexSandboxProjection.d.ts +17 -0
- package/dist/runtime/codexSandboxProjection.d.ts.map +1 -0
- package/dist/runtime/codexSandboxProjection.js +40 -0
- package/dist/runtime/contract-manifest.json +1 -0
- package/dist/runtime/contract-manifest.sha256 +1 -0
- package/dist/runtime/contractManifest.d.ts +8 -0
- package/dist/runtime/contractManifest.d.ts.map +1 -0
- package/dist/runtime/contractManifest.js +4 -0
- package/dist/runtime/engineBrokerCapabilities.d.ts +30 -0
- package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -0
- package/dist/runtime/engineBrokerCapabilities.js +59 -0
- package/dist/runtime/engineBrokerControlClient.d.ts +44 -0
- package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -0
- package/dist/runtime/engineBrokerControlClient.js +132 -0
- package/dist/runtime/engineBrokerCredentialJournal.d.ts +10 -0
- package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -0
- package/dist/runtime/engineBrokerCredentialJournal.js +17 -0
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts +52 -0
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -0
- package/dist/runtime/engineBrokerInferenceProtocol.js +65 -0
- package/dist/runtime/engineBrokerMcpCallLog.d.ts +160 -0
- package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -0
- package/dist/runtime/engineBrokerMcpCallLog.js +219 -0
- package/dist/runtime/engineBrokerMcpFacade.d.ts +56 -0
- package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -0
- package/dist/runtime/engineBrokerMcpFacade.js +343 -0
- package/dist/runtime/engineBrokerNativeClient.d.ts +52 -0
- package/dist/runtime/engineBrokerNativeClient.d.ts.map +1 -0
- package/dist/runtime/engineBrokerNativeClient.js +151 -0
- package/dist/runtime/engineBrokerProtocol.d.ts +135 -0
- package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -0
- package/dist/runtime/engineBrokerProtocol.js +274 -0
- package/dist/runtime/engineBrokerSealLedger.d.ts +70 -0
- package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -0
- package/dist/runtime/engineBrokerSealLedger.js +123 -0
- package/dist/runtime/engineBrokerService.d.ts +37 -0
- package/dist/runtime/engineBrokerService.d.ts.map +1 -0
- package/dist/runtime/engineBrokerService.js +138 -0
- package/dist/runtime/engineBrokerServiceCli.d.ts +5 -0
- package/dist/runtime/engineBrokerServiceCli.d.ts.map +1 -0
- package/dist/runtime/engineBrokerServiceCli.js +32 -0
- package/dist/runtime/engineBrokerServiceConfig.d.ts +50 -0
- package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -0
- package/dist/runtime/engineBrokerServiceConfig.js +92 -0
- package/dist/runtime/engineBrokerSingleflight.d.ts +13 -0
- package/dist/runtime/engineBrokerSingleflight.d.ts.map +1 -0
- package/dist/runtime/engineBrokerSingleflight.js +24 -0
- package/dist/runtime/engineBrokerTurnAccounting.d.ts +76 -0
- package/dist/runtime/engineBrokerTurnAccounting.d.ts.map +1 -0
- package/dist/runtime/engineBrokerTurnAccounting.js +108 -0
- package/dist/runtime/engineBrokerTurnRegistry.d.ts +57 -0
- package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -0
- package/dist/runtime/engineBrokerTurnRegistry.js +158 -0
- package/dist/runtime/engineDispatcher.d.ts +36 -0
- package/dist/runtime/engineDispatcher.d.ts.map +1 -0
- package/dist/runtime/engineDispatcher.js +216 -0
- package/dist/runtime/engineReadiness.d.ts +23 -0
- package/dist/runtime/engineReadiness.d.ts.map +1 -0
- package/dist/runtime/engineReadiness.js +222 -0
- package/dist/runtime/grokAuthenticationError.d.ts +8 -0
- package/dist/runtime/grokAuthenticationError.d.ts.map +1 -0
- package/dist/runtime/grokAuthenticationError.js +20 -0
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts +22 -0
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -0
- package/dist/runtime/grokBrokerCredentialAuthority.js +124 -0
- package/dist/runtime/grokBrokerCredentialReader.d.ts +5 -0
- package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -0
- package/dist/runtime/grokBrokerCredentialReader.js +37 -0
- package/dist/runtime/grokBrokerModelPolicy.d.ts +23 -0
- package/dist/runtime/grokBrokerModelPolicy.d.ts.map +1 -0
- package/dist/runtime/grokBrokerModelPolicy.js +28 -0
- package/dist/runtime/grokBrokerProjection.d.ts +106 -0
- package/dist/runtime/grokBrokerProjection.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProjection.js +94 -0
- package/dist/runtime/grokBrokerProxy.d.ts +55 -0
- package/dist/runtime/grokBrokerProxy.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProxy.js +262 -0
- package/dist/runtime/grokBrokerProxyRequest.d.ts +30 -0
- package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProxyRequest.js +74 -0
- package/dist/runtime/grokBrokerRealmLease.d.ts +4 -0
- package/dist/runtime/grokBrokerRealmLease.d.ts.map +1 -0
- package/dist/runtime/grokBrokerRealmLease.js +33 -0
- package/dist/runtime/grokBrokerRefresh.d.ts +2 -0
- package/dist/runtime/grokBrokerRefresh.d.ts.map +1 -0
- package/dist/runtime/grokBrokerRefresh.js +15 -0
- package/dist/runtime/grokBrokerTurnMeter.d.ts +128 -0
- package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -0
- package/dist/runtime/grokBrokerTurnMeter.js +251 -0
- package/dist/runtime/grokBrokerWorkerConfig.d.ts +86 -0
- package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -0
- package/dist/runtime/grokBrokerWorkerConfig.js +135 -0
- package/dist/runtime/grokEngineBroker.d.ts +48 -0
- package/dist/runtime/grokEngineBroker.d.ts.map +1 -0
- package/dist/runtime/grokEngineBroker.js +114 -0
- package/dist/runtime/grokEngineBrokerLedger.d.ts +52 -0
- package/dist/runtime/grokEngineBrokerLedger.d.ts.map +1 -0
- package/dist/runtime/grokEngineBrokerLedger.js +114 -0
- package/dist/runtime/grokEngineBrokerMetering.d.ts +51 -0
- package/dist/runtime/grokEngineBrokerMetering.d.ts.map +1 -0
- package/dist/runtime/grokEngineBrokerMetering.js +34 -0
- package/dist/runtime/grokEngineBrokerTurn.d.ts +58 -0
- package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -0
- package/dist/runtime/grokEngineBrokerTurn.js +165 -0
- package/dist/runtime/grokInferenceClientConfig.d.ts +41 -0
- package/dist/runtime/grokInferenceClientConfig.d.ts.map +1 -0
- package/dist/runtime/grokInferenceClientConfig.js +62 -0
- package/dist/runtime/grokInferenceGrants.d.ts +77 -0
- package/dist/runtime/grokInferenceGrants.d.ts.map +1 -0
- package/dist/runtime/grokInferenceGrants.js +116 -0
- package/dist/runtime/grokInferenceProxy.d.ts +29 -0
- package/dist/runtime/grokInferenceProxy.d.ts.map +1 -0
- package/dist/runtime/grokInferenceProxy.js +82 -0
- package/dist/runtime/grokInferenceProxyRequest.d.ts +23 -0
- package/dist/runtime/grokInferenceProxyRequest.d.ts.map +1 -0
- package/dist/runtime/grokInferenceProxyRequest.js +63 -0
- package/dist/runtime/grokSlotPreflightReceipt.d.ts +70 -0
- package/dist/runtime/grokSlotPreflightReceipt.d.ts.map +1 -0
- package/dist/runtime/grokSlotPreflightReceipt.js +101 -0
- package/dist/runtime/grokSubscriptionRealm.d.ts +4 -0
- package/dist/runtime/grokSubscriptionRealm.d.ts.map +1 -0
- package/dist/runtime/grokSubscriptionRealm.js +435 -0
- package/dist/runtime/grokSubscriptionRealmTypes.d.ts +26 -0
- package/dist/runtime/grokSubscriptionRealmTypes.d.ts.map +1 -0
- package/dist/runtime/grokSubscriptionRealmTypes.js +1 -0
- package/dist/runtime/grokWorkerAttestation.d.ts +170 -0
- package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -0
- package/dist/runtime/grokWorkerAttestation.js +266 -0
- package/dist/runtime/grokWorkerDenyPlacement.d.ts +80 -0
- package/dist/runtime/grokWorkerDenyPlacement.d.ts.map +1 -0
- package/dist/runtime/grokWorkerDenyPlacement.js +128 -0
- package/dist/runtime/grokWorkerHomeAttestation.d.ts +30 -0
- package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -0
- package/dist/runtime/grokWorkerHomeAttestation.js +69 -0
- package/dist/runtime/grokWorkerSandboxProfile.d.ts +27 -0
- package/dist/runtime/grokWorkerSandboxProfile.d.ts.map +1 -0
- package/dist/runtime/grokWorkerSandboxProfile.js +44 -0
- package/dist/runtime/grokWorkerTmpAttestation.d.ts +55 -0
- package/dist/runtime/grokWorkerTmpAttestation.d.ts.map +1 -0
- package/dist/runtime/grokWorkerTmpAttestation.js +63 -0
- package/dist/runtime/index.d.ts +26 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +23 -0
- package/dist/runtime/inferenceUsageLedger.d.ts +38 -0
- package/dist/runtime/inferenceUsageLedger.d.ts.map +1 -0
- package/dist/runtime/inferenceUsageLedger.js +53 -0
- package/dist/runtime/mcpToolResult.d.ts +127 -0
- package/dist/runtime/mcpToolResult.d.ts.map +1 -0
- package/dist/runtime/mcpToolResult.js +214 -0
- package/dist/runtime/moltnetMachineRead.d.ts +97 -0
- package/dist/runtime/moltnetMachineRead.d.ts.map +1 -0
- package/dist/runtime/moltnetMachineRead.js +183 -0
- package/dist/runtime/native/daimon-engine-broker +0 -0
- package/dist/runtime/organizationRuntime.d.ts +165 -0
- package/dist/runtime/organizationRuntime.d.ts.map +1 -0
- package/dist/runtime/organizationRuntime.js +3 -0
- package/dist/runtime/organizationRuntimeControl.d.ts +42 -0
- package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeControl.js +235 -0
- package/dist/runtime/organizationRuntimeHost.d.ts +19 -0
- package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeHost.js +359 -0
- package/dist/runtime/organizationRuntimeParsing.d.ts +6 -0
- package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeParsing.js +370 -0
- package/dist/runtime/organizationRuntimeReadiness.d.ts +12 -0
- package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeReadiness.js +59 -0
- package/dist/runtime/physicalReadiness.d.ts +47 -0
- package/dist/runtime/physicalReadiness.d.ts.map +1 -0
- package/dist/runtime/physicalReadiness.js +142 -0
- package/dist/runtime/portableCredentialAuth.d.ts +6 -0
- package/dist/runtime/portableCredentialAuth.d.ts.map +1 -0
- package/dist/runtime/portableCredentialAuth.js +70 -0
- package/dist/runtime/portableCredentialMaterial.d.ts +8 -0
- package/dist/runtime/portableCredentialMaterial.d.ts.map +1 -0
- package/dist/runtime/portableCredentialMaterial.js +169 -0
- package/dist/runtime/productionAgentTools.d.ts +5 -0
- package/dist/runtime/productionAgentTools.d.ts.map +1 -0
- package/dist/runtime/productionAgentTools.js +328 -0
- package/dist/runtime/runtimeHomeLayout.d.ts +48 -0
- package/dist/runtime/runtimeHomeLayout.d.ts.map +1 -0
- package/dist/runtime/runtimeHomeLayout.js +84 -0
- package/dist/runtime/schedule.d.ts +40 -0
- package/dist/runtime/schedule.d.ts.map +1 -0
- package/dist/runtime/schedule.js +371 -0
- package/dist/runtime/storeCoordination.d.ts +23 -0
- package/dist/runtime/storeCoordination.d.ts.map +1 -0
- package/dist/runtime/storeCoordination.js +94 -0
- package/dist/runtime/toolResultSpill.d.ts +152 -0
- package/dist/runtime/toolResultSpill.d.ts.map +1 -0
- package/dist/runtime/toolResultSpill.js +351 -0
- package/dist/runtime/turnRequestLedger.d.ts +160 -0
- package/dist/runtime/turnRequestLedger.d.ts.map +1 -0
- package/dist/runtime/turnRequestLedger.js +249 -0
- package/dist/runtime/turnUsageLedger.d.ts +143 -0
- package/dist/runtime/turnUsageLedger.d.ts.map +1 -0
- package/dist/runtime/turnUsageLedger.js +203 -0
- package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +17 -0
- package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceProcessIdentity.js +50 -0
- package/dist/runtime/wakeAcceptanceReconciliation.d.ts +211 -0
- package/dist/runtime/wakeAcceptanceReconciliation.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceReconciliation.js +289 -0
- package/dist/runtime/wakeAcceptanceRecord.d.ts +23 -0
- package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceRecord.js +56 -0
- package/dist/runtime/wakeAcceptanceRetention.d.ts +12 -0
- package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceRetention.js +12 -0
- package/dist/runtime/wakeAcceptanceStore.d.ts +113 -0
- package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceStore.js +558 -0
- package/dist/runtime/wakeAcceptanceTypes.d.ts +179 -0
- package/dist/runtime/wakeAcceptanceTypes.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceTypes.js +95 -0
- package/dist/runtime/wakeFuse.d.ts +69 -0
- package/dist/runtime/wakeFuse.d.ts.map +1 -0
- package/dist/runtime/wakeFuse.js +367 -0
- package/package.json +25 -17
- package/dist/examples/mixed-engine-org.d.ts +0 -2
- package/dist/examples/mixed-engine-org.d.ts.map +0 -1
- package/dist/examples/mixed-engine-org.js +0 -351
- package/dist/examples/mixedEngineCli.d.ts +0 -15
- package/dist/examples/mixedEngineCli.d.ts.map +0 -1
- package/dist/examples/mixedEngineCli.js +0 -174
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { GROK_BROKER_MODELS, GROK_BROKER_REASONING_EFFORTS } from "../contracts/grokWorkerContract.js";
|
|
2
|
+
import { parseAttention } from "./attention.js";
|
|
3
|
+
import { ORGANIZATION_RUNTIME_CODEX_REASONING_EFFORTS, ORGANIZATION_RUNTIME_CODEX_WORKSPACE_NO_NETWORK_POLICY, ORGANIZATION_RUNTIME_MAX_AGENTS, ORGANIZATION_RUNTIME_MAX_CONFIG_BYTES, ORGANIZATION_RUNTIME_MAX_INSTRUCTIONS_CODEPOINTS, ORGANIZATION_RUNTIME_MAX_STRING_BYTES, ORGANIZATION_RUNTIME_MAX_STRING_CODEPOINTS, ORGANIZATION_RUNTIME_MAX_WAKE_TEXT_BYTES, ORGANIZATION_RUNTIME_MAX_SCHEDULE_INTERVAL_MS, ORGANIZATION_RUNTIME_MAX_SCHEDULE_JITTER_SECONDS, ORGANIZATION_RUNTIME_V2_VERSION, ORGANIZATION_RUNTIME_VERSION } from "./organizationRuntime.js";
|
|
4
|
+
const ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
5
|
+
const ENGINE_KINDS = new Set(["codex", "grok", "agy"]);
|
|
6
|
+
const CRON_FIELD_BOUNDS = [[0, 59], [0, 23], [1, 31], [1, 12], [0, 7]];
|
|
7
|
+
export function parseOrganizationRuntimeConfig(value) {
|
|
8
|
+
const root = object(snapshot(value, "config"), "config");
|
|
9
|
+
size(root);
|
|
10
|
+
exact(root, ["version", "host", "agents"], "config");
|
|
11
|
+
const version = string(root.version, "config.version");
|
|
12
|
+
if (version !== ORGANIZATION_RUNTIME_VERSION && version !== ORGANIZATION_RUNTIME_V2_VERSION)
|
|
13
|
+
throw new TypeError("config.version is not supported");
|
|
14
|
+
const hostValue = object(root.host, "config.host");
|
|
15
|
+
exact(hostValue, ["bindHost", "port", "controlTokenEnv"], "config.host");
|
|
16
|
+
const host = {
|
|
17
|
+
bindHost: nonEmpty(hostValue.bindHost, "config.host.bindHost"), port: port(hostValue.port, "config.host.port"), controlTokenEnv: envName(hostValue.controlTokenEnv, "config.host.controlTokenEnv")
|
|
18
|
+
};
|
|
19
|
+
const rawAgents = array(root.agents, "config.agents");
|
|
20
|
+
if (rawAgents.length === 0 || rawAgents.length > ORGANIZATION_RUNTIME_MAX_AGENTS)
|
|
21
|
+
throw new TypeError(`config.agents must contain between 1 and ${ORGANIZATION_RUNTIME_MAX_AGENTS} agents`);
|
|
22
|
+
const ids = new Set();
|
|
23
|
+
const agents = rawAgents.map((item, index) => {
|
|
24
|
+
const agent = parseAgent(item, `config.agents[${index}]`, version === ORGANIZATION_RUNTIME_V2_VERSION);
|
|
25
|
+
if (ids.has(agent.id))
|
|
26
|
+
throw new TypeError(`config.agents has duplicate id ${agent.id}`);
|
|
27
|
+
ids.add(agent.id);
|
|
28
|
+
return agent;
|
|
29
|
+
});
|
|
30
|
+
isolated(agents);
|
|
31
|
+
isolatedMemory(agents);
|
|
32
|
+
return { version: version, host, agents };
|
|
33
|
+
}
|
|
34
|
+
export function parseOrganizationRuntimeWakeRequest(value) {
|
|
35
|
+
const request = object(snapshot(value, "wake request"), "wake request");
|
|
36
|
+
exact(request, ["token", "agentId", "event"], "wake request");
|
|
37
|
+
const event = object(request.event, "wake request.event");
|
|
38
|
+
exact(event, ["version", "id", "kind", "text", "occurredAt"], "wake request.event");
|
|
39
|
+
if (string(event.version, "wake request.event.version") !== "noopolis.daimon.wake.v1")
|
|
40
|
+
throw new TypeError("wake request.event.version is not supported");
|
|
41
|
+
const kind = string(event.kind, "wake request.event.kind");
|
|
42
|
+
if (kind !== "manual" && kind !== "message" && kind !== "schedule" && kind !== "external")
|
|
43
|
+
throw new TypeError("wake request.event.kind is not supported");
|
|
44
|
+
const text = string(event.text, "wake request.event.text");
|
|
45
|
+
if (Buffer.byteLength(text, "utf8") > ORGANIZATION_RUNTIME_MAX_WAKE_TEXT_BYTES)
|
|
46
|
+
throw new TypeError("wake request.event.text exceeds the wake text limit");
|
|
47
|
+
return { token: request.token === undefined ? undefined : string(request.token, "wake request.token"), agentId: nonEmpty(request.agentId, "wake request.agentId"), event: { version: "noopolis.daimon.wake.v1", id: nonEmpty(event.id, "wake request.event.id"), kind, text, occurredAt: rfc3339(event.occurredAt) } };
|
|
48
|
+
}
|
|
49
|
+
export function validateOrganizationRuntimeConfig(value) {
|
|
50
|
+
try {
|
|
51
|
+
parseOrganizationRuntimeConfig(value);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export const isOrganizationRuntimeConfig = validateOrganizationRuntimeConfig;
|
|
59
|
+
function parseAgent(value, label, v2) {
|
|
60
|
+
const agent = object(value, label);
|
|
61
|
+
exactOptional(agent, v2 ? ["id", "name", "instructions", "workspacePath", "runtimeHomePath", "engine", "schedule"] : ["id", "name", "instructions", "workspacePath", "runtimeHomePath", "engine"], ["mcp", "moltnet", "memory", "attention"], label);
|
|
62
|
+
return {
|
|
63
|
+
id: nonEmpty(agent.id, `${label}.id`), name: nonEmpty(agent.name, `${label}.name`), instructions: nonEmpty(agent.instructions, `${label}.instructions`, ORGANIZATION_RUNTIME_MAX_INSTRUCTIONS_CODEPOINTS), workspacePath: absolute(agent.workspacePath, `${label}.workspacePath`), runtimeHomePath: absolute(agent.runtimeHomePath, `${label}.runtimeHomePath`), engine: engine(agent.engine, `${label}.engine`),
|
|
64
|
+
...(agent.attention === undefined ? {} : { attention: parseAttention(agent.attention) }),
|
|
65
|
+
...(v2 ? { schedule: schedule(agent.schedule, `${label}.schedule`) } : {}),
|
|
66
|
+
...(agent.mcp === undefined ? {} : { mcp: mcpServers(agent.mcp, `${label}.mcp`) }),
|
|
67
|
+
...(agent.moltnet === undefined ? {} : { moltnet: moltnet(agent.moltnet, `${label}.moltnet`) }),
|
|
68
|
+
...(agent.memory === undefined ? {} : { memory: memory(agent.memory, `${label}.memory`) })
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function mcpServers(value, label) {
|
|
72
|
+
const rows = array(value, label);
|
|
73
|
+
if (rows.length > 8)
|
|
74
|
+
throw new TypeError(`${label} exceeds server limit`);
|
|
75
|
+
const names = new Set();
|
|
76
|
+
return rows.map((value, index) => {
|
|
77
|
+
const item = object(value, `${label}[${index}]`);
|
|
78
|
+
exactOptional(item, ["name", "transport", "args", "env", "tools"], ["command", "url", "authSecretEnv"], `${label}[${index}]`);
|
|
79
|
+
const name = nonEmpty(item.name, `${label}[${index}].name`);
|
|
80
|
+
if (names.has(name))
|
|
81
|
+
throw new TypeError(`${label} has duplicate name`);
|
|
82
|
+
names.add(name);
|
|
83
|
+
const transport = string(item.transport, `${label}[${index}].transport`);
|
|
84
|
+
if (!["stdio", "sse", "streamable_http"].includes(transport))
|
|
85
|
+
throw new TypeError(`${label} transport is invalid`);
|
|
86
|
+
const args = array(item.args, `${label}[${index}].args`).map((entry) => string(entry, `${label}.args`));
|
|
87
|
+
if (args.length > 32)
|
|
88
|
+
throw new TypeError(`${label} args exceed limit`);
|
|
89
|
+
const envInput = object(item.env, `${label}[${index}].env`);
|
|
90
|
+
const env = Object.fromEntries(Object.entries(envInput).map(([key, entry]) => [envName(key, `${label}.env key`), string(entry, `${label}.env.${key}`)]));
|
|
91
|
+
const tools = array(item.tools, `${label}[${index}].tools`).map((entry) => nonEmpty(entry, `${label}.tools`));
|
|
92
|
+
if (tools.length === 0 || tools.length > 32 || new Set(tools).size !== tools.length)
|
|
93
|
+
throw new TypeError(`${label} tools are invalid`);
|
|
94
|
+
const command = item.command === undefined ? undefined : absolute(item.command, `${label}.command`);
|
|
95
|
+
const url = item.url === undefined ? undefined : nonEmpty(item.url, `${label}.url`);
|
|
96
|
+
if ((transport === "stdio") !== (command !== undefined) || (transport === "stdio") === (url !== undefined))
|
|
97
|
+
throw new TypeError(`${label} endpoint is invalid`);
|
|
98
|
+
if (url !== undefined) {
|
|
99
|
+
const parsed = new URL(url);
|
|
100
|
+
if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && ["127.0.0.1", "localhost"].includes(parsed.hostname)))
|
|
101
|
+
throw new TypeError(`${label}.url must be HTTPS or loopback HTTP`);
|
|
102
|
+
}
|
|
103
|
+
return { name, transport: transport, args, env, tools, ...(command ? { command } : {}), ...(url ? { url } : {}), ...(item.authSecretEnv === undefined ? {} : { authSecretEnv: envName(item.authSecretEnv, `${label}.authSecretEnv`) }) };
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function moltnet(value, label) {
|
|
107
|
+
const item = object(value, label);
|
|
108
|
+
exact(item, ["cliPath", "configPath", "networks"], label);
|
|
109
|
+
const networks = array(item.networks, `${label}.networks`).map((value, index) => { const row = object(value, `${label}.networks[${index}]`); exact(row, ["id", "rooms", "dms"], `${label}.networks[${index}]`); return { id: nonEmpty(row.id, `${label}.id`), rooms: array(row.rooms, `${label}.rooms`).map((room) => nonEmpty(room, `${label}.room`)), dms: row.dms === true }; });
|
|
110
|
+
if (networks.length > 16 || new Set(networks.map((entry) => entry.id)).size !== networks.length)
|
|
111
|
+
throw new TypeError(`${label}.networks are invalid`);
|
|
112
|
+
return { cliPath: absolute(item.cliPath, `${label}.cliPath`), configPath: absolute(item.configPath, `${label}.configPath`), networks };
|
|
113
|
+
}
|
|
114
|
+
function memory(value, label) {
|
|
115
|
+
const item = object(value, label);
|
|
116
|
+
exactOptional(item, ["runtimeHomePath"], ["source", "tokenBudget"], label);
|
|
117
|
+
return {
|
|
118
|
+
runtimeHomePath: absolute(item.runtimeHomePath, `${label}.runtimeHomePath`),
|
|
119
|
+
...(item.source === undefined ? {} : { source: nonEmpty(item.source, `${label}.source`) }),
|
|
120
|
+
...(item.tokenBudget === undefined ? {} : { tokenBudget: tokenBudget(item.tokenBudget, `${label}.tokenBudget`) })
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function tokenBudget(value, label) {
|
|
124
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1 || value > 1_000_000)
|
|
125
|
+
throw new TypeError(`${label} must be an integer between 1 and 1000000`);
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
function schedule(value, label) {
|
|
129
|
+
const input = object(value, label);
|
|
130
|
+
const kind = string(input.kind, `${label}.kind`);
|
|
131
|
+
if (kind === "disabled") {
|
|
132
|
+
exact(input, ["kind"], label);
|
|
133
|
+
return { kind };
|
|
134
|
+
}
|
|
135
|
+
if (kind === "every") {
|
|
136
|
+
exactOptional(input, ["kind", "interval_ms", "prompt"], ["jitter_seconds"], label);
|
|
137
|
+
if (typeof input.interval_ms !== "number" || !Number.isInteger(input.interval_ms) || input.interval_ms < 1 || input.interval_ms > ORGANIZATION_RUNTIME_MAX_SCHEDULE_INTERVAL_MS)
|
|
138
|
+
throw new TypeError(`${label}.interval_ms is outside its bound`);
|
|
139
|
+
return { kind, interval_ms: input.interval_ms, prompt: nonEmpty(input.prompt, `${label}.prompt`), ...jitterSeconds(input.jitter_seconds, label) };
|
|
140
|
+
}
|
|
141
|
+
if (kind === "cron") {
|
|
142
|
+
exactOptional(input, ["kind", "cron", "timezone", "prompt"], ["jitter_seconds"], label);
|
|
143
|
+
const cron = nonEmpty(input.cron, `${label}.cron`).trim().replace(/\s+/gu, " ");
|
|
144
|
+
if (!validCron(cron) || !cronCalendarPossible(cron))
|
|
145
|
+
throw new TypeError(`${label}.cron is invalid or impossible`);
|
|
146
|
+
const timezone = nonEmpty(input.timezone, `${label}.timezone`);
|
|
147
|
+
try {
|
|
148
|
+
new Intl.DateTimeFormat("en-US", { timeZone: timezone });
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
throw new TypeError(`${label}.timezone is not an IANA timezone`);
|
|
152
|
+
}
|
|
153
|
+
return { kind, cron, timezone, prompt: nonEmpty(input.prompt, `${label}.prompt`), ...jitterSeconds(input.jitter_seconds, label) };
|
|
154
|
+
}
|
|
155
|
+
throw new TypeError(`${label}.kind is not supported`);
|
|
156
|
+
}
|
|
157
|
+
function jitterSeconds(value, label) {
|
|
158
|
+
if (value === undefined)
|
|
159
|
+
return {};
|
|
160
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > ORGANIZATION_RUNTIME_MAX_SCHEDULE_JITTER_SECONDS)
|
|
161
|
+
throw new TypeError(`${label}.jitter_seconds is outside its bound`);
|
|
162
|
+
return { jitter_seconds: value };
|
|
163
|
+
}
|
|
164
|
+
function validCron(value) {
|
|
165
|
+
const fields = value.split(/\s+/u);
|
|
166
|
+
return fields.length === 5 && fields.every((field, index) => validCronField(field, CRON_FIELD_BOUNDS[index]));
|
|
167
|
+
}
|
|
168
|
+
function validCronField(field, [minimum, maximum]) {
|
|
169
|
+
return field.split(",").every((part) => {
|
|
170
|
+
const pieces = part.split("/");
|
|
171
|
+
const step = Number(pieces[1] ?? 1);
|
|
172
|
+
if (pieces.length > 2 || !pieces[0] || (pieces[1] !== undefined && !/^\d+$/u.test(pieces[1])) || !Number.isSafeInteger(step) || step < 1)
|
|
173
|
+
return false;
|
|
174
|
+
const range = pieces[0];
|
|
175
|
+
if (range === "*")
|
|
176
|
+
return true;
|
|
177
|
+
const bounds = range.split("-");
|
|
178
|
+
if (bounds.length > 2 || !bounds.every((bound) => /^\d+$/u.test(bound)))
|
|
179
|
+
return false;
|
|
180
|
+
const first = Number(bounds[0]);
|
|
181
|
+
const last = Number(bounds[1] ?? bounds[0]);
|
|
182
|
+
return first >= minimum && last <= maximum && first <= last;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function cronCalendarPossible(cron) {
|
|
186
|
+
const fields = cron.split(/\s+/u).map((field, index) => cronValues(field, CRON_FIELD_BOUNDS[index]));
|
|
187
|
+
for (let year = 2000; year < 2400; year += 1)
|
|
188
|
+
for (const month of fields[3]) {
|
|
189
|
+
const days = new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
190
|
+
for (const day of fields[2])
|
|
191
|
+
if (day <= days && fields[4].includes(new Date(Date.UTC(year, month - 1, day)).getUTCDay()))
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
function cronValues(field, [minimum, maximum]) {
|
|
197
|
+
const result = new Set();
|
|
198
|
+
for (const part of field.split(",")) {
|
|
199
|
+
const [range, rawStep] = part.split("/");
|
|
200
|
+
const step = Number(rawStep ?? 1);
|
|
201
|
+
const bounds = range === "*" ? [minimum, maximum] : range.split("-").map(Number);
|
|
202
|
+
for (let value = bounds[0]; value <= (bounds[1] ?? bounds[0]); value += step)
|
|
203
|
+
result.add(value === 7 && maximum === 7 ? 0 : value);
|
|
204
|
+
}
|
|
205
|
+
return [...result];
|
|
206
|
+
}
|
|
207
|
+
function engine(value, label) {
|
|
208
|
+
const input = object(value, label);
|
|
209
|
+
const kind = string(input.kind, `${label}.kind`);
|
|
210
|
+
if (!ENGINE_KINDS.has(kind))
|
|
211
|
+
throw new TypeError(`${label}.kind is not a supported engine`);
|
|
212
|
+
// `codexSandbox` is codex-only; `model`/`reasoningEffort` are accepted for
|
|
213
|
+
// codex (open model name, Codex effort list) and for grok (closed broker
|
|
214
|
+
// lists, declared together or not at all). agy owns its own model selection.
|
|
215
|
+
const allowed = kind === "codex" ? ["kind", "model", "reasoningEffort", "codexSandbox"] : kind === "grok" ? ["kind", "model", "reasoningEffort"] : ["kind"];
|
|
216
|
+
const extras = Object.keys(input).filter((key) => !allowed.includes(key));
|
|
217
|
+
if (extras.length > 0) {
|
|
218
|
+
if (kind === "agy" && (extras.includes("model") || extras.includes("reasoningEffort") || extras.includes("codexSandbox"))) {
|
|
219
|
+
throw new TypeError(`${label}.model, ${label}.reasoningEffort, and ${label}.codexSandbox are codex-only for agy; its subscription auth, model selection, and sandbox policy are Daimon-owned`);
|
|
220
|
+
}
|
|
221
|
+
if (kind === "grok" && extras.includes("codexSandbox"))
|
|
222
|
+
throw new TypeError(`${label}.codexSandbox is codex-only; the Grok worker sandbox is Daimon-owned`);
|
|
223
|
+
throw new TypeError(`${label} must contain exactly ${allowed.join(", ")}`);
|
|
224
|
+
}
|
|
225
|
+
if (kind === "grok")
|
|
226
|
+
return grokEngine(input, label);
|
|
227
|
+
return {
|
|
228
|
+
kind: kind,
|
|
229
|
+
...(input.model === undefined ? {} : { model: nonEmpty(input.model, `${label}.model`) }),
|
|
230
|
+
...(input.reasoningEffort === undefined ? {} : { reasoningEffort: reasoningEffort(input.reasoningEffort, `${label}.reasoningEffort`) }),
|
|
231
|
+
...(input.codexSandbox === undefined ? {} : { codexSandbox: codexSandbox(input.codexSandbox, `${label}.codexSandbox`) })
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* A Grok model is declared explicitly or not at all: both members from the
|
|
236
|
+
* closed broker lists, never one of them with the other inherited. Omitting
|
|
237
|
+
* both keeps a config parseable by pre-declaration producers; the brokered
|
|
238
|
+
* paths that need a model (`grokBrokerProjection.ts`, `service.json` v2)
|
|
239
|
+
* require it there instead of defaulting it here.
|
|
240
|
+
*/
|
|
241
|
+
function grokEngine(input, label) {
|
|
242
|
+
if ((input.model === undefined) !== (input.reasoningEffort === undefined))
|
|
243
|
+
throw new TypeError(`${label}.model and ${label}.reasoningEffort must be declared together for grok`);
|
|
244
|
+
if (input.model === undefined)
|
|
245
|
+
return { kind: "grok" };
|
|
246
|
+
const model = string(input.model, `${label}.model`), effort = string(input.reasoningEffort, `${label}.reasoningEffort`);
|
|
247
|
+
if (!GROK_BROKER_MODELS.includes(model))
|
|
248
|
+
throw new TypeError(`${label}.model must be one of ${GROK_BROKER_MODELS.join(", ")}`);
|
|
249
|
+
if (!GROK_BROKER_REASONING_EFFORTS.includes(effort))
|
|
250
|
+
throw new TypeError(`${label}.reasoningEffort must be one of ${GROK_BROKER_REASONING_EFFORTS.join(", ")}`);
|
|
251
|
+
return { kind: "grok", model, reasoningEffort: effort };
|
|
252
|
+
}
|
|
253
|
+
function codexSandbox(value, label) {
|
|
254
|
+
const input = object(value, label);
|
|
255
|
+
exact(input, ["mode", "networkAccess", "webSearch"], label);
|
|
256
|
+
if (input.mode !== ORGANIZATION_RUNTIME_CODEX_WORKSPACE_NO_NETWORK_POLICY.mode || input.networkAccess !== false || input.webSearch !== ORGANIZATION_RUNTIME_CODEX_WORKSPACE_NO_NETWORK_POLICY.webSearch) {
|
|
257
|
+
throw new TypeError(`${label} must be workspace-write with network disabled and web search disabled`);
|
|
258
|
+
}
|
|
259
|
+
return ORGANIZATION_RUNTIME_CODEX_WORKSPACE_NO_NETWORK_POLICY;
|
|
260
|
+
}
|
|
261
|
+
function reasoningEffort(value, label) {
|
|
262
|
+
const result = string(value, label);
|
|
263
|
+
if (!ORGANIZATION_RUNTIME_CODEX_REASONING_EFFORTS.includes(result)) {
|
|
264
|
+
throw new TypeError(`${label} must be one of ${ORGANIZATION_RUNTIME_CODEX_REASONING_EFFORTS.join(", ")}`);
|
|
265
|
+
}
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
function snapshot(value, label) {
|
|
269
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
270
|
+
return value;
|
|
271
|
+
if (typeof value === "number") {
|
|
272
|
+
if (!Number.isFinite(value))
|
|
273
|
+
throw new TypeError(`${label} must be JSON data`);
|
|
274
|
+
return value;
|
|
275
|
+
}
|
|
276
|
+
if (typeof value !== "object")
|
|
277
|
+
throw new TypeError(`${label} must be JSON data`);
|
|
278
|
+
if (Array.isArray(value)) {
|
|
279
|
+
const result = [];
|
|
280
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
281
|
+
if (key === "length")
|
|
282
|
+
continue;
|
|
283
|
+
if (typeof key !== "string" || !/^(0|[1-9][0-9]*)$/.test(key))
|
|
284
|
+
throw new TypeError(`${label} must contain only indexed data properties`);
|
|
285
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
286
|
+
if (descriptor === undefined || !descriptor.enumerable || !("value" in descriptor))
|
|
287
|
+
throw new TypeError(`${label}[${String(key)}] must be an enumerable data property`);
|
|
288
|
+
}
|
|
289
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
290
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
291
|
+
if (descriptor === undefined || !("value" in descriptor))
|
|
292
|
+
throw new TypeError(`${label}[${index}] must be a present record`);
|
|
293
|
+
result.push(snapshot(descriptor.value, `${label}[${index}]`));
|
|
294
|
+
}
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
|
|
298
|
+
throw new TypeError(`${label} must be a plain own-properties object`);
|
|
299
|
+
const result = Object.create(null);
|
|
300
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
301
|
+
if (typeof key !== "string")
|
|
302
|
+
throw new TypeError(`${label} must not contain symbol properties`);
|
|
303
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
304
|
+
if (descriptor === undefined || !descriptor.enumerable || !("value" in descriptor))
|
|
305
|
+
throw new TypeError(`${label}.${key} must be an enumerable data property`);
|
|
306
|
+
result[key] = snapshot(descriptor.value, `${label}.${key}`);
|
|
307
|
+
}
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
function object(value, label) {
|
|
311
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
312
|
+
throw new TypeError(`${label} must be an object`);
|
|
313
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)
|
|
314
|
+
throw new TypeError(`${label} must be a plain own-properties object`);
|
|
315
|
+
return value;
|
|
316
|
+
}
|
|
317
|
+
function array(value, label) { if (!Array.isArray(value))
|
|
318
|
+
throw new TypeError(`${label} must be an array`); return value; }
|
|
319
|
+
function exact(value, expected, label) { const extras = Object.keys(value).filter((key) => !expected.includes(key)); const missing = expected.filter((key) => !Object.hasOwn(value, key)); if (extras.length || missing.length)
|
|
320
|
+
throw new TypeError(`${label} must contain exactly ${expected.join(", ")}`); }
|
|
321
|
+
function exactOptional(value, required, optional, label) { const extras = Object.keys(value).filter((key) => !required.includes(key) && !optional.includes(key)); const missing = required.filter((key) => !Object.hasOwn(value, key)); if (extras.length || missing.length)
|
|
322
|
+
throw new TypeError(`${label} has invalid fields`); }
|
|
323
|
+
function isolated(agents) { const paths = agents.flatMap((agent) => [{ agentId: agent.id, kind: "workspacePath", value: agent.workspacePath }, { agentId: agent.id, kind: "runtimeHomePath", value: agent.runtimeHomePath }]); for (let left = 0; left < paths.length; left += 1)
|
|
324
|
+
for (let right = left + 1; right < paths.length; right += 1) {
|
|
325
|
+
const first = paths[left];
|
|
326
|
+
const second = paths[right];
|
|
327
|
+
if (first.value === second.value || first.value.startsWith(`${second.value}/`) || second.value.startsWith(`${first.value}/`))
|
|
328
|
+
throw new TypeError(`agents ${first.agentId}.${first.kind} and ${second.agentId}.${second.kind} must not overlap`);
|
|
329
|
+
} }
|
|
330
|
+
/**
|
|
331
|
+
* A declared bank may sit inside its own agent's runtime home, or be shared
|
|
332
|
+
* verbatim by another agent's declared bank; it must never reach into another
|
|
333
|
+
* agent's private roots, and it must never sit inside its own agent's
|
|
334
|
+
* model-writable workspace (the bash tool's cwd), which would let the sandboxed
|
|
335
|
+
* model tamper with its own ledger and bypass Mneme's policy layer entirely.
|
|
336
|
+
*/
|
|
337
|
+
function isolatedMemory(agents) {
|
|
338
|
+
for (const agent of agents) {
|
|
339
|
+
if (agent.memory === undefined)
|
|
340
|
+
continue;
|
|
341
|
+
const value = agent.memory.runtimeHomePath;
|
|
342
|
+
if (value === agent.workspacePath || value.startsWith(`${agent.workspacePath}/`) || agent.workspacePath.startsWith(`${value}/`))
|
|
343
|
+
throw new TypeError(`agent ${agent.id}.memory.runtimeHomePath and ${agent.id}.workspacePath must not overlap`);
|
|
344
|
+
for (const peer of agents) {
|
|
345
|
+
if (peer.id === agent.id)
|
|
346
|
+
continue;
|
|
347
|
+
for (const [kind, peerValue] of [["workspacePath", peer.workspacePath], ["runtimeHomePath", peer.runtimeHomePath]]) {
|
|
348
|
+
if (value === peerValue || value.startsWith(`${peerValue}/`) || peerValue.startsWith(`${value}/`))
|
|
349
|
+
throw new TypeError(`agent ${agent.id}.memory.runtimeHomePath and ${peer.id}.${kind} must not overlap`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function string(value, label, maxCodepoints = ORGANIZATION_RUNTIME_MAX_STRING_CODEPOINTS) { if (typeof value !== "string")
|
|
355
|
+
throw new TypeError(`${label} must be a string`); if (Buffer.byteLength(value, "utf8") > ORGANIZATION_RUNTIME_MAX_STRING_BYTES || Array.from(value).length > maxCodepoints)
|
|
356
|
+
throw new TypeError(`${label} exceeds the runtime string limit`); return value; }
|
|
357
|
+
function nonEmpty(value, label, maxCodepoints) { const result = string(value, label, maxCodepoints); if (!result.trim())
|
|
358
|
+
throw new TypeError(`${label} must not be empty`); return result; }
|
|
359
|
+
function absolute(value, label) { const result = nonEmpty(value, label); if (!path.posix.isAbsolute(result))
|
|
360
|
+
throw new TypeError(`${label} must be an absolute POSIX path`); const normalized = path.posix.normalize(result); if (normalized === "/")
|
|
361
|
+
throw new TypeError(`${label} must not overlap filesystem root`); return normalized.replace(/\/+$/, ""); }
|
|
362
|
+
function envName(value, label) { const result = nonEmpty(value, label); if (!ENV_NAME.test(result))
|
|
363
|
+
throw new TypeError(`${label} must be a safe environment variable name`); return result; }
|
|
364
|
+
function port(value, label) { if (typeof value !== "number" || !Number.isInteger(value) || value < 1 || value > 65_535)
|
|
365
|
+
throw new TypeError(`${label} must be an integer between 1 and 65535`); return value; }
|
|
366
|
+
function size(value) { const serialized = JSON.stringify(value); if (serialized === undefined || Buffer.byteLength(serialized, "utf8") > ORGANIZATION_RUNTIME_MAX_CONFIG_BYTES)
|
|
367
|
+
throw new TypeError("config exceeds the runtime byte limit"); }
|
|
368
|
+
function rfc3339(value) { const result = nonEmpty(value, "wake request.event.occurredAt"); if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(result) || Number.isNaN(Date.parse(result)) || new Date(result).toISOString() !== result)
|
|
369
|
+
throw new TypeError("wake request.event.occurredAt must be an exact RFC3339 timestamp"); return result; }
|
|
370
|
+
import path from "node:path";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type AgySubscriptionRealm } from "./agySubscriptionRealm.js";
|
|
2
|
+
import type { OrganizationRuntimeConfig } from "./organizationRuntime.js";
|
|
3
|
+
import { type OrganizationRuntimePathAuthority } from "./physicalReadiness.js";
|
|
4
|
+
import { EngineBrokerControlClient } from "./engineBrokerControlClient.js";
|
|
5
|
+
export type OrganizationRuntimeHostReadiness = Readonly<{
|
|
6
|
+
agyRealm?: AgySubscriptionRealm;
|
|
7
|
+
grokBroker?: EngineBrokerControlClient;
|
|
8
|
+
paths: OrganizationRuntimePathAuthority;
|
|
9
|
+
close(): Promise<void>;
|
|
10
|
+
}>;
|
|
11
|
+
export declare function prepareProductionReadiness(config: OrganizationRuntimeConfig): Promise<OrganizationRuntimeHostReadiness>;
|
|
12
|
+
//# sourceMappingURL=organizationRuntimeReadiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organizationRuntimeReadiness.d.ts","sourceRoot":"","sources":["../../src/runtime/organizationRuntimeReadiness.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjG,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAmC,KAAK,gCAAgC,EAAE,MAAM,wBAAwB,CAAC;AAEhH,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC;IACtD,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,KAAK,EAAE,gCAAgC,CAAC;IACxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC,CAAC;AAEH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,gCAAgC,CAAC,CA8D3C"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { startAgySubscriptionRealm } from "./agySubscriptionRealm.js";
|
|
2
|
+
import { prepareEngineExecutable, verifyAgySubscriptionEnrollment } from "./engineReadiness.js";
|
|
3
|
+
import { prepareOrganizationRuntimePaths } from "./physicalReadiness.js";
|
|
4
|
+
import { materializePortableCredential } from "./portableCredentialMaterial.js";
|
|
5
|
+
import { EngineBrokerControlClient } from "./engineBrokerControlClient.js";
|
|
6
|
+
export async function prepareProductionReadiness(config) {
|
|
7
|
+
const paths = await prepareOrganizationRuntimePaths(config.agents);
|
|
8
|
+
let realm;
|
|
9
|
+
let grokBroker;
|
|
10
|
+
try {
|
|
11
|
+
for (const agent of config.agents) {
|
|
12
|
+
if (agent.engine.kind !== "codex")
|
|
13
|
+
continue;
|
|
14
|
+
const canonical = paths.forAgent(agent);
|
|
15
|
+
await canonical.verify();
|
|
16
|
+
await materializePortableCredential(agent, canonical.runtimeHomePath);
|
|
17
|
+
await canonical.verify();
|
|
18
|
+
}
|
|
19
|
+
const grokAgents = config.agents.filter((agent) => agent.engine.kind === "grok");
|
|
20
|
+
if (grokAgents.length > 0) {
|
|
21
|
+
grokBroker = new EngineBrokerControlClient();
|
|
22
|
+
await grokBroker.ready();
|
|
23
|
+
}
|
|
24
|
+
const agy = config.agents.find((agent) => agent.engine.kind === "agy");
|
|
25
|
+
if (agy !== undefined) {
|
|
26
|
+
realm = await startAgySubscriptionRealm();
|
|
27
|
+
const canonical = paths.forAgent(agy);
|
|
28
|
+
await canonical.verify();
|
|
29
|
+
const executable = await prepareEngineExecutable(agy.id, "agy");
|
|
30
|
+
await verifyAgySubscriptionEnrollment(agy.id, executable.executablePath, canonical.runtimeHomePath, realm.busAddress);
|
|
31
|
+
await executable.verify();
|
|
32
|
+
await canonical.verify();
|
|
33
|
+
}
|
|
34
|
+
let closed = false;
|
|
35
|
+
return {
|
|
36
|
+
...(realm === undefined ? {} : { agyRealm: realm }),
|
|
37
|
+
...(grokBroker === undefined ? {} : { grokBroker }),
|
|
38
|
+
paths,
|
|
39
|
+
async close() {
|
|
40
|
+
if (closed)
|
|
41
|
+
return;
|
|
42
|
+
closed = true;
|
|
43
|
+
const results = await Promise.allSettled([realm?.close(), paths.close()].filter((value) => value !== undefined));
|
|
44
|
+
const failures = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
45
|
+
if (failures.length > 0) {
|
|
46
|
+
throw new AggregateError(failures, "organization runtime readiness cleanup failed");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
const cleanup = await Promise.allSettled([realm?.close(), paths.close()].filter((value) => value !== undefined));
|
|
53
|
+
const failures = cleanup.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
54
|
+
if (failures.length > 0) {
|
|
55
|
+
throw new AggregateError([error, ...failures], "organization runtime readiness failed and cleanup was incomplete");
|
|
56
|
+
}
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { OrganizationRuntimeAgentConfig } from "./organizationRuntime.js";
|
|
2
|
+
/**
|
|
3
|
+
* `private` is every engine's runtime home: 0700, nothing but the runtime user.
|
|
4
|
+
*
|
|
5
|
+
* `worker-traversable` is the brokered Grok shape, and only that shape: the
|
|
6
|
+
* agent's own sandboxed worker runs as another uid and must be able to *walk
|
|
7
|
+
* into* this home to read the setgid `tool-output/` spill directory the
|
|
8
|
+
* truncation notice sends it to (`GROK_ENGINE_BROKER.worker.home.organizationRuntimeHome`).
|
|
9
|
+
* Traverse-only means `0710`: no group read (the worker cannot list the home or
|
|
10
|
+
* see the acceptance store, telemetry, memory or credential names) and no group
|
|
11
|
+
* write. Anything wider — `0711`, `0750`, `0770`, any world bit — is refused,
|
|
12
|
+
* as is a group that is not a worker group. Daimon cannot tell *which* worker
|
|
13
|
+
* gid belongs to this agent; the per-slot mapping is the deployment's
|
|
14
|
+
* provisioning contract, re-checked by the slot preflight receipt's worker-uid
|
|
15
|
+
* canaries.
|
|
16
|
+
*/
|
|
17
|
+
type DirectoryShape = "safe" | "private" | "worker-traversable";
|
|
18
|
+
/**
|
|
19
|
+
* Holds identities for caller-created roots. Daimon neither creates nor rolls
|
|
20
|
+
* back these directories: the deployer owns their lifecycle and contents.
|
|
21
|
+
*/
|
|
22
|
+
export type OrganizationRuntimePathAuthority = Readonly<{
|
|
23
|
+
forAgent(agent: OrganizationRuntimeAgentConfig): Readonly<{
|
|
24
|
+
workspacePath: string;
|
|
25
|
+
runtimeHomePath: string;
|
|
26
|
+
verify(): Promise<void>;
|
|
27
|
+
}>;
|
|
28
|
+
close(): Promise<void>;
|
|
29
|
+
}>;
|
|
30
|
+
export declare function prepareOrganizationRuntimePaths(agents: readonly OrganizationRuntimeAgentConfig[]): Promise<OrganizationRuntimePathAuthority>;
|
|
31
|
+
/** Identity of the process Daimon runs as; a seam so every refusal is testable unprivileged. */
|
|
32
|
+
export type RuntimeIdentity = Readonly<{
|
|
33
|
+
uid: number;
|
|
34
|
+
gid: number;
|
|
35
|
+
firstWorkerUid?: number;
|
|
36
|
+
}>;
|
|
37
|
+
type DirectoryEntry = Readonly<{
|
|
38
|
+
uid: number;
|
|
39
|
+
gid: number;
|
|
40
|
+
mode: number;
|
|
41
|
+
isDirectory(): boolean;
|
|
42
|
+
isSymbolicLink(): boolean;
|
|
43
|
+
}>;
|
|
44
|
+
/** Pure shape check for a caller-prepared runtime root. */
|
|
45
|
+
export declare function assertRuntimeDirectory(entry: DirectoryEntry, label: string, shape: DirectoryShape, runtime: RuntimeIdentity): void;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=physicalReadiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physicalReadiness.d.ts","sourceRoot":"","sources":["../../src/runtime/physicalReadiness.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAG/E;;;;;;;;;;;;;;GAcG;AACH,KAAK,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,oBAAoB,CAAC;AAGhE;;;GAGG;AACH,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC;IACtD,QAAQ,CAAC,KAAK,EAAE,8BAA8B,GAAG,QAAQ,CAAC;QACxD,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;KACzB,CAAC,CAAC;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC,CAAC;AAOH,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,SAAS,8BAA8B,EAAE,GAChD,OAAO,CAAC,gCAAgC,CAAC,CA8C3C;AA4CD,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC9F,KAAK,cAAc,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,IAAI,OAAO,CAAC;IAAC,cAAc,IAAI,OAAO,CAAA;CAAE,CAAC,CAAC;AAE9H,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAalI"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { lstat, open, realpath } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { GROK_ENGINE_BROKER } from "../contracts/runtimeContractManifest.js";
|
|
5
|
+
/** Only a brokered Grok agent's home is worker-traversable; every other engine keeps 0700. */
|
|
6
|
+
function runtimeHomeShape(agent) {
|
|
7
|
+
return agent.engine.kind === "grok" ? "worker-traversable" : "private";
|
|
8
|
+
}
|
|
9
|
+
export async function prepareOrganizationRuntimePaths(agents) {
|
|
10
|
+
const workspaces = new Map();
|
|
11
|
+
const homes = new Map();
|
|
12
|
+
try {
|
|
13
|
+
for (const agent of agents) {
|
|
14
|
+
workspaces.set(agent.id, await verifyDirectory(agent.workspacePath, "workspacePath", "safe"));
|
|
15
|
+
homes.set(agent.id, await verifyDirectory(agent.runtimeHomePath, "runtimeHomePath", runtimeHomeShape(agent)));
|
|
16
|
+
}
|
|
17
|
+
const roots = [...workspaces.values(), ...homes.values()];
|
|
18
|
+
for (let left = 0; left < roots.length; left += 1)
|
|
19
|
+
for (let right = left + 1; right < roots.length; right += 1) {
|
|
20
|
+
const first = roots[left];
|
|
21
|
+
const second = roots[right];
|
|
22
|
+
if (sameIdentity(first.identity, second.identity) || overlaps(first.real, second.real)) {
|
|
23
|
+
throw new Error(`physical runtime paths overlap: ${first.configured} and ${second.configured}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
const closeError = await closeAll([...workspaces.values(), ...homes.values()]);
|
|
29
|
+
if (closeError !== undefined)
|
|
30
|
+
throw new AggregateError([error, closeError], "runtime path validation cleanup failed");
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
let closed = false;
|
|
34
|
+
const verify = async (agent) => {
|
|
35
|
+
if (closed)
|
|
36
|
+
throw new Error("runtime path authority is closed");
|
|
37
|
+
const workspace = workspaces.get(agent.id);
|
|
38
|
+
const home = homes.get(agent.id);
|
|
39
|
+
if (workspace === undefined || home === undefined)
|
|
40
|
+
throw new Error(`no runtime path authority for ${agent.id}`);
|
|
41
|
+
await Promise.all([
|
|
42
|
+
verifyIdentity(workspace, "workspacePath", "safe"),
|
|
43
|
+
verifyIdentity(home, "runtimeHomePath", runtimeHomeShape(agent))
|
|
44
|
+
]);
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
forAgent(agent) {
|
|
48
|
+
const workspace = workspaces.get(agent.id);
|
|
49
|
+
const home = homes.get(agent.id);
|
|
50
|
+
if (workspace === undefined || home === undefined)
|
|
51
|
+
throw new Error(`no runtime path authority for ${agent.id}`);
|
|
52
|
+
return { workspacePath: workspace.real, runtimeHomePath: home.real, verify: () => verify(agent) };
|
|
53
|
+
},
|
|
54
|
+
async close() {
|
|
55
|
+
if (closed)
|
|
56
|
+
return;
|
|
57
|
+
const failure = await closeAll([...workspaces.values(), ...homes.values()]);
|
|
58
|
+
if (failure !== undefined)
|
|
59
|
+
throw failure;
|
|
60
|
+
closed = true;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function verifyDirectory(configured, label, shape) {
|
|
65
|
+
await assertNoSymlinkComponents(configured);
|
|
66
|
+
const before = await lstat(configured);
|
|
67
|
+
assertDirectory(before, label, shape);
|
|
68
|
+
const fd = await open(configured, constants.O_RDONLY | directoryFlag() | noFollow());
|
|
69
|
+
try {
|
|
70
|
+
const opened = await fd.stat();
|
|
71
|
+
const real = await realpath(configured);
|
|
72
|
+
const after = await lstat(configured);
|
|
73
|
+
if (!sameIdentity(identity(before), identity(opened)) || !sameIdentity(identity(before), identity(after))) {
|
|
74
|
+
throw new Error(`${label} changed during validation`);
|
|
75
|
+
}
|
|
76
|
+
return { configured, real, fd, identity: identity(before), closed: false };
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
await fd.close().catch(() => undefined);
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function verifyIdentity(directory, label, shape) {
|
|
84
|
+
if (directory.closed)
|
|
85
|
+
throw new Error(`${label} authority is closed`);
|
|
86
|
+
await assertNoSymlinkComponents(directory.configured);
|
|
87
|
+
const entry = await lstat(directory.configured);
|
|
88
|
+
const opened = await directory.fd.stat();
|
|
89
|
+
if (!sameIdentity(identity(entry), directory.identity) || !sameIdentity(identity(opened), directory.identity)) {
|
|
90
|
+
throw new Error(`${label} changed after readiness validation`);
|
|
91
|
+
}
|
|
92
|
+
assertDirectory(entry, label, shape);
|
|
93
|
+
if (await realpath(directory.configured) !== directory.real)
|
|
94
|
+
throw new Error(`${label} changed after readiness validation`);
|
|
95
|
+
}
|
|
96
|
+
async function assertNoSymlinkComponents(target) {
|
|
97
|
+
const parsed = path.parse(target);
|
|
98
|
+
let current = parsed.root;
|
|
99
|
+
for (const part of path.relative(parsed.root, target).split(path.sep).filter(Boolean)) {
|
|
100
|
+
current = path.join(current, part);
|
|
101
|
+
// macOS exposes /var as a system compatibility symlink to /private/var.
|
|
102
|
+
// It is an OS-root alias, not a caller-controlled component.
|
|
103
|
+
if ((await lstat(current)).isSymbolicLink() && current !== "/var")
|
|
104
|
+
throw new Error(`path contains symlink: ${current}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Pure shape check for a caller-prepared runtime root. */
|
|
108
|
+
export function assertRuntimeDirectory(entry, label, shape, runtime) {
|
|
109
|
+
if (!entry.isDirectory() || entry.isSymbolicLink())
|
|
110
|
+
throw new Error(`${label} must be an existing real directory`);
|
|
111
|
+
if (entry.uid !== runtime.uid)
|
|
112
|
+
throw new Error(`${label} must be owned by the runtime user`);
|
|
113
|
+
const permissions = Number(entry.mode) & 0o7777;
|
|
114
|
+
if (shape === "private" && permissions !== 0o700)
|
|
115
|
+
throw new Error(`${label} must have mode 0700`);
|
|
116
|
+
if (shape === "worker-traversable") {
|
|
117
|
+
const home = GROK_ENGINE_BROKER.worker.home.organizationRuntimeHome;
|
|
118
|
+
if (permissions !== home.mode)
|
|
119
|
+
throw new Error(`${label} must have mode 0710 for a brokered Grok agent`);
|
|
120
|
+
if (entry.gid < (runtime.firstWorkerUid ?? GROK_ENGINE_BROKER.identities.firstWorkerUid) || entry.gid === runtime.gid) {
|
|
121
|
+
throw new Error(`${label} must be group-owned by the agent's Grok worker group`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (shape === "safe" && (permissions & 0o022) !== 0)
|
|
125
|
+
throw new Error(`${label} must not grant group or other write access`);
|
|
126
|
+
}
|
|
127
|
+
function assertDirectory(entry, label, shape) {
|
|
128
|
+
assertRuntimeDirectory(entry, label, shape, { uid: process.getuid?.() ?? -1, gid: process.getgid?.() ?? -1 });
|
|
129
|
+
}
|
|
130
|
+
function identity(entry) { return { dev: entry.dev, ino: entry.ino, uid: entry.uid, mode: entry.mode & 0o7777 }; }
|
|
131
|
+
function sameIdentity(left, right) { return left.dev === right.dev && left.ino === right.ino && left.uid === right.uid && left.mode === right.mode; }
|
|
132
|
+
function overlaps(left, right) { return left === right || left.startsWith(`${right}${path.sep}`) || right.startsWith(`${left}${path.sep}`); }
|
|
133
|
+
function noFollow() { return constants.O_NOFOLLOW ?? 0; }
|
|
134
|
+
function directoryFlag() { return constants.O_DIRECTORY ?? 0; }
|
|
135
|
+
async function closeAll(directories) {
|
|
136
|
+
const results = await Promise.allSettled(directories.filter((directory) => !directory.closed).map(async (directory) => {
|
|
137
|
+
await directory.fd.close();
|
|
138
|
+
directory.closed = true;
|
|
139
|
+
}));
|
|
140
|
+
const failures = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
141
|
+
return failures.length === 0 ? undefined : new AggregateError(failures, "runtime path authority cleanup failed");
|
|
142
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type PortableCredentialKind = "codex" | "grok";
|
|
2
|
+
/** Validates only the bounded provider-native shape needed for refresh. */
|
|
3
|
+
export declare function hasRefreshablePortableCredential(engine: PortableCredentialKind, bytes: Uint8Array): boolean;
|
|
4
|
+
/** Returns only the provider-native bearer values for exact in-process redaction. */
|
|
5
|
+
export declare function portableCredentialSecretValues(engine: PortableCredentialKind, bytes: Uint8Array): readonly string[];
|
|
6
|
+
//# sourceMappingURL=portableCredentialAuth.d.ts.map
|