@obora/runtime 0.1.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/LICENSE +21 -0
- package/README.md +183 -0
- package/dist/_legacy/actor/base/BaseActor.d.ts +87 -0
- package/dist/_legacy/actor/pool/ActorPool.d.ts +194 -0
- package/dist/_legacy/actor/pool/NoOpMessageBus.d.ts +16 -0
- package/dist/_legacy/actor/pool/PoolManager.d.ts +76 -0
- package/dist/_legacy/actor/pool/index.d.ts +3 -0
- package/dist/_legacy/actor/runtime/ActorRunner.d.ts +54 -0
- package/dist/_legacy/actor/runtime/ActorRuntime.d.ts +161 -0
- package/dist/_legacy/actor/runtime/DefaultActorFactory.d.ts +44 -0
- package/dist/_legacy/actor/runtime/types.d.ts +41 -0
- package/dist/_legacy/actor/runtime/utils/delay.d.ts +7 -0
- package/dist/_legacy/actor/supervision/Supervisor.d.ts +102 -0
- package/dist/_legacy/actor/supervision/SupervisorTree.d.ts +54 -0
- package/dist/_legacy/actor/supervision/types.d.ts +130 -0
- package/dist/_legacy/actor/types/action.d.ts +65 -0
- package/dist/_legacy/actor/types/actor.d.ts +251 -0
- package/dist/_legacy/actor/types/blackboard.d.ts +46 -0
- package/dist/_legacy/actor/types/crypto.d.ts +6 -0
- package/dist/_legacy/actor/types/message.d.ts +209 -0
- package/dist/_legacy/actor/types/metrics.d.ts +43 -0
- package/dist/_legacy/actor/types/observation.d.ts +45 -0
- package/dist/_legacy/actor/types/result.d.ts +110 -0
- package/dist/_legacy/agents/roles/analyst-agent.d.ts +18 -0
- package/dist/_legacy/agents/roles/base-agent.d.ts +320 -0
- package/dist/_legacy/agents/roles/director-agent.d.ts +26 -0
- package/dist/_legacy/agents/roles/executor-agent.d.ts +26 -0
- package/dist/_legacy/agents/roles/factory.d.ts +30 -0
- package/dist/_legacy/agents/roles/index.d.ts +6 -0
- package/dist/_legacy/agents/roles/verifier-agent.d.ts +18 -0
- package/dist/_legacy/blackboard/core/accessors/decisions-accessor.d.ts +190 -0
- package/dist/_legacy/blackboard/core/accessors/index.d.ts +7 -0
- package/dist/_legacy/blackboard/core/accessors/knowledge-accessor.d.ts +154 -0
- package/dist/_legacy/blackboard/core/accessors/state-accessor.d.ts +173 -0
- package/dist/_legacy/blackboard/core/blackboard-events.d.ts +105 -0
- package/dist/_legacy/blackboard/core/blackboard.d.ts +286 -0
- package/dist/_legacy/blackboard/core/id-generator.d.ts +53 -0
- package/dist/_legacy/blackboard/core/immutable.d.ts +45 -0
- package/dist/_legacy/blackboard/core/index.d.ts +13 -0
- package/dist/_legacy/blackboard/core/path-utils.d.ts +75 -0
- package/dist/_legacy/blackboard/core/tkg.d.ts +50 -0
- package/dist/_legacy/blackboard/core/versioning.d.ts +80 -0
- package/dist/_legacy/blackboard/domains/agenda/AgendaStore.d.ts +34 -0
- package/dist/_legacy/blackboard/domains/agenda/events.d.ts +12 -0
- package/dist/_legacy/blackboard/domains/agenda/index.d.ts +6 -0
- package/dist/_legacy/blackboard/domains/agenda/types.d.ts +26 -0
- package/dist/_legacy/blackboard/domains/consensus/ConsensusRuleEngine.d.ts +10 -0
- package/dist/_legacy/blackboard/domains/consensus/index.d.ts +4 -0
- package/dist/_legacy/blackboard/domains/consensus/types.d.ts +27 -0
- package/dist/_legacy/blackboard/domains/tkg/InMemoryTKG.d.ts +38 -0
- package/dist/_legacy/blackboard/domains/tkg/JsonFileReflectorStateStore.d.ts +9 -0
- package/dist/_legacy/blackboard/domains/tkg/ObserverReflector.d.ts +114 -0
- package/dist/_legacy/blackboard/domains/tkg/index.d.ts +4 -0
- package/dist/_legacy/blackboard/domains/voting/VotingSessionStore.d.ts +14 -0
- package/dist/_legacy/blackboard/domains/voting/index.d.ts +3 -0
- package/dist/_legacy/blackboard/domains/voting/types.d.ts +32 -0
- package/dist/_legacy/blackboard/events/event-bus.d.ts +254 -0
- package/dist/_legacy/blackboard/events/event-factory.d.ts +80 -0
- package/dist/_legacy/blackboard/events/index.d.ts +17 -0
- package/dist/_legacy/blackboard/events/types.d.ts +554 -0
- package/dist/_legacy/blackboard/snapshot/compression.d.ts +170 -0
- package/dist/_legacy/blackboard/snapshot/id-utils.d.ts +20 -0
- package/dist/_legacy/blackboard/snapshot/index.d.ts +21 -0
- package/dist/_legacy/blackboard/snapshot/serializer.d.ts +123 -0
- package/dist/_legacy/blackboard/snapshot/snapshot-comparer.d.ts +102 -0
- package/dist/_legacy/blackboard/snapshot/snapshot-creator.d.ts +49 -0
- package/dist/_legacy/blackboard/snapshot/snapshot-manager.d.ts +253 -0
- package/dist/_legacy/blackboard/snapshot/snapshot-restorer.d.ts +54 -0
- package/dist/_legacy/blackboard/snapshot/snapshot-serializer.d.ts +45 -0
- package/dist/_legacy/blackboard/snapshot/snapshot-validator.d.ts +55 -0
- package/dist/_legacy/blackboard/snapshot/type-guards.d.ts +12 -0
- package/dist/_legacy/blackboard/snapshot/types.d.ts +151 -0
- package/dist/_legacy/blackboard/snapshot/utils.d.ts +20 -0
- package/dist/_legacy/blackboard/types/agent.d.ts +89 -0
- package/dist/_legacy/blackboard/types/base.d.ts +213 -0
- package/dist/_legacy/blackboard/types/blackboard.d.ts +217 -0
- package/dist/_legacy/blackboard/types/decision.d.ts +260 -0
- package/dist/_legacy/blackboard/types/index.d.ts +12 -0
- package/dist/_legacy/blackboard/types/knowledge.d.ts +224 -0
- package/dist/_legacy/blackboard/types/message.d.ts +162 -0
- package/dist/_legacy/blackboard/types/task.d.ts +154 -0
- package/dist/_legacy/blackboard/types/tkg.d.ts +189 -0
- package/dist/_legacy/blackboard/workflow/meeting-state-machine/MeetingStateMachine.d.ts +22 -0
- package/dist/_legacy/blackboard/workflow/meeting-state-machine/types.d.ts +30 -0
- package/dist/_legacy/cli-runtime/runtime/agent-registry.d.ts +33 -0
- package/dist/_legacy/cli-runtime/runtime/blackboard.d.ts +41 -0
- package/dist/_legacy/cli-runtime/runtime/context-builder.d.ts +88 -0
- package/dist/_legacy/cli-runtime/runtime/retry-policy.d.ts +8 -0
- package/dist/_legacy/cli-runtime/runtime/step-executor.d.ts +33 -0
- package/dist/_legacy/cli-runtime/runtime/types.d.ts +12 -0
- package/dist/_legacy/cli-runtime/runtime/utils.d.ts +2 -0
- package/dist/_legacy/database/src/duckdb-client.d.ts +178 -0
- package/dist/_legacy/workflow/errors/diagnosis.d.ts +32 -0
- package/dist/_legacy/workflow/errors/index.d.ts +52 -0
- package/dist/_legacy/workflow/graph/index.d.ts +57 -0
- package/dist/_legacy/workflow/index.d.ts +9 -0
- package/dist/_legacy/workflow/parser/workflow-parser.d.ts +13 -0
- package/dist/_legacy/workflow/resolver/dependency-resolver.d.ts +83 -0
- package/dist/_legacy/workflow/types/workflow.d.ts +173 -0
- package/dist/_legacy/workflow/utils.d.ts +2 -0
- package/dist/_legacy/workflow/validator/workflow-validator.d.ts +71 -0
- package/dist/artifacts/index.d.ts +2 -0
- package/dist/artifacts/local-file-artifact-store.d.ts +22 -0
- package/dist/artifacts/types.d.ts +19 -0
- package/dist/audit/AuditReplay.d.ts +4 -0
- package/dist/audit/AuditStore.d.ts +13 -0
- package/dist/audit/AuditTrail.d.ts +28 -0
- package/dist/audit/DefaultAuditRecorder.d.ts +10 -0
- package/dist/audit/EventBusAdapter.d.ts +12 -0
- package/dist/audit/InMemoryAuditStore.d.ts +9 -0
- package/dist/audit/ReExecutionDiffReport.d.ts +24 -0
- package/dist/audit/ReExecutionPlanner.d.ts +30 -0
- package/dist/audit/ReExecutionRuntime.d.ts +35 -0
- package/dist/audit/database-api.d.ts +32 -0
- package/dist/audit/database-index.d.ts +5 -0
- package/dist/audit/event-bus.d.ts +1 -0
- package/dist/audit/event-factory.d.ts +1 -0
- package/dist/audit/index.d.ts +12 -0
- package/dist/audit/testing.d.ts +15 -0
- package/dist/audit/tkg/InMemoryTKG.d.ts +1 -0
- package/dist/audit/tkg/JsonFileReflectorStateStore.d.ts +1 -0
- package/dist/audit/tkg/ObserverReflector.d.ts +1 -0
- package/dist/audit/tkg/index.d.ts +1 -0
- package/dist/audit/types.d.ts +23 -0
- package/dist/blackboard/core/accessors/decisions-accessor.d.ts +190 -0
- package/dist/blackboard/core/accessors/index.d.ts +7 -0
- package/dist/blackboard/core/accessors/knowledge-accessor.d.ts +154 -0
- package/dist/blackboard/core/accessors/state-accessor.d.ts +173 -0
- package/dist/blackboard/core/blackboard-events.d.ts +105 -0
- package/dist/blackboard/core/blackboard.d.ts +286 -0
- package/dist/blackboard/core/id-generator.d.ts +53 -0
- package/dist/blackboard/core/immutable.d.ts +45 -0
- package/dist/blackboard/core/index.d.ts +13 -0
- package/dist/blackboard/core/path-utils.d.ts +75 -0
- package/dist/blackboard/core/tkg.d.ts +50 -0
- package/dist/blackboard/core/versioning.d.ts +80 -0
- package/dist/blackboard/events/event-bus.d.ts +254 -0
- package/dist/blackboard/events/event-factory.d.ts +80 -0
- package/dist/blackboard/events/index.d.ts +17 -0
- package/dist/blackboard/events/types.d.ts +554 -0
- package/dist/blackboard/index.d.ts +20 -0
- package/dist/blackboard/observer-reflector.d.ts +114 -0
- package/dist/blackboard/snapshot/compression.d.ts +170 -0
- package/dist/blackboard/snapshot/id-utils.d.ts +20 -0
- package/dist/blackboard/snapshot/index.d.ts +21 -0
- package/dist/blackboard/snapshot/serializer.d.ts +123 -0
- package/dist/blackboard/snapshot/snapshot-comparer.d.ts +102 -0
- package/dist/blackboard/snapshot/snapshot-creator.d.ts +49 -0
- package/dist/blackboard/snapshot/snapshot-manager.d.ts +253 -0
- package/dist/blackboard/snapshot/snapshot-restorer.d.ts +54 -0
- package/dist/blackboard/snapshot/snapshot-serializer.d.ts +45 -0
- package/dist/blackboard/snapshot/snapshot-validator.d.ts +55 -0
- package/dist/blackboard/snapshot/type-guards.d.ts +12 -0
- package/dist/blackboard/snapshot/types.d.ts +151 -0
- package/dist/blackboard/snapshot/utils.d.ts +20 -0
- package/dist/blackboard/types/agent.d.ts +89 -0
- package/dist/blackboard/types/base.d.ts +213 -0
- package/dist/blackboard/types/blackboard.d.ts +217 -0
- package/dist/blackboard/types/decision.d.ts +260 -0
- package/dist/blackboard/types/index.d.ts +12 -0
- package/dist/blackboard/types/knowledge.d.ts +224 -0
- package/dist/blackboard/types/message.d.ts +162 -0
- package/dist/blackboard/types/task.d.ts +154 -0
- package/dist/blackboard/types/tkg.d.ts +189 -0
- package/dist/cell/ActorPool.d.ts +1 -0
- package/dist/cell/AgentFactory.d.ts +1 -0
- package/dist/cell/AgentRegistry.d.ts +1 -0
- package/dist/cell/BaseActor.d.ts +1 -0
- package/dist/cell/CellContext.d.ts +39 -0
- package/dist/cell/CellManager.d.ts +80 -0
- package/dist/cell/ExecutionCell.d.ts +44 -0
- package/dist/cell/PoolManager.d.ts +1 -0
- package/dist/cell/actor-types/action.d.ts +65 -0
- package/dist/cell/actor-types/actor.d.ts +251 -0
- package/dist/cell/actor-types/blackboard.d.ts +46 -0
- package/dist/cell/actor-types/crypto.d.ts +6 -0
- package/dist/cell/actor-types/index.d.ts +12 -0
- package/dist/cell/actor-types/message.d.ts +209 -0
- package/dist/cell/actor-types/metrics.d.ts +43 -0
- package/dist/cell/actor-types/observation.d.ts +45 -0
- package/dist/cell/actor-types/result.d.ts +110 -0
- package/dist/cell/agents/AnalystCellAgent.d.ts +2 -0
- package/dist/cell/agents/BaseRuntimeAgent.d.ts +2 -0
- package/dist/cell/agents/DirectorCellAgent.d.ts +2 -0
- package/dist/cell/agents/ExecutorCellAgent.d.ts +2 -0
- package/dist/cell/agents/VerifierCellAgent.d.ts +2 -0
- package/dist/cell/agents/index.d.ts +5 -0
- package/dist/cell/index.d.ts +9 -0
- package/dist/cell/internal/ActorRunnerAdapter.d.ts +2 -0
- package/dist/cell/internal/CellActorFactory.d.ts +2 -0
- package/dist/cell/internal/NoOpRuntimeBus.d.ts +2 -0
- package/dist/cell/internal/delay.d.ts +1 -0
- package/dist/cell/pool-index.d.ts +1 -0
- package/dist/cell/types.d.ts +47 -0
- package/dist/checkpoint/CheckpointFactoryRegistry.d.ts +16 -0
- package/dist/checkpoint/CheckpointManager.d.ts +41 -0
- package/dist/checkpoint/index.d.ts +5 -0
- package/dist/checkpoint/policy-hash.d.ts +11 -0
- package/dist/consensus/ConsensusGate.d.ts +83 -0
- package/dist/consensus/ConsensusRuleEngine.d.ts +1 -0
- package/dist/consensus/agenda/AgendaStore.d.ts +1 -0
- package/dist/consensus/agenda/events.d.ts +1 -0
- package/dist/consensus/agenda/index.d.ts +1 -0
- package/dist/consensus/agenda/types.d.ts +1 -0
- package/dist/consensus/index.d.ts +2 -0
- package/dist/consensus/types.d.ts +1 -0
- package/dist/consensus/voting/VotingSessionStore.d.ts +1 -0
- package/dist/consensus/voting/index.d.ts +1 -0
- package/dist/consensus/voting/types.d.ts +1 -0
- package/dist/errors/OboraErrorCode.d.ts +28 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/gates/GateAssignment.d.ts +28 -0
- package/dist/gates/MultiStageApproval.d.ts +74 -0
- package/dist/gates/SLAManager.d.ts +21 -0
- package/dist/gates/index.d.ts +4 -0
- package/dist/gates/types.d.ts +19 -0
- package/dist/index.cjs +26588 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +26330 -0
- package/dist/index.js.map +1 -0
- package/dist/judgment/JudgmentEngine.d.ts +24 -0
- package/dist/judgment/JudgmentNormalizer.d.ts +37 -0
- package/dist/judgment/JudgmentPolicy.d.ts +74 -0
- package/dist/judgment/JudgmentReporter.d.ts +70 -0
- package/dist/judgment/OperationalLogger.d.ts +68 -0
- package/dist/judgment/index.d.ts +6 -0
- package/dist/judgment/types.d.ts +42 -0
- package/dist/orchestrator/ExecutionContextBuilder.d.ts +1 -0
- package/dist/orchestrator/RuntimeOrchestrator.d.ts +94 -0
- package/dist/orchestrator/StepScheduler.d.ts +2 -0
- package/dist/orchestrator/index.d.ts +4 -0
- package/dist/orchestrator/types.d.ts +80 -0
- package/dist/orchestrator/utils.d.ts +1 -0
- package/dist/patterns/CustomPatternAPI.d.ts +10 -0
- package/dist/patterns/PatternRegistry.d.ts +19 -0
- package/dist/patterns/builtin/BrainstormPattern.d.ts +13 -0
- package/dist/patterns/builtin/CompositePattern.d.ts +11 -0
- package/dist/patterns/builtin/ConsensusPattern.d.ts +17 -0
- package/dist/patterns/builtin/DiscussionPattern.d.ts +13 -0
- package/dist/patterns/builtin/FanOutFanInPattern.d.ts +21 -0
- package/dist/patterns/builtin/PeerReviewPattern.d.ts +40 -0
- package/dist/patterns/builtin/PipelinePattern.d.ts +6 -0
- package/dist/patterns/builtin/RedBluePattern.d.ts +13 -0
- package/dist/patterns/builtin/SupervisorPattern.d.ts +13 -0
- package/dist/patterns/builtin/discussion/MeetingStateMachine.d.ts +1 -0
- package/dist/patterns/builtin/discussion/index.d.ts +2 -0
- package/dist/patterns/builtin/discussion/types.d.ts +1 -0
- package/dist/patterns/examples/OxfordDebatePattern.d.ts +11 -0
- package/dist/patterns/examples/index.d.ts +1 -0
- package/dist/patterns/index.d.ts +14 -0
- package/dist/patterns/resolveCustomPattern.d.ts +22 -0
- package/dist/patterns/types.d.ts +252 -0
- package/dist/plugins/PluginLoader.d.ts +16 -0
- package/dist/plugins/PluginRegistry.d.ts +15 -0
- package/dist/plugins/builtins.d.ts +137 -0
- package/dist/plugins/index.d.ts +5 -0
- package/dist/plugins/types.d.ts +52 -0
- package/dist/plugins/validator.d.ts +3 -0
- package/dist/policy/DefaultPolicyEngine.d.ts +43 -0
- package/dist/policy/DynamicPolicyContext.d.ts +21 -0
- package/dist/policy/DynamicQuotaEvaluator.d.ts +9 -0
- package/dist/policy/DynamicToolPolicy.d.ts +10 -0
- package/dist/policy/PolicyEngine.d.ts +14 -0
- package/dist/policy/PolicyLoader.d.ts +3 -0
- package/dist/policy/expressions/ExpressionEvaluator.d.ts +37 -0
- package/dist/policy/expressions/ExpressionParser.d.ts +35 -0
- package/dist/policy/expressions/constants.d.ts +5 -0
- package/dist/policy/expressions/index.d.ts +2 -0
- package/dist/policy/index.d.ts +9 -0
- package/dist/policy/rules/GateRule.d.ts +7 -0
- package/dist/policy/rules/ResourceRule.d.ts +7 -0
- package/dist/policy/rules/SandboxRule.d.ts +7 -0
- package/dist/policy/rules/ToolRule.d.ts +23 -0
- package/dist/policy/rules/index.d.ts +4 -0
- package/dist/policy/types.d.ts +156 -0
- package/dist/recovery/RecoveryEngine.d.ts +11 -0
- package/dist/recovery/RetryStrategy.d.ts +2 -0
- package/dist/recovery/SupervisionTree.d.ts +1 -0
- package/dist/recovery/index.d.ts +4 -0
- package/dist/recovery/types.d.ts +103 -0
- package/dist/state/RuntimeBlackboardCompat.d.ts +1 -0
- package/dist/state/StateBinder.d.ts +40 -0
- package/dist/state/StateManager.d.ts +1 -0
- package/dist/state/accessors/decisions-accessor.d.ts +1 -0
- package/dist/state/accessors/index.d.ts +1 -0
- package/dist/state/accessors/knowledge-accessor.d.ts +1 -0
- package/dist/state/accessors/state-accessor.d.ts +1 -0
- package/dist/state/blackboard-events.d.ts +1 -0
- package/dist/state/core-index.d.ts +1 -0
- package/dist/state/id-generator.d.ts +1 -0
- package/dist/state/immutable.d.ts +1 -0
- package/dist/state/index.d.ts +6 -0
- package/dist/state/path-utils.d.ts +1 -0
- package/dist/state/snapshot/compression.d.ts +1 -0
- package/dist/state/snapshot/id-utils.d.ts +1 -0
- package/dist/state/snapshot/index.d.ts +1 -0
- package/dist/state/snapshot/serializer.d.ts +1 -0
- package/dist/state/snapshot/snapshot-comparer.d.ts +1 -0
- package/dist/state/snapshot/snapshot-creator.d.ts +1 -0
- package/dist/state/snapshot/snapshot-manager.d.ts +1 -0
- package/dist/state/snapshot/snapshot-restorer.d.ts +1 -0
- package/dist/state/snapshot/snapshot-serializer.d.ts +1 -0
- package/dist/state/snapshot/snapshot-validator.d.ts +1 -0
- package/dist/state/snapshot/type-guards.d.ts +1 -0
- package/dist/state/snapshot/types.d.ts +1 -0
- package/dist/state/snapshot/utils.d.ts +1 -0
- package/dist/state/tkg.d.ts +1 -0
- package/dist/state/types/agent.d.ts +1 -0
- package/dist/state/types/base.d.ts +1 -0
- package/dist/state/types/blackboard.d.ts +1 -0
- package/dist/state/types/decision.d.ts +1 -0
- package/dist/state/types/index.d.ts +1 -0
- package/dist/state/types/knowledge.d.ts +1 -0
- package/dist/state/types/message.d.ts +1 -0
- package/dist/state/types/task.d.ts +1 -0
- package/dist/state/types/tkg.d.ts +1 -0
- package/dist/state/versioning.d.ts +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/inmemory-adapter.d.ts +27 -0
- package/dist/storage/sqlite-adapter.d.ts +43 -0
- package/dist/storage/types.d.ts +129 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/_legacy/actor/types/crypto.ts","../src/_legacy/actor/types/actor.ts","../src/_legacy/actor/types/message.ts","../src/_legacy/actor/types/metrics.ts","../src/_legacy/actor/base/BaseActor.ts","../src/_legacy/actor/runtime/utils/delay.ts","../src/_legacy/actor/runtime/ActorRuntime.ts","../src/cell/ExecutionCell.ts","../src/_legacy/actor/types/action.ts","../src/_legacy/actor/types/observation.ts","../src/_legacy/actor/types/result.ts","../src/cell/CellManager.ts","../src/_legacy/actor/pool/NoOpMessageBus.ts","../src/_legacy/actor/pool/ActorPool.ts","../src/_legacy/actor/pool/PoolManager.ts","../src/_legacy/actor/runtime/ActorRunner.ts","../src/_legacy/actor/runtime/DefaultActorFactory.ts","../src/policy/PolicyLoader.ts","../src/policy/DefaultPolicyEngine.ts","../src/errors/OboraErrorCode.ts","../src/policy/expressions/constants.ts","../src/policy/expressions/ExpressionParser.ts","../src/policy/expressions/ExpressionEvaluator.ts","../src/policy/DynamicToolPolicy.ts","../src/policy/rules/ToolRule.ts","../src/policy/rules/SandboxRule.ts","../src/policy/DynamicQuotaEvaluator.ts","../src/policy/rules/ResourceRule.ts","../src/policy/rules/GateRule.ts","../src/policy/DynamicPolicyContext.ts","../src/_legacy/blackboard/types/base.ts","../src/_legacy/blackboard/core/versioning.ts","../src/_legacy/blackboard/core/immutable.ts","../src/_legacy/blackboard/core/path-utils.ts","../src/_legacy/blackboard/types/agent.ts","../src/_legacy/blackboard/types/task.ts","../src/_legacy/blackboard/types/decision.ts","../src/_legacy/blackboard/types/message.ts","../src/_legacy/blackboard/types/tkg.ts","../src/_legacy/blackboard/core/accessors/state-accessor.ts","../src/_legacy/blackboard/core/accessors/knowledge-accessor.ts","../src/_legacy/blackboard/core/accessors/decisions-accessor.ts","../src/_legacy/blackboard/snapshot/types.ts","../src/_legacy/blackboard/snapshot/id-utils.ts","../src/_legacy/blackboard/snapshot/compression.ts","../src/_legacy/blackboard/snapshot/type-guards.ts","../src/_legacy/blackboard/snapshot/utils.ts","../src/_legacy/blackboard/snapshot/serializer.ts","../src/_legacy/blackboard/snapshot/snapshot-creator.ts","../src/_legacy/blackboard/snapshot/snapshot-validator.ts","../src/_legacy/blackboard/snapshot/snapshot-restorer.ts","../src/_legacy/blackboard/snapshot/snapshot-serializer.ts","../src/_legacy/blackboard/snapshot/snapshot-comparer.ts","../src/_legacy/blackboard/snapshot/snapshot-manager.ts","../src/_legacy/blackboard/core/blackboard.ts","../src/state/StateBinder.ts","../src/_legacy/cli-runtime/runtime/utils.ts","../src/_legacy/cli-runtime/runtime/blackboard.ts","../src/_legacy/blackboard/domains/consensus/ConsensusRuleEngine.ts","../src/_legacy/blackboard/domains/consensus/types.ts","../src/_legacy/blackboard/domains/voting/VotingSessionStore.ts","../src/consensus/ConsensusGate.ts","../src/gates/types.ts","../src/gates/MultiStageApproval.ts","../src/gates/GateAssignment.ts","../src/gates/SLAManager.ts","../src/audit/InMemoryAuditStore.ts","../src/audit/DefaultAuditRecorder.ts","../src/audit/EventBusAdapter.ts","../src/audit/ReExecutionPlanner.ts","../src/audit/ReExecutionDiffReport.ts","../src/audit/ReExecutionRuntime.ts","../src/audit/AuditReplay.ts","../src/_legacy/blackboard/events/event-bus.ts","../src/_legacy/blackboard/events/event-factory.ts","../src/_legacy/blackboard/domains/tkg/InMemoryTKG.ts","../src/_legacy/blackboard/domains/tkg/JsonFileReflectorStateStore.ts","../src/recovery/RetryStrategy.ts","../src/_legacy/actor/supervision/Supervisor.ts","../src/_legacy/actor/supervision/types.ts","../src/recovery/RecoveryEngine.ts","../src/_legacy/actor/supervision/SupervisorTree.ts","../src/orchestrator/RuntimeOrchestrator.ts","../src/_legacy/workflow/utils.ts","../src/_legacy/workflow/errors/index.ts","../src/_legacy/workflow/errors/diagnosis.ts","../src/_legacy/workflow/parser/workflow-parser.ts","../src/_legacy/workflow/graph/index.ts","../src/_legacy/workflow/validator/workflow-validator.ts","../src/_legacy/workflow/resolver/dependency-resolver.ts","../src/checkpoint/CheckpointManager.ts","../src/checkpoint/policy-hash.ts","../src/_legacy/cli-runtime/runtime/step-executor.ts","../src/_legacy/cli-runtime/runtime/retry-policy.ts","../src/_legacy/cli-runtime/runtime/context-builder.ts","../src/patterns/types.ts","../src/patterns/PatternRegistry.ts","../src/patterns/CustomPatternAPI.ts","../src/patterns/resolveCustomPattern.ts","../src/patterns/builtin/PipelinePattern.ts","../src/_legacy/blackboard/domains/agenda/types.ts","../src/_legacy/blackboard/domains/agenda/events.ts","../src/_legacy/blackboard/domains/agenda/AgendaStore.ts","../src/_legacy/blackboard/workflow/meeting-state-machine/MeetingStateMachine.ts","../src/_legacy/blackboard/workflow/meeting-state-machine/types.ts","../src/patterns/builtin/DiscussionPattern.ts","../src/patterns/builtin/ConsensusPattern.ts","../src/patterns/builtin/BrainstormPattern.ts","../src/patterns/builtin/PeerReviewPattern.ts","../src/patterns/builtin/SupervisorPattern.ts","../src/patterns/builtin/FanOutFanInPattern.ts","../src/patterns/builtin/RedBluePattern.ts","../src/patterns/builtin/CompositePattern.ts","../src/plugins/validator.ts","../src/plugins/PluginRegistry.ts","../src/plugins/PluginLoader.ts","../src/plugins/builtins.ts","../src/storage/inmemory-adapter.ts","../src/storage/sqlite-adapter.ts","../src/artifacts/local-file-artifact-store.ts","../src/checkpoint/CheckpointFactoryRegistry.ts","../src/_legacy/agents/roles/base-agent.ts","../src/_legacy/agents/roles/analyst-agent.ts","../src/_legacy/agents/roles/executor-agent.ts","../src/_legacy/agents/roles/verifier-agent.ts","../src/_legacy/agents/roles/director-agent.ts","../src/_legacy/agents/roles/factory.ts","../src/judgment/JudgmentEngine.ts","../src/judgment/JudgmentPolicy.ts","../src/judgment/JudgmentNormalizer.ts","../src/judgment/JudgmentReporter.ts","../src/judgment/OperationalLogger.ts","../src/blackboard/types/base.ts","../src/blackboard/core/versioning.ts","../src/blackboard/core/immutable.ts","../src/blackboard/core/path-utils.ts","../src/blackboard/types/tkg.ts","../src/blackboard/core/accessors/state-accessor.ts","../src/blackboard/core/accessors/knowledge-accessor.ts","../src/blackboard/core/accessors/decisions-accessor.ts","../src/blackboard/snapshot/types.ts","../src/blackboard/snapshot/id-utils.ts","../src/blackboard/snapshot/compression.ts","../src/blackboard/snapshot/type-guards.ts","../src/blackboard/snapshot/utils.ts","../src/blackboard/snapshot/serializer.ts","../src/blackboard/snapshot/snapshot-creator.ts","../src/blackboard/snapshot/snapshot-validator.ts","../src/blackboard/snapshot/snapshot-restorer.ts","../src/blackboard/snapshot/snapshot-serializer.ts","../src/blackboard/snapshot/snapshot-comparer.ts","../src/blackboard/snapshot/snapshot-manager.ts","../src/blackboard/core/blackboard.ts","../src/blackboard/events/event-bus.ts","../src/blackboard/observer-reflector.ts"],"sourcesContent":["export * from \"./cell/index.js\";\nexport * from \"./policy/index.js\";\nexport * from \"./state/index.js\";\nexport * from \"./consensus/index.js\";\nexport * from \"./gates/index.js\";\nexport * from \"./audit/index.js\";\nexport * from \"./errors/index.js\";\nexport * from \"./recovery/index.js\";\nexport * from \"./orchestrator/index.js\";\nexport * from \"./patterns/index.js\";\nexport * from \"./plugins/index.js\";\nexport * from \"./storage/index.js\";\nexport * from \"./artifacts/index.js\";\nexport * from \"./checkpoint/index.js\";\n/**\n * @deprecated Legacy workflow API — will be removed in v0.3.0.\n * Use @obora/sdk Workflow and OboraRuntime instead.\n */\nexport * from \"./_legacy/workflow/index.js\";\n\n/**\n * @deprecated Legacy agent roles API — will be removed in v0.3.0.\n * Use cell/agents or @obora/sdk Agent instead.\n */\nexport * from \"./_legacy/agents/roles/index.js\";\nexport * from \"./judgment/index.js\";\n\n/**\n * Promoted blackboard API — canonical location for blackboard pattern.\n * Previously at _legacy/blackboard.\n *\n * NOTE: The full blackboard module is available via direct import from\n * packages/runtime/src/blackboard/index.ts. Only selected exports are\n * re-exported here to avoid naming conflicts with the legacy\n * Blackboard class from state/RuntimeBlackboardCompat.\n */\nexport { Blackboard as BoardBlackboard } from \"./blackboard/core/blackboard.js\";\nexport { createSessionId } from \"./blackboard/types/base.js\";\nexport type { SessionId } from \"./blackboard/types/base.js\";\nexport { TKGObserver, TKGReflector } from \"./blackboard/observer-reflector.js\";\nexport type { ObserverOptions, ReflectorOptions } from \"./blackboard/observer-reflector.js\";\n","import { randomUUID } from \"crypto\";\n\n/**\n * Unified Actor ID generation using cryptographically-secure UUIDs.\n * @param role Actor role to prefix the ID with\n * @returns ActorId-style string: `<role>-<uuid>`\n */\nexport function generateActorId(role: string): string {\n const uuid = randomUUID();\n return `${role}-${uuid}`;\n}\n","/**\n * @module actor\n * @description Actor 타입 정의 - 액터의 기본 인터페이스와 상태 관리\n */\n\nimport type { Action } from \"./action\";\nimport type { IBlackboard } from \"./blackboard\";\nimport type { Message } from \"./message\";\nimport type { IMessageBus } from \"./message\";\nimport type { ActorMetrics } from \"./metrics\";\nimport type { Observation } from \"./observation\";\nimport type { Result } from \"./result\";\nimport { generateActorId } from \"./crypto\";\n\n/**\n * Actor 고유 ID 타입\n * @description 브랜드 타입을 사용하여 타입 안전성을 확보\n *\n * 형식: `<role>-<uuid>`\n * 예: analyst-550e8400-e29b-41d4-a716-446655440000\n */\nexport type ActorId = string & { readonly __brand: \"ActorId\" };\n\n/**\n * Task 고유 ID 타입\n * @description 브랜드 타입을 사용하여 타입 안전성을 확보\n */\nexport type TaskId = string & { readonly __brand: \"TaskId\" };\n\n/**\n * Actor 역할 타입\n * @description 액터가 수행하는 역할을 정의\n */\nexport type ActorRole = \"analyst\" | \"executor\" | \"verifier\" | \"director\";\n\n/**\n * Actor 역할 설명\n * @description 각 역할의 설명 정의\n */\nexport const ActorRoleDescription: Record<ActorRole, string> = {\n analyst: \"데이터 분석, 추론, 위험 평가 수행\",\n executor: \"API 호출, 파일 처리, 외부 작업 실행\",\n verifier: \"결과 검증, 품질 체크, 오류 탐지\",\n director: \"회의 진행, 투표 관리, 의사결정 조율\",\n};\n\n/**\n * Actor 역할별 권한 레벨\n * @description 각 역할의 권한 레벨 정의\n */\nexport const ActorRoleLevel: Record<ActorRole, number> = {\n analyst: 1,\n executor: 1,\n verifier: 1,\n director: 2,\n};\n\n/**\n * Actor 생명주기 상태 열거형\n * @description 액터의 현재 실행 상태를 나타냄\n */\nexport enum ActorLifecycleStatus {\n /** 생성됨 - 초기화 완료, 시작 대기 */\n CREATED = \"created\",\n /** 시작 중 - 초기화 및 리소스 로딩 중 */\n STARTING = \"starting\",\n /** 실행 중 - 정상적으로 동작 중 */\n RUNNING = \"running\",\n /** 유휴 상태 - 대기 중, 작업 수행 가능 */\n IDLE = \"idle\",\n /** 바쁨 - 현재 작업 수행 중 */\n BUSY = \"busy\",\n /** 중지 중 - 종료 처리 중 */\n STOPPING = \"stopping\",\n /** 중지됨 - 완전히 종료됨 */\n STOPPED = \"stopped\",\n /** 재시작 중 - 재시작 처리 중 */\n RESTARTING = \"restarting\",\n /** 오류 상태 - 오류 발생으로 중단됨 */\n ERROR = \"error\",\n}\n\n/**\n * Actor 상태 인터페이스\n * @description 액터의 현재 상태 정보\n */\nexport interface ActorStatus {\n /** Actor ID */\n id: ActorId;\n /** Actor 이름 */\n name: string;\n /** Actor 역할 */\n role: ActorRole;\n /** 생명주기 상태 */\n status: ActorLifecycleStatus;\n /** 메시지 큐 상태 */\n messageQueue: {\n pending: number;\n processing: boolean;\n };\n /** 현재 작업 */\n currentTask?: {\n id: TaskId;\n type: string;\n startedAt: Date;\n };\n /** 성능 메트릭 */\n metrics: {\n totalMessagesProcessed: number;\n totalActionsExecuted: number;\n totalErrors: number;\n averageResponseTime: number;\n uptime: number;\n };\n /** 마지막 활동 시간 */\n lastSeen: Date;\n /** 마지막 활동 유형 */\n lastActivity?: \"message_received\" | \"action_executed\" | \"error_occurred\";\n /** 에러 카운트 */\n errorCount: number;\n /** 마지막 에러 */\n lastError?: {\n message: string;\n timestamp: Date;\n };\n}\n\n/**\n * 상태 전이 유효성 검사 함수\n *\n * 상태 전이 다이어그램:\n * CREATED → STARTING\n * STARTING → RUNNING | ERROR\n * RUNNING → IDLE | BUSY | STOPPING | ERROR | RESTARTING\n * IDLE → BUSY | STOPPING | RESTARTING\n * BUSY → IDLE | ERROR | RESTARTING\n * ERROR → RESTARTING | STOPPING\n * RESTARTING → RUNNING | ERROR\n * STOPPING → STOPPED\n * STOPPED → (터미널 상태)\n *\n * @param current - 현재 상태\n * @param next - 다음 상태\n * @returns 전환 가능 여부\n */\nexport function isValidTransition(\n current: ActorLifecycleStatus,\n next: ActorLifecycleStatus\n): boolean {\n const transitions: Record<ActorLifecycleStatus, ActorLifecycleStatus[]> = {\n [ActorLifecycleStatus.CREATED]: [ActorLifecycleStatus.STARTING],\n [ActorLifecycleStatus.STARTING]: [ActorLifecycleStatus.RUNNING, ActorLifecycleStatus.ERROR],\n [ActorLifecycleStatus.RUNNING]: [\n ActorLifecycleStatus.IDLE,\n ActorLifecycleStatus.BUSY,\n ActorLifecycleStatus.STOPPING,\n ActorLifecycleStatus.ERROR,\n ActorLifecycleStatus.RESTARTING,\n ],\n [ActorLifecycleStatus.IDLE]: [\n ActorLifecycleStatus.BUSY,\n ActorLifecycleStatus.STOPPING,\n ActorLifecycleStatus.RESTARTING,\n ],\n [ActorLifecycleStatus.BUSY]: [\n ActorLifecycleStatus.IDLE,\n ActorLifecycleStatus.ERROR,\n ActorLifecycleStatus.RESTARTING,\n ],\n [ActorLifecycleStatus.ERROR]: [ActorLifecycleStatus.RESTARTING, ActorLifecycleStatus.STOPPING],\n [ActorLifecycleStatus.RESTARTING]: [ActorLifecycleStatus.RUNNING, ActorLifecycleStatus.ERROR],\n [ActorLifecycleStatus.STOPPING]: [ActorLifecycleStatus.STOPPED],\n [ActorLifecycleStatus.STOPPED]: [],\n };\n\n return transitions[current]?.includes(next) ?? false;\n}\n\n// IBlackboard는 blackboard.ts에서 정의됩니다.\n// IMessageBus는 message.ts에서 정의됩니다.\n\n/**\n * Actor 인터페이스\n * @description 모든 액터가 구현해야 하는 기본 인터페이스\n */\nexport interface Actor {\n /** 고유 식별자 */\n readonly id: ActorId;\n /** 액터 이름 */\n readonly name: string;\n /** 액터 역할 */\n readonly role: ActorRole;\n /** 현재 상태 */\n readonly status: ActorStatus;\n /** 공유 데이터 저장소 (Blackboard) */\n board: IBlackboard;\n /** 메시지 버스 (message.ts의 IMessageBus 타입 사용) */\n messageBus: IMessageBus;\n /** 마지막 활동 시간 */\n lastActivity: Date;\n /** 생성 시간 */\n createdAt: Date;\n /** 성능 메트릭 */\n metrics: ActorMetrics;\n\n /**\n * 메시지 수신\n * @param message - 수신할 메시지\n * @returns 메시지 처리 결과\n */\n receive(message: Message): void | Promise<void>;\n\n /**\n * 환경 관찰\n * @returns 관찰 결과\n */\n observe(): Observation | Promise<Observation>;\n\n /**\n * 의사결정 (생각)\n * @param observation - 관찰 결과\n * @returns 결정된 행동\n */\n think(observation: Observation): Action | Promise<Action>;\n\n /**\n * 행동 수행\n * @param action - 수행할 행동\n * @returns 행동 결과\n */\n act(action: Action): Result | Promise<Result>;\n\n /**\n * 결과 보고\n * @param result - 보고할 결과\n */\n report(result: Result): void | Promise<void>;\n\n /**\n * 액터 시작\n */\n start(): void | Promise<void>;\n\n /**\n * 액터 중지\n */\n stop(): void | Promise<void>;\n\n /**\n * 액터 재시작\n */\n restart(): void | Promise<void>;\n\n /**\n * 액터 현재 상태 조회\n */\n getStatus(): ActorStatus;\n\n /**\n * 액터가 살아있는지 확인\n */\n isAlive(): boolean;\n}\n\n/**\n * Actor ID 생성 함수\n * @param role - Actor 역할\n * @returns 브랜드 타입이 적용된 ActorId\n * @example\n * ```typescript\n * const actorId = createActorId('analyst');\n * // 결과: \"analyst-550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function createActorId(role: ActorRole): ActorId {\n const id = generateActorId(role);\n return id as ActorId;\n}\n\n/**\n * Actor ID 유효성 검사\n * @param value - 확인할 값\n * @returns 유효한 ActorId 여부\n * @example\n * ```typescript\n * const value = 'analyst-550e8400-e29b-41d4-a716-446655440000';\n * if (isValidActorId(value)) {\n * // value는 유효한 ActorId\n * }\n * ```\n */\nexport function isValidActorId(value: unknown): value is ActorId {\n if (typeof value !== \"string\") {\n return false;\n }\n const pattern =\n /^(analyst|executor|verifier|director)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n return pattern.test(value);\n}\n\n/**\n * Task ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 TaskId\n * @example\n * ```typescript\n * const taskId = createTaskId('task-001');\n * // 타입: TaskId\n * ```\n */\nexport function createTaskId(id: string): TaskId {\n if (!/^task-.+/.test(id)) {\n throw new Error(\"TaskId must start with 'task-' followed by an identifier\");\n }\n return id as TaskId;\n}\n\n/**\n * Task ID 유효성 검사\n * @param value - 확인할 값\n * @returns 유효한 TaskId 여부\n * @example\n * ```typescript\n * const value = 'task-001';\n * if (isValidTaskId(value)) {\n * // value는 유효한 TaskId\n * }\n * ```\n */\nexport function isValidTaskId(value: unknown): value is TaskId {\n return typeof value === \"string\" && /^task-.+/.test(value);\n}\n\nexport type { IBlackboard } from \"./blackboard\";\n","/**\n * @module message\n * @description Message 타입 정의 - 액터 간 통신\n */\n\nimport type { ActorId } from \"./actor\";\n\n/**\n * Message 고유 ID 타입\n * @description 브랜드 타입을 사용하여 타입 안전성을 확보\n */\nexport type MessageId = string & { readonly __brand: \"MessageId\" };\n\n/**\n * 메시지 우선순위 열거형\n * @description 메시지 처리 우선순위를 정의\n */\nexport enum MessagePriority {\n /** 낮음 */\n LOW = 0,\n /** 보통 */\n NORMAL = 1,\n /** 높음 */\n HIGH = 2,\n /** 매우 높음 */\n CRITICAL = 3,\n}\n\n/**\n * 메시지 유형 열거형\n * @description 메시지의 종류를 정의\n */\nexport enum MessageType {\n // 상태 관련\n /** 상태 읽기 */\n STATE_READ = \"state.read\",\n /** 상태 쓰기 */\n STATE_WRITE = \"state.write\",\n /** 상태 구독 */\n STATE_SUBSCRIBE = \"state.subscribe\",\n /** 상태 구독 취소 */\n STATE_UNSUBSCRIBE = \"state.unsubscribe\",\n\n // 작업 관련\n /** 작업 할당 */\n TASK_ASSIGN = \"task.assign\",\n /** 작업 시작 */\n TASK_START = \"task.start\",\n /** 작업 완료 */\n TASK_COMPLETE = \"task.complete\",\n /** 작업 실패 */\n TASK_FAILED = \"task.failed\",\n /** 작업 취소 */\n TASK_CANCEL = \"task.cancel\",\n\n // 의사결정 관련\n /** 의사결정 요청 */\n DECISION_REQUEST = \"decision.request\",\n /** 의견 제출 */\n OPINION_SUBMIT = \"opinion.submit\",\n /** 의견 요청 */\n OPINION_REQUEST = \"opinion.request\",\n /** 투표 제출 */\n VOTE_SUBMIT = \"vote.submit\",\n /** 투표 요청 */\n VOTE_REQUEST = \"vote.request\",\n /** 합의 도달 */\n CONSENSUS_REACHED = \"consensus.reached\",\n\n // 시스템 관련\n /** 핑 */\n PING = \"ping\",\n /** 퐁 */\n PONG = \"pong\",\n /** 하트비트 */\n HEARTBEAT = \"heartbeat\",\n /** 상태 요청 */\n STATUS_REQUEST = \"status.request\",\n /** 상태 응답 */\n STATUS_RESPONSE = \"status.response\",\n\n // 에러 관련\n /** 에러 */\n ERROR = \"error\",\n /** 에러 승인 */\n ERROR_ACK = \"error.ack\",\n\n // 생명주기 관련\n /** 시작 */\n START = \"start\",\n /** 중지 */\n STOP = \"stop\",\n /** 재시작 */\n RESTART = \"restart\",\n /** 강제 종료 */\n KILL = \"kill\",\n\n // 사용자 정의\n /** 사용자 정의 메시지 */\n CUSTOM = \"custom\",\n}\n\n/**\n * Message 인터페이스\n * @description 액터 간 통신에 사용되는 메시지\n */\nexport interface Message<T = unknown> {\n /** 고유 식별자 */\n id: MessageId;\n /** 메시지 유형 */\n type: MessageType;\n /** 발신자 액터 ID */\n from: ActorId;\n /** 수신자 액터 ID ('broadcast' 시 전체 전송) */\n to: ActorId | \"broadcast\";\n /** 메시지 내용 */\n payload: T;\n /** 메시지 생성 시간 */\n timestamp: Date;\n /** 상관 관계 ID (선택적) - 응답 메시지와 요청 메시지 연결 */\n correlationId?: string;\n /** 응답 대상 (선택적) - 응답 메시지의 수신자 */\n replyTo?: ActorId;\n /** 메시지 우선순위 (선택적) */\n priority?: MessagePriority;\n /** Time to Live (선택적) - 메시지 유효 시간 (ms) */\n ttl?: number;\n /** 전달 확인 요청 (선택적) */\n deliveryReceipt?: boolean;\n}\n\n/**\n * 구독 취소 함수 타입\n * @description 메시지 구독을 취소하는 함수\n */\nexport type UnsubscribeFn = () => void;\n\n/**\n * IMessageBus 인터페이스\n * @description 액터 간 메시지 전달 시스템\n */\nexport interface IMessageBus {\n /**\n * 메시지 전송\n * @param message - 전송할 메시지\n */\n send(message: Message): void;\n\n /**\n * 특정 Actor에 메시지 전송\n * @param to - 수신자 Actor ID\n * @param message - 전송할 메시지 (to 필드 제외)\n */\n sendTo(to: ActorId, message: Omit<Message, \"to\">): void;\n\n /**\n * 브로드캐스트 전송\n * @param message - 전송할 메시지 (to 필드 제외)\n */\n broadcast(message: Omit<Message, \"to\">): void;\n\n /**\n * 메시지 수신 핸들러 등록\n * @param handler - 메시지 처리 핸들러\n */\n receive(handler: (message: Message) => void): void;\n\n /**\n * 요청-응답 패턴\n * @param message - 요청 메시지\n * @param timeoutMs - 타임아웃 시간 (ms)\n * @returns 응답 메시지 Promise\n */\n request<T>(message: Message, timeoutMs?: number): Promise<Message<T>>;\n\n /**\n * 메시지 타입 구독\n * @param messageType - 구독할 메시지 타입\n * @param handler - 메시지 처리 핸들러\n * @returns 구독 취소 함수\n */\n subscribe(messageType: MessageType, handler: (message: Message) => void): UnsubscribeFn;\n\n /**\n * 메시지 큐 크기 조회\n * @param actorId - Actor ID\n * @returns 큐에 대기 중인 메시지 수\n */\n getQueueSize(actorId: ActorId): number;\n\n /**\n * 메시지 큐 비우기\n * @param actorId - Actor ID\n */\n clearQueue(actorId: ActorId): void;\n\n /**\n * 메시지 필터링\n * @param predicate - 필터링 조건\n */\n filter(predicate: (message: Message) => boolean): Message[];\n}\n\n/**\n * Message ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 MessageId\n * @example\n * ```typescript\n * const messageId = createMessageId('msg-001');\n * // 타입: MessageId\n * ```\n */\nexport function createMessageId(id: string): MessageId {\n if (!id.startsWith(\"msg-\")) {\n throw new Error(\"MessageId must start with 'msg-'\");\n }\n return id as MessageId;\n}\n\n/**\n * Message ID 유효성 검사\n * @param value - 확인할 값\n * @returns 유효한 MessageId 여부\n */\nexport function isValidMessageId(value: unknown): value is MessageId {\n return typeof value === \"string\" && value.length > 0 && value.startsWith(\"msg-\");\n}\n\n/**\n * Message 생성 함수\n * @param params - Message 생성 파라미터\n * @returns 생성된 Message 객체\n * @example\n * ```typescript\n * const message = createMessage({\n * id: createMessageId('msg-001'),\n * type: MessageType.COMMAND,\n * from: createActorId('analyst-550e8400-e29b-41d4-a716-446655440000'),\n * to: createActorId('executor-550e8400-e29b-41d4-a716-446655440001'),\n * payload: { action: 'start' }\n * });\n * ```\n */\nexport function createMessage<T>(params: Omit<Message<T>, \"timestamp\">): Message<T> {\n return {\n ...params,\n timestamp: new Date(),\n };\n}\n","/**\n * @module metrics\n * @description Metrics 타입 정의 - 액터 성능 메트릭\n */\n\nimport type { ActorId } from \"./actor\";\n\n/**\n * Actor 성능 메트릭 인터페이스\n * @description 액터의 성능 및 실행 통계\n */\nexport interface ActorMetrics {\n /** 총 실행 횟수 */\n totalRuns: number;\n /** 성공 횟수 */\n successCount: number;\n /** 실패 횟수 */\n failureCount: number;\n /** 마지막 오류 */\n lastError: Error | null;\n /** 평균 실행 시간 */\n averageExecutionTime: number;\n /** 총 실행 시간 (밀리초) */\n totalExecutionTimeMs: number;\n /** 마지막 실행 시간 */\n lastRunAt?: Date;\n /** 생성 시간 */\n createdAt: Date;\n /** 마지막 업데이트 시간 */\n updatedAt: Date;\n /** 마지막 실행 시간 (밀리초) */\n lastExecutionTime: number | null;\n /** 총 CPU 사용 시간 (밀리초) */\n totalCpuTime: number;\n /** 메모리 사용량 (바이트) */\n memoryUsage: number;\n}\n\n/**\n * Actor 메트릭 생성 함수\n * @returns 생성된 ActorMetrics 객체\n * @example\n * ```typescript\n * const metrics = createActorMetrics();\n * ```\n */\nexport function createActorMetrics(): ActorMetrics {\n const now = new Date();\n return {\n totalRuns: 0,\n successCount: 0,\n failureCount: 0,\n lastError: null,\n averageExecutionTime: 0,\n totalExecutionTimeMs: 0,\n createdAt: now,\n updatedAt: now,\n lastExecutionTime: null,\n totalCpuTime: 0,\n memoryUsage: 0,\n };\n}\n","import type { Action } from \"../types/action\";\nimport {\n Actor,\n ActorId,\n ActorRole,\n ActorStatus,\n ActorLifecycleStatus,\n isValidTransition,\n} from \"../types/actor\";\nimport type { IBlackboard } from \"../types/blackboard\";\nimport type { IMessageBus, Message, MessageId } from \"../types/message\";\nimport { createMessageId } from \"../types/message\";\nimport { MessageType } from \"../types/message\";\nimport { createActorMetrics, ActorMetrics } from \"../types/metrics\";\nimport type { Observation } from \"../types/observation\";\nimport type { Result } from \"../types/result\";\n\n/**\n * Actor 구현을 위한 추상 기본 클래스 (스펙 기준)\n *\n * 구체적인 Actor 구현 시 이 클래스를 상속받아 필요한 메서드를 구현합니다.\n *\n * 참고: [[spec/13-actor.md|13-actor.md]]\n */\nexport abstract class BaseActor implements Actor {\n readonly id: ActorId;\n readonly name: string;\n readonly role: ActorRole;\n board: IBlackboard;\n messageBus: IMessageBus;\n private _status: ActorStatus;\n lastActivity: Date;\n createdAt: Date;\n metrics: ActorMetrics;\n private subscriptions: (() => void)[] = [];\n\n constructor(\n id: ActorId,\n name: string,\n role: ActorRole,\n board: IBlackboard,\n messageBus: IMessageBus\n ) {\n this.id = id;\n this.name = name;\n this.role = role;\n this.board = board;\n this.messageBus = messageBus;\n this.createdAt = new Date();\n this.lastActivity = this.createdAt;\n this.metrics = createActorMetrics();\n this._status = {\n id: this.id,\n name: this.name,\n role: this.role,\n status: ActorLifecycleStatus.CREATED,\n messageQueue: {\n pending: 0,\n processing: false,\n },\n metrics: {\n totalMessagesProcessed: 0,\n totalActionsExecuted: 0,\n totalErrors: 0,\n averageResponseTime: 0,\n uptime: 0,\n },\n lastSeen: this.createdAt,\n errorCount: 0,\n };\n }\n\n get status(): ActorStatus {\n return this._status;\n }\n\n protected setStatus(newStatus: ActorLifecycleStatus): void {\n if (!isValidTransition(this._status.status, newStatus)) {\n throw new Error(`Invalid status transition: ${this._status.status} → ${newStatus}`);\n }\n this._status.status = newStatus;\n this.lastActivity = new Date();\n this._status.lastSeen = this.lastActivity;\n }\n\n /**\n * 하위 클래스에서 observe()를 구현해야 합니다.\n * 동기 또는 비동기 구현 모두 가능합니다.\n */\n abstract observe(): Observation | Promise<Observation>;\n\n /**\n * 하위 클래스에서 think()를 구현해야 합니다.\n * 동기 또는 비동기 구현 모두 가능합니다.\n */\n abstract think(observation: Observation): Action | Promise<Action>;\n\n /**\n * 하위 클래스에서 act()를 구현해야 합니다.\n * 동기 또는 비동기 구현 모두 가능합니다.\n */\n abstract act(action: Action): Result | Promise<Result>;\n\n /**\n * receive()의 기본 구현 - 메시지 처리\n */\n async receive(message: Message): Promise<void> {\n this.updateLastActivity();\n\n switch (message.type) {\n case MessageType.PING:\n this.handlePing(message);\n break;\n case MessageType.TASK_ASSIGN:\n await this.handleTaskAssign(message);\n break;\n case MessageType.STATUS_REQUEST:\n this.handleStatusRequest(message);\n break;\n case MessageType.STOP:\n await this.stop();\n break;\n case MessageType.RESTART:\n await this.restart();\n break;\n default:\n this.handleCustomMessage(message);\n }\n }\n\n /**\n * report()의 기본 구현 - Blackboard에 결과 기록\n * 동기 또는 비동기 구현 모두 가능합니다.\n */\n report(result: Result): void | Promise<void> {\n if (result.toRecord) {\n const { section, data } = result.toRecord;\n this.board.write(section, data);\n }\n\n this.updateMetrics(result);\n\n // 이벤트 발행\n this.messageBus.broadcast({\n id: createMessageId(`msg-${crypto.randomUUID()}`),\n type: MessageType.TASK_COMPLETE,\n from: this.id,\n payload: { taskId: result.actionId, result },\n timestamp: new Date(),\n });\n }\n\n /**\n * start()의 기본 구현\n */\n async start(): Promise<void> {\n if (this.isAlive()) return;\n\n this.setStatus(ActorLifecycleStatus.STARTING);\n\n try {\n // 메시지 수신 시작\n this.setupMessageHandlers();\n\n // 상태 변경\n this.setStatus(ActorLifecycleStatus.RUNNING);\n\n // 하트비트 시작\n this.startHeartbeat();\n } catch (error) {\n this.setStatus(ActorLifecycleStatus.ERROR);\n throw error;\n }\n }\n\n /**\n * stop()의 기본 구현\n */\n async stop(): Promise<void> {\n if (this._status.status === ActorLifecycleStatus.STOPPED) return;\n\n const canStop = [\n ActorLifecycleStatus.RUNNING,\n ActorLifecycleStatus.IDLE,\n ActorLifecycleStatus.ERROR,\n ].includes(this._status.status);\n\n if (!canStop) {\n throw new Error(\n `Cannot stop from ${this._status.status} state - valid states for stop: RUNNING, IDLE, ERROR`\n );\n }\n\n this.setStatus(ActorLifecycleStatus.STOPPING);\n\n // 구독 해제\n this.teardownMessageHandlers();\n\n // 하트비트 정지\n this.stopHeartbeat();\n\n this.setStatus(ActorLifecycleStatus.STOPPED);\n }\n\n /**\n * restart()의 기본 구현\n */\n async restart(): Promise<void> {\n const currentStatus = this._status.status;\n\n // STOPPED is a terminal state, cannot restart\n if (currentStatus === ActorLifecycleStatus.STOPPED) {\n throw new Error(\"Cannot restart from STOPPED state - it is a terminal state\");\n }\n\n // Direct restart via RESTARTING state (for alive states and ERROR)\n if (\n [\n ActorLifecycleStatus.RUNNING,\n ActorLifecycleStatus.IDLE,\n ActorLifecycleStatus.BUSY,\n ActorLifecycleStatus.ERROR,\n ].includes(currentStatus)\n ) {\n this.setStatus(ActorLifecycleStatus.RESTARTING);\n\n try {\n this.stopHeartbeat();\n this.setupMessageHandlers();\n this.setStatus(ActorLifecycleStatus.RUNNING);\n this.startHeartbeat();\n } catch (error) {\n this.setStatus(ActorLifecycleStatus.ERROR);\n throw error;\n }\n }\n // For other states (CREATED, STARTING, STOPPING, RESTARTING), just start\n else {\n await this.start();\n }\n }\n\n /**\n * isAlive() 기본 구현\n */\n isAlive(): boolean {\n return (\n this._status.status === ActorLifecycleStatus.RUNNING ||\n this._status.status === ActorLifecycleStatus.IDLE ||\n this._status.status === ActorLifecycleStatus.BUSY\n );\n }\n\n /**\n * getStatus() 기본 구현\n */\n getStatus(): ActorStatus {\n const statusCopy = { ...this._status };\n statusCopy.metrics = { ...this._status.metrics };\n statusCopy.metrics.uptime = Date.now() - this.createdAt.getTime();\n return statusCopy;\n }\n\n /**\n * 메트릭 업데이트\n */\n protected updateMetrics(result: Result): void {\n this.metrics.totalRuns++;\n if (result.status === \"success\") {\n this.metrics.successCount++;\n } else {\n this.metrics.failureCount++;\n this.metrics.lastError = result.error ? new Error(result.error) : null;\n }\n this.metrics.lastExecutionTime = result.metrics?.duration ?? null;\n this.metrics.averageExecutionTime =\n (this.metrics.averageExecutionTime * (this.metrics.totalRuns - 1) +\n (result.metrics?.duration ?? 0)) /\n this.metrics.totalRuns;\n\n // 내부 status 메트릭도 동기화\n this._status.metrics.totalActionsExecuted++;\n this._status.metrics.uptime = Date.now() - this.createdAt.getTime();\n if (result.status !== \"success\") {\n this._status.metrics.totalErrors++;\n }\n }\n\n // ==================== 핸들러 ====================\n\n private async handleTaskAssign(_message: Message): Promise<void> {\n // 작업 수행\n const observation = await this.observe();\n const action = await this.think(observation);\n const result = await this.act(action);\n await this.report(result);\n }\n\n private handlePing(message: Message): void {\n this.messageBus.sendTo(message.from, {\n id: createMessageId(`msg-${crypto.randomUUID()}`),\n type: MessageType.PONG,\n from: this.id,\n payload: {},\n timestamp: new Date(),\n });\n }\n\n private handleStatusRequest(message: Message): void {\n const status = this.getStatus();\n\n this.messageBus.sendTo(message.from, {\n id: createMessageId(`msg-${crypto.randomUUID()}`),\n type: MessageType.STATUS_RESPONSE,\n from: this.id,\n payload: { status },\n timestamp: new Date(),\n });\n }\n\n protected handleCustomMessage(_message: Message): void {\n // 서브클래스에서 오버라이드\n }\n\n private teardownMessageHandlers(): void {\n this.subscriptions.forEach((unsubscribe) => unsubscribe());\n this.subscriptions = [];\n }\n\n private setupMessageHandlers(): void {\n // 기존 구독 해제\n this.teardownMessageHandlers();\n\n // 새로운 구독 등록\n this.subscriptions.push(\n this.messageBus.subscribe(MessageType.PING, (msg) => this.receive(msg))\n );\n this.subscriptions.push(\n this.messageBus.subscribe(MessageType.TASK_ASSIGN, (msg) => this.receive(msg))\n );\n this.subscriptions.push(\n this.messageBus.subscribe(MessageType.STATUS_REQUEST, (msg) => this.receive(msg))\n );\n this.subscriptions.push(\n this.messageBus.subscribe(MessageType.STOP, (msg) => this.receive(msg))\n );\n this.subscriptions.push(\n this.messageBus.subscribe(MessageType.RESTART, (msg) => this.receive(msg))\n );\n }\n\n private heartbeatTimer?: ReturnType<typeof setInterval>;\n\n private startHeartbeat(): void {\n this.heartbeatTimer = setInterval(() => {\n this.messageBus.broadcast({\n id: createMessageId(`msg-${crypto.randomUUID()}`),\n type: MessageType.HEARTBEAT,\n from: this.id,\n payload: {\n timestamp: new Date(),\n status: this._status.status,\n },\n timestamp: new Date(),\n });\n }, 30000); // 30초마다\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = undefined;\n }\n }\n\n private updateLastActivity(): void {\n this.lastActivity = new Date();\n this._status.lastSeen = this.lastActivity;\n }\n}\n","/**\n * 지정된 시간만큼 대기하는 Promise를 반환합니다.\n * @param ms 대기할 시간(밀리초)\n * @param signal 취소 신호 (optional)\n * @returns Promise<void>\n */\nexport function delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n\n const timeoutId = setTimeout(resolve, ms);\n\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timeoutId);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n },\n { once: true }\n );\n });\n}\n","import { ActorLifecycleStatus } from \"../types/actor\";\nimport type { Actor, ActorId, ActorRole } from \"../types/actor\";\nimport type { IBlackboard } from \"../types/actor\";\nimport type { IMessageBus } from \"../types/message\";\n\nimport type { ActorFactory, ActorConfig } from \"./types\";\nimport { delay } from \"./utils/delay\";\n\nexport class ActorStopTimeoutError extends Error {\n constructor(actorId: ActorId) {\n super(`Actor stop timeout: ${actorId}`);\n this.name = \"ActorStopTimeoutError\";\n }\n}\n\n/**\n * Actor runtime configuration.\n */\nexport interface RuntimeConfig {\n /** Maximum number of concurrent actors. */\n maxActors?: number;\n\n /** Default timeout for actor spawn/start in milliseconds. */\n spawnTimeout?: number;\n\n /** Default timeout for actor stop in milliseconds. */\n stopTimeout?: number;\n\n /** Maximum number of restart attempts. */\n maxRestarts?: number;\n\n /** Initial restart backoff in milliseconds. */\n initialBackoff?: number;\n\n /** Maximum restart backoff in milliseconds. */\n maxBackoff?: number;\n\n /** Enables debug logging. */\n debug?: boolean;\n}\n\n/**\n * Actor runtime.\n *\n * Responsible for actor creation, management, and shutdown.\n */\nexport interface RuntimeStopResult {\n stopped: ActorId[];\n failed: Array<{ id: ActorId; error: unknown }>;\n}\n\nexport class ActorRuntime {\n private readonly actors: Map<ActorId, Actor>;\n private readonly actorConfigs: Map<ActorId, ActorConfig>;\n private readonly spawningActorIds: Set<ActorId>;\n private readonly zombies: Set<ActorId>;\n private readonly board: IBlackboard;\n private readonly messageBus: IMessageBus;\n private readonly config: Required<RuntimeConfig>;\n private readonly factory: ActorFactory;\n private isRunning: boolean;\n\n constructor(\n board: IBlackboard,\n messageBus: IMessageBus,\n factory: ActorFactory,\n config?: RuntimeConfig\n ) {\n this.board = board;\n this.messageBus = messageBus;\n this.factory = factory;\n this.actors = new Map();\n this.actorConfigs = new Map();\n this.spawningActorIds = new Set();\n this.zombies = new Set();\n this.isRunning = false;\n\n // Default configuration\n const defaults: Required<RuntimeConfig> = {\n maxActors: 100,\n spawnTimeout: 5000,\n stopTimeout: 5000,\n maxRestarts: 3,\n initialBackoff: 1000,\n maxBackoff: 30000,\n debug: false,\n };\n this.config = { ...defaults, ...config };\n\n // Validate RuntimeConfig\n this.validateRuntimeConfig(this.config);\n }\n\n /**\n * Starts the runtime.\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"Runtime is already running\");\n }\n this.isRunning = true;\n this.log(\"Runtime started\");\n }\n\n /**\n * Stops the runtime.\n */\n async stop(): Promise<RuntimeStopResult> {\n // Runtime shutdown is idempotent\n if (!this.isRunning) {\n return { stopped: [], failed: [] };\n }\n\n this.log(\"Stopping runtime...\");\n\n const actorIds = Array.from(this.actors.keys());\n const settled = await Promise.allSettled(actorIds.map((actorId) => this.stopActor(actorId)));\n\n const stopped: ActorId[] = [];\n const failed: Array<{ id: ActorId; error: unknown }> = [];\n\n settled.forEach((result, index) => {\n const actorId = actorIds[index]!;\n if (result.status === \"fulfilled\") {\n stopped.push(actorId);\n } else {\n failed.push({ id: actorId, error: result.reason });\n }\n });\n\n const failedIds = new Set(failed.map((entry) => entry.id));\n for (const zombieId of this.zombies) {\n if (!failedIds.has(zombieId)) {\n failed.push({ id: zombieId, error: new ActorStopTimeoutError(zombieId) });\n }\n }\n\n this.actors.clear();\n this.isRunning = false;\n this.log(\"Runtime stopped\");\n\n return { stopped, failed };\n }\n\n /**\n * Stops a specific actor by ID.\n * @param actorId Actor ID.\n */\n async stopById(actorId: ActorId): Promise<void> {\n if (!this.isRunning) {\n return;\n }\n\n const actor = this.getActor(actorId);\n await this.stopActor(actor.id);\n }\n\n /**\n * Spawns a new actor.\n * @param config Actor configuration.\n * @returns The created actor.\n */\n async spawn(config: ActorConfig): Promise<Actor> {\n if (!this.isRunning) {\n throw new Error(\"Runtime is not running\");\n }\n\n // Validate ActorConfig input\n this.validateConfig(config);\n\n // Check maximum actor count (including in-flight spawns)\n if (this.actors.size + this.spawningActorIds.size >= this.config.maxActors) {\n throw new Error(`Maximum actors limit reached: ${this.config.maxActors}`);\n }\n\n // Node.js는 단일 스레드이므로 await 이전 구간은 원자적으로 실행됩니다.\n // 다만 await 경계 사이에서는 interleaving이 발생할 수 있으므로,\n // 명시 ID는 spawn 시작 시 placeholder(Set)로 선점하여 TOCTOU를 방지합니다.\n const reservedId = config.id;\n if (reservedId) {\n if (this.actors.has(reservedId) || this.spawningActorIds.has(reservedId)) {\n throw new Error(`Actor already exists: ${reservedId}`);\n }\n this.spawningActorIds.add(reservedId);\n }\n\n this.log(`Spawning actor: ${config.id || \"auto-generated\"} (${config.role})`);\n\n const startTime = Date.now();\n let actor: Actor | null = null;\n\n try {\n const spawnAbort = new AbortController();\n const createAbort = new AbortController();\n const createPromise = this.factory.create(config, this.board, this.messageBus, {\n signal: createAbort.signal,\n });\n createPromise.catch(() => {});\n\n try {\n actor = await Promise.race([\n createPromise,\n delay(this.config.spawnTimeout, spawnAbort.signal).then(() => {\n createAbort.abort();\n throw new Error(`Actor spawn timeout: ${config.id || \"unknown\"}`);\n }),\n ]);\n createAbort.abort();\n spawnAbort.abort();\n } catch (error) {\n spawnAbort.abort();\n createAbort.abort();\n throw error;\n }\n\n // Protect auto-generated IDs during in-flight start/registration window\n const hadSpawningActorId = this.spawningActorIds.has(actor.id);\n if (hadSpawningActorId && actor.id !== reservedId) {\n throw new Error(`Actor already exists: ${actor.id}`);\n }\n this.spawningActorIds.add(actor.id);\n\n const startAbort = new AbortController();\n const startPromise = Promise.resolve(actor!.start());\n startPromise.catch(() => {});\n\n try {\n await Promise.race([\n startPromise,\n delay(this.config.spawnTimeout, startAbort.signal).then(() => {\n throw new Error(`Actor start timeout: ${actor!.id}`);\n }),\n ]);\n startAbort.abort();\n } catch (error) {\n startAbort.abort();\n throw error;\n }\n\n // Check duplication before registration (including auto-generated IDs)\n if (this.actors.has(actor.id)) {\n throw new Error(`Actor ID collision: ${actor.id}`);\n }\n\n this.actors.set(actor.id, actor);\n this.actorConfigs.set(actor.id, config);\n this.spawningActorIds.delete(actor.id);\n this.zombies.delete(actor.id);\n\n const duration = Date.now() - startTime;\n this.log(`Actor spawned: ${actor.id} (${duration}ms)`);\n\n return actor;\n } catch (error) {\n // Cleanup on timeout or error\n if (actor) {\n const cleanupAbort = new AbortController();\n const cleanupStopPromise = Promise.resolve(actor.stop());\n cleanupStopPromise.catch(() => {});\n\n try {\n const cleanupResult = await Promise.race<\"stopped\" | \"timeout\">([\n cleanupStopPromise.then(() => \"stopped\"),\n delay(this.config.stopTimeout ?? this.config.spawnTimeout, cleanupAbort.signal).then(\n () => \"timeout\"\n ),\n ]);\n\n cleanupAbort.abort();\n\n if (cleanupResult === \"timeout\") {\n this.zombies.add(actor.id);\n this.log(`Spawn cleanup timeout, actor ${actor.id} added to zombies`);\n }\n } catch (cleanupError) {\n cleanupAbort.abort();\n this.zombies.add(actor.id);\n this.log(`Spawn cleanup failed, actor ${actor.id} added to zombies`, cleanupError);\n }\n }\n const duration = Date.now() - startTime;\n this.log(`Actor spawn failed: ${config.id || \"unknown\"} (${duration}ms)`, error);\n throw error;\n } finally {\n if (reservedId) {\n this.spawningActorIds.delete(reservedId);\n }\n if (actor) {\n this.spawningActorIds.delete(actor.id);\n }\n }\n }\n\n /**\n * Restarts an actor.\n *\n * Total restart attempts are capped at `maxRestarts`.\n * @param actorId Actor ID.\n * @param restartCount Current restart attempt count (internal use).\n * @internal\n */\n async restart(actorId: ActorId, restartCount = 0): Promise<Actor> {\n if (restartCount >= this.config.maxRestarts) {\n throw new Error(`Max restarts (${this.config.maxRestarts}) exceeded for actor: ${actorId}`);\n }\n\n const actor = this.actors.get(actorId);\n const config = this.actorConfigs.get(actorId);\n\n if (!actor || !config) {\n throw new Error(`Actor or config not found: ${actorId}`);\n }\n\n const savedConfig = { ...config, id: actorId };\n\n this.log(`Restarting actor: ${actorId} (attempt ${restartCount + 1})`);\n\n try {\n await this.stopActor(actor.id);\n return this.retryRestart(actorId, savedConfig, restartCount);\n } catch (error) {\n this.log(`Actor restart failed: ${actorId}`, error);\n throw error;\n }\n }\n\n /**\n * Retries actor spawn with exponential backoff.\n * @param actorId Actor ID.\n * @param config Actor configuration.\n * @param restartCount Current restart attempt count.\n */\n private async retryRestart(\n actorId: ActorId,\n config: ActorConfig,\n restartCount: number\n ): Promise<Actor> {\n let attempt = restartCount;\n\n while (attempt < this.config.maxRestarts) {\n this.log(`Retrying actor restart: ${actorId} (attempt ${attempt + 1})`);\n\n const backoff = this.calculateBackoff(attempt);\n if (backoff > 0) {\n await delay(backoff);\n }\n\n try {\n const newActor = await this.spawn(config);\n this.log(`Actor restarted: ${actorId}`);\n return newActor;\n } catch (error) {\n this.log(`Actor retry restart failed: ${actorId}`, error);\n attempt += 1;\n }\n }\n\n throw new Error(`Max restarts (${this.config.maxRestarts}) exceeded for actor: ${actorId}`);\n }\n\n /**\n * Gets an actor by ID.\n * @param actorId Actor ID.\n * @returns Actor instance.\n */\n getActor(actorId: ActorId): Actor {\n const actor = this.actors.get(actorId);\n if (!actor) {\n throw new Error(`Actor not found: ${actorId}`);\n }\n return actor;\n }\n\n /**\n * Checks whether an actor exists.\n * @param actorId Actor ID.\n * @returns True if the actor exists.\n */\n hasActor(actorId: ActorId): boolean {\n return this.actors.has(actorId);\n }\n\n /**\n * Returns all actor IDs.\n * @returns Array of actor IDs.\n */\n listActors(): ActorId[] {\n return Array.from(this.actors.keys());\n }\n\n /**\n * Returns actors filtered by role.\n * @param role Actor role.\n * @returns Array of actor IDs.\n */\n listActorsByRole(role: ActorRole): ActorId[] {\n return Array.from(this.actors.values())\n .filter((actor) => actor.role === role)\n .map((actor) => actor.id);\n }\n\n /**\n * Returns actors filtered by lifecycle status.\n * @param status Actor lifecycle status.\n * @returns Array of actor IDs.\n */\n listActorsByStatus(status: ActorLifecycleStatus): ActorId[] {\n return Array.from(this.actors.values())\n .filter((actor) => actor.status.status === status)\n .map((actor) => actor.id);\n }\n\n /**\n * Returns the current number of actors.\n */\n size(): number {\n return this.actors.size;\n }\n\n /**\n * Returns runtime status.\n */\n getStatus(): { running: boolean; actorCount: number } {\n return {\n running: this.isRunning,\n actorCount: this.actors.size,\n };\n }\n\n /**\n * Returns actor IDs that timed out during stop and may still be running.\n */\n getZombies(): ActorId[] {\n return Array.from(this.zombies);\n }\n\n // ==================== Internal methods ====================\n\n /**\n * Stops a managed actor and releases runtime references.\n *\n * Timeout trade-off:\n * - `actor.stop()` is raced against `stopTimeout`.\n * - In `finally`, the runtime always removes actor/config map entries, even when\n * stop fails or times out.\n *\n * Why: keeping stale map entries blocks respawn/restart paths and leaks management state.\n * Trade-off: the underlying actor implementation might still be running after timeout\n * (\"zombie\" actor) because JavaScript promises are not force-cancelled.\n */\n private async stopActor(actorId: ActorId): Promise<void> {\n const actor = this.actors.get(actorId);\n if (!actor) return;\n\n this.log(`Stopping actor: ${actorId}`);\n\n let timedOut = false;\n\n try {\n const stopAbort = new AbortController();\n const stopPromise = Promise.resolve(actor.stop());\n stopPromise.catch(() => {});\n\n try {\n await Promise.race([\n stopPromise,\n delay(this.config.stopTimeout, stopAbort.signal).then(() => {\n throw new ActorStopTimeoutError(actorId);\n }),\n ]);\n stopAbort.abort();\n } catch (error) {\n stopAbort.abort();\n if (this.isStopTimeoutError(error, actorId)) {\n timedOut = true;\n this.zombies.add(actorId);\n }\n throw error;\n }\n\n this.zombies.delete(actorId);\n this.log(`Actor stopped: ${actorId}`);\n } catch (error) {\n this.log(`Actor stop failed or timed out: ${actorId}`, error);\n throw error;\n } finally {\n this.actors.delete(actorId);\n this.actorConfigs.delete(actorId);\n if (timedOut) {\n this.log(`Actor marked as zombie: ${actorId}`);\n }\n this.log(`Actor removed: ${actorId}`);\n }\n }\n\n private isStopTimeoutError(error: unknown, _actorId: ActorId): boolean {\n return error instanceof ActorStopTimeoutError;\n }\n\n /**\n * Calculates exponential backoff for restart attempts.\n * @param restartCount Current restart attempt count.\n * @returns Backoff duration in milliseconds.\n */\n private calculateBackoff(restartCount: number): number {\n const factor = Math.pow(2, restartCount);\n const backoff = this.config.initialBackoff * factor;\n return Math.min(backoff, this.config.maxBackoff);\n }\n\n /**\n * Validates ActorConfig input.\n * @param config ActorConfig to validate.\n */\n private validateConfig(config: ActorConfig): void {\n if (!config.name || config.name.trim() === \"\") {\n throw new Error(\"Actor name is required\");\n }\n if (!config.role) {\n throw new Error(\"Actor role is required\");\n }\n if (!config.type || config.type.trim() === \"\") {\n throw new Error(\"Actor type is required\");\n }\n }\n\n /**\n * Validates RuntimeConfig input.\n * @param config RuntimeConfig to validate.\n */\n private validateRuntimeConfig(config: Required<RuntimeConfig>): void {\n if (config.maxActors <= 0) {\n throw new Error(\"maxActors must be positive\");\n }\n if (config.spawnTimeout <= 0) {\n throw new Error(\"spawnTimeout must be positive\");\n }\n if (config.stopTimeout <= 0) {\n throw new Error(\"stopTimeout must be positive\");\n }\n if (config.maxRestarts < 0) {\n throw new Error(\"maxRestarts must be non-negative\");\n }\n if (config.initialBackoff <= 0) {\n throw new Error(\"initialBackoff must be positive\");\n }\n if (config.maxBackoff <= 0) {\n throw new Error(\"maxBackoff must be positive\");\n }\n }\n\n private log(message: string, error?: unknown): void {\n if (!this.config.debug) return;\n\n if (error) {\n console.error(`[ActorRuntime] ${message}`, error);\n } else {\n console.log(`[ActorRuntime] ${message}`);\n }\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { BaseActor } from \"./BaseActor.js\";\nimport type { IBlackboard } from \"../_legacy/actor/types/blackboard.js\";\nimport { createActorId } from \"../_legacy/actor/types/actor.js\";\nimport type { ActorId, ActorRole } from \"../_legacy/actor/types/actor.js\";\nimport type { IMessageBus, Message, MessageType } from \"../_legacy/actor/types/message.js\";\nimport { createAction } from \"../_legacy/actor/types/action.js\";\nimport { createObservation } from \"../_legacy/actor/types/observation.js\";\nimport { createFailureResult, createSuccessResult } from \"../_legacy/actor/types/result.js\";\nimport type {\n CellId,\n CellMetrics,\n CellResult,\n CellStatus,\n StateChange,\n Task,\n ToolCallRecord,\n} from \"./types.js\";\nimport type { AuditRecorder, CellContext, StateAccessor, ToolSet } from \"./CellContext.js\";\n\nexport interface ExecutionCell {\n readonly id: CellId;\n readonly status: CellStatus;\n\n execute(task: Task): Promise<CellResult>;\n suspend(): Promise<void>;\n resume(): Promise<void>;\n abort(reason: string): Promise<void>;\n}\n\ninterface DefaultExecutionCellOptions {\n id: CellId;\n context: CellContext;\n runTask?: (task: Task, context: CellContext) => Promise<unknown>;\n actorRole?: ActorRole;\n actorName?: string;\n}\n\nclass NoOpMessageBus implements IMessageBus {\n send(_message: Message): void {}\n sendTo(_to: ActorId, _message: Omit<Message, \"to\">): void {}\n broadcast(_message: Omit<Message, \"to\">): void {}\n receive(_handler: (message: Message) => void): void {}\n request<T>(_message: Message, _timeoutMs?: number): Promise<Message<T>> {\n return Promise.reject(new Error(\"NoOpMessageBus does not support request\"));\n }\n subscribe(_messageType: MessageType, _handler: (message: Message) => void): () => void {\n return () => {};\n }\n getQueueSize(_actorId: ActorId): number {\n return 0;\n }\n clearQueue(_actorId: ActorId): void {}\n filter(_predicate: (message: Message) => boolean): Message[] {\n return [];\n }\n}\n\nclass BlackboardAdapter implements IBlackboard {\n private readonly keysSet = new Set<string>();\n\n constructor(private readonly accessor: StateAccessor) {}\n\n get version(): number {\n return this.keysSet.size;\n }\n\n read(key: string): unknown {\n return this.accessor.read(key);\n }\n\n write(key: string, value: unknown): void {\n this.keysSet.add(key);\n this.accessor.write(key, value);\n }\n\n delete(_key: string): void {}\n\n keys(): string[] {\n return [...this.keysSet];\n }\n\n find(pattern: string): string[] {\n return [...this.keysSet].filter((key) => key.includes(pattern));\n }\n}\n\nclass CellActor extends BaseActor {\n private currentTask: Task | null = null;\n\n constructor(\n id: CellId,\n blackboard: IBlackboard,\n messageBus: IMessageBus,\n private readonly runner: (task: Task) => Promise<unknown>\n ) {\n super(createActorId(\"executor\"), `cell-${id}`, \"executor\", blackboard, messageBus);\n }\n\n setTask(task: Task): void {\n this.currentTask = task;\n }\n\n async observe() {\n return createObservation({ actorId: this.id });\n }\n\n async think() {\n if (!this.currentTask) {\n throw new Error(\"Task is not set\");\n }\n\n return createAction(this.id, \"execute\", { task: this.currentTask }, this.currentTask.id);\n }\n\n async act(action: ReturnType<typeof createAction>) {\n const task = (action.params?.task as Task | undefined) ?? this.currentTask;\n if (!task) {\n return createFailureResult(action.id, this.id, \"Task is not set\", 0);\n }\n\n const startedAt = Date.now();\n try {\n const output = await this.runner(task);\n return createSuccessResult(action.id, this.id, output, Date.now() - startedAt);\n } catch (error) {\n return createFailureResult(action.id, this.id, (error as Error).message, Date.now() - startedAt);\n }\n }\n}\n\nexport class DefaultExecutionCell implements ExecutionCell {\n readonly id: CellId;\n\n private readonly actor: CellActor;\n private readonly rawContext: CellContext;\n private readonly defaultRunner: (task: Task, context: CellContext) => Promise<unknown>;\n private readonly stateChanges: StateChange[] = [];\n private readonly toolCalls: ToolCallRecord[] = [];\n private statusValue: CellStatus = \"idle\";\n private abortReason: string | null = null;\n private suspendedResolver: (() => void) | null = null;\n private suspendedWaiter: Promise<void> | null = null;\n\n constructor(options: DefaultExecutionCellOptions) {\n this.id = options.id;\n this.rawContext = options.context;\n this.defaultRunner =\n options.runTask ??\n (async (task, context) => {\n if (typeof task.input === \"object\" && task.input && \"tool\" in (task.input as Record<string, unknown>)) {\n const input = task.input as { tool: string; params?: unknown };\n return context.tools.invoke(input.tool, input.params ?? {});\n }\n return task.input;\n });\n\n const blackboard = new BlackboardAdapter(options.context.blackboard);\n const messageBus = new NoOpMessageBus();\n this.actor = new CellActor(this.id, blackboard, messageBus, async (task) => {\n await this.waitIfSuspended();\n this.throwIfAborted();\n return this.defaultRunner(task, this.buildInstrumentedContext(task));\n });\n }\n\n get status(): CellStatus {\n return this.statusValue;\n }\n\n async execute(task: Task): Promise<CellResult> {\n if (this.statusValue === \"running\") {\n throw new Error(`Cell ${this.id} is already running`);\n }\n\n this.abortReason = null;\n this.statusValue = \"running\";\n this.stateChanges.length = 0;\n this.toolCalls.length = 0;\n\n const startTime = new Date();\n const startMs = Date.now();\n\n try {\n await Promise.resolve(this.rawContext.policy?.beforeExecute?.(task));\n\n this.actor.setTask(task);\n const observation = await this.actor.observe();\n await this.waitIfSuspended();\n this.throwIfAborted();\n\n const action = await this.actor.think(observation);\n await this.waitIfSuspended();\n this.throwIfAborted();\n\n const execution = this.actor.act(action);\n const result = this.rawContext.config.timeout\n ? await this.withTimeout(execution, this.rawContext.config.timeout)\n : await execution;\n\n if (result.status !== \"success\") {\n throw new Error(result.error ?? \"Cell execution failed\");\n }\n\n const output = result.output;\n const endTime = new Date();\n const metrics: CellMetrics = {\n startTime,\n endTime,\n durationMs: endTime.getTime() - startMs,\n toolCallCount: this.toolCalls.length,\n };\n\n this.statusValue = \"completed\";\n await this.recordAudit(\"cell_end\", { status: this.statusValue, taskId: task.id });\n await Promise.resolve(this.rawContext.policy?.afterExecute?.(task, { success: true, output }));\n\n return {\n success: true,\n output,\n stateChanges: [...this.stateChanges],\n toolCalls: [...this.toolCalls],\n metrics,\n };\n } catch (error) {\n const endTime = new Date();\n this.statusValue = \"failed\";\n await this.recordAudit(\"cell_error\", {\n taskId: task.id,\n reason: (error as Error).message,\n });\n await Promise.resolve(\n this.rawContext.policy?.afterExecute?.(task, {\n success: false,\n output: { error: (error as Error).message },\n })\n );\n\n return {\n success: false,\n output: { error: (error as Error).message },\n stateChanges: [...this.stateChanges],\n toolCalls: [...this.toolCalls],\n metrics: {\n startTime,\n endTime,\n durationMs: endTime.getTime() - startMs,\n toolCallCount: this.toolCalls.length,\n },\n };\n }\n }\n\n async suspend(): Promise<void> {\n if (this.statusValue !== \"running\") {\n return;\n }\n this.statusValue = \"suspended\";\n this.suspendedWaiter = new Promise((resolve) => {\n this.suspendedResolver = resolve;\n });\n }\n\n async resume(): Promise<void> {\n if (this.statusValue !== \"suspended\") {\n return;\n }\n this.statusValue = \"running\";\n this.suspendedResolver?.();\n this.suspendedResolver = null;\n this.suspendedWaiter = null;\n }\n\n async abort(reason: string): Promise<void> {\n this.abortReason = reason;\n this.statusValue = \"failed\";\n this.suspendedResolver?.();\n this.suspendedResolver = null;\n this.suspendedWaiter = null;\n }\n\n private buildInstrumentedContext(task: Task): CellContext {\n return {\n ...this.rawContext,\n blackboard: this.wrapBlackboard(this.rawContext.blackboard),\n tools: this.wrapTools(this.rawContext.tools, task),\n };\n }\n\n private wrapBlackboard(accessor: StateAccessor): StateAccessor {\n return {\n read: (path: string) => accessor.read(path),\n write: (path: string, value: unknown) => {\n const oldValue = accessor.read(path);\n accessor.write(path, value);\n this.stateChanges.push({\n path,\n oldValue,\n newValue: value,\n timestamp: new Date(),\n });\n },\n };\n }\n\n private wrapTools(tools: ToolSet, task: Task): ToolSet {\n return {\n invoke: async (toolName: string, params: unknown) => {\n if (\n this.rawContext.config.maxToolCalls !== undefined &&\n this.toolCalls.length >= this.rawContext.config.maxToolCalls\n ) {\n throw new Error(`Tool call limit exceeded: ${this.rawContext.config.maxToolCalls}`);\n }\n\n await Promise.resolve(\n this.rawContext.policy?.beforeToolCall?.({\n cellId: this.id,\n toolName,\n params,\n task,\n })\n );\n\n const toolCallId = randomUUID();\n const startedAt = new Date();\n const start = Date.now();\n\n try {\n const result = await tools.invoke(toolName, params);\n const durationMs = Date.now() - start;\n const endedAt = new Date();\n\n this.toolCalls.push({\n id: toolCallId,\n toolName,\n params,\n status: \"success\",\n result,\n startedAt,\n endedAt,\n durationMs,\n });\n\n await this.recordAudit(\"tool_call\", {\n cellId: this.id,\n toolCallId,\n toolName,\n durationMs,\n status: \"success\",\n });\n await this.recordAudit(\"tool_result\", {\n cellId: this.id,\n toolCallId,\n toolName,\n durationMs,\n });\n\n await Promise.resolve(\n this.rawContext.policy?.afterToolCall?.({\n cellId: this.id,\n toolName,\n params,\n task,\n durationMs,\n result,\n })\n );\n\n return result;\n } catch (error) {\n const durationMs = Date.now() - start;\n const endedAt = new Date();\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n\n this.toolCalls.push({\n id: toolCallId,\n toolName,\n params,\n status: \"error\",\n error: normalizedError.message,\n startedAt,\n endedAt,\n durationMs,\n });\n\n await this.recordAudit(\"tool_call\", {\n cellId: this.id,\n toolCallId,\n toolName,\n durationMs,\n status: \"error\",\n });\n await this.recordAudit(\"tool_error\", {\n cellId: this.id,\n toolCallId,\n toolName,\n durationMs,\n error: normalizedError.message,\n });\n\n await Promise.resolve(\n this.rawContext.policy?.afterToolCall?.({\n cellId: this.id,\n toolName,\n params,\n task,\n durationMs,\n error: normalizedError,\n })\n );\n\n throw normalizedError;\n }\n },\n };\n }\n\n private async withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<T>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n reject(new Error(`Execution timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n private async waitIfSuspended(): Promise<void> {\n if (this.suspendedWaiter) {\n await this.suspendedWaiter;\n }\n }\n\n private throwIfAborted(): void {\n if (this.abortReason) {\n throw new Error(`Execution aborted: ${this.abortReason}`);\n }\n }\n\n private async recordAudit(eventType: string, data: Record<string, unknown>): Promise<void> {\n await Promise.resolve(this.rawContext.audit.record(eventType, data));\n }\n}\n","/**\n * @module action\n * @description Action 타입 정의 - 액터가 수행하는 행동\n */\n\nimport type { ActorId } from \"./actor\";\n\n/**\n * Action 고유 ID 타입\n * @description 브랜드 타입을 사용하여 타입 안전성을 확보\n */\nexport type ActionId = string & { readonly __brand: \"ActionId\" };\n\n/**\n * Action 유형\n * @description 액터가 수행할 수 있는 행동의 종류\n */\nexport type ActionType =\n | \"analyze\"\n | \"execute\"\n | \"verify\"\n | \"coordinate\"\n | \"submit_opinion\"\n | \"submit_vote\"\n | \"create_agenda\"\n | \"unknown\";\n\n/**\n * Action 인터페이스\n * @description 액터가 수행하는 행동의 정의\n */\nexport interface Action {\n /** 고유 식별자 */\n readonly id: ActionId;\n /** 행동을 수행하는 액터 ID */\n actorId: ActorId;\n /** 행동 유형 */\n type: ActionType;\n /** 행동 생성 시간 */\n timestamp: Date;\n /** 행동 파라미터 (선택적) */\n params?: Record<string, unknown>;\n /** 관련 작업 ID (선택적) */\n taskId?: string;\n}\n\n/**\n * Action ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 ActionId\n * @example\n * ```typescript\n * const actionId = createActionId('action-001');\n * // 타입: ActionId\n * ```\n */\nexport function createActionId(id: string): ActionId {\n if (!id.startsWith(\"action-\")) {\n throw new Error(\"ActionId must start with 'action-'\");\n }\n return id as ActionId;\n}\n\n/**\n * Action ID 유효성 검사\n * @param value - 확인할 값\n * @returns 유효한 ActionId 여부\n */\nexport function isValidActionId(value: unknown): value is ActionId {\n return typeof value === \"string\" && value.length > 0 && value.startsWith(\"action-\");\n}\n\n/**\n * Action 생성 함수\n * @param actorId - 액터 ID\n * @param type - 행동 유형\n * @param params - 행동 파라미터 (선택적)\n * @param taskId - 관련 작업 ID (선택적)\n * @returns 생성된 Action 객체\n * @example\n * ```typescript\n * const action = createAction('actor-001', 'analyze', { target: 'data-001' });\n * ```\n */\nexport function createAction(\n actorId: ActorId,\n type: ActionType,\n params?: Record<string, unknown>,\n taskId?: string\n): Action {\n return {\n id: createActionId(`action-${crypto.randomUUID()}`),\n actorId,\n type,\n params,\n taskId,\n timestamp: new Date(),\n };\n}\n","/**\n * @module observation\n * @description Observation 타입 정의 - 액터의 환경 관찰 결과\n */\n\nimport type { ActorId } from \"./actor\";\n\n/**\n * 관찰 인터페이스\n * @description 액터가 환경에서 관찰한 정보\n */\nexport interface Observation {\n /** 관찰을 수행한 액터 ID */\n actorId: ActorId;\n /** 관찰 시간 */\n timestamp: Date;\n /** 관찰된 상태 (선택적) */\n state?: {\n context: Record<string, unknown>;\n agents: unknown[];\n tasks: unknown[];\n };\n /** 획득한 지식 (선택적) */\n knowledge?: {\n facts: unknown[];\n inferences: unknown[];\n };\n /** 관찰된 결정사항 (선택적) */\n decisions?: {\n currentAgenda: unknown | null;\n opinions: unknown[];\n };\n}\n\n/**\n * 관찰 생성 함수\n * @param params - 관찰 생성 파라미터\n * @returns 생성된 Observation 객체\n * @example\n * ```typescript\n * const observation = createObservation({\n * actorId: createActorId('actor-001'),\n * state: { temperature: 25 },\n * knowledge: [{ id: 'k1', content: 'fact', confidence: 0.9 }]\n * });\n * ```\n */\nexport function createObservation(params: Omit<Observation, \"timestamp\">): Observation {\n return {\n ...params,\n timestamp: new Date(),\n };\n}\n","/**\n * @module result\n * @description Result 타입 정의 - Action 수행 결과\n */\n\nimport type { ActionId } from \"./action\";\nimport type { ActorId } from \"./actor\";\n\n/**\n * Result 고유 ID 타입\n * @description 브랜드 타입을 사용하여 타입 안전성을 확보\n */\nexport type ResultId = string & { readonly __brand: \"ResultId\" };\n\n/**\n * Result 상태\n * @description 행동 수행 결과의 상태\n */\nexport type ResultStatus = \"success\" | \"failure\" | \"partial\";\n\n/**\n * Result 메트릭\n * @description 행동 수행의 성능 메트릭\n */\nexport interface ResultMetrics {\n /** 실행 시간 (밀리초) */\n duration: number;\n /** 메모리 사용량 (바이트) */\n memoryUsage?: number;\n /** 추가 메트릭 */\n [key: string]: unknown;\n}\n\n/**\n * Result 인터페이스\n * @description Action 수행 결과\n */\nexport interface Result {\n /** 고유 식별자 */\n readonly id: ResultId;\n /** 관련 Action ID */\n actionId: ActionId;\n /** 결과를 생성한 액터 ID */\n actorId: ActorId;\n /** 결과 생성 시간 */\n timestamp: Date;\n /** 결과 상태 */\n status: ResultStatus;\n /** 출력 데이터 (성공 시) */\n output?: unknown;\n /** 오류 정보 (실패 시) - 문자열 형태 */\n error?: string;\n /** 성능 메트릭 */\n metrics?: ResultMetrics;\n /** 보드에 기록할 데이터 */\n toRecord?: {\n section: \"state\" | \"knowledge\" | \"decisions\";\n data: unknown;\n };\n}\n\n/**\n * Result ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 ResultId\n * @example\n * ```typescript\n * const resultId = createResultId('result-001');\n * // 타입: ResultId\n * ```\n */\nexport function createResultId(id: string): ResultId {\n if (!id.startsWith(\"result-\")) {\n throw new Error(\"ResultId must start with 'result-'\");\n }\n return id as ResultId;\n}\n\n/**\n * Result ID 유효성 검사\n * @param value - 확인할 값\n * @returns 유효한 ResultId 여부\n */\nexport function isValidResultId(value: unknown): value is ResultId {\n return typeof value === \"string\" && value.length > 0 && value.startsWith(\"result-\");\n}\n\n/**\n * 성공 Result 생성 함수\n * @param actionId - Action ID\n * @param actorId - 액터 ID\n * @param output - 출력 데이터\n * @param duration - 실행 시간 (밀리초)\n * @returns 생성된 성공 Result 객체\n * @example\n * ```typescript\n * const result = createSuccessResult(\n * createActionId('action-001'),\n * createActorId('actor-001'),\n * { data: 'analysis result' },\n * 100\n * );\n * ```\n */\nexport function createSuccessResult(\n actionId: ActionId,\n actorId: ActorId,\n output: unknown,\n duration: number\n): Result {\n return {\n id: createResultId(`result-${crypto.randomUUID()}`),\n actionId,\n actorId,\n timestamp: new Date(),\n status: \"success\",\n output,\n metrics: { duration },\n };\n}\n\n/**\n * 실패 Result 생성 함수\n * @param actionId - Action ID\n * @param actorId - 액터 ID\n * @param error - 오류 메시지\n * @param duration - 실행 시간 (밀리초)\n * @returns 생성된 실패 Result 객체\n * @example\n * ```typescript\n * const result = createFailureResult(\n * createActionId('action-001'),\n * createActorId('actor-001'),\n * 'Analysis failed',\n * 50\n * );\n * ```\n */\nexport function createFailureResult(\n actionId: ActionId,\n actorId: ActorId,\n error: string,\n duration: number\n): Result {\n return {\n id: createResultId(`result-${crypto.randomUUID()}`),\n actionId,\n actorId,\n timestamp: new Date(),\n status: \"failure\",\n error,\n metrics: { duration },\n };\n}\n","import { ActorRuntime, ActorStopTimeoutError } from \"../_legacy/actor/runtime/ActorRuntime.js\";\nimport { DefaultExecutionCell } from \"./ExecutionCell.js\";\nimport type { CellContext } from \"./CellContext.js\";\nimport type { CellConfig, CellId, CellResult, CellStatus, Task } from \"./types.js\";\n\nexport type CellDispatchStrategy = \"fifo\" | \"priority\";\n\nexport interface CellRegistrationOptions {\n id?: CellId;\n config?: CellConfig;\n context?: CellContext;\n runTask?: (task: Task, context: CellContext) => Promise<unknown>;\n}\n\nexport interface CellManagerTaskOptions {\n priority?: number;\n}\n\nexport interface CellManagerConfig {\n maxConcurrentExecutions?: number;\n maxQueuedExecutions?: number;\n dispatchStrategy?: CellDispatchStrategy;\n defaultCellConfig?: CellConfig;\n createCellContext: (cellId: CellId, config: CellConfig) => CellContext;\n createCell?: (options: {\n id: CellId;\n context: CellContext;\n config: CellConfig;\n runTask?: (task: Task, context: CellContext) => Promise<unknown>;\n }) => {\n readonly id: CellId;\n readonly status: CellStatus;\n execute(task: Task): Promise<CellResult>;\n suspend(): Promise<void>;\n resume(): Promise<void>;\n abort(reason: string): Promise<void>;\n };\n}\n\nexport interface CellSnapshot {\n id: CellId;\n status: CellStatus;\n config: CellConfig;\n}\n\ninterface QueueItem {\n cellId: CellId;\n task: Task;\n priority: number;\n enqueuedAt: number;\n resolve: (value: CellResult) => void;\n reject: (reason?: unknown) => void;\n}\n\nconst DEFAULT_MAX_CONCURRENT_EXECUTIONS = 4;\nconst DEFAULT_MAX_QUEUED_EXECUTIONS = 200;\nconst DEFAULT_DISPATCH_STRATEGY: CellDispatchStrategy = \"fifo\";\n\nexport class CellManager {\n private readonly cells = new Map<\n CellId,\n {\n cell: {\n readonly id: CellId;\n readonly status: CellStatus;\n execute(task: Task): Promise<CellResult>;\n suspend(): Promise<void>;\n resume(): Promise<void>;\n abort(reason: string): Promise<void>;\n };\n config: CellConfig;\n }\n >();\n\n private readonly queue: QueueItem[] = [];\n private readonly inFlight = new Set<Promise<void>>();\n\n private readonly maxConcurrentExecutions: number;\n private readonly maxQueuedExecutions: number;\n private readonly dispatchStrategy: CellDispatchStrategy;\n private readonly defaultCellConfig: CellConfig;\n\n constructor(private readonly config: CellManagerConfig) {\n this.maxConcurrentExecutions =\n config.maxConcurrentExecutions ?? DEFAULT_MAX_CONCURRENT_EXECUTIONS;\n this.maxQueuedExecutions = config.maxQueuedExecutions ?? DEFAULT_MAX_QUEUED_EXECUTIONS;\n this.dispatchStrategy = config.dispatchStrategy ?? DEFAULT_DISPATCH_STRATEGY;\n this.defaultCellConfig = config.defaultCellConfig ?? {};\n\n this.validateConfig();\n }\n\n createCell(options: CellRegistrationOptions = {}): CellId {\n const cellId = options.id ?? crypto.randomUUID();\n\n if (this.cells.has(cellId)) {\n throw new Error(`Cell already exists: ${cellId}`);\n }\n\n const resolvedConfig = {\n ...this.defaultCellConfig,\n ...(options.config ?? {}),\n };\n\n const resolvedContext = options.context ?? this.config.createCellContext(cellId, resolvedConfig);\n\n const cell =\n this.config.createCell?.({\n id: cellId,\n context: resolvedContext,\n config: resolvedConfig,\n runTask: options.runTask,\n }) ??\n new DefaultExecutionCell({\n id: cellId,\n context: resolvedContext,\n runTask: options.runTask,\n });\n\n this.cells.set(cellId, {\n cell,\n config: resolvedConfig,\n });\n\n return cellId;\n }\n\n getCell(id: CellId) {\n return this.cells.get(id)?.cell;\n }\n\n getCellSnapshot(id: CellId): CellSnapshot | undefined {\n const entry = this.cells.get(id);\n if (!entry) {\n return undefined;\n }\n\n return {\n id,\n status: entry.cell.status,\n config: { ...entry.config },\n };\n }\n\n listCells(): CellSnapshot[] {\n return Array.from(this.cells.entries()).map(([id, entry]) => ({\n id,\n status: entry.cell.status,\n config: { ...entry.config },\n }));\n }\n\n async execute(cellId: CellId, task: Task, options: CellManagerTaskOptions = {}): Promise<CellResult> {\n if (!this.cells.has(cellId)) {\n throw new Error(`Cell not found: ${cellId}`);\n }\n\n if (this.queue.length >= this.maxQueuedExecutions) {\n throw new Error(`CellManager queue is full: ${this.maxQueuedExecutions}`);\n }\n\n return new Promise<CellResult>((resolve, reject) => {\n this.queue.push({\n cellId,\n task,\n priority: options.priority ?? task.priority ?? 0,\n enqueuedAt: Date.now(),\n resolve,\n reject,\n });\n\n this.processQueue();\n });\n }\n\n async suspendCell(id: CellId): Promise<void> {\n const cell = this.requireCell(id);\n await cell.suspend();\n }\n\n async resumeCell(id: CellId): Promise<void> {\n const cell = this.requireCell(id);\n await cell.resume();\n this.processQueue();\n }\n\n async stopCell(id: CellId, reason = \"Cell stopped by manager\"): Promise<void> {\n const cell = this.requireCell(id);\n await cell.abort(reason);\n this.cells.delete(id);\n this.rejectQueuedTasksForCell(id, reason);\n }\n\n async stopAll(reason = \"CellManager stopped\"): Promise<void> {\n const stopTasks = Array.from(this.cells.keys()).map((cellId) => this.stopCell(cellId, reason));\n await Promise.allSettled(stopTasks);\n }\n\n getQueueSize(): number {\n return this.queue.length;\n }\n\n getRunningCount(): number {\n return this.inFlight.size;\n }\n\n getStatus(): { totalCells: number; running: number; queued: number } {\n return {\n totalCells: this.cells.size,\n running: this.inFlight.size,\n queued: this.queue.length,\n };\n }\n\n private processQueue(): void {\n while (this.inFlight.size < this.maxConcurrentExecutions && this.queue.length > 0) {\n const next = this.pickNext();\n if (!next) {\n return;\n }\n\n const execution = this.runQueueItem(next)\n .catch((error) => {\n next.reject(error);\n })\n .finally(() => {\n this.inFlight.delete(execution);\n this.processQueue();\n });\n\n this.inFlight.add(execution);\n }\n }\n\n private pickNext(): QueueItem | undefined {\n if (this.queue.length === 0) {\n return undefined;\n }\n\n if (this.dispatchStrategy === \"priority\") {\n let selectedIndex = 0;\n for (let i = 1; i < this.queue.length; i++) {\n const current = this.queue[i]!;\n const selected = this.queue[selectedIndex]!;\n\n if (current.priority > selected.priority) {\n selectedIndex = i;\n continue;\n }\n\n if (current.priority === selected.priority && current.enqueuedAt < selected.enqueuedAt) {\n selectedIndex = i;\n }\n }\n\n return this.queue.splice(selectedIndex, 1)[0];\n }\n\n return this.queue.shift();\n }\n\n private async runQueueItem(item: QueueItem): Promise<void> {\n const cell = this.requireCell(item.cellId);\n const result = await cell.execute(item.task);\n item.resolve(result);\n }\n\n private requireCell(id: CellId) {\n const entry = this.cells.get(id);\n if (!entry) {\n throw new Error(`Cell not found: ${id}`);\n }\n return entry.cell;\n }\n\n private rejectQueuedTasksForCell(id: CellId, reason: string): void {\n for (let i = this.queue.length - 1; i >= 0; i--) {\n const item = this.queue[i]!;\n if (item.cellId === id) {\n this.queue.splice(i, 1);\n item.reject(new Error(`Execution aborted: ${reason}`));\n }\n }\n }\n\n private validateConfig(): void {\n if (this.maxConcurrentExecutions <= 0) {\n throw new Error(\"maxConcurrentExecutions must be positive\");\n }\n\n if (this.maxQueuedExecutions <= 0) {\n throw new Error(\"maxQueuedExecutions must be positive\");\n }\n\n if (this.dispatchStrategy !== \"fifo\" && this.dispatchStrategy !== \"priority\") {\n throw new Error(`Unsupported dispatch strategy: ${this.dispatchStrategy}`);\n }\n }\n}\n\nexport { ActorRuntime, ActorStopTimeoutError };\nexport * from \"../_legacy/actor/runtime/ActorRuntime.js\";\n","import type { IMessageBus, Message, MessageType, UnsubscribeFn } from \"../types/message\";\nimport type { ActorId } from \"../types/actor\";\n\n/**\n * No-Op MessageBus - 기본값으로 사용되는 빈 구현\n */\nexport class NoOpMessageBus implements IMessageBus {\n send(message: Message): void {}\n sendTo(to: ActorId, message: Omit<Message, \"to\">): void {}\n broadcast(message: Omit<Message, \"to\">): void {}\n receive(handler: (message: Message) => void): void {}\n request<T>(message: Message, timeoutMs?: number): Promise<Message<T>> {\n return Promise.resolve(message as Message<T>);\n }\n subscribe(messageType: MessageType, handler: (message: Message) => void): UnsubscribeFn {\n return () => {};\n }\n getQueueSize(actorId: ActorId): number {\n return 0;\n }\n clearQueue(actorId: ActorId): void {}\n filter(predicate: (message: Message) => boolean): Message[] {\n return [];\n }\n}\n","import type { ActorFactory, ActorConfig } from \"../runtime/types\";\nimport type { Actor, ActorId, ActorRole, ActorStatus } from \"../types/actor\";\nimport type { IBlackboard } from \"../types/actor\";\nimport type { IMessageBus } from \"../types/message\";\n\nimport { NoOpMessageBus } from \"./NoOpMessageBus\";\n\n/**\n * Actor Pool 설정\n */\nexport interface PoolConfig {\n /** 풀 이름 */\n name: string;\n\n /** Actor 역할 (풀 내 모든 Actor는 동일 역할) */\n role: ActorRole;\n\n /** Actor 유형 */\n type: string;\n\n /** 초기 Actor 수 */\n initialSize?: number;\n\n /** 최소 Actor 수 */\n minSize?: number;\n\n /** 최대 Actor 수 */\n maxSize?: number;\n\n /** Idle 타임아웃 (ms) - 지정 시간 동안 작업 없으면 Actor 종료 */\n idleTimeout?: number;\n\n /** 확장 전략 */\n scaleStrategy?: \"fixed\" | \"dynamic\" | \"adaptive\";\n\n /** 작업 분배 전략 */\n dispatchStrategy?: \"round-robin\" | \"least-busy\" | \"random\";\n\n /** 작업 큐 최대 크기 */\n maxQueueSize?: number;\n\n /** 작업 대기 타임아웃 (ms) */\n taskTimeout?: number;\n\n /** 디버그 모드 */\n debug?: boolean;\n}\n\n/**\n * 작업\n */\nexport interface Task<T = unknown> {\n /** 작업 ID */\n id: string;\n\n /** 작업 데이터 */\n data: T;\n\n /** 생성 시간 */\n createdAt: Date;\n\n /** 우선순위 (높을수록 우선) */\n priority: number;\n\n /** 만료 시간 */\n expiresAt?: Date;\n\n /** 완료 콜백 */\n onComplete?: (result: unknown, error?: Error) => void;\n}\n\n/**\n * 작업 결과\n */\nexport interface TaskResult {\n /** 작업 ID */\n taskId: string;\n\n /** 처리한 Actor ID */\n actorId: ActorId;\n\n /** 결과 데이터 */\n result: unknown;\n\n /** 에러 (실패 시) */\n error?: Error;\n\n /** 시작 시간 */\n startedAt: Date;\n\n /** 완료 시간 */\n completedAt: Date;\n\n /** 실행 시간 (ms) */\n duration: number;\n}\n\n/**\n * Actor Pool 메트릭\n */\nexport interface PoolMetrics {\n /** 총 Actor 수 */\n totalActors: number;\n\n /** 활성 Actor 수 */\n activeActors: number;\n\n /** Idle 상태 Actor 수 */\n idleActors: number;\n\n /** 에러 상태 Actor 수 */\n errorActors: number;\n\n /** 대기열 크기 */\n queueSize: number;\n\n /** 평균 대기 시간 (ms) */\n averageQueueTime: number;\n\n /** 처리량 */\n throughput: {\n messagesPerSecond: number;\n actionsPerSecond: number;\n };\n\n /** 이용률 (0.0 ~ 1.0) */\n utilization: number;\n}\n\n/**\n * Actor Pool\n *\n * 동적으로 확장/축소 가능한 Actor 풀을 관리하고,\n * 작업을 분배하여 효율적인 리소스 사용을 제공합니다.\n */\nexport class ActorPool {\n private readonly config: Required<PoolConfig>;\n private readonly board: IBlackboard;\n private readonly messageBus: IMessageBus;\n private readonly factory: ActorFactory;\n private readonly actors: Map<ActorId, Actor>;\n private readonly taskQueue: Task[];\n private readonly inProgress: Map<string, { task: Task; actorId: ActorId }>;\n private readonly completedTasks: TaskResult[];\n private readonly pendingResults: Map<string, TaskResult>;\n private readonly waitingTasks: Set<string>;\n private readonly actorConfigs: Map<ActorId, ActorConfig>;\n private readonly idleTimers: Map<ActorId, ReturnType<typeof setTimeout>>;\n private readonly metrics: PoolMetrics;\n private isRunning: boolean;\n private roundRobinIndex: number;\n private scaleTimer?: ReturnType<typeof setInterval>;\n private dispatchTimer?: ReturnType<typeof setInterval>;\n\n constructor(\n config: PoolConfig,\n board: IBlackboard,\n factory: ActorFactory,\n messageBus: IMessageBus = new NoOpMessageBus()\n ) {\n this.board = board;\n this.messageBus = messageBus;\n this.factory = factory;\n this.actors = new Map();\n this.taskQueue = [];\n this.inProgress = new Map();\n this.completedTasks = [];\n this.pendingResults = new Map();\n this.waitingTasks = new Set();\n this.actorConfigs = new Map();\n this.idleTimers = new Map();\n this.isRunning = false;\n this.roundRobinIndex = 0;\n\n // 기본 설정\n const defaults: Required<PoolConfig> = {\n name: config.name,\n role: config.role,\n type: config.type,\n initialSize: config.initialSize ?? 3,\n minSize: config.minSize ?? 1,\n maxSize: config.maxSize ?? 10,\n idleTimeout: config.idleTimeout ?? 30000,\n scaleStrategy: config.scaleStrategy ?? \"dynamic\",\n dispatchStrategy: config.dispatchStrategy ?? \"round-robin\",\n maxQueueSize: config.maxQueueSize ?? 100,\n taskTimeout: config.taskTimeout ?? 30000,\n debug: config.debug ?? false,\n };\n this.config = defaults;\n\n // 설정 검증\n this.validateConfig(defaults);\n\n // 메트릭 초기화\n this.metrics = {\n totalActors: 0,\n activeActors: 0,\n idleActors: 0,\n errorActors: 0,\n queueSize: 0,\n averageQueueTime: 0,\n throughput: {\n messagesPerSecond: 0,\n actionsPerSecond: 0,\n },\n utilization: 0,\n };\n }\n\n /**\n * 풀 시작\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"Pool is already running\");\n }\n\n this.isRunning = true;\n\n // 초기 Actor 생성\n await this.scaleTo(this.config.initialSize);\n\n // 작업 분배 시작\n this.startDispatch();\n\n // 자동 스케일링 시작 (dynamic/adaptive 모드)\n if (this.config.scaleStrategy !== \"fixed\") {\n this.startAutoScale();\n }\n\n this.log(`Pool started: ${this.config.name} (${this.config.initialSize} actors)`);\n }\n\n /**\n * 풀 종료\n */\n async stop(): Promise<void> {\n if (!this.isRunning) {\n return;\n }\n\n this.isRunning = false;\n\n // 타이머 정리\n this.clearTimers();\n\n // Idle 타이머 정리\n this.idleTimers.forEach((timer) => clearTimeout(timer));\n this.idleTimers.clear();\n\n // 모든 Actor 중지\n const stopPromises = Array.from(this.actors.values()).map((actor) => actor.stop());\n await Promise.allSettled(stopPromises);\n\n // 정리\n this.actors.clear();\n this.actorConfigs.clear();\n this.taskQueue.length = 0;\n this.inProgress.clear();\n this.pendingResults.clear();\n this.waitingTasks.clear();\n\n // 메트릭 리셋\n this.metrics.totalActors = 0;\n this.metrics.activeActors = 0;\n this.metrics.idleActors = 0;\n\n this.log(`Pool stopped: ${this.config.name}`);\n }\n\n /**\n * 작업 제출\n * @param data 작업 데이터\n * @param priority 우선순위 (높을수록 우선)\n * @param expiresIn 만료 시간 (ms, 선택)\n * @returns 작업 ID\n */\n async submit<T = unknown>(data: T, priority: number = 0, expiresIn?: number): Promise<string> {\n if (!this.isRunning) {\n throw new Error(\"Pool is not running\");\n }\n\n // 큐 크기 체크\n if (this.taskQueue.length >= this.config.maxQueueSize) {\n throw new Error(`Task queue is full: ${this.config.maxQueueSize}`);\n }\n\n const now = new Date();\n const expiresAt = expiresIn\n ? new Date(now.getTime() + expiresIn)\n : this.config.taskTimeout > 0\n ? new Date(now.getTime() + this.config.taskTimeout)\n : undefined;\n\n const task: Task<T> = {\n id: crypto.randomUUID(),\n data,\n createdAt: now,\n priority,\n expiresAt,\n };\n\n // 우선순위 순으로 삽입\n this.enqueueTask(task);\n\n this.log(`Task submitted: ${task.id} (priority: ${priority})`);\n\n return task.id;\n }\n\n /**\n * 작업 제출 및 결과 대기\n * @param data 작업 데이터\n * @param priority 우선순위\n * @returns 작업 결과\n */\n async submitAndWait<T = unknown, R = unknown>(data: T, priority: number = 0): Promise<R> {\n const taskId = await this.submit(data, priority);\n\n // 대기 중인 작업으로 등록 (recordTaskResult에서 pendingResults에 저장하도록)\n this.waitingTasks.add(taskId);\n\n return new Promise<R>((resolve, reject) => {\n let waiter: { cleanup: () => void } | null = null;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let settled = false;\n\n // 모든 리소스 정리\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n waiter?.cleanup();\n // 대기 목록에서 제거\n this.waitingTasks.delete(taskId);\n };\n\n // taskTimeout <= 0이면 무제한 대기 (타임아웃 없음)\n if (this.config.taskTimeout > 0) {\n timeout = setTimeout(() => {\n if (settled) return;\n settled = true;\n cleanup();\n\n // 타임아웃 시 큐에서도 제거\n const queueIndex = this.taskQueue.findIndex((t) => t.id === taskId);\n if (queueIndex !== -1) {\n this.taskQueue.splice(queueIndex, 1);\n this.metrics.queueSize = this.taskQueue.length;\n }\n // inProgress에서는 제거하지 않음 (작업 중인 경우 완료까지 대기)\n // 대신 타임아웃 에러를 reject\n reject(new Error(`Task timeout: ${taskId}`));\n }, this.config.taskTimeout);\n }\n\n waiter = this.waitForTaskResult(\n taskId,\n () => {\n if (settled) return;\n settled = true;\n cleanup();\n },\n resolve,\n reject\n );\n });\n }\n\n /**\n * 풀 크기 조정\n * @param size 목표 크기\n */\n async scaleTo(size: number): Promise<void> {\n const targetSize = Math.max(this.config.minSize, Math.min(size, this.config.maxSize));\n const currentSize = this.actors.size;\n\n if (targetSize === currentSize) {\n return;\n }\n\n this.log(`Scaling pool: ${currentSize} → ${targetSize}`);\n\n if (targetSize > currentSize) {\n // 확장\n const diff = targetSize - currentSize;\n for (let i = 0; i < diff; i++) {\n await this.spawnActor();\n }\n } else {\n // 축소\n const diff = currentSize - targetSize;\n await this.removeIdleActors(diff);\n }\n }\n\n /**\n * 풀 크기 증가\n * @param count 증가할 Actor 수\n */\n async scaleUp(count: number = 1): Promise<void> {\n const newSize = Math.min(this.actors.size + count, this.config.maxSize);\n await this.scaleTo(newSize);\n }\n\n /**\n * 풀 크기 감소\n * @param count 감소할 Actor 수\n */\n async scaleDown(count: number = 1): Promise<void> {\n const newSize = Math.max(this.actors.size - count, this.config.minSize);\n await this.scaleTo(newSize);\n }\n\n /**\n * 풀 메트릭 조회\n */\n getMetrics(): PoolMetrics {\n this.updateMetrics();\n return { ...this.metrics };\n }\n\n /**\n * Actor 목록 조회\n */\n getActors(): ActorId[] {\n return Array.from(this.actors.keys());\n }\n\n /**\n * Actor 상태 조회\n */\n getActorStatus(actorId: ActorId): ActorStatus {\n const actor = this.actors.get(actorId);\n if (!actor) {\n throw new Error(`Actor not found: ${actorId}`);\n }\n return actor.getStatus();\n }\n\n /**\n * 풀 이름\n */\n get name(): string {\n return this.config.name;\n }\n\n // ==================== 내부 메서드 ====================\n\n private validateConfig(config: Required<PoolConfig>): void {\n if (!config.name || config.name.trim() === \"\") {\n throw new Error(\"Pool name is required\");\n }\n if (!config.role) {\n throw new Error(\"Pool role is required\");\n }\n if (!config.type || config.type.trim() === \"\") {\n throw new Error(\"Pool type is required\");\n }\n if (config.minSize < 0) {\n throw new Error(\"minSize must be non-negative\");\n }\n if (config.maxSize < config.minSize) {\n throw new Error(\"maxSize must be >= minSize\");\n }\n if (config.initialSize < config.minSize || config.initialSize > config.maxSize) {\n throw new Error(\"initialSize must be between minSize and maxSize\");\n }\n }\n\n private async spawnActor(): Promise<Actor> {\n const uuid = crypto.randomUUID();\n const id = `${this.config.role}-${uuid}` as ActorId;\n const config: ActorConfig = {\n id,\n name: `${this.config.name}-${uuid.slice(0, 8)}`,\n role: this.config.role,\n type: this.config.type,\n };\n\n this.actorConfigs.set(id, config);\n\n const actor = await this.factory.create(config, this.board, this.messageBus);\n await actor.start();\n this.actors.set(id, actor);\n\n // Idle 타이머 시작\n this.startIdleTimer(id);\n\n // 메트릭 업데이트\n this.metrics.totalActors = this.actors.size;\n this.metrics.idleActors++;\n\n this.log(`Actor spawned: ${id}`);\n return actor;\n }\n\n private async removeIdleActors(count: number): Promise<void> {\n let removed = 0;\n\n for (const [id] of this.actors.entries()) {\n if (removed >= count) break;\n\n // Idle 상태인 Actor만 제거 (작업 중이 아닌)\n if (!this.isActorBusy(id)) {\n await this.removeActor(id);\n removed++;\n }\n }\n }\n\n private async removeActor(actorId: ActorId): Promise<void> {\n const actor = this.actors.get(actorId);\n if (!actor) return;\n\n // Idle 타이머 정리\n const timer = this.idleTimers.get(actorId);\n if (timer) {\n clearTimeout(timer);\n this.idleTimers.delete(actorId);\n }\n\n // Actor 종료\n await actor.stop();\n this.actors.delete(actorId);\n this.actorConfigs.delete(actorId);\n\n // 메트릭 업데이트\n this.metrics.totalActors = this.actors.size;\n if (!this.isActorBusy(actorId)) {\n this.metrics.idleActors = Math.max(0, this.metrics.idleActors - 1);\n }\n\n this.log(`Actor removed: ${actorId}`);\n }\n\n private selectActor(): Actor | null {\n const idleActors = Array.from(this.actors.entries())\n .filter(([id]) => !this.isActorBusy(id))\n .map(([, actor]) => actor);\n\n if (idleActors.length === 0) {\n return null;\n }\n\n switch (this.config.dispatchStrategy) {\n case \"round-robin\":\n return this.selectRoundRobin(idleActors);\n case \"least-busy\":\n return this.selectLeastBusy(idleActors);\n case \"random\":\n return this.selectRandom(idleActors);\n default:\n return idleActors[0];\n }\n }\n\n private selectRoundRobin(actors: Actor[]): Actor {\n const index = this.roundRobinIndex % actors.length;\n this.roundRobinIndex++;\n return actors[index];\n }\n\n private selectLeastBusy(actors: Actor[]): Actor {\n return actors.reduce((least, actor) => {\n const leastStatus = least.getStatus();\n const actorStatus = actor.getStatus();\n const leastQueue = leastStatus.messageQueue.pending;\n const actorQueue = actorStatus.messageQueue.pending;\n return actorQueue < leastQueue ? actor : least;\n });\n }\n\n private selectRandom(actors: Actor[]): Actor {\n const index = Math.floor(Math.random() * actors.length);\n return actors[index];\n }\n\n private async dispatchTaskToActor(task: Task, actor: Actor): Promise<void> {\n this.inProgress.set(task.id, { task, actorId: actor.id });\n\n // Idle 타이머 리셋\n this.resetIdleTimer(actor.id);\n\n // 메트릭 업데이트\n this.metrics.idleActors = Math.max(0, this.metrics.idleActors - 1);\n this.metrics.activeActors++;\n\n this.log(`Task ${task.id} → Actor ${actor.id}`);\n\n try {\n const startTime = Date.now();\n\n // 작업 데이터를 blackboard에 기록 (Actor가 observe()에서 읽을 수 있도록)\n // task별 고유 키 사용하여 병렬 처리 시 충돌 방지\n const taskSection = `pool:${this.config.name}:task:${task.id}`;\n this.board.write(taskSection, {\n taskId: task.id,\n actorId: actor.id,\n data: task.data,\n priority: task.priority,\n createdAt: task.createdAt,\n });\n\n // 작업 실행 (Actor의 OODA 루프)\n const obs = await actor.observe();\n const action = await actor.think(obs);\n const result = await actor.act(action);\n await actor.report(result);\n\n const duration = Date.now() - startTime;\n\n // 결과 기록\n const taskResult: TaskResult = {\n taskId: task.id,\n actorId: actor.id,\n result: result.output,\n error: result.error ? new Error(result.error) : undefined,\n startedAt: new Date(startTime),\n completedAt: new Date(),\n duration,\n };\n\n this.recordTaskResult(taskResult);\n\n // 콜백 호출\n task.onComplete?.(result.output, taskResult.error);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.log(`Task ${task.id} failed`, err);\n\n const taskResult: TaskResult = {\n taskId: task.id,\n actorId: actor.id,\n result: null,\n error: err,\n startedAt: new Date(),\n completedAt: new Date(),\n duration: 0,\n };\n\n this.recordTaskResult(taskResult);\n task.onComplete?.(null, err);\n } finally {\n this.inProgress.delete(task.id);\n this.metrics.activeActors = Math.max(0, this.metrics.activeActors - 1);\n this.metrics.idleActors++;\n this.resetIdleTimer(actor.id);\n }\n }\n\n private recordTaskResult(result: TaskResult): void {\n // 메트릭용 히스토리에 저장 (최근 1000개 유지)\n this.completedTasks.push(result);\n\n // 대기 중인 작업만 결과 캐시에 저장 (submit만 호출된 경우 제외)\n if (this.waitingTasks.has(result.taskId)) {\n this.pendingResults.set(result.taskId, result);\n }\n\n // 최근 1초 내 완료된 작업 수로 throughput 계산\n const now = Date.now();\n const oneSecondAgo = now - 1000;\n const recentCompletions = this.completedTasks.filter(\n (r) => r.completedAt.getTime() >= oneSecondAgo\n ).length;\n\n this.metrics.throughput.actionsPerSecond = recentCompletions;\n\n // 메트릭용 히스토리 크기 제한 (최근 1000개 유지)\n if (this.completedTasks.length > 1000) {\n this.completedTasks.shift();\n }\n }\n\n private enqueueTask(task: Task): void {\n // 우선순위 순으로 삽입\n let inserted = false;\n for (let i = 0; i < this.taskQueue.length; i++) {\n if (task.priority > this.taskQueue[i].priority) {\n this.taskQueue.splice(i, 0, task);\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n this.taskQueue.push(task);\n }\n\n this.metrics.queueSize = this.taskQueue.length;\n }\n\n private startDispatch(): void {\n this.dispatchTimer = setInterval(() => {\n while (this.taskQueue.length > 0) {\n // 먼저 만료된 작업을 큐 앞에서 제거\n const peek = this.taskQueue[0];\n if (peek.expiresAt && peek.expiresAt.getTime() < Date.now()) {\n this.taskQueue.shift();\n this.metrics.queueSize = this.taskQueue.length;\n this.log(`Task expired: ${peek.id}`);\n const expiredError = new Error(`Task expired: ${peek.id}`);\n const taskResult: TaskResult = {\n taskId: peek.id,\n actorId: \"\" as ActorId,\n result: null,\n error: expiredError,\n startedAt: new Date(),\n completedAt: new Date(),\n duration: 0,\n };\n this.recordTaskResult(taskResult);\n peek.onComplete?.(null, expiredError);\n continue;\n }\n\n // 사용 가능한 Actor가 없으면 중단\n const actor = this.selectActor();\n if (!actor) break;\n\n const task = this.taskQueue.shift()!;\n this.metrics.queueSize = this.taskQueue.length;\n this.dispatchTaskToActor(task, actor);\n }\n }, 100); // 100ms마다 체크\n }\n\n private startAutoScale(): void {\n this.scaleTimer = setInterval(() => {\n this.autoScale();\n }, 5000); // 5초마다 체크\n }\n\n private autoScale(): void {\n if (this.config.scaleStrategy === \"fixed\") {\n return;\n }\n\n const queueLength = this.taskQueue.length;\n const totalActors = this.metrics.totalActors;\n const idleRatio = totalActors > 0 ? this.metrics.idleActors / totalActors : 1;\n\n if (this.config.scaleStrategy === \"dynamic\") {\n if (queueLength > 2 && totalActors < this.config.maxSize) {\n this.scaleUp();\n } else if (idleRatio > 0.5 && totalActors > this.config.minSize) {\n this.scaleDown();\n }\n } else if (this.config.scaleStrategy === \"adaptive\") {\n if (queueLength > 5 && totalActors < this.config.maxSize) {\n this.scaleUp();\n } else if (idleRatio > 0.7 && totalActors > this.config.minSize) {\n this.scaleDown();\n }\n }\n }\n\n private startIdleTimer(actorId: ActorId): void {\n const timer = setTimeout(() => {\n // busy 상태면 제거하지 않음\n if (this.isActorBusy(actorId)) {\n // 타이머 재시작\n this.startIdleTimer(actorId);\n return;\n }\n\n // 최소 크기 유지 체크\n if (this.metrics.totalActors > this.config.minSize) {\n this.removeActor(actorId);\n }\n }, this.config.idleTimeout);\n\n this.idleTimers.set(actorId, timer);\n }\n\n private resetIdleTimer(actorId: ActorId): void {\n const timer = this.idleTimers.get(actorId);\n if (timer) {\n clearTimeout(timer);\n }\n this.startIdleTimer(actorId);\n }\n\n private isActorBusy(actorId: ActorId): boolean {\n for (const { actorId: busyId } of this.inProgress.values()) {\n if (busyId === actorId) {\n return true;\n }\n }\n return false;\n }\n\n private waitForTaskResult<T>(\n taskId: string,\n onSettled: () => void,\n resolve: (value: T) => void,\n reject: (reason?: unknown) => void\n ): { cleanup: () => void } {\n const checkInterval = setInterval(() => {\n // Pool이 종료되면 즉시 reject\n if (!this.isRunning) {\n clearInterval(checkInterval);\n onSettled();\n reject(new Error(\"Pool has been stopped\"));\n return;\n }\n const result = this.pendingResults.get(taskId);\n if (result) {\n // 메모리 최적화: 사용된 결과 캐시에서 제거\n // (메트릭용 completedTasks는 유지됨)\n this.pendingResults.delete(taskId);\n\n clearInterval(checkInterval);\n onSettled();\n\n if (result.error) {\n reject(result.error);\n } else {\n resolve(result.result as T);\n }\n }\n }, 100);\n\n // cleanup 함수 반환\n return {\n cleanup: () => {\n clearInterval(checkInterval);\n },\n };\n }\n\n private clearTimers(): void {\n if (this.scaleTimer) {\n clearInterval(this.scaleTimer);\n this.scaleTimer = undefined;\n }\n if (this.dispatchTimer) {\n clearInterval(this.dispatchTimer);\n this.dispatchTimer = undefined;\n }\n }\n\n private updateMetrics(): void {\n this.metrics.totalActors = this.actors.size;\n this.metrics.queueSize = this.taskQueue.length;\n\n // 이용률 계산\n if (this.metrics.totalActors > 0) {\n this.metrics.utilization = this.metrics.activeActors / this.metrics.totalActors;\n } else {\n this.metrics.utilization = 0;\n }\n\n // 평균 대기 시간 계산\n // 최근 작업들의 duration으로 대략적인 처리 시간 추정\n if (this.completedTasks.length > 0) {\n const recentTasks = this.completedTasks.slice(-100);\n const avgDuration = recentTasks.reduce((sum, t) => sum + t.duration, 0) / recentTasks.length;\n // 큐 크기 기반 예상 대기 시간\n this.metrics.averageQueueTime = this.taskQueue.length * avgDuration;\n } else {\n // 완료된 작업이 없으면 0으로 리셋\n this.metrics.averageQueueTime = 0;\n }\n }\n\n private log(message: string, error?: unknown): void {\n // 에러는 항상 출력 (debug 옵션 무관)\n if (error) {\n console.error(`[ActorPool:${this.config.name}] ${message}`, error);\n return;\n }\n\n // 일반 로그는 debug 모드에서만\n if (!this.config.debug) return;\n console.log(`[ActorPool:${this.config.name}] ${message}`);\n }\n}\n","import type { ActorFactory } from \"../runtime/types\";\nimport type { IBlackboard } from \"../types/actor\";\nimport type { IMessageBus } from \"../types/message\";\n\nimport { ActorPool, PoolConfig, PoolMetrics } from \"./ActorPool\";\nimport { NoOpMessageBus } from \"./NoOpMessageBus\";\n\n/**\n * Pool Manager\n *\n * 여러 Actor Pool을 관리하는 매니저입니다.\n */\nexport class PoolManager {\n private readonly board: IBlackboard;\n private readonly messageBus: IMessageBus;\n private readonly factory: ActorFactory;\n private readonly pools: Map<string, ActorPool>;\n private isRunning: boolean;\n\n constructor(\n board: IBlackboard,\n factory: ActorFactory,\n messageBus: IMessageBus = new NoOpMessageBus()\n ) {\n this.board = board;\n this.messageBus = messageBus;\n this.factory = factory;\n this.pools = new Map();\n this.isRunning = false;\n }\n\n /**\n * 매니저 시작\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"PoolManager is already running\");\n }\n\n this.isRunning = true;\n\n // 모든 Pool 시작\n const startPromises = Array.from(this.pools.values()).map((pool) => pool.start());\n await Promise.all(startPromises);\n\n this.log(\"PoolManager started\");\n }\n\n /**\n * 매니저 종료\n */\n async stop(): Promise<void> {\n if (!this.isRunning) {\n return;\n }\n\n // 모든 Pool 종료\n const stopPromises = Array.from(this.pools.values()).map((pool) => pool.stop());\n await Promise.allSettled(stopPromises);\n\n this.isRunning = false;\n this.log(\"PoolManager stopped\");\n }\n\n /**\n * Pool 등록\n * @param config Pool 설정\n * @returns 생성된 Pool\n */\n registerPool(config: PoolConfig): ActorPool {\n if (this.pools.has(config.name)) {\n throw new Error(`Pool already exists: ${config.name}`);\n }\n\n const pool = new ActorPool(config, this.board, this.factory, this.messageBus);\n this.pools.set(config.name, pool);\n\n // 이미 실행 중이면 Pool 시작\n if (this.isRunning) {\n pool.start().catch((err) => {\n console.error(`Failed to start pool: ${config.name}`, err);\n });\n }\n\n this.log(`Pool registered: ${config.name}`);\n return pool;\n }\n\n /**\n * Pool 등록 해제\n * @param name Pool 이름\n */\n async unregisterPool(name: string): Promise<void> {\n const pool = this.pools.get(name);\n if (!pool) {\n throw new Error(`Pool not found: ${name}`);\n }\n\n await pool.stop();\n this.pools.delete(name);\n this.log(`Pool unregistered: ${name}`);\n }\n\n /**\n * Pool 조회\n * @param name Pool 이름\n * @returns Pool 인스턴스\n */\n getPool(name: string): ActorPool {\n const pool = this.pools.get(name);\n if (!pool) {\n throw new Error(`Pool not found: ${name}`);\n }\n return pool;\n }\n\n /**\n * Pool 존재 여부 확인\n * @param name Pool 이름\n * @returns 존재 여부\n */\n hasPool(name: string): boolean {\n return this.pools.has(name);\n }\n\n /**\n * 모든 Pool 이름 조회\n * @returns Pool 이름 배열\n */\n listPools(): string[] {\n return Array.from(this.pools.keys());\n }\n\n /**\n * 모든 Pool의 메트릭 조회\n * @returns Pool 이름별 메트릭 맵\n */\n getAllMetrics(): Map<string, PoolMetrics> {\n const metrics = new Map<string, PoolMetrics>();\n for (const [name, pool] of this.pools.entries()) {\n metrics.set(name, pool.getMetrics());\n }\n return metrics;\n }\n\n /**\n * 특정 Pool의 메트릭 조회\n * @param name Pool 이름\n * @returns Pool 메트릭\n */\n getPoolMetrics(name: string): PoolMetrics {\n const pool = this.getPool(name);\n return pool.getMetrics();\n }\n\n /**\n * Pool 개수\n */\n size(): number {\n return this.pools.size;\n }\n\n /**\n * 실행 상태\n */\n getStatus(): { running: boolean; poolCount: number } {\n return {\n running: this.isRunning,\n poolCount: this.pools.size,\n };\n }\n\n private log(message: string): void {\n // PoolManager 로그는 디버그용으로만 사용\n // console.log(`[PoolManager] ${message}`);\n }\n}\n","import type { Actor } from \"../types/actor\";\nimport { ActorLifecycleStatus } from \"../types/actor\";\n\nimport { delay } from \"./utils/delay\";\n\n/**\n * Actor 실행 루프 옵션\n */\nexport interface RunnerOptions {\n /** 실행 간격 (ms) */\n interval?: number;\n\n /** 최대 연속 실행 횟수 */\n maxIterations?: number;\n\n /** 에러 발생 시 중지 여부 */\n stopOnError?: boolean;\n\n /** 종료 조건 콜백 */\n stopCondition?: () => boolean | Promise<boolean>;\n\n /** 디버그 모드 */\n debug?: boolean;\n}\n\n/**\n * Actor 실행 루프\n *\n * Actor의 observe-think-act-report 사이클을 반복 실행합니다.\n */\nexport class ActorRunner {\n private readonly actor: Actor;\n private readonly options: Required<RunnerOptions>;\n private isRunning: boolean = false;\n private iterationCount: number = 0;\n private abortController: AbortController | null = null;\n\n constructor(actor: Actor, options?: RunnerOptions) {\n this.actor = actor;\n this.options = {\n interval: 1000,\n maxIterations: Infinity,\n stopOnError: true,\n stopCondition: () => false,\n debug: false,\n ...options,\n };\n }\n\n /**\n * 실행 루프 시작\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new Error(\"Runner is already running\");\n }\n\n this.isRunning = true;\n this.iterationCount = 0;\n this.abortController = new AbortController();\n\n try {\n while (this.isRunning) {\n // 종료 조건 확인\n if (await this.shouldStop()) {\n break;\n }\n\n // 최대 반복 횟수 확인\n if (this.iterationCount >= this.options.maxIterations) {\n break;\n }\n\n // Actor 상태 확인\n if (this.actor.status.status !== ActorLifecycleStatus.RUNNING) {\n break;\n }\n\n try {\n // 한 사이클 실행\n await this.runCycle();\n this.iterationCount++;\n } catch (error) {\n // 에러 로깅 (debug 모드와 무관하게 항상 로그)\n this.log(`Cycle error`, error);\n if (this.options.stopOnError) {\n throw error;\n }\n // 에러 무시하고 계속\n }\n\n // 대기 (AbortSignal 연동)\n try {\n await delay(this.options.interval, this.abortController?.signal);\n } catch {\n // abort 시 무시하고 루프 종료\n break;\n }\n }\n } finally {\n this.isRunning = false;\n this.abortController = null;\n }\n }\n\n /**\n * 실행 루프 중지\n */\n stop(): void {\n if (!this.isRunning) {\n return;\n }\n\n this.isRunning = false;\n this.abortController?.abort();\n }\n\n /**\n * 현재 실행 중인지 확인\n */\n running(): boolean {\n return this.isRunning;\n }\n\n /**\n * 현재 반복 횟수\n */\n getIterationCount(): number {\n return this.iterationCount;\n }\n\n // ==================== 내부 메서드 ====================\n\n private async runCycle(): Promise<void> {\n // 1. Observe\n const obs = await Promise.resolve(this.actor.observe());\n\n // 2. Think\n const action = await Promise.resolve(this.actor.think(obs));\n\n // 3. Act\n const result = await Promise.resolve(this.actor.act(action));\n\n // 4. Report\n await Promise.resolve(this.actor.report(result));\n }\n\n private async shouldStop(): Promise<boolean> {\n // AbortController 확인\n if (this.abortController?.signal.aborted) {\n return true;\n }\n\n // 종료 조건 확인 (sync/async 모두 지원)\n return Promise.resolve(this.options.stopCondition());\n }\n\n /**\n * 내부 로그 출력.\n *\n * - `error`가 전달되면 `debug` 옵션과 무관하게 `console.error`로 항상 출력합니다.\n * - 일반 로그는 `debug: true`일 때만 `console.log`로 출력합니다.\n */\n private log(message: string, error?: unknown): void {\n if (error) {\n console.error(`[ActorRunner] ${message}`, error);\n } else if (this.options.debug) {\n console.log(`[ActorRunner] ${message}`);\n }\n }\n}\n","import type { Actor, ActorId, ActorRole, IBlackboard } from \"../types/actor\";\nimport type { IMessageBus } from \"../types/message\";\nimport type { ActorFactory, ActorConfig } from \"./types\";\n\nimport { generateActorId } from \"../types/crypto\";\n\n/**\n * Actor 클래스 등록소\n */\ntype ActorConstructor = new (\n id: ActorId,\n name: string,\n role: ActorRole,\n board: IBlackboard,\n messageBus: IMessageBus,\n config?: Record<string, unknown>\n) => Actor;\n\n/**\n * 기본 Actor 팩토리\n *\n * Actor 클래스를 등록하고 생성할 수 있는 팩토리입니다.\n */\nexport class DefaultActorFactory implements ActorFactory {\n private readonly registry: Map<string, ActorConstructor>;\n\n constructor() {\n this.registry = new Map();\n }\n\n /**\n * Actor 클래스 등록\n * @param type Actor 유형 식별자\n * @param constructor Actor 생성자\n */\n register(type: string, constructor: ActorConstructor): void {\n this.registry.set(type, constructor);\n }\n\n /**\n * Actor 클래스 등록 해제\n * @param type Actor 유형 식별자\n */\n unregister(type: string): void {\n this.registry.delete(type);\n }\n\n /**\n * Actor 인스턴스 생성\n * @param config Actor 설정\n * @param board Blackboard 인스턴스\n * @param messageBus MessageBus 인스턴스\n * @returns 생성된 Actor 인스턴스\n */\n async create(\n config: ActorConfig,\n board: IBlackboard,\n messageBus: IMessageBus,\n _options?: { signal?: AbortSignal }\n ): Promise<Actor> {\n const { id, name, role, type, config: actorConfig } = config;\n\n // 등록된 생성자 조회\n const Constructor = this.registry.get(type);\n if (!Constructor) {\n throw new Error(`Unknown actor type: ${type}`);\n }\n\n // Actor ID 생성 또는 사용\n const actorId = id || this.generateId(role);\n\n // Actor 생성\n const actor = new Constructor(actorId, name, role, board, messageBus, actorConfig ?? {});\n\n return actor;\n }\n\n /**\n * Actor ID 생성\n * @param role Actor 역할\n * @returns Actor ID\n */\n private generateId(role: string): ActorId {\n const id = generateActorId(role);\n return id as ActorId;\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport { parse } from \"yaml\";\nimport type {\n DynamicQuotaConfig,\n DynamicResourceLimit,\n DynamicToolRule,\n GatePolicy,\n PolicySet,\n ResourcePolicy,\n SandboxPolicy,\n ToolPolicy,\n} from \"./types.js\";\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction toStringArray(value: unknown, field: string): string[] {\n if (value === undefined) return [];\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n throw new Error(`Invalid ${field}: expected string[]`);\n }\n return value;\n}\n\nfunction normalizeToolPolicy(input: unknown, index: number): ToolPolicy {\n if (!isObject(input)) {\n throw new Error(`Invalid tools[${index}]: expected object`);\n }\n\n const { name, effect, when } = input;\n if (typeof name !== \"string\" || name.length === 0) {\n throw new Error(`Invalid tools[${index}].name: expected non-empty string`);\n }\n\n if (effect !== \"allow\" && effect !== \"deny\" && effect !== \"transform\" && effect !== \"gate\") {\n throw new Error(`Invalid tools[${index}].effect: ${String(effect)}`);\n }\n\n let normalizedWhen: ToolPolicy[\"when\"];\n if (when !== undefined) {\n if (!isObject(when)) {\n throw new Error(`Invalid tools[${index}].when: expected object`);\n }\n\n if (when.condition !== undefined && typeof when.condition !== \"string\") {\n throw new Error(`Invalid tools[${index}].when.condition: expected string`);\n }\n\n normalizedWhen = {\n matches: toStringArray(when.matches, `tools[${index}].when.matches`),\n not_matches: toStringArray(when.not_matches, `tools[${index}].when.not_matches`),\n condition: when.condition,\n };\n }\n\n const transform = input.transform;\n let normalizedTransform: ToolPolicy[\"transform\"];\n if (transform !== undefined) {\n if (!isObject(transform) || typeof transform.fn !== \"string\" || transform.fn.length === 0) {\n throw new Error(`Invalid tools[${index}].transform.fn: expected non-empty string`);\n }\n normalizedTransform = { fn: transform.fn };\n }\n\n const gate = input.gate;\n let normalizedGate: ToolPolicy[\"gate\"];\n if (gate !== undefined) {\n if (!isObject(gate)) {\n throw new Error(`Invalid tools[${index}].gate: expected object`);\n }\n\n if (gate.type !== \"human-approval\" && gate.type !== \"consensus\" && gate.type !== \"external\") {\n throw new Error(`Invalid tools[${index}].gate.type: ${String(gate.type)}`);\n }\n\n if (gate.timeout !== undefined && typeof gate.timeout !== \"string\") {\n throw new Error(`Invalid tools[${index}].gate.timeout: expected string`);\n }\n\n normalizedGate = {\n type: gate.type,\n timeout: gate.timeout,\n };\n }\n\n return { name, effect, when: normalizedWhen, transform: normalizedTransform, gate: normalizedGate };\n}\n\nfunction normalizeSandboxPolicy(input: unknown): SandboxPolicy | undefined {\n if (input === undefined) return undefined;\n if (!isObject(input)) {\n throw new Error(\"Invalid sandbox: expected object\");\n }\n\n const root = input.root;\n const denyOutsideRoot = input.denyOutsideRoot ?? input.deny_outside_root;\n const denyPatterns = input.denyPatterns ?? input.deny_patterns;\n const maxFileSize = input.maxFileSize ?? input.max_file_size;\n\n if (typeof root !== \"string\" || root.length === 0) {\n throw new Error(\"Invalid sandbox.root: expected non-empty string\");\n }\n if (typeof denyOutsideRoot !== \"boolean\") {\n throw new Error(\"Invalid sandbox.denyOutsideRoot: expected boolean\");\n }\n if (denyPatterns !== undefined && (!Array.isArray(denyPatterns) || denyPatterns.some((v) => typeof v !== \"string\"))) {\n throw new Error(\"Invalid sandbox.denyPatterns: expected string[]\");\n }\n if (maxFileSize !== undefined && typeof maxFileSize !== \"string\") {\n throw new Error(\"Invalid sandbox.maxFileSize: expected string\");\n }\n\n return {\n root,\n denyOutsideRoot,\n denyPatterns,\n maxFileSize,\n };\n}\n\nfunction normalizeResourcePolicy(input: unknown): ResourcePolicy | undefined {\n if (input === undefined) return undefined;\n if (!isObject(input)) {\n throw new Error(\"Invalid resources: expected object\");\n }\n\n const timeoutMs = input.timeoutMs ?? input.timeout_ms;\n const maxTokens = input.maxTokens ?? input.max_tokens;\n const maxCostUsd = input.maxCostUsd ?? input.max_cost_usd;\n const maxToolCalls = input.maxToolCalls ?? input.max_tool_calls;\n const maxOutputSize = input.maxOutputSize ?? input.max_output_size;\n\n const numericFields: Array<[string, unknown]> = [\n [\"resources.timeoutMs\", timeoutMs],\n [\"resources.maxTokens\", maxTokens],\n [\"resources.maxCostUsd\", maxCostUsd],\n [\"resources.maxToolCalls\", maxToolCalls],\n ];\n\n for (const [field, value] of numericFields) {\n if (value !== undefined && typeof value !== \"number\") {\n throw new Error(`Invalid ${field}: expected number`);\n }\n }\n if (maxOutputSize !== undefined && typeof maxOutputSize !== \"string\") {\n throw new Error(\"Invalid resources.maxOutputSize: expected string\");\n }\n\n return {\n timeoutMs,\n maxTokens,\n maxCostUsd,\n maxToolCalls,\n maxOutputSize,\n dynamicQuota: normalizeDynamicQuota(input.dynamicQuota ?? input.dynamic_quota),\n };\n}\n\nfunction normalizeDynamicToolRule(input: unknown, index: number): DynamicToolRule {\n if (!isObject(input)) {\n throw new Error(`Invalid dynamicToolRules[${index}]: expected object`);\n }\n\n const { name, condition, effect, priority } = input;\n if (typeof name !== \"string\" || name.length === 0) {\n throw new Error(`Invalid dynamicToolRules[${index}].name: expected non-empty string`);\n }\n if (typeof condition !== \"string\" || condition.length === 0) {\n throw new Error(`Invalid dynamicToolRules[${index}].condition: expected non-empty string`);\n }\n if (effect !== \"allow\" && effect !== \"deny\" && effect !== \"transform\" && effect !== \"gate\") {\n throw new Error(`Invalid dynamicToolRules[${index}].effect: ${String(effect)}`);\n }\n if (priority !== undefined && typeof priority !== \"number\") {\n throw new Error(`Invalid dynamicToolRules[${index}].priority: expected number`);\n }\n\n const transformFn = input.transformFn;\n if (transformFn !== undefined && (typeof transformFn !== \"string\" || transformFn.length === 0)) {\n throw new Error(`Invalid dynamicToolRules[${index}].transformFn: expected non-empty string`);\n }\n\n const gate = input.gate;\n let normalizedGate: DynamicToolRule[\"gate\"];\n if (gate !== undefined) {\n if (!isObject(gate)) {\n throw new Error(`Invalid dynamicToolRules[${index}].gate: expected object`);\n }\n if (gate.type !== \"human-approval\" && gate.type !== \"consensus\" && gate.type !== \"external\") {\n throw new Error(`Invalid dynamicToolRules[${index}].gate.type: ${String(gate.type)}`);\n }\n if (gate.timeout !== undefined && typeof gate.timeout !== \"string\") {\n throw new Error(`Invalid dynamicToolRules[${index}].gate.timeout: expected string`);\n }\n normalizedGate = { type: gate.type, timeout: gate.timeout };\n }\n\n return { name, condition, effect, priority, transformFn, gate: normalizedGate };\n}\n\nfunction normalizeDynamicQuota(input: unknown): DynamicQuotaConfig | undefined {\n if (input === undefined) {\n return undefined;\n }\n if (!isObject(input)) {\n throw new Error(\"Invalid resources.dynamicQuota: expected object\");\n }\n\n const limits = input.limits;\n if (!Array.isArray(limits)) {\n throw new Error(\"Invalid resources.dynamicQuota.limits: expected array\");\n }\n\n const normalizedLimits: DynamicResourceLimit[] = limits.map((limit, index) => {\n if (!isObject(limit)) {\n throw new Error(`Invalid resources.dynamicQuota.limits[${index}]: expected object`);\n }\n\n const { field, condition, action, limit: limitValue } = limit;\n if (field !== \"tokens\" && field !== \"cost\" && field !== \"tool_calls\" && field !== \"duration_ms\") {\n throw new Error(`Invalid resources.dynamicQuota.limits[${index}].field: ${String(field)}`);\n }\n if (typeof condition !== \"string\" || condition.length === 0) {\n throw new Error(`Invalid resources.dynamicQuota.limits[${index}].condition: expected non-empty string`);\n }\n if (typeof limitValue !== \"number\") {\n throw new Error(`Invalid resources.dynamicQuota.limits[${index}].limit: expected number`);\n }\n if (action !== \"deny\" && action !== \"warn\" && action !== \"gate\") {\n throw new Error(`Invalid resources.dynamicQuota.limits[${index}].action: ${String(action)}`);\n }\n\n return {\n field,\n condition,\n limit: limitValue,\n action,\n };\n });\n\n return { limits: normalizedLimits };\n}\n\nfunction normalizeGatePolicy(input: unknown, index: number): GatePolicy {\n if (!isObject(input)) {\n throw new Error(`Invalid gates[${index}]: expected object`);\n }\n\n const { step, type, required, timeout, fallback } = input;\n if (typeof step !== \"string\" || step.length === 0) {\n throw new Error(`Invalid gates[${index}].step: expected non-empty string`);\n }\n if (type !== \"human-approval\" && type !== \"consensus\" && type !== \"external\") {\n throw new Error(`Invalid gates[${index}].type: ${String(type)}`);\n }\n if (typeof required !== \"boolean\") {\n throw new Error(`Invalid gates[${index}].required: expected boolean`);\n }\n if (timeout !== undefined && typeof timeout !== \"string\") {\n throw new Error(`Invalid gates[${index}].timeout: expected string`);\n }\n if (\n fallback !== undefined\n && fallback !== \"fail\"\n && fallback !== \"escalate\"\n && fallback !== \"auto-approve\"\n ) {\n throw new Error(`Invalid gates[${index}].fallback: ${String(fallback)}`);\n }\n\n return { step, type, required, timeout, fallback };\n}\n\nexport function normalizePolicySet(input: unknown): PolicySet {\n if (!isObject(input)) {\n throw new Error(\"Invalid policy YAML: expected object\");\n }\n\n const toolsRaw = input.tools;\n const gatesRaw = input.gates;\n const dynamicToolRulesRaw = input.dynamicToolRules ?? input.dynamic_tool_rules;\n\n if (toolsRaw !== undefined && !Array.isArray(toolsRaw)) {\n throw new Error(\"Invalid tools: expected array\");\n }\n if (gatesRaw !== undefined && !Array.isArray(gatesRaw)) {\n throw new Error(\"Invalid gates: expected array\");\n }\n if (dynamicToolRulesRaw !== undefined && !Array.isArray(dynamicToolRulesRaw)) {\n throw new Error(\"Invalid dynamicToolRules: expected array\");\n }\n\n const policySet: PolicySet = {\n version: typeof input.version === \"string\" ? input.version : undefined,\n tools: toolsRaw?.map((tool, index) => normalizeToolPolicy(tool, index)),\n dynamicToolRules: dynamicToolRulesRaw?.map((rule, index) => normalizeDynamicToolRule(rule, index)),\n sandbox: normalizeSandboxPolicy(input.sandbox),\n resources: normalizeResourcePolicy(input.resources),\n gates: gatesRaw?.map((gate, index) => normalizeGatePolicy(gate, index)),\n };\n\n return policySet;\n}\n\nexport async function loadPolicyFromYaml(path: string): Promise<PolicySet> {\n const content = await readFile(path, \"utf-8\");\n const parsed = parse(content);\n return normalizePolicySet(parsed);\n}\n","import { createHash } from \"node:crypto\";\nimport { OboraErrorCode } from \"../errors/OboraErrorCode.js\";\nimport { parseExpression } from \"./expressions/ExpressionParser.js\";\nimport type { PolicyEngine } from \"./PolicyEngine.js\";\nimport { loadPolicyFromYaml } from \"./PolicyLoader.js\";\nimport { GateRule, ResourceRule, SandboxRule, ToolRule, type PolicyConditionAuditEvent } from \"./rules/index.js\";\nimport type {\n PolicyAction,\n PolicyContext,\n PolicyDecision,\n PolicyRulePlugin,\n PolicySet,\n PolicySnapshot,\n PolicyVersion,\n} from \"./types.js\";\n\nexport interface PolicyLifecycleEvent {\n type: \"load\" | \"reload_success\" | \"reload_failure\";\n version?: PolicyVersion;\n source: string;\n error?: string;\n}\n\nexport interface PolicySnapshotPinnedAuditEvent {\n type: \"policy_snapshot_pinned\";\n executionId: string;\n version: string;\n}\n\nexport interface DefaultPolicyEngineOptions {\n onLifecycleEvent?: (event: PolicyLifecycleEvent) => void | Promise<void>;\n onAuditEvent?: (event: PolicyConditionAuditEvent | PolicySnapshotPinnedAuditEvent) => void | Promise<void>;\n}\n\nexport class DefaultPolicyEngine implements PolicyEngine {\n private policyPath?: string;\n private policySet: PolicySet = {};\n private policyVersion?: PolicyVersion;\n private readonly versions: PolicyVersion[] = [];\n private readonly rules: readonly PolicyRulePlugin[];\n private readonly onLifecycleEvent?: (event: PolicyLifecycleEvent) => void | Promise<void>;\n private readonly onAuditEvent?: (event: PolicyConditionAuditEvent | PolicySnapshotPinnedAuditEvent) => void | Promise<void>;\n private readonly pinnedSnapshots = new Map<string, PolicySnapshot>();\n\n constructor(rules?: readonly PolicyRulePlugin[], options?: DefaultPolicyEngineOptions) {\n this.rules = rules ?? [new ToolRule({ onAuditEvent: options?.onAuditEvent }), new SandboxRule(), new ResourceRule(), new GateRule()];\n this.onLifecycleEvent = options?.onLifecycleEvent;\n this.onAuditEvent = options?.onAuditEvent;\n }\n\n async load(pathToPolicy: string): Promise<PolicyVersion> {\n const loaded = await loadPolicyFromYaml(pathToPolicy);\n this.policyPath = pathToPolicy;\n const version = this.applyPolicy(loaded, pathToPolicy);\n await this.emit({ type: \"load\", source: pathToPolicy, version });\n return version;\n }\n\n loadInline(policies: PolicySet, source = \"inline\"): PolicyVersion {\n this.policyPath = undefined;\n const version = this.applyPolicy(policies, source);\n void this.emit({ type: \"load\", source, version });\n return version;\n }\n\n enforce(action: PolicyAction, context: PolicyContext): PolicyDecision {\n const pinned = context.executionId ? this.pinnedSnapshots.get(context.executionId) : undefined;\n if (pinned) {\n return pinned.enforce(action, context);\n }\n\n for (const rule of this.rules) {\n const decision = rule.evaluate(action, context, this.policySet);\n if (decision) {\n return decision;\n }\n }\n\n return { type: \"allow\" };\n }\n\n async reload(): Promise<PolicyVersion | undefined> {\n if (!this.policyPath) {\n return undefined;\n }\n\n try {\n const reloaded = await loadPolicyFromYaml(this.policyPath);\n const version = this.applyPolicy(reloaded, this.policyPath);\n await this.emit({ type: \"reload_success\", source: this.policyPath, version });\n return version;\n } catch (error) {\n await this.emit({\n type: \"reload_failure\",\n source: this.policyPath,\n error: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }\n\n version(): string {\n return this.policyVersion?.version ?? \"unknown\";\n }\n\n currentVersion(): PolicyVersion | undefined {\n return this.policyVersion;\n }\n\n history(): readonly PolicyVersion[] {\n return [...this.versions];\n }\n\n snapshot(): PolicySnapshot {\n const snapPolicy = clonePolicy(this.policySet);\n const snapVersion = this.policyVersion ?? buildVersion(this.policySet, this.policyPath ?? \"inline\");\n\n return {\n version: snapVersion,\n enforce: (action, context) => this.enforceWithPolicy(snapPolicy, action, context),\n };\n }\n\n pinForExecution(executionId: string): PolicySnapshot {\n const snapshot = this.snapshot();\n this.pinnedSnapshots.set(executionId, snapshot);\n void this.onAuditEvent?.({\n type: \"policy_snapshot_pinned\",\n executionId,\n version: snapshot.version.version,\n });\n return snapshot;\n }\n\n unpinExecution(executionId: string): void {\n this.pinnedSnapshots.delete(executionId);\n }\n\n getPinnedSnapshot(executionId: string): PolicySnapshot | undefined {\n return this.pinnedSnapshots.get(executionId);\n }\n\n private enforceWithPolicy(policySet: PolicySet, action: PolicyAction, context: PolicyContext): PolicyDecision {\n for (const rule of this.rules) {\n const decision = rule.evaluate(action, context, policySet);\n if (decision) {\n return decision;\n }\n }\n\n return { type: \"allow\" };\n }\n\n private applyPolicy(policySet: PolicySet, source: string): PolicyVersion {\n validatePolicyConditions(policySet);\n this.policySet = clonePolicy(policySet);\n this.policyVersion = buildVersion(this.policySet, source);\n this.versions.push(this.policyVersion);\n return this.policyVersion;\n }\n\n private async emit(event: PolicyLifecycleEvent): Promise<void> {\n await Promise.resolve(this.onLifecycleEvent?.(event));\n }\n}\n\nfunction validatePolicyConditions(policySet: PolicySet): void {\n for (const tool of policySet.tools ?? []) {\n const condition = tool.when?.condition;\n if (!condition) {\n continue;\n }\n\n try {\n parseExpression(condition);\n } catch (error) {\n const details = error instanceof Error ? error.message : String(error);\n const wrapped = new Error(\n `[${OboraErrorCode.POLICY_LOAD_FAILED}] Invalid tool condition at tools.${tool.name}: ${details}`,\n ) as Error & { code?: OboraErrorCode };\n wrapped.code = OboraErrorCode.POLICY_LOAD_FAILED;\n throw wrapped;\n }\n }\n\n for (const rule of policySet.dynamicToolRules ?? []) {\n try {\n parseExpression(rule.condition);\n } catch (error) {\n const details = error instanceof Error ? error.message : String(error);\n const wrapped = new Error(\n `[${OboraErrorCode.POLICY_LOAD_FAILED}] Invalid dynamic tool condition at dynamicToolRules.${rule.name}: ${details}`,\n ) as Error & { code?: OboraErrorCode };\n wrapped.code = OboraErrorCode.POLICY_LOAD_FAILED;\n throw wrapped;\n }\n }\n\n for (const limit of policySet.resources?.dynamicQuota?.limits ?? []) {\n try {\n parseExpression(limit.condition);\n } catch (error) {\n const details = error instanceof Error ? error.message : String(error);\n const wrapped = new Error(\n `[${OboraErrorCode.POLICY_LOAD_FAILED}] Invalid dynamic quota condition at resources.dynamicQuota.${limit.field}: ${details}`,\n ) as Error & { code?: OboraErrorCode };\n wrapped.code = OboraErrorCode.POLICY_LOAD_FAILED;\n throw wrapped;\n }\n }\n}\n\nfunction buildVersion(policySet: PolicySet, source: string): PolicyVersion {\n const hash = createHash(\"sha256\").update(stableStringify(policySet)).digest(\"hex\");\n return {\n version: policySet.version ?? hash.slice(0, 12),\n source,\n hash,\n loadedAt: new Date(),\n };\n}\n\nfunction clonePolicy(policySet: PolicySet): PolicySet {\n return structuredClone(policySet);\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value);\n }\n\n if (typeof value !== \"object\") {\n return JSON.stringify(value);\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableStringify(item)).join(\",\")}]`;\n }\n\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) => a.localeCompare(b));\n return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(\",\")}}`;\n}\n","export enum OboraErrorCode {\n CELL_TIMEOUT = \"CELL_1001\",\n CELL_TOOL_DENIED = \"CELL_1002\",\n CELL_LLM_ERROR = \"CELL_1003\",\n CELL_ABORTED = \"CELL_1004\",\n\n POLICY_DENY = \"POLICY_2001\",\n POLICY_GATE_REQUIRED = \"POLICY_2002\",\n POLICY_GATE_TIMEOUT = \"POLICY_2003\",\n POLICY_GATE_REJECTED = \"POLICY_2004\",\n POLICY_SANDBOX_VIOLATION = \"POLICY_2005\",\n POLICY_RESOURCE_EXCEEDED = \"POLICY_2006\",\n POLICY_LOAD_FAILED = \"POLICY_2007\",\n\n CONSENSUS_FAIL = \"CONSENSUS_3001\",\n CONSENSUS_TIMEOUT = \"CONSENSUS_3002\",\n CONSENSUS_QUORUM_NOT_MET = \"CONSENSUS_3003\",\n\n RECOVERY_RETRY_EXHAUSTED = \"RECOVERY_4001\",\n RECOVERY_ROLLBACK_FAILED = \"RECOVERY_4002\",\n RECOVERY_ESCALATION_TIMEOUT = \"RECOVERY_4003\",\n\n ORCH_WORKFLOW_NOT_FOUND = \"ORCH_5001\",\n ORCH_STEP_NOT_FOUND = \"ORCH_5002\",\n ORCH_DEPENDENCY_FAILED = \"ORCH_5003\",\n ORCH_EXECUTION_TIMEOUT = \"ORCH_5004\",\n\n AUDIT_STORE_ERROR = \"AUDIT_6001\",\n AUDIT_REPLAY_NOT_FOUND = \"AUDIT_6002\",\n\n ADAPTER_LLM_UNAVAILABLE = \"ADAPTER_7001\",\n ADAPTER_AUTH_FAILED = \"ADAPTER_7002\",\n ADAPTER_TOOL_NOT_FOUND = \"ADAPTER_7003\",\n}\n","export const MAX_EXPRESSION_DEPTH = 50;\n\nexport const ALLOWED_EXPRESSION_ROOTS = new Set([\n \"action\",\n \"context\",\n \"state\",\n \"step\",\n \"execution\",\n \"actor\",\n \"metrics\",\n \"previousResults\",\n]);\n\nexport const BLOCKED_FIELD_NAMES = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\n\nexport const ALLOWED_EXPRESSION_FUNCTIONS = new Set([\n \"contains\",\n \"matches\",\n \"startsWith\",\n \"endsWith\",\n \"in\",\n]);\n\nexport const MAX_REGEX_PATTERN_LENGTH = 256;\n","import { OboraErrorCode } from \"../../errors/OboraErrorCode.js\";\n\nexport type ExpressionAST =\n | ComparisonExpression\n | LogicalExpression\n | FunctionCallExpression\n | LiteralExpression\n | FieldRefExpression\n | NotExpression\n | ArrayLiteralExpression;\n\nexport interface ComparisonExpression {\n type: \"comparison\";\n operator: \"==\" | \"!=\" | \">\" | \">=\" | \"<\" | \"<=\";\n left: ExpressionAST;\n right: ExpressionAST;\n}\n\nexport interface LogicalExpression {\n type: \"logical\";\n operator: \"&&\" | \"||\";\n left: ExpressionAST;\n right: ExpressionAST;\n}\n\nexport interface FunctionCallExpression {\n type: \"function_call\";\n name: \"contains\" | \"matches\" | \"startsWith\" | \"endsWith\" | \"in\";\n args: ExpressionAST[];\n}\n\nexport interface LiteralExpression {\n type: \"literal\";\n value: string | number | boolean | null;\n}\n\nexport interface FieldRefExpression {\n type: \"field_ref\";\n path: string[];\n}\n\nexport interface NotExpression {\n type: \"not\";\n expression: ExpressionAST;\n}\n\nexport interface ArrayLiteralExpression {\n type: \"array_literal\";\n items: ExpressionAST[];\n}\n\nimport {\n ALLOWED_EXPRESSION_FUNCTIONS,\n ALLOWED_EXPRESSION_ROOTS,\n BLOCKED_FIELD_NAMES,\n MAX_EXPRESSION_DEPTH,\n} from \"./constants.js\";\n\ntype TokenType =\n | \"identifier\"\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"null\"\n | \"operator\"\n | \"paren_open\"\n | \"paren_close\"\n | \"bracket_open\"\n | \"bracket_close\"\n | \"comma\"\n | \"eof\";\n\ninterface Token {\n type: TokenType;\n value: string;\n index: number;\n}\n\nclass ExpressionParseError extends Error {\n readonly code = OboraErrorCode.POLICY_LOAD_FAILED;\n\n constructor(message: string) {\n super(`[${OboraErrorCode.POLICY_LOAD_FAILED}] ${message}`);\n this.name = \"ExpressionParseError\";\n }\n}\n\nclass Tokenizer {\n private readonly input: string;\n private index = 0;\n\n constructor(input: string) {\n this.input = input;\n }\n\n tokenize(): Token[] {\n const tokens: Token[] = [];\n\n while (this.index < this.input.length) {\n this.skipWhitespace();\n if (this.index >= this.input.length) {\n break;\n }\n\n const char = this.input[this.index];\n if (char === undefined) break;\n const next = this.input[this.index + 1] ?? \"\";\n\n if (char === \"(\") {\n tokens.push(this.make(\"paren_open\", char));\n this.index += 1;\n continue;\n }\n if (char === \")\") {\n tokens.push(this.make(\"paren_close\", char));\n this.index += 1;\n continue;\n }\n if (char === \"[\") {\n tokens.push(this.make(\"bracket_open\", char));\n this.index += 1;\n continue;\n }\n if (char === \"]\") {\n tokens.push(this.make(\"bracket_close\", char));\n this.index += 1;\n continue;\n }\n if (char === \",\") {\n tokens.push(this.make(\"comma\", char));\n this.index += 1;\n continue;\n }\n\n const twoChar = `${char}${next}`;\n if ([\"==\", \"!=\", \">=\", \"<=\", \"&&\", \"||\"].includes(twoChar)) {\n tokens.push(this.make(\"operator\", twoChar));\n this.index += 2;\n continue;\n }\n\n if ([\"!\", \">\", \"<\"].includes(char)) {\n tokens.push(this.make(\"operator\", char));\n this.index += 1;\n continue;\n }\n\n if (char === '\"' || char === \"'\") {\n tokens.push(this.readString(char));\n continue;\n }\n\n if (/[0-9]/.test(char)) {\n tokens.push(this.readNumber());\n continue;\n }\n\n if (/[A-Za-z_]/.test(char)) {\n tokens.push(this.readIdentifier());\n continue;\n }\n\n throw new ExpressionParseError(`Unexpected character '${char}' at position ${this.index}`);\n }\n\n tokens.push({ type: \"eof\", value: \"\", index: this.index });\n return tokens;\n }\n\n private make(type: TokenType, value: string): Token {\n return { type, value, index: this.index };\n }\n\n private skipWhitespace(): void {\n while (this.index < this.input.length && /\\s/.test(this.input[this.index] ?? \"\")) {\n this.index += 1;\n }\n }\n\n private readString(quote: string): Token {\n const start = this.index;\n this.index += 1;\n let value = \"\";\n\n while (this.index < this.input.length) {\n const ch = this.input[this.index];\n if (ch === undefined) break;\n if (ch === \"\\\\\") {\n const escaped = this.input[this.index + 1];\n if (escaped === undefined) {\n throw new ExpressionParseError(`Unterminated string starting at position ${start}`);\n }\n value += escaped;\n this.index += 2;\n continue;\n }\n if (ch === quote) {\n this.index += 1;\n return { type: \"string\", value, index: start };\n }\n value += ch;\n this.index += 1;\n }\n\n throw new ExpressionParseError(`Unterminated string starting at position ${start}`);\n }\n\n private readNumber(): Token {\n const start = this.index;\n while (this.index < this.input.length && /[0-9.]/.test(this.input[this.index] ?? \"\")) {\n this.index += 1;\n }\n\n const value = this.input.slice(start, this.index);\n if (!/^\\d+(\\.\\d+)?$/.test(value)) {\n throw new ExpressionParseError(`Invalid number '${value}' at position ${start}`);\n }\n\n return { type: \"number\", value, index: start };\n }\n\n private readIdentifier(): Token {\n const start = this.index;\n while (this.index < this.input.length && /[A-Za-z0-9_.]/.test(this.input[this.index] ?? \"\")) {\n this.index += 1;\n }\n\n const value = this.input.slice(start, this.index);\n if (value === \"true\" || value === \"false\") {\n return { type: \"boolean\", value, index: start };\n }\n if (value === \"null\") {\n return { type: \"null\", value, index: start };\n }\n\n return { type: \"identifier\", value, index: start };\n }\n}\n\nclass Parser {\n private readonly tokens: Token[];\n private index = 0;\n private depth = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n private enterDepth(): void {\n this.depth += 1;\n if (this.depth > MAX_EXPRESSION_DEPTH) {\n throw new ExpressionParseError(`Expression nesting depth exceeds maximum (${MAX_EXPRESSION_DEPTH})`);\n }\n }\n\n private exitDepth(): void {\n this.depth = Math.max(0, this.depth - 1);\n }\n\n parse(): ExpressionAST {\n const expression = this.parseOrExpression();\n this.expect(\"eof\");\n return expression;\n }\n\n private parseOrExpression(): ExpressionAST {\n this.enterDepth();\n try {\n let left = this.parseAndExpression();\n\n while (this.matchOperator(\"||\")) {\n const right = this.parseAndExpression();\n left = { type: \"logical\", operator: \"||\", left, right };\n }\n\n return left;\n } finally {\n this.exitDepth();\n }\n }\n\n private parseAndExpression(): ExpressionAST {\n this.enterDepth();\n try {\n let left = this.parseUnaryExpression();\n\n while (this.matchOperator(\"&&\")) {\n const right = this.parseUnaryExpression();\n left = { type: \"logical\", operator: \"&&\", left, right };\n }\n\n return left;\n } finally {\n this.exitDepth();\n }\n }\n\n private parseUnaryExpression(): ExpressionAST {\n this.enterDepth();\n try {\n if (this.matchOperator(\"!\")) {\n return { type: \"not\", expression: this.parseUnaryExpression() };\n }\n\n return this.parseComparisonExpression();\n } finally {\n this.exitDepth();\n }\n }\n\n private parseComparisonExpression(): ExpressionAST {\n this.enterDepth();\n try {\n const left = this.parsePrimaryExpression();\n const token = this.peek();\n\n if (token.type === \"operator\" && [\"==\", \"!=\", \">\", \">=\", \"<\", \"<=\"].includes(token.value)) {\n this.index += 1;\n const right = this.parsePrimaryExpression();\n return {\n type: \"comparison\",\n operator: token.value as ComparisonExpression[\"operator\"],\n left,\n right,\n };\n }\n\n return left;\n } finally {\n this.exitDepth();\n }\n }\n\n private parsePrimaryExpression(): ExpressionAST {\n this.enterDepth();\n try {\n const token = this.peek();\n\n if (token.type === \"paren_open\") {\n this.index += 1;\n const expression = this.parseOrExpression();\n this.expect(\"paren_close\");\n return expression;\n }\n\n if (token.type === \"string\") {\n this.index += 1;\n return { type: \"literal\", value: token.value };\n }\n\n if (token.type === \"number\") {\n this.index += 1;\n return { type: \"literal\", value: Number(token.value) };\n }\n\n if (token.type === \"boolean\") {\n this.index += 1;\n return { type: \"literal\", value: token.value === \"true\" };\n }\n\n if (token.type === \"null\") {\n this.index += 1;\n return { type: \"literal\", value: null };\n }\n\n if (token.type === \"bracket_open\") {\n return this.parseArrayLiteral();\n }\n\n if (token.type === \"identifier\") {\n this.index += 1;\n const identifier = token.value;\n\n if (this.peek().type === \"paren_open\") {\n return this.parseFunctionCall(identifier, token.index);\n }\n\n return this.parseFieldRef(identifier, token.index);\n }\n\n throw new ExpressionParseError(`Unexpected token '${token.value}' at position ${token.index}`);\n } finally {\n this.exitDepth();\n }\n }\n\n private parseArrayLiteral(): ExpressionAST {\n this.expect(\"bracket_open\");\n const items: ExpressionAST[] = [];\n\n while (this.peek().type !== \"bracket_close\") {\n items.push(this.parsePrimaryExpression());\n if (this.peek().type === \"comma\") {\n this.index += 1;\n } else {\n break;\n }\n }\n\n this.expect(\"bracket_close\");\n return { type: \"array_literal\", items };\n }\n\n private parseFunctionCall(name: string, index: number): FunctionCallExpression {\n if (!ALLOWED_EXPRESSION_FUNCTIONS.has(name)) {\n throw new ExpressionParseError(`Unsupported function '${name}' at position ${index}`);\n }\n\n this.expect(\"paren_open\");\n const args: ExpressionAST[] = [];\n\n while (this.peek().type !== \"paren_close\") {\n args.push(this.parseOrExpression());\n if (this.peek().type === \"comma\") {\n this.index += 1;\n } else {\n break;\n }\n }\n\n this.expect(\"paren_close\");\n\n return {\n type: \"function_call\",\n name: name as FunctionCallExpression[\"name\"],\n args,\n };\n }\n\n private parseFieldRef(identifier: string, index: number): FieldRefExpression {\n const path = identifier.split(\".\");\n\n const root = path[0];\n if (path.length === 0 || root === undefined || !ALLOWED_EXPRESSION_ROOTS.has(root)) {\n throw new ExpressionParseError(\n `Field reference '${identifier}' must start with action/context/state/step/execution/actor/metrics/previousResults at ${index}`,\n );\n }\n\n for (const segment of path) {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(segment)) {\n throw new ExpressionParseError(`Invalid field segment '${segment}' in '${identifier}' at ${index}`);\n }\n if (BLOCKED_FIELD_NAMES.has(segment)) {\n throw new ExpressionParseError(`Blocked field segment '${segment}' in '${identifier}'`);\n }\n }\n\n return {\n type: \"field_ref\",\n path,\n };\n }\n\n private matchOperator(operator: string): boolean {\n const token = this.peek();\n if (token.type === \"operator\" && token.value === operator) {\n this.index += 1;\n return true;\n }\n\n return false;\n }\n\n private expect(type: TokenType): Token {\n const token = this.peek();\n if (token.type !== type) {\n throw new ExpressionParseError(`Expected token ${type} but got '${token.value}' at position ${token.index}`);\n }\n this.index += 1;\n return token;\n }\n\n private peek(): Token {\n const token = this.tokens[this.index] ?? this.tokens[this.tokens.length - 1];\n if (token === undefined) {\n throw new ExpressionParseError(\"Unexpected end of expression\");\n }\n return token;\n }\n}\n\nexport function parseExpression(expr: string): ExpressionAST {\n if (expr.trim().length === 0) {\n throw new ExpressionParseError(\"Expression cannot be empty\");\n }\n\n const tokenizer = new Tokenizer(expr);\n const tokens = tokenizer.tokenize();\n const parser = new Parser(tokens);\n return parser.parse();\n}\n","import { OboraErrorCode } from \"../../errors/OboraErrorCode.js\";\nimport type { PolicyAction, PolicyContext } from \"../types.js\";\nimport type { ArrayLiteralExpression, ComparisonExpression, ExpressionAST, FunctionCallExpression } from \"./ExpressionParser.js\";\n\nexport interface ExpressionContext {\n action: PolicyAction;\n context: PolicyContext;\n state?: Record<string, unknown>;\n step?: {\n name: string;\n agent: string;\n config?: Record<string, unknown>;\n };\n execution?: {\n id: string;\n workflowName: string;\n startedAt: Date;\n elapsedMs: number;\n totalTokens: number;\n totalCost: number;\n totalToolCalls: number;\n completedSteps: string[];\n };\n actor?: {\n id: string;\n role?: string;\n };\n metrics?: {\n errorCount: number;\n retryCount: number;\n avgStepDurationMs: number;\n maxStepDurationMs: number;\n };\n previousResults?: Record<string, { success: boolean; output?: unknown }>;\n}\n\nimport { BLOCKED_FIELD_NAMES, MAX_REGEX_PATTERN_LENGTH } from \"./constants.js\";\n\nclass ExpressionEvaluationError extends Error {\n readonly code = OboraErrorCode.POLICY_DENY;\n\n constructor(message: string) {\n super(`[${OboraErrorCode.POLICY_DENY}] ${message}`);\n this.name = \"ExpressionEvaluationError\";\n }\n}\n\nexport function evaluateExpression(ast: ExpressionAST, ctx: ExpressionContext): boolean {\n const result = evaluateNode(ast, ctx);\n return Boolean(result);\n}\n\nfunction evaluateNode(ast: ExpressionAST, ctx: ExpressionContext): unknown {\n switch (ast.type) {\n case \"literal\":\n return ast.value;\n case \"field_ref\":\n return resolveField(ast.path, ctx);\n case \"array_literal\":\n return ast.items.map((item) => evaluateNode(item, ctx));\n case \"not\":\n return !Boolean(evaluateNode(ast.expression, ctx));\n case \"logical\": {\n if (ast.operator === \"&&\") {\n return Boolean(evaluateNode(ast.left, ctx)) && Boolean(evaluateNode(ast.right, ctx));\n }\n return Boolean(evaluateNode(ast.left, ctx)) || Boolean(evaluateNode(ast.right, ctx));\n }\n case \"comparison\":\n return evaluateComparison(ast, ctx);\n case \"function_call\":\n return evaluateFunctionCall(ast, ctx);\n default:\n return assertNever(ast);\n }\n}\n\nfunction evaluateComparison(ast: ComparisonExpression, ctx: ExpressionContext): boolean {\n const left = evaluateNode(ast.left, ctx);\n const right = evaluateNode(ast.right, ctx);\n\n switch (ast.operator) {\n case \"==\":\n return left === right;\n case \"!=\":\n return left !== right;\n case \">\":\n ensureComparable(left, right, ast.operator);\n return (left as number | string) > (right as number | string);\n case \">=\":\n ensureComparable(left, right, ast.operator);\n return (left as number | string) >= (right as number | string);\n case \"<\":\n ensureComparable(left, right, ast.operator);\n return (left as number | string) < (right as number | string);\n case \"<=\":\n ensureComparable(left, right, ast.operator);\n return (left as number | string) <= (right as number | string);\n default:\n return assertNever(ast.operator);\n }\n}\n\nfunction evaluateFunctionCall(ast: FunctionCallExpression, ctx: ExpressionContext): boolean {\n const evaluatedArgs = ast.args.map((arg) => evaluateNode(arg, ctx));\n\n switch (ast.name) {\n case \"contains\": {\n ensureArgCount(ast, 2);\n const [value, needle] = evaluatedArgs;\n return String(value ?? \"\").includes(String(needle ?? \"\"));\n }\n case \"startsWith\": {\n ensureArgCount(ast, 2);\n const [value, prefix] = evaluatedArgs;\n return String(value ?? \"\").startsWith(String(prefix ?? \"\"));\n }\n case \"endsWith\": {\n ensureArgCount(ast, 2);\n const [value, suffix] = evaluatedArgs;\n return String(value ?? \"\").endsWith(String(suffix ?? \"\"));\n }\n case \"matches\": {\n ensureArgCount(ast, 2);\n const [value, regexPattern] = evaluatedArgs;\n try {\n const pattern = String(regexPattern ?? \"\");\n validateRegexPattern(pattern);\n const regex = new RegExp(pattern);\n return regex.test(String(value ?? \"\"));\n } catch (error) {\n throw new ExpressionEvaluationError(\n `Invalid regex in matches(): ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n case \"in\": {\n ensureArgCount(ast, 2);\n const [value, list] = evaluatedArgs;\n if (!Array.isArray(list)) {\n throw new ExpressionEvaluationError(\"in() expects an array as the second argument\");\n }\n return list.some((item) => item === value);\n }\n default:\n return assertNever(ast.name);\n }\n}\n\n\nfunction validateRegexPattern(pattern: string): void {\n if (pattern.length > MAX_REGEX_PATTERN_LENGTH) {\n throw new Error(`regex pattern exceeds maximum length (${MAX_REGEX_PATTERN_LENGTH})`);\n }\n\n // Basic ReDoS guard: block obvious nested quantifiers like (a+)+, (.*)+, (.+)*\n if (/\\((?:[^()]*[+*][^()]*)\\)[+*{]/.test(pattern)) {\n throw new Error(\"potentially unsafe regex pattern (nested quantifier) is not allowed\");\n }\n}\n\nfunction resolveField(path: string[], ctx: ExpressionContext): unknown {\n const [root, ...segments] = path;\n let current: unknown;\n\n if (root === \"action\") {\n current = ctx.action;\n } else if (root === \"context\") {\n current = ctx.context;\n } else if (root === \"state\") {\n current = ctx.state;\n } else if (root === \"step\") {\n current = ctx.step;\n } else if (root === \"execution\") {\n current = ctx.execution;\n } else if (root === \"actor\") {\n current = ctx.actor;\n } else if (root === \"metrics\") {\n current = ctx.metrics;\n } else if (root === \"previousResults\") {\n current = ctx.previousResults;\n } else {\n throw new ExpressionEvaluationError(`Unsupported root '${root}' in field path`);\n }\n\n for (const segment of segments) {\n if (BLOCKED_FIELD_NAMES.has(segment)) {\n throw new ExpressionEvaluationError(`Blocked field segment '${segment}'`);\n }\n\n if (!isObject(current)) {\n return undefined;\n }\n\n if (!Object.hasOwn(current, segment)) {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current;\n}\n\nfunction ensureComparable(left: unknown, right: unknown, operator: string): void {\n const sameType = typeof left === typeof right;\n const allowedType = typeof left === \"number\" || typeof left === \"string\";\n\n if (!sameType || !allowedType) {\n throw new ExpressionEvaluationError(\n `Operator '${operator}' expects both sides to be the same comparable type (number or string)`,\n );\n }\n}\n\nfunction ensureArgCount(ast: FunctionCallExpression, expected: number): void {\n if (ast.args.length !== expected) {\n throw new ExpressionEvaluationError(`${ast.name}() expects ${expected} arguments, got ${ast.args.length}`);\n }\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\";\n}\n\nfunction assertNever(value: never): never {\n throw new ExpressionEvaluationError(`Unsupported AST node: ${JSON.stringify(value)}`);\n}\n","import { evaluateExpression, type ExpressionContext } from \"./expressions/ExpressionEvaluator.js\";\nimport { parseExpression, type ExpressionAST } from \"./expressions/ExpressionParser.js\";\nimport type { DynamicToolRule, PolicyAction, PolicyContext, PolicyDecision } from \"./types.js\";\n\n// Module-level expression AST cache shared across all resolveDynamicToolRule calls.\n// Uses FIFO eviction at MAX_CACHE_SIZE. For multi-engine isolation, consider\n// injecting cache via options in the future.\nconst MAX_CACHE_SIZE = 1000;\nconst expressionCache = new Map<string, ExpressionAST>();\n\nfunction getExpressionAst(expression: string): ExpressionAST {\n const cached = expressionCache.get(expression);\n if (cached) {\n return cached;\n }\n\n const ast = parseExpression(expression);\n if (expressionCache.size >= MAX_CACHE_SIZE) {\n const oldestKey = expressionCache.keys().next().value;\n if (oldestKey !== undefined) {\n expressionCache.delete(oldestKey);\n }\n }\n expressionCache.set(expression, ast);\n return ast;\n}\n\ninterface IndexedDynamicToolRule extends DynamicToolRule {\n /** Original array index, used for deterministic tie-breaking */\n _index: number;\n}\n\nfunction compareDynamicRules(a: IndexedDynamicToolRule, b: IndexedDynamicToolRule): number {\n const priorityDiff = (b.priority ?? 0) - (a.priority ?? 0);\n if (priorityDiff !== 0) {\n return priorityDiff;\n }\n\n if (a.effect === \"deny\" && b.effect !== \"deny\") {\n return -1;\n }\n if (b.effect === \"deny\" && a.effect !== \"deny\") {\n return 1;\n }\n\n // Stable tie-break: preserve original declaration order\n return a._index - b._index;\n}\n\nexport interface DynamicToolRuleResolution {\n matchedRule?: DynamicToolRule;\n denyDecision?: PolicyDecision;\n}\n\nexport function resolveDynamicToolRule(\n action: PolicyAction,\n context: PolicyContext,\n rules: DynamicToolRule[] | undefined,\n): DynamicToolRuleResolution {\n if (action.type !== \"tool_call\" || !rules || rules.length === 0) {\n return {};\n }\n\n const candidates: IndexedDynamicToolRule[] = [];\n\n for (let i = 0; i < rules.length; i++) {\n const rule = rules[i];\n if (rule.name !== action.name) {\n continue;\n }\n\n try {\n const ast = getExpressionAst(rule.condition);\n const evalContext: ExpressionContext = {\n action,\n context,\n state: context.dynamicVars?.state,\n step: context.dynamicVars?.step,\n execution: context.dynamicVars?.execution,\n actor: context.dynamicVars?.actor,\n metrics: context.dynamicVars?.metrics,\n previousResults: context.dynamicVars?.previousResults,\n };\n\n if (evaluateExpression(ast, evalContext)) {\n candidates.push({ ...rule, _index: i });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n denyDecision: {\n type: \"deny\",\n reason: `dynamic tool rule condition evaluation failed: ${message}`,\n rule: rule.name,\n },\n };\n }\n }\n\n if (candidates.length === 0) {\n return {};\n }\n\n return { matchedRule: [...candidates].sort(compareDynamicRules)[0] };\n}\n\nexport const __internal = {\n getExpressionCacheSize: (): number => expressionCache.size,\n clearExpressionCache: (): void => {\n expressionCache.clear();\n },\n};\n","import { resolveDynamicToolRule } from \"../DynamicToolPolicy.js\";\nimport { evaluateExpression, type ExpressionContext } from \"../expressions/ExpressionEvaluator.js\";\nimport { parseExpression, type ExpressionAST } from \"../expressions/ExpressionParser.js\";\nimport type { DynamicToolRule, PolicyAction, PolicyContext, PolicyDecision, PolicyRulePlugin, PolicySet, ToolPolicy } from \"../types.js\";\n\nexport interface PolicyConditionAuditEvent {\n type: \"policy_condition_evaluated\";\n expression: string;\n result: boolean;\n rule: string;\n action: string;\n error?: string;\n}\n\nexport interface ToolRuleOptions {\n onAuditEvent?: (event: PolicyConditionAuditEvent) => void | Promise<void>;\n}\n\nfunction toActionText(action: PolicyAction): string {\n if (typeof action.params === \"string\") {\n return action.params;\n }\n if (action.params === undefined) {\n return \"\";\n }\n\n try {\n return JSON.stringify(action.params);\n } catch {\n return String(action.params);\n }\n}\n\nfunction matchesToolRule(\n rule: ToolPolicy,\n action: PolicyAction,\n context: PolicyContext,\n getExpressionAst: (expression: string) => ExpressionAST,\n onAuditEvent?: ToolRuleOptions[\"onAuditEvent\"],\n): { matched: boolean; evaluationError?: string } {\n if (rule.name !== action.name) {\n return { matched: false };\n }\n\n const when = rule.when;\n if (!when) {\n return { matched: true };\n }\n\n const text = toActionText(action);\n const matches = when.matches ?? [];\n const notMatches = when.not_matches ?? [];\n\n const includesAnyMatch = matches.length === 0 || matches.some((pattern) => text.includes(pattern));\n const includesNotMatch = notMatches.some((pattern) => text.includes(pattern));\n\n if (!(includesAnyMatch && !includesNotMatch)) {\n return { matched: false };\n }\n\n if (!when.condition) {\n return { matched: true };\n }\n\n const rulePath = `tools.${rule.name}`;\n\n try {\n const ast = getExpressionAst(when.condition);\n const evalContext: ExpressionContext = { action, context };\n const result = evaluateExpression(ast, evalContext);\n\n void onAuditEvent?.({\n type: \"policy_condition_evaluated\",\n expression: when.condition,\n result,\n rule: rulePath,\n action: action.name,\n });\n\n return { matched: result };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n void onAuditEvent?.({\n type: \"policy_condition_evaluated\",\n expression: when.condition,\n result: false,\n rule: rulePath,\n action: action.name,\n error: message,\n });\n\n return {\n matched: true,\n evaluationError: `Policy condition evaluation failed for '${rulePath}': ${message}`,\n };\n }\n}\n\nexport class ToolRule implements PolicyRulePlugin {\n readonly name = \"tool\";\n readonly version = \"1.1.0\";\n readonly type = \"policy-rule\" as const;\n\n private readonly expressionCache = new Map<string, ExpressionAST>();\n private readonly onAuditEvent?: ToolRuleOptions[\"onAuditEvent\"];\n\n constructor(options?: ToolRuleOptions) {\n this.onAuditEvent = options?.onAuditEvent;\n }\n\n evaluate(action: PolicyAction, context: PolicyContext, policies: PolicySet): PolicyDecision | null {\n if (action.type !== \"tool_call\") {\n return null;\n }\n\n const dynamicResolution = resolveDynamicToolRule(action, context, policies.dynamicToolRules);\n if (dynamicResolution.denyDecision) {\n return dynamicResolution.denyDecision;\n }\n\n if (dynamicResolution.matchedRule) {\n return this.toDecisionFromDynamicRule(action, dynamicResolution.matchedRule);\n }\n\n for (const rule of policies.tools ?? []) {\n const matchResult = matchesToolRule(rule, action, context, this.getExpressionAst.bind(this), this.onAuditEvent);\n if (!matchResult.matched) {\n continue;\n }\n\n if (matchResult.evaluationError) {\n return {\n type: \"deny\",\n reason: matchResult.evaluationError,\n rule: `tools.${rule.name}`,\n };\n }\n\n if (rule.effect === \"allow\") {\n return { type: \"allow\" };\n }\n\n if (rule.effect === \"deny\") {\n return {\n type: \"deny\",\n reason: `Tool call denied for ${action.name}`,\n rule: `tools.${rule.name}`,\n };\n }\n\n if (rule.effect === \"gate\") {\n return {\n type: \"gate\",\n gateType: rule.gate?.type ?? \"human-approval\",\n config: {\n tool: action.name,\n timeout: rule.gate?.timeout,\n rule: `tools.${rule.name}`,\n },\n };\n }\n\n return {\n type: \"transform\",\n original: action.params,\n transformed: {\n params: action.params,\n transform: rule.transform?.fn,\n },\n rule: `tools.${rule.name}`,\n transformFn: rule.transform?.fn,\n };\n }\n\n return null;\n }\n\n private toDecisionFromDynamicRule(action: PolicyAction, rule: DynamicToolRule): PolicyDecision {\n if (rule.effect === \"allow\") {\n return { type: \"allow\" };\n }\n\n if (rule.effect === \"deny\") {\n return {\n type: \"deny\",\n reason: `Tool call denied for ${action.name}`,\n rule: `dynamicTools.${rule.name}`,\n };\n }\n\n if (rule.effect === \"gate\") {\n return {\n type: \"gate\",\n gateType: rule.gate?.type ?? \"human-approval\",\n config: {\n tool: action.name,\n timeout: rule.gate?.timeout,\n rule: `dynamicTools.${rule.name}`,\n },\n };\n }\n\n // effect === \"transform\"\n return {\n type: \"transform\",\n original: action.params,\n transformed: {\n params: action.params,\n transform: rule.transformFn ?? \"dynamic\",\n },\n rule: `dynamicTools.${rule.name}`,\n transformFn: rule.transformFn ?? \"dynamic\",\n };\n }\n\n private getExpressionAst(expression: string): ExpressionAST {\n const cached = this.expressionCache.get(expression);\n if (cached) {\n return cached;\n }\n\n const ast = parseExpression(expression);\n this.expressionCache.set(expression, ast);\n return ast;\n }\n}\n","import path from \"node:path\";\nimport type { PolicyAction, PolicyContext, PolicyDecision, PolicyRulePlugin, PolicySet } from \"../types.js\";\n\nfunction isPathOutsideRoot(root: string, filePath: string): boolean {\n const relative = path.relative(root, filePath);\n return relative === \"\" ? false : relative.startsWith(\"..\") || path.isAbsolute(relative);\n}\n\nexport class SandboxRule implements PolicyRulePlugin {\n readonly name = \"sandbox\";\n readonly version = \"1.0.0\";\n readonly type = \"policy-rule\" as const;\n\n evaluate(action: PolicyAction, _context: PolicyContext, policies: PolicySet): PolicyDecision | null {\n if (action.type !== \"file_access\" || !policies.sandbox) {\n return null;\n }\n\n const filePath = (action.params as { path?: string } | undefined)?.path;\n if (!filePath) {\n return null;\n }\n\n const root = path.resolve(policies.sandbox.root);\n const resolvedPath = path.resolve(filePath);\n\n if (policies.sandbox.denyOutsideRoot && isPathOutsideRoot(root, resolvedPath)) {\n return {\n type: \"deny\",\n reason: `File path outside sandbox root: ${filePath}`,\n rule: \"sandbox.denyOutsideRoot\",\n };\n }\n\n for (const pattern of policies.sandbox.denyPatterns ?? []) {\n if (resolvedPath.includes(pattern)) {\n return {\n type: \"deny\",\n reason: `File path blocked by sandbox pattern: ${pattern}`,\n rule: \"sandbox.denyPatterns\",\n };\n }\n }\n\n return null;\n }\n}\n","import { evaluateExpression, type ExpressionContext } from \"./expressions/ExpressionEvaluator.js\";\nimport { parseExpression, type ExpressionAST } from \"./expressions/ExpressionParser.js\";\nimport type { DynamicResourceLimit, PolicyAction, PolicyContext, PolicyDecision, PolicyWarning, ResourcePolicy } from \"./types.js\";\n\nconst fieldToContextValue: Record<DynamicResourceLimit[\"field\"], (context: PolicyContext) => number> = {\n tokens: (context) => context.currentTokens ?? 0,\n cost: (context) => context.currentCost ?? 0,\n tool_calls: (context) => context.currentToolCalls ?? 0,\n duration_ms: (context) => context.currentDurationMs ?? 0,\n};\n\nconst fieldToRulePath: Record<DynamicResourceLimit[\"field\"], string> = {\n tokens: \"resources.maxTokens\",\n cost: \"resources.maxCostUsd\",\n tool_calls: \"resources.maxToolCalls\",\n duration_ms: \"resources.timeoutMs\",\n};\n\nconst fieldToReason: Record<DynamicResourceLimit[\"field\"], string> = {\n tokens: \"Token limit exceeded\",\n cost: \"Cost limit exceeded\",\n tool_calls: \"Tool call limit exceeded\",\n duration_ms: \"Timeout exceeded\",\n};\n\n// Module-level expression AST cache shared across all evaluateDynamicResourceDecision calls.\n// Uses FIFO eviction at MAX_CACHE_SIZE. For multi-engine isolation, consider\n// injecting cache via options in the future.\nconst MAX_CACHE_SIZE = 1000;\nconst expressionCache = new Map<string, ExpressionAST>();\n\nfunction getExpressionAst(expression: string): ExpressionAST {\n const cached = expressionCache.get(expression);\n if (cached) {\n return cached;\n }\n\n const ast = parseExpression(expression);\n if (expressionCache.size >= MAX_CACHE_SIZE) {\n const oldestKey = expressionCache.keys().next().value;\n if (oldestKey !== undefined) {\n expressionCache.delete(oldestKey);\n }\n }\n expressionCache.set(expression, ast);\n return ast;\n}\n\nfunction conditionMatches(limit: DynamicResourceLimit, action: PolicyAction, context: PolicyContext): boolean {\n const ast = getExpressionAst(limit.condition);\n const evalContext: ExpressionContext = {\n action,\n context,\n state: context.dynamicVars?.state,\n step: context.dynamicVars?.step,\n execution: context.dynamicVars?.execution,\n actor: context.dynamicVars?.actor,\n metrics: context.dynamicVars?.metrics,\n previousResults: context.dynamicVars?.previousResults,\n };\n\n return evaluateExpression(ast, evalContext);\n}\n\nexport function evaluateDynamicResourceDecision(\n policy: ResourcePolicy,\n action: PolicyAction,\n context: PolicyContext,\n): PolicyDecision | null {\n const limits = policy.dynamicQuota?.limits ?? [];\n\n for (const limit of limits) {\n let matches = false;\n try {\n matches = conditionMatches(limit, action, context);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n type: \"deny\",\n reason: `dynamic quota condition evaluation failed: ${message}`,\n rule: \"dynamic-quota\",\n };\n }\n\n if (!matches) {\n continue;\n }\n\n const current = fieldToContextValue[limit.field](context);\n if (current <= limit.limit) {\n continue;\n }\n\n if (limit.action === \"deny\") {\n return {\n type: \"deny\",\n reason: fieldToReason[limit.field],\n rule: `resources.dynamic.${limit.field}`,\n };\n }\n\n if (limit.action === \"warn\") {\n // warn: allow the action but attach a warning for upstream consumers\n return {\n type: \"allow\",\n warning: {\n reason: `${fieldToReason[limit.field]} (dynamic)`,\n rule: `resources.dynamic.${limit.field}`,\n field: limit.field,\n limit: limit.limit,\n current,\n },\n };\n }\n\n // action === \"gate\"\n return {\n type: \"gate\",\n gateType: \"human-approval\",\n config: {\n reason: `${fieldToReason[limit.field]} (dynamic)`,\n action: limit.action,\n field: limit.field,\n limit: limit.limit,\n current,\n rule: `resources.dynamic.${limit.field}`,\n },\n };\n }\n\n return null;\n}\n\nexport function getEffectiveStaticLimit(policy: ResourcePolicy, field: DynamicResourceLimit[\"field\"]): number | undefined {\n switch (field) {\n case \"tokens\":\n return policy.maxTokens;\n case \"cost\":\n return policy.maxCostUsd;\n case \"tool_calls\":\n return policy.maxToolCalls;\n case \"duration_ms\":\n return policy.timeoutMs;\n default:\n return undefined;\n }\n}\n\nexport function getStaticRulePath(field: DynamicResourceLimit[\"field\"]): string {\n return fieldToRulePath[field];\n}\n\nexport function getStaticReason(field: DynamicResourceLimit[\"field\"]): string {\n return fieldToReason[field];\n}\n\nexport const __internal = {\n getExpressionCacheSize: (): number => expressionCache.size,\n clearExpressionCache: (): void => {\n expressionCache.clear();\n },\n};\n","import { evaluateDynamicResourceDecision } from \"../DynamicQuotaEvaluator.js\";\nimport type { PolicyAction, PolicyContext, PolicyDecision, PolicyRulePlugin, PolicySet } from \"../types.js\";\n\nexport class ResourceRule implements PolicyRulePlugin {\n readonly name = \"resource\";\n readonly version = \"1.0.0\";\n readonly type = \"policy-rule\" as const;\n\n evaluate(action: PolicyAction, context: PolicyContext, policies: PolicySet): PolicyDecision | null {\n if (action.type !== \"resource_use\" || !policies.resources) {\n return null;\n }\n\n const resources = policies.resources;\n\n const dynamicDecision = evaluateDynamicResourceDecision(resources, action, context);\n if (dynamicDecision) {\n return dynamicDecision;\n }\n\n if (resources.timeoutMs !== undefined && (context.currentDurationMs ?? 0) > resources.timeoutMs) {\n return { type: \"deny\", reason: \"Timeout exceeded\", rule: \"resources.timeoutMs\" };\n }\n if (resources.maxTokens !== undefined && (context.currentTokens ?? 0) > resources.maxTokens) {\n return { type: \"deny\", reason: \"Token limit exceeded\", rule: \"resources.maxTokens\" };\n }\n if (resources.maxCostUsd !== undefined && (context.currentCost ?? 0) > resources.maxCostUsd) {\n return { type: \"deny\", reason: \"Cost limit exceeded\", rule: \"resources.maxCostUsd\" };\n }\n if (resources.maxToolCalls !== undefined && (context.currentToolCalls ?? 0) > resources.maxToolCalls) {\n return { type: \"deny\", reason: \"Tool call limit exceeded\", rule: \"resources.maxToolCalls\" };\n }\n\n return null;\n }\n}\n","import type { PolicyAction, PolicyContext, PolicyDecision, PolicyRulePlugin, PolicySet } from \"../types.js\";\n\nexport class GateRule implements PolicyRulePlugin {\n readonly name = \"gate\";\n readonly version = \"1.0.0\";\n readonly type = \"policy-rule\" as const;\n\n evaluate(action: PolicyAction, _context: PolicyContext, policies: PolicySet): PolicyDecision | null {\n if (action.type !== \"step_start\") {\n return null;\n }\n\n const gate = (policies.gates ?? []).find((policy) => policy.step === action.name && policy.required);\n if (!gate) {\n return null;\n }\n\n return {\n type: \"gate\",\n gateType: gate.type,\n config: {\n step: gate.step,\n timeout: gate.timeout,\n fallback: gate.fallback,\n },\n };\n }\n}\n","import type { AuditEvent } from \"../audit/types.js\";\nimport type { DynamicPolicyVars } from \"./types.js\";\n\nexport interface BuildDynamicPolicyVarsParams {\n executionId: string;\n workflowName: string;\n startedAt: Date;\n stepName: string;\n stepAgent: string;\n stepIndex: number;\n stepConfig?: Record<string, unknown>;\n actorId: string;\n actorRole?: string;\n state: Record<string, unknown>;\n auditEvents: AuditEvent[];\n completedSteps: string[];\n previousResults: Record<string, { success: boolean; output?: unknown }>;\n}\n\nfunction toNumber(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n}\n\nexport function buildDynamicPolicyVars(params: BuildDynamicPolicyVarsParams): DynamicPolicyVars {\n const now = Date.now();\n const durations = params.auditEvents\n .map((event) => toNumber(event.metadata?.durationMs))\n .filter((duration) => duration > 0);\n\n const errorCount = params.auditEvents.filter((event) => event.type === \"error\").length;\n const retryCount = params.auditEvents.filter((event) => event.type === \"recovery_start\").length;\n\n const totalDuration = durations.reduce((sum, duration) => sum + duration, 0);\n const avgStepDurationMs = durations.length === 0 ? 0 : totalDuration / durations.length;\n const maxStepDurationMs = durations.length === 0 ? 0 : Math.max(...durations);\n\n const totalTokens = params.auditEvents.reduce((sum, event) => sum + toNumber(event.metadata?.tokens), 0);\n const totalCost = params.auditEvents.reduce((sum, event) => sum + toNumber(event.metadata?.costUsd), 0);\n const totalToolCalls = params.auditEvents.filter((event) => event.type === \"tool_call\").length;\n\n return {\n execution: {\n id: params.executionId,\n workflowName: params.workflowName,\n startedAt: params.startedAt,\n elapsedMs: Math.max(0, now - params.startedAt.getTime()),\n totalTokens,\n totalCost,\n totalToolCalls,\n completedSteps: [...params.completedSteps],\n },\n step: {\n name: params.stepName,\n agent: params.stepAgent,\n index: params.stepIndex,\n config: params.stepConfig,\n },\n actor: {\n id: params.actorId,\n role: params.actorRole,\n },\n state: { ...params.state },\n metrics: {\n errorCount,\n retryCount,\n avgStepDurationMs,\n maxStepDurationMs,\n },\n previousResults: structuredClone(params.previousResults),\n };\n}\n","/**\n * @module base\n * @description 기본 타입 정의 - ID 타입, 공통 인터페이스\n */\n\n/**\n * 고유 식별자 타입들\n * @description 브랜드 타입을 사용하여 타입 안전성을 확보\n */\n\n/** 에이전트 고유 ID 타입 */\nexport type AgentId = string & { readonly __brand: 'AgentId' };\n\n/** 작업 고유 ID 타입 */\nexport type TaskId = string & { readonly __brand: 'TaskId' };\n\n/** 안건 고유 ID 타입 */\nexport type AgendaId = string & { readonly __brand: 'AgendaId' };\n\n/** 세션 고유 ID 타입 */\nexport type SessionId = string & { readonly __brand: 'SessionId' };\n\n/** 사실 고유 ID 타입 */\nexport type FactId = string & { readonly __brand: 'FactId' };\n\n/** 추론 고유 ID 타입 */\nexport type InferenceId = string & { readonly __brand: 'InferenceId' };\n\n/** 패턴 고유 ID 타입 */\nexport type PatternId = string & { readonly __brand: 'PatternId' };\n\n/** 의견 고유 ID 타입 */\nexport type OpinionId = string & { readonly __brand: 'OpinionId' };\n\n/**\n * 타입 가드 및 생성 함수\n */\n\n/**\n * 에이전트 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 AgentId\n * @example\n * ```typescript\n * const agentId = createAgentId('agent-001');\n * // 타입: AgentId\n * ```\n */\nexport function createAgentId(id: string): AgentId {\n return id as AgentId;\n}\n\n/**\n * 작업 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 TaskId\n * @example\n * ```typescript\n * const taskId = createTaskId('task-001');\n * // 타입: TaskId\n * ```\n */\nexport function createTaskId(id: string): TaskId {\n return id as TaskId;\n}\n\n/**\n * 안건 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 AgendaId\n * @example\n * ```typescript\n * const agendaId = createAgendaId('agenda-001');\n * // 타입: AgendaId\n * ```\n */\nexport function createAgendaId(id: string): AgendaId {\n return id as AgendaId;\n}\n\n/**\n * 세션 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 SessionId\n * @example\n * ```typescript\n * const sessionId = createSessionId('session-001');\n * // 타입: SessionId\n * ```\n */\nexport function createSessionId(id: string): SessionId {\n return id as SessionId;\n}\n\n/**\n * 사실 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 FactId\n * @example\n * ```typescript\n * const factId = createFactId('fact-001');\n * // 타입: FactId\n * ```\n */\nexport function createFactId(id: string): FactId {\n return id as FactId;\n}\n\n/**\n * 추론 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 InferenceId\n * @example\n * ```typescript\n * const inferenceId = createInferenceId('inference-001');\n * // 타입: InferenceId\n * ```\n */\nexport function createInferenceId(id: string): InferenceId {\n return id as InferenceId;\n}\n\n/**\n * 패턴 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 PatternId\n * @example\n * ```typescript\n * const patternId = createPatternId('pattern-001');\n * // 타입: PatternId\n * ```\n */\nexport function createPatternId(id: string): PatternId {\n return id as PatternId;\n}\n\n/**\n * 의견 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 OpinionId\n * @example\n * ```typescript\n * const opinionId = createOpinionId('opinion-001');\n * // 타입: OpinionId\n * ```\n */\nexport function createOpinionId(id: string): OpinionId {\n return id as OpinionId;\n}\n\n/**\n * 에이전트 ID 타입 가드\n * @param value - 확인할 값\n * @returns AgentId 여부\n * @example\n * ```typescript\n * const value = 'agent-001';\n * if (isAgentId(value)) {\n * // value는 AgentId로 취급됨\n * }\n * ```\n */\nexport function isAgentId(value: unknown): value is AgentId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 작업 ID 타입 가드\n * @param value - 확인할 값\n * @returns TaskId 여부\n * @example\n * ```typescript\n * const value = 'task-001';\n * if (isTaskId(value)) {\n * // value는 TaskId로 취급됨\n * }\n * ```\n */\nexport function isTaskId(value: unknown): value is TaskId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 안건 ID 타입 가드\n * @param value - 확인할 값\n * @returns AgendaId 여부\n * @example\n * ```typescript\n * const value = 'agenda-001';\n * if (isAgendaId(value)) {\n * // value는 AgendaId로 취급됨\n * }\n * ```\n */\nexport function isAgendaId(value: unknown): value is AgendaId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 세션 ID 타입 가드\n * @param value - 확인할 값\n * @returns SessionId 여부\n * @example\n * ```typescript\n * const value = 'session-001';\n * if (isSessionId(value)) {\n * // value는 SessionId로 취급됨\n * }\n * ```\n */\nexport function isSessionId(value: unknown): value is SessionId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 공통 인터페이스\n */\n\n/**\n * 타임스탬프가 포함된 기본 엔티티\n * @description 생성 및 수정 시간을 추적하는 엔티티\n */\nexport interface Timestamped {\n /** 생성 시간 */\n readonly createdAt: Date;\n /** 마지막 수정 시간 */\n readonly updatedAt: Date;\n}\n\n/**\n * 버전 관리가 포함된 엔티티\n * @description optimistic locking 및 변경 이력 추적용 버전 필드\n */\nexport interface Versioned {\n /** 버전 번호 */\n readonly version: number;\n}\n\n/**\n * 식별 가능한 엔티티\n * @description 고유 ID를 가진 엔티티\n * @typeParam T - ID 타입 (기본값: string)\n */\nexport interface Identifiable<T extends string = string> {\n /** 고유 식별자 */\n readonly id: T;\n}\n","/**\n * @module versioning\n * @description 버전 관리 (optimistic locking)\n */\n\n// Global setTimeout declaration for non-Node environments\ndeclare const setTimeout: (callback: () => void, ms: number) => unknown;\n\n/**\n * 버전 관리 설정\n */\nexport interface VersioningConfig {\n /** 충돌 시 재시도 횟수 */\n maxRetries: number;\n /** 재시도 간격 (ms) */\n retryDelay: number;\n /** 지수 백오프 사용 여부 */\n exponentialBackoff: boolean;\n}\n\n/**\n * 기본 버전 관리 설정\n */\nexport const DEFAULT_VERSIONING_CONFIG: VersioningConfig = {\n maxRetries: 3,\n retryDelay: 100,\n exponentialBackoff: true,\n};\n\n/**\n * 버전 충돌 에러\n */\nexport class VersionConflictError extends Error {\n constructor(\n public readonly expectedVersion: number,\n public readonly actualVersion: number,\n public readonly path: string\n ) {\n super(`Version conflict at ${path}: expected ${expectedVersion}, got ${actualVersion}`);\n this.name = \"VersionConflictError\";\n }\n}\n\n/**\n * Optimistic Locking 관리자\n * @description 동시 쓰기 충돌을 감지하고 처리\n */\nexport class VersionManager {\n constructor(private config: VersioningConfig = DEFAULT_VERSIONING_CONFIG) {}\n\n /**\n * 버전 검증\n * @param currentVersion - 현재 버전\n * @param expectedVersion - 예상 버전\n * @param path - 경로 (에러 메시지용)\n * @throws {VersionConflictError} 버전 불일치 시\n */\n validateVersion(currentVersion: number, expectedVersion: number, path: string): void {\n if (currentVersion !== expectedVersion) {\n throw new VersionConflictError(expectedVersion, currentVersion, path);\n }\n }\n\n /**\n * 버전 증가\n * @param currentVersion - 현재 버전\n * @returns 새 버전\n */\n incrementVersion(currentVersion: number): number {\n if (currentVersion < 0) {\n throw new Error(`Invalid version: ${currentVersion}`);\n }\n return currentVersion + 1;\n }\n\n /**\n * 재시도 가능한 쓰기 실행\n * @param operation - 실행할 쓰기 연산\n * @param context - 컨텍스트 정보 (로그용)\n * @returns 최종 결과\n */\n async executeWithRetry<T>(\n operation: () => T | Promise<T>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _context?: string\n ): Promise<T> {\n let lastError: Error | null = null;\n\n // 최대 maxRetries번 시도 (첫 시도 + 재시도 maxRetries-1번)\n for (let attempt = 0; attempt < this.config.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // VersionConflictError가 아니면 바로 throw\n if (!(lastError instanceof VersionConflictError)) {\n throw lastError;\n }\n\n // 마지막 시도면 throw\n if (attempt === this.config.maxRetries - 1) {\n throw lastError;\n }\n\n // 재시도 지연\n const delay = this.calculateDelay(attempt);\n await this.sleep(delay);\n }\n }\n\n throw lastError;\n }\n\n /**\n * 재시도 지연 계산\n * @param attempt - 현재 시도 횟수 (0부터)\n * @returns 지연 시간 (ms)\n */\n calculateDelay(attempt: number): number {\n if (this.config.exponentialBackoff) {\n // 지수 백오프: delay * 2^attempt + random jitter\n const baseDelay = this.config.retryDelay * Math.pow(2, attempt);\n const jitter = Math.random() * this.config.retryDelay * 0.5;\n return Math.floor(baseDelay + jitter);\n }\n return this.config.retryDelay;\n }\n\n /**\n * 지연 (내부 유틸리티)\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * 설정 업데이트\n * @param partialConfig - 업데이트할 설정 (부분)\n */\n updateConfig(partialConfig: Partial<VersioningConfig>): void {\n this.config = { ...this.config, ...partialConfig };\n }\n\n /**\n * 현재 설정 조회\n */\n getConfig(): Readonly<VersioningConfig> {\n return { ...this.config };\n }\n}\n\n/**\n * 기본 버전 관리자 인스턴스\n */\nexport const defaultVersionManager = new VersionManager();\n","/**\n * @module immutable\n * @description 딥 클론 및 불변성 유틸리티\n */\n\n/**\n * 깊은 복사\n * @param obj - 복사할 객체\n * @param cloneMap - 순환 참조 추적용 WeakMap (낮은용)\n * @returns 깊은 복사본\n */\nexport function deepClone<T>(obj: T, cloneMap = new WeakMap<object, object>()): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n // 순환 참조 감지 - 이미 복사한 객체가 있으면 해당 복사본 반환\n if (cloneMap.has(obj as object)) {\n return cloneMap.get(obj as object) as T;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n if (obj instanceof Map) {\n const clonedMap = new Map();\n cloneMap.set(obj as object, clonedMap);\n for (const [key, value] of obj.entries()) {\n clonedMap.set(deepClone(key, cloneMap), deepClone(value, cloneMap));\n }\n return clonedMap as T;\n }\n\n if (obj instanceof Set) {\n const clonedSet = new Set();\n cloneMap.set(obj as object, clonedSet);\n for (const value of obj) {\n clonedSet.add(deepClone(value, cloneMap));\n }\n return clonedSet as T;\n }\n\n if (obj instanceof Array) {\n const clonedArray: unknown[] = [];\n cloneMap.set(obj as object, clonedArray);\n for (let i = 0; i < obj.length; i++) {\n clonedArray[i] = deepClone(obj[i], cloneMap);\n }\n return clonedArray as T;\n }\n\n // 일반 객체\n const clonedObj = {} as T;\n cloneMap.set(obj as object, clonedObj as object);\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n (clonedObj as Record<string, unknown>)[key] = deepClone(\n (obj as Record<string, unknown>)[key],\n cloneMap\n );\n }\n }\n return clonedObj;\n}\n\n/**\n * 깊은 동결 (불변 객체 생성)\n * @param obj - 동결할 객체\n * @returns 동결된 객체\n */\nexport function deepFreeze<T>(obj: T): Readonly<T> {\n if (obj === null || typeof obj !== \"object\") {\n return obj as Readonly<T>;\n }\n\n Object.freeze(obj);\n\n const propNames = Object.getOwnPropertyNames(obj);\n\n for (const name of propNames) {\n const value = (obj as Record<string, unknown>)[name];\n if (value !== null && typeof value === \"object\") {\n deepFreeze(value);\n }\n }\n\n return obj as Readonly<T>;\n}\n\n/**\n * 불변 업데이트\n * @description 중첩된 객체를 불변성을 유지하며 업데이트\n * @param obj - 원본 객체\n * @param path - 업데이트할 경로\n * @param updater - 업데이트 함수\n * @returns 새 객체\n */\nexport function immutableUpdate<T>(obj: T, path: string, updater: (value: unknown) => unknown): T {\n const segments = path.split(\".\");\n const newObj = deepClone(obj);\n\n let current: Record<string, unknown> = newObj as Record<string, unknown>;\n const pathStack: string[] = [];\n\n // 해당 경로까지 이동\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n pathStack.push(segment);\n\n if (!(segment in current)) {\n (current[segment] as Record<string, unknown>) = {};\n } else {\n // 불변성 유지를 위해 복사\n current[segment] = deepClone(current[segment]);\n }\n current = current[segment] as Record<string, unknown>;\n }\n\n // 마지막 경로에 업데이트\n const lastSegment = segments[segments.length - 1];\n current[lastSegment] = updater(current[lastSegment]);\n\n return newObj;\n}\n\n/**\n * Map을 일반 객체로 변환\n * @param map - 변환할 Map\n * @returns 일반 객체\n */\nexport function mapToObject<K extends string, V>(map: Map<K, V>): Record<K, V> {\n const obj = {} as Record<K, V>;\n for (const [key, value] of map.entries()) {\n obj[key] = value;\n }\n return obj;\n}\n\n/**\n * 일반 객체를 Map으로 변환\n * @param obj - 변환할 객체\n * @returns Map\n */\nexport function objectToMap<K extends string, V>(obj: Record<K, V>): Map<K, V> {\n return new Map(Object.entries(obj) as [K, V][]);\n}\n\n/**\n * 객체 병합 (불변)\n * @param target - 대상 객체\n * @param sources - 병합할 소스들\n * @returns 병합된 새 객체\n */\nexport function merge<T extends Record<string, unknown>>(target: T, ...sources: Partial<T>[]): T {\n const result = deepClone(target);\n\n for (const source of sources) {\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const value = source[key];\n if (value !== null && typeof value === \"object\") {\n const existingValue = (result as Record<string, unknown>)[key];\n if (existingValue !== null && typeof existingValue === \"object\") {\n (result as Record<string, unknown>)[key] = merge(\n existingValue as Record<string, unknown>,\n value as Record<string, unknown>\n );\n } else {\n (result as Record<string, unknown>)[key] = deepClone(value);\n }\n } else {\n (result as Record<string, unknown>)[key] = value;\n }\n }\n }\n }\n\n return result;\n}\n","/**\n * @module path-utils\n * @description 경로 유틸리티\n */\n\nimport { deepClone } from \"./immutable\";\n\n/**\n * 경로 파싱 결과\n */\nexport interface ParsedPath {\n /** 섹션 (meta, state, knowledge, decisions) */\n section: \"meta\" | \"state\" | \"knowledge\" | \"decisions\";\n /** 나머지 경로 세그먼트 */\n segments: string[];\n /** 전체 경로 */\n full: string;\n}\n\n/**\n * 유효한 섹션 이름들\n */\nconst VALID_SECTIONS = [\"meta\", \"state\", \"knowledge\", \"decisions\"] as const;\n\n/**\n * 프로토타입 오염 방지: 위험한 키 목록\n */\nconst DANGEROUS_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/**\n * 섹션인지 확인\n */\nfunction isValidSection(section: string): section is (typeof VALID_SECTIONS)[number] {\n return VALID_SECTIONS.includes(section as (typeof VALID_SECTIONS)[number]);\n}\n\n/**\n * 프로토타입 오염 방지: 경로 세그먼트 검증\n * @param segments - 검증할 경로 세그먼트 배열\n * @throws {Error} 위험한 키가 포함된 경우\n */\nfunction validatePathSegments(segments: string[]): void {\n for (const segment of segments) {\n if (DANGEROUS_KEYS.has(segment)) {\n throw new Error(`Invalid path segment: ${segment} is not allowed`);\n }\n }\n}\n\n/**\n * 경로 기반 값 접근\n * @param obj - 대상 객체\n * @param path - 점(.)으로 구분된 경로\n * @returns 해당 경로의 값\n */\nexport function getByPath<T = unknown>(obj: unknown, path: string): T | undefined {\n if (typeof obj !== \"object\" || obj === null) {\n return undefined;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n validatePathSegments(segments);\n\n if (segments.length === 0) {\n return obj as T;\n }\n\n let current: unknown = obj;\n\n for (const segment of segments) {\n if (typeof current !== \"object\" || current === null) {\n return undefined;\n }\n\n // Map 처리\n if (current instanceof Map) {\n current = current.get(segment);\n continue;\n }\n\n // 배열 처리 (숫자 인덱스)\n if (Array.isArray(current)) {\n const index = parseInt(segment, 10);\n if (!isNaN(index) && index >= 0 && index < current.length) {\n current = current[index];\n continue;\n }\n return undefined;\n }\n\n // 일반 객체\n if (!(segment in current)) {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current as T;\n}\n\n/**\n * 경로 기반 값 설정 (불변)\n * @param obj - 대상 객체\n * @param path - 점(.)으로 구분된 경로\n * @param value - 설정할 값\n * @returns 수정된 객체 (불변성 유지)\n */\nexport function setByPath<T>(obj: T, path: string, value: unknown): T {\n if (typeof obj !== \"object\" || obj === null) {\n return obj;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n validatePathSegments(segments);\n\n if (segments.length === 0) {\n return value as T;\n }\n\n const newObj = deepClone(obj) as Record<string, unknown>;\n\n let current: Record<string, unknown> = newObj;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n\n if (!(segment in current)) {\n current[segment] = {};\n } else {\n current[segment] = deepClone(current[segment]);\n }\n\n if (typeof current[segment] !== \"object\" || current[segment] === null) {\n current[segment] = {};\n }\n\n current = current[segment] as Record<string, unknown>;\n }\n\n const lastSegment = segments[segments.length - 1];\n current[lastSegment] = deepClone(value);\n\n return newObj as T;\n}\n\n/**\n * 경로 기반 값 삭제\n * @param obj - 대상 객체\n * @param path - 점(.)으로 구분된 경로\n * @returns 수정된 객체 (불변성 유지)\n */\nexport function deleteByPath<T>(obj: T, path: string): T {\n if (typeof obj !== \"object\" || obj === null) {\n return obj;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n validatePathSegments(segments);\n\n if (segments.length === 0) {\n return obj;\n }\n\n const newObj = deepClone(obj) as Record<string, unknown>;\n\n // 단일 세그먼트인 경우 바로 삭제\n if (segments.length === 1) {\n delete newObj[segments[0]];\n return newObj as T;\n }\n\n let current: Record<string, unknown> = newObj;\n\n // 마지막 전까지 이동\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n\n if (!(segment in current)) {\n return obj; // 경로가 존재하지 않으면 원본 반환\n }\n\n current[segment] = deepClone(current[segment]);\n\n if (typeof current[segment] !== \"object\" || current[segment] === null) {\n return obj;\n }\n\n current = current[segment] as Record<string, unknown>;\n }\n\n const lastSegment = segments[segments.length - 1];\n delete current[lastSegment];\n\n return newObj as T;\n}\n\n/**\n * 경로 파싱\n * @param path - 전체 경로\n * @returns 파싱된 경로 정보\n */\nexport function parsePath(path: string): ParsedPath {\n const normalized = normalizePath(path);\n const segments = normalized.split(\".\").filter(Boolean);\n\n if (segments.length === 0) {\n throw new Error(`Invalid path: ${path}`);\n }\n\n validatePathSegments(segments);\n\n const section = segments[0];\n\n if (!isValidSection(section)) {\n throw new Error(`Invalid section: ${section}. Valid sections: ${VALID_SECTIONS.join(\", \")}`);\n }\n\n return {\n section,\n segments: segments.slice(1),\n full: normalized,\n };\n}\n\n/**\n * 경로 검증\n * @param path - 검증할 경로\n * @returns 유효 여부\n */\nexport function isValidPath(path: string): boolean {\n try {\n const parsed = parsePath(path);\n return parsed.section !== undefined;\n } catch {\n return false;\n }\n}\n\n/**\n * 경로 정규화\n * @param path - 정규화할 경로\n * @returns 정규화된 경로\n */\nexport function normalizePath(path: string): string {\n return path\n .trim()\n .replace(/\\s+/g, \"\")\n .replace(/\\.+/g, \".\")\n .replace(/^\\.+|\\.+$/g, \"\");\n}\n\n/**\n * 경로 결합\n * @param parts - 결합할 경로들\n * @returns 결합된 경로\n */\nexport function joinPath(...parts: string[]): string {\n return parts\n .map((p) => normalizePath(p))\n .filter(Boolean)\n .join(\".\");\n}\n\n/**\n * 경로가 다른 경로의 하위 경로인지 확인\n * @param parent - 부모 경로\n * @param child - 자식 경로\n * @returns 하위 경로 여부\n */\nexport function isSubPath(parent: string, child: string): boolean {\n const normalizedParent = normalizePath(parent);\n const normalizedChild = normalizePath(child);\n\n if (normalizedParent === normalizedChild) {\n return false;\n }\n\n return normalizedChild.startsWith(normalizedParent + \".\");\n}\n\n/**\n * 경로의 상위 경로 반환\n * @param path - 경로\n * @param levels - 올라갈 레벨 수 (기본: 1)\n * @returns 상위 경로\n */\nexport function getParentPath(path: string, levels: number = 1): string {\n const normalized = normalizePath(path);\n const segments = normalized.split(\".\").filter(Boolean);\n\n if (segments.length <= levels) {\n return \"\";\n }\n\n return segments.slice(0, segments.length - levels).join(\".\");\n}\n","/**\n * @module agent\n * @description 에이전트 관련 타입 정의\n */\n\nimport type { Timestamped } from \"./base\";\nimport type { AgentId, TaskId } from \"./base\";\n\n/**\n * 에이전트 상태 enum\n * @description 에이전트의 현재 활동 상태를 나타냄\n */\nexport enum AgentStatusEnum {\n /** 유휴 상태 - 작업 대기 중 */\n IDLE = \"idle\",\n /** 작업 중 - 활성 상태 */\n BUSY = \"busy\",\n /** 오류 상태 - 복구 필요 */\n ERROR = \"error\",\n /** 중지됨 */\n STOPPED = \"stopped\",\n}\n\n/**\n * 에이전트 역할 타입\n * @description 에이전트가 수행할 수 있는 역할\n */\nexport type AgentRole = \"analyst\" | \"executor\" | \"verifier\" | \"director\";\n\n/**\n * 에이전트 상태 정보\n * @description 에이전트의 현재 상태와 작업 정보를 담는 인터페이스\n *\n * @example\n * ```typescript\n * const agentStatus: AgentStatus = {\n * id: createAgentId('agent-001'),\n * role: 'analyst',\n * status: AgentStatusEnum.BUSY,\n * currentTask: createTaskId('task-001'),\n * lastHeartbeat: new Date(),\n * createdAt: new Date(),\n * updatedAt: new Date(),\n * metadata: { model: 'gpt-4' }\n * };\n * ```\n */\nexport interface AgentStatus extends Timestamped {\n /** 에이전트 고유 ID */\n readonly id: AgentId;\n /** 에이전트 역할 */\n readonly role: AgentRole;\n /** 현재 상태 */\n status: AgentStatusEnum;\n /** 현재 수행 중인 작업 (없으면 null) */\n currentTask: TaskId | null;\n /** 마지막 하트비트 시간 */\n lastHeartbeat: Date;\n /** 추가 메타데이터 */\n metadata: Record<string, unknown>;\n}\n\n/**\n * 에이전트 상태 업데이트 옵션\n * @description 부분 업데이트를 위한 선택적 필드 인터페이스\n */\nexport interface AgentStatusUpdate {\n /** 새로운 상태 */\n status?: AgentStatusEnum;\n /** 새로운 현재 작업 */\n currentTask?: TaskId | null;\n /** 마지막 하트비트 시간 */\n lastHeartbeat?: Date;\n /** 업데이트할 메타데이터 */\n metadata?: Partial<Record<string, unknown>>;\n}\n\n/**\n * 에이전트 통계\n * @description 에이전트의 성능 및 활동 통계\n */\nexport interface AgentStats {\n /** 에이전트 ID */\n agentId: AgentId;\n /** 완료한 작업 수 */\n tasksCompleted: number;\n /** 실패한 작업 수 */\n tasksFailed: number;\n /** 총 작업 시간 (밀리초) */\n totalTaskTime: number;\n /** 평균 작업 시간 (밀리초) */\n averageTaskTime: number;\n /** 마지막 활동 시간 */\n lastActiveTime: Date;\n}\n","/**\n * @module task\n * @description 작업(Task) 관련 타입 정의\n */\n\nimport type { Identifiable, Timestamped, Versioned } from './base';\nimport type { AgentId, TaskId } from './base';\n\n/**\n * 작업 상태 enum\n * @description 작업의 진행 상태를 나타냄\n */\nexport enum TaskStatus {\n /** 대기 중 */\n PENDING = 'pending',\n /** 실행 중 */\n RUNNING = 'running',\n /** 완료됨 */\n COMPLETED = 'completed',\n /** 실패함 */\n FAILED = 'failed',\n /** 취소됨 */\n CANCELLED = 'cancelled',\n}\n\n/**\n * 작업 우선순위\n * @description 작업의 중요도를 나타내는 순위\n */\nexport enum TaskPriority {\n LOW = 0,\n NORMAL = 1,\n HIGH = 2,\n CRITICAL = 3,\n}\n\n/**\n * 작업 정의\n * @description 시스템에서 실행할 작업의 정의\n *\n * @example\n * ```typescript\n * const task: Task = {\n * id: createTaskId('task-001'),\n * name: '데이터 분석',\n * description: '사용자 행동 데이터 분석',\n * assignedTo: createAgentId('agent-001'),\n * status: TaskStatus.PENDING,\n * priority: TaskPriority.HIGH,\n * inputs: { dataset: 'users-2026-01' },\n * outputs: null,\n * dependsOn: [],\n * error: null,\n * startedAt: null,\n * completedAt: null,\n * timeout: 3600000,\n * version: 1,\n * createdAt: new Date(),\n * updatedAt: new Date(),\n * };\n * ```\n */\nexport interface Task extends Identifiable<TaskId>, Timestamped, Versioned {\n /** 작업 이름 */\n name: string;\n /** 작업 설명 */\n description: string;\n /** 할당된 에이전트 */\n assignedTo: AgentId | null;\n /** 현재 상태 */\n status: TaskStatus;\n /** 우선순위 */\n priority: TaskPriority;\n /** 입력 데이터 */\n inputs: Record<string, unknown>;\n /** 출력 데이터 (완료 시) */\n outputs: Record<string, unknown> | null;\n /** 의존하는 작업 ID 목록 */\n dependsOn: TaskId[];\n /** 에러 정보 (실패 시) */\n error: TaskError | null;\n /** 시작 시간 */\n startedAt: Date | null;\n /** 완료 시간 */\n completedAt: Date | null;\n /** 제한 시간 (밀리초) */\n timeout: number | null;\n}\n\n/**\n * 작업 에러 정보\n * @description 작업 실행 중 발생한 에러의 상세 정보\n */\nexport interface TaskError {\n /** 에러 코드 */\n code: string;\n /** 에러 메시지 */\n message: string;\n /** 스택 트레이스 */\n stack?: string;\n /** 재시도 가능 여부 */\n retryable: boolean;\n}\n\n/**\n * 작업 생성 옵션\n * @description 새 작업 생성 시 필요한 필드\n */\nexport interface TaskCreateInput {\n /** 작업 이름 */\n name: string;\n /** 작업 설명 */\n description: string;\n /** 할당할 에이전트 (선택) */\n assignedTo?: AgentId | null;\n /** 우선순위 (기본: NORMAL) */\n priority?: TaskPriority;\n /** 입력 데이터 */\n inputs?: Record<string, unknown>;\n /** 의존하는 작업 ID 목록 */\n dependsOn?: TaskId[];\n /** 제한 시간 (밀리초) */\n timeout?: number | null;\n}\n\n/**\n * 작업 업데이트 옵션\n * @description 작업 상태 업데이트를 위한 선택적 필드\n */\nexport interface TaskUpdateInput {\n /** 새로운 상태 */\n status?: TaskStatus;\n /** 할당된 에이전트 */\n assignedTo?: AgentId | null;\n /** 우선순위 */\n priority?: TaskPriority;\n /** 출력 데이터 */\n outputs?: Record<string, unknown> | null;\n /** 에러 정보 */\n error?: TaskError | null;\n /** 시작 시간 */\n startedAt?: Date | null;\n /** 완료 시간 */\n completedAt?: Date | null;\n}\n\n/**\n * 작업 진행 상황\n * @description 작업 실행 중의 진행 상황 보고\n */\nexport interface TaskProgress {\n /** 작업 ID */\n taskId: TaskId;\n /** 진행률 (0.0 - 1.0) */\n progress: number;\n /** 현재 단계 설명 */\n currentStep: string;\n /** 남은 예상 시간 (밀리초) */\n estimatedTimeRemaining?: number;\n /** 추가 메시지 */\n message?: string;\n}\n","/**\n * @module decision\n * @description 의사결정 관련 타입 정의 - Agenda, Opinion, Resolution\n */\n\nimport type { Identifiable, Timestamped, Versioned } from \"./base\";\nimport type { AgentId, AgendaId, OpinionId } from \"./base\";\n\n/**\n * 투표 방식\n * @description 안건 결정을 위한 투표 방식\n */\nexport type VotingMethod = \"majority\" | \"unanimous\" | \"weighted\" | \"supermajority\";\n\n/**\n * 안건 상태\n * @description 안건의 현재 진행 상태\n */\nexport enum AgendaStatus {\n /** 초안 - 아직 제출되지 않음 */\n DRAFT = \"draft\",\n /** 제출됨 - 논의 대기 */\n SUBMITTED = \"submitted\",\n /** 논의 중 */\n DISCUSSING = \"discussing\",\n /** 토론 중 */\n DEBATING = \"debating\",\n /** 투표 중 */\n VOTING = \"voting\",\n /** 결정됨 */\n RESOLVED = \"resolved\",\n /** 연기됨 */\n DEFERRED = \"deferred\",\n /** 취소됨 */\n CANCELLED = \"cancelled\",\n}\n\n/**\n * 입장 (스탠스)\n * @description 의견 제출자의 입장\n */\nexport type Stance = \"approve\" | \"reject\" | \"conditional\" | \"abstain\";\n\n/**\n * 최종 결정 유형\n * @description 안건에 대한 최종 결정의 유형\n */\nexport type DecisionType = \"approved\" | \"rejected\" | \"deferred\" | \"amended\";\n\n/**\n * 첨부 자료\n * @description 안건에 첨부된 문서, 데이터 등\n */\nexport interface Attachment {\n /** 파일명 */\n name: string;\n /** MIME 타입 */\n mimeType: string;\n /** URL 또는 데이터 참조 */\n url: string;\n /** 크기 (바이트) */\n size: number;\n}\n\n/**\n * 안건 (의제)\n * @description AI 이사회에서 논의할 주제\n *\n * @example\n * ```typescript\n * const agenda: Agenda = {\n * id: createAgendaId('agenda-001'),\n * title: '신규 서비스 출시 검토',\n * description: 'Q2에 출시 예정인 신규 서비스의 적합성 검토',\n * proposer: createAgentId('ceo-agent'),\n * status: AgendaStatus.SUBMITTED,\n * deadline: new Date('2026-02-10'),\n * requiredQuorum: 3,\n * votingMethod: 'majority',\n * priority: 1,\n * tags: ['business', 'strategy'],\n * attachments: [],\n * createdAt: new Date(),\n * updatedAt: new Date(),\n * version: 1,\n * };\n * ```\n */\nexport interface Agenda extends Identifiable<AgendaId>, Timestamped, Versioned {\n /** 안건 제목 */\n title: string;\n /** 안건 상세 설명 */\n description: string;\n /** 제안자 에이전트 ID */\n proposer: AgentId;\n /** 현재 상태 */\n status: AgendaStatus;\n /** 마감 기한 (선택) */\n deadline: Date | null;\n /** 필요 정족수 */\n requiredQuorum: number;\n /** 투표 방식 */\n votingMethod: VotingMethod;\n /** 우선순위 (0-10, 높을수록 중요) */\n priority: number;\n /** 태그 */\n tags: string[];\n /** 첨부 자료 */\n attachments: Attachment[];\n}\n\n/**\n * 의견\n * @description 에이전트가 안건에 대해 제출하는 의견\n *\n * @example\n * ```typescript\n * const opinion: Opinion = {\n * id: createOpinionId('opinion-001'),\n * agentId: createAgentId('agent-001'),\n * agendaId: createAgendaId('agenda-001'),\n * stance: 'approve',\n * reason: '시장 조사 결과가 긍정적임',\n * conditions: ['마케팅 예산 확보 필요'],\n * confidence: 0.85,\n * references: ['fact-001', 'inference-002'],\n * createdAt: new Date(),\n * updatedAt: new Date(),\n * };\n * ```\n */\nexport interface Opinion extends Identifiable<OpinionId>, Timestamped {\n /** 의견 제출자 */\n agentId: AgentId;\n /** 관련 안건 ID */\n agendaId: AgendaId;\n /** 입장 */\n stance: Stance;\n /** 의견 내용 (근거) */\n reason: string;\n /** 조건 (conditional일 경우) */\n conditions: string[];\n /** 확신도 (0.0 - 1.0) */\n confidence: number;\n /** 참조한 사실/추론 ID 목록 */\n references: string[];\n}\n\n/**\n * 투표 요약\n * @description 투표 결과의 요약 통계\n */\nexport interface VoteSummary {\n /** 찬성 수 */\n approve: number;\n /** 반대 수 */\n reject: number;\n /** 기권 수 */\n abstain: number;\n /** 조건부 찬성 수 */\n conditional: number;\n /** 총 투표 수 */\n total: number;\n}\n\n/**\n * 다음 단계 행동\n * @description 결정 후 이행할 행동 항목\n */\nexport interface NextAction {\n /** 행동 설명 */\n description: string;\n /** 담당자 */\n assignee: AgentId | null;\n /** 기한 */\n dueDate: Date | null;\n}\n\n/**\n * 결정 (해결)\n * @description 안건에 대한 최종 결정 기록\n *\n * @example\n * ```typescript\n * const resolution: Resolution = {\n * id: 'res-001',\n * agendaId: createAgendaId('agenda-001'),\n * decision: 'approved',\n * summary: '신규 서비스 출시 승인',\n * voteSummary: {\n * approve: 3,\n * reject: 1,\n * abstain: 0,\n * conditional: 0,\n * total: 4,\n * },\n * conditions: ['Q2 내 출시'],\n * dissent: ['보안 검토 필요'],\n * decidedBy: createAgentId('director-agent'),\n * nextActions: [\n * {\n * description: '출시 계획 수립',\n * assignee: createAgentId('pm-agent'),\n * dueDate: new Date('2026-02-15'),\n * },\n * ],\n * createdAt: new Date(),\n * updatedAt: new Date(),\n * };\n * ```\n */\nexport interface Resolution extends Identifiable, Timestamped {\n /** 관련 안건 ID */\n agendaId: AgendaId;\n /** 결정 유형 */\n decision: DecisionType;\n /** 결정 요약 */\n summary: string;\n /** 투표 결과 요약 */\n voteSummary: VoteSummary;\n /** 이행 조건 (있는 경우) */\n conditions: string[];\n /** 반대 의견 요약 (있는 경우) */\n dissent: string[];\n /** 결정 주체 (director) */\n decidedBy: AgentId;\n /** 다음 단계 행동 */\n nextActions: NextAction[];\n}\n\n/**\n * 안건 생성 옵션\n * @description 새 안건 생성 시 필요한 필드\n */\nexport interface AgendaCreateInput {\n /** 안건 제목 */\n title: string;\n /** 안건 상세 설명 */\n description: string;\n /** 제안자 에이전트 ID */\n proposer: AgentId;\n /** 마감 기한 (선택) */\n deadline?: Date | null;\n /** 필요 정족수 (기본: 3) */\n requiredQuorum?: number;\n /** 투표 방식 (기본: majority) */\n votingMethod?: VotingMethod;\n /** 우선순위 (기본: 1) */\n priority?: number;\n /** 태그 */\n tags?: string[];\n /** 첨부 자료 */\n attachments?: Attachment[];\n}\n\n/**\n * 의견 생성 옵션\n * @description 새 의견 제출 시 필요한 필드\n */\nexport interface OpinionCreateInput {\n /** 관련 안건 ID */\n agendaId: AgendaId;\n /** 입장 */\n stance: Stance;\n /** 의견 내용 (근거) */\n reason: string;\n /** 조건 (conditional일 경우) */\n conditions?: string[];\n /** 확신도 (기본: 1.0) */\n confidence?: number;\n /** 참조한 사실/추론 ID 목록 */\n references?: string[];\n}\n","/**\n * @module message\n * @description 메시지 관련 타입 정의\n */\n\nimport type { Identifiable, Timestamped } from './base';\nimport type { AgentId, TaskId } from './base';\n\n/**\n * 메시지 타입 enum\n * @description 시스템 내 모든 메시지 유형\n */\nexport enum MessageType {\n // === 상태 관련 ===\n /** 상태 읽기 요청 */\n STATE_READ = 'state.read',\n /** 상태 쓰기 요청 */\n STATE_WRITE = 'state.write',\n /** 상태 구독 */\n STATE_SUBSCRIBE = 'state.subscribe',\n /** 상태 변경 알림 */\n STATE_UPDATED = 'state.updated',\n\n // === 의사결정 관련 ===\n /** 안건 제출 요청 */\n DECISION_REQUEST = 'decision.request',\n /** 의견 제출 */\n OPINION_SUBMIT = 'opinion.submit',\n /** 투표 제출 */\n VOTE_SUBMIT = 'vote.submit',\n /** 합의 도달 알림 */\n CONSENSUS_REACHED = 'consensus.reached',\n\n // === 작업 관련 ===\n /** 작업 할당 */\n TASK_ASSIGN = 'task.assign',\n /** 작업 완료 */\n TASK_COMPLETE = 'task.complete',\n /** 작업 실패 */\n TASK_FAILED = 'task.failed',\n /** 작업 진행 상황 */\n TASK_PROGRESS = 'task.progress',\n\n // === 지식 관련 ===\n /** 사실 추가 */\n KNOWLEDGE_FACT_ADD = 'knowledge.fact.add',\n /** 추론 추가 */\n KNOWLEDGE_INFERENCE_ADD = 'knowledge.inference.add',\n\n // === 시스템 관련 ===\n /** 하트비트 */\n HEARTBEAT = 'heartbeat',\n /** 에러 */\n ERROR = 'error',\n /** 시스템 알림 */\n SYSTEM_NOTIFICATION = 'system.notification',\n}\n\n/**\n * 메시지 기본 인터페이스\n * @description 시스템 내에서 주고받는 모든 메시지의 기본 구조\n * @typeParam T - 페이로드 타입\n *\n * @example\n * ```typescript\n * const message: Message<string> = {\n * id: 'msg-001',\n * type: MessageType.HEARTBEAT,\n * from: createAgentId('agent-001'),\n * to: 'broadcast',\n * payload: 'ping',\n * priority: 1,\n * ttl: null,\n * createdAt: new Date(),\n * updatedAt: new Date(),\n * };\n * ```\n */\nexport interface Message<T = unknown> extends Identifiable, Timestamped {\n /** 메시지 타입 */\n type: MessageType;\n /** 발신자 ID */\n from: AgentId;\n /** 수신자 ID ('broadcast'면 전체) */\n to: AgentId | 'broadcast';\n /** 메시지 내용 */\n payload: T;\n /** 상관 ID (요청-응답 연결용) */\n correlationId?: string;\n /** 우선순위 */\n priority: number;\n /** TTL (밀리초, null이면 무제한) */\n ttl: number | null;\n}\n\n/**\n * 상태 읽기 요청 페이로드\n * @description Blackboard의 특정 섹션을 읽기 위한 요청\n */\nexport interface StateReadPayload {\n /** 읽을 섹션 */\n section: 'state' | 'knowledge' | 'decisions';\n /** 경로 */\n path: string;\n /** 쿼리 파라미터 */\n query?: Record<string, unknown>;\n}\n\n/**\n * 상태 쓰기 요청 페이로드\n * @description Blackboard의 특정 섹션에 쓰기 위한 요청\n */\nexport interface StateWritePayload {\n /** 쓸 섹션 */\n section: 'state' | 'knowledge' | 'decisions';\n /** 경로 */\n path: string;\n /** 데이터 */\n data: unknown;\n /** 기대 버전 (optimistic locking용) */\n expectedVersion?: number;\n}\n\n/**\n * 에러 페이로드\n * @description 에러 발생 시 전달하는 정보\n */\nexport interface ErrorPayload {\n /** 에러 코드 */\n code: string;\n /** 에러 메시지 */\n message: string;\n /** 상세 정보 */\n details?: Record<string, unknown>;\n /** 재시도 가능 여부 */\n retryable: boolean;\n}\n\n/**\n * 하트비트 페이로드\n * @description 에이전트 하트비트 정보\n */\nexport interface HeartbeatPayload {\n /** 에이전트 ID */\n agentId: AgentId;\n /** 현재 작업 ID (없으면 null) */\n currentTask?: TaskId | null;\n /** 타임스탬프 */\n timestamp: Date;\n /** 추가 상태 정보 */\n status?: Record<string, unknown>;\n}\n\n/**\n * 메시지 전송 옵션\n * @description 메시지 전송 시 설정 가능한 옵션\n */\nexport interface MessageSendOptions {\n /** 수신자 ID */\n to: AgentId | 'broadcast';\n /** 메시지 타입 */\n type: MessageType;\n /** 우선순위 (기본: 1) */\n priority?: number;\n /** TTL (밀리초) */\n ttl?: number | null;\n /** 상관 ID */\n correlationId?: string;\n}\n\n/**\n * 메시지 핸들러 타입\n * @description 메시지를 처리하는 핸들러 함수의 타입\n */\nexport type MessageHandler<T = unknown> = (message: Message<T>) => void | Promise<void>;\n\n/**\n * 메시지 필터 타입\n * @description 메시지를 필터링하는 조건 함수의 타입\n */\nexport type MessageFilter<T = unknown> = (message: Message<T>) => boolean;\n","/**\n * @module types/tkg\n * @description Temporal Knowledge Graph(TKG) 타입/계약 (spec/12 정렬)\n */\n\nimport type { AgentId } from './base';\n\n/** TKG 노드 ID */\nexport type NodeId = string & { readonly __brand: 'NodeId' };\n\n/** TKG 엣지 ID */\nexport type EdgeId = string & { readonly __brand: 'EdgeId' };\n\n/** 노드 ID 생성기 */\nexport function createNodeId(id: string): NodeId {\n if (id.trim().length === 0) {\n throw new Error('NodeId must be a non-empty string');\n }\n return id as NodeId;\n}\n\n/** 엣지 ID 생성기 */\nexport function createEdgeId(id: string): EdgeId {\n if (id.trim().length === 0) {\n throw new Error('EdgeId must be a non-empty string');\n }\n return id as EdgeId;\n}\n\n/** 노드 종류 */\nexport type TemporalNodeType = 'entity' | 'fact' | 'decision' | 'task' | 'pattern';\n\n/** 엣지 종류 */\nexport type EdgeType =\n | 'relates_to' | 'part_of' | 'contains'\n | 'supports' | 'contradicts' | 'explains' | 'based_on'\n | 'decided_by' | 'decided_on' | 'leads_to'\n | 'assigned_to' | 'depends_on' | 'blocks' | 'precedes'\n | 'exemplifies' | 'generalizes' | 'specializes';\n\nexport interface EntityData {\n readonly name: string;\n readonly entityType: 'agent' | 'task' | 'resource' | 'concept';\n readonly attributes: Readonly<Record<string, unknown>>;\n}\n\nexport interface FactData {\n readonly statement: string;\n readonly context?: string;\n readonly evidence?: readonly NodeId[];\n readonly verified: boolean;\n}\n\nexport interface DecisionData {\n readonly agendaId: string;\n readonly outcome: 'approve' | 'reject' | 'deferred';\n readonly reason: string;\n readonly participants: readonly AgentId[];\n}\n\nexport interface TaskData {\n readonly description: string;\n readonly status: 'pending' | 'running' | 'completed' | 'failed';\n readonly assignedTo?: AgentId;\n readonly result?: unknown;\n}\n\nexport interface PatternData {\n readonly description: string;\n readonly frequency: number;\n readonly examples: readonly string[];\n readonly accuracy?: number;\n}\n\nexport type NodeData = EntityData | FactData | DecisionData | TaskData | PatternData;\n\n/**\n * 시간축을 가진 TKG 노드\n */\nexport interface TemporalNode {\n readonly id: NodeId;\n readonly type: TemporalNodeType;\n readonly valid_from: Date;\n readonly valid_to?: Date;\n readonly observed_at: Date;\n readonly updated_at: Date;\n readonly confidence: number;\n readonly source: AgentId;\n readonly version: number;\n readonly tags?: readonly string[];\n readonly data: NodeData;\n}\n\n/**\n * 시간축을 가진 TKG 엣지\n */\nexport interface TemporalEdge {\n readonly id: EdgeId;\n readonly from: NodeId;\n readonly to: NodeId;\n readonly type: EdgeType;\n readonly valid_from: Date;\n readonly valid_to?: Date;\n readonly observed_at: Date;\n readonly confidence: number;\n readonly source: AgentId;\n readonly weight?: number;\n}\n\n/**\n * TKG 조회 쿼리\n */\nexport interface GraphQuery {\n readonly nodeTypes?: readonly TemporalNodeType[];\n readonly nodeIds?: readonly NodeId[];\n readonly tags?: readonly string[];\n readonly minConfidence?: number;\n readonly edgeTypes?: readonly EdgeType[];\n readonly from?: NodeId;\n readonly to?: NodeId;\n readonly depth?: number;\n}\n\n/**\n * TKG 조회 결과\n */\nexport interface QueryResult {\n readonly nodes: readonly TemporalNode[];\n readonly edges: readonly TemporalEdge[];\n readonly metadata: {\n readonly queryTime: Date;\n readonly resultCount: number;\n readonly confidenceRange: readonly [number, number];\n };\n}\n\nexport interface ValidationError {\n readonly field: string;\n readonly message: string;\n readonly code: string;\n}\n\nexport interface ValidationWarning {\n readonly field: string;\n readonly message: string;\n readonly code: string;\n}\n\n/**\n * 유효성 검사 결과\n */\nexport interface ValidationResult {\n readonly valid: boolean;\n readonly errors: readonly ValidationError[];\n readonly warnings: readonly ValidationWarning[];\n}\n\nexport type ConflictResolution =\n | 'pending'\n | 'supersedes'\n | 'higher_confidence'\n | 'merge'\n | 'discard'\n | 'soft_delete';\n\nexport interface Conflict {\n readonly id: string;\n readonly type: 'version' | 'contradiction' | 'supersedes' | 'confidence';\n readonly nodes: readonly [TemporalNode, TemporalNode];\n readonly detectedAt: Date;\n readonly status: 'pending' | 'resolved' | 'deferred';\n readonly resolution?: ConflictResolution;\n readonly metadata?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * 승격(Promotion) 메타데이터\n */\nexport interface PromotionMeta {\n readonly promotedBy?: string;\n readonly reason?: string;\n readonly promotedAt?: Date;\n}\n\n/**\n * 개별 승격 결과\n */\nexport interface PromotionResult {\n readonly nodeId: NodeId;\n readonly success: boolean;\n readonly timestamp: Date;\n readonly reason?: string;\n readonly conflict?: Conflict;\n}\n\n/**\n * 병합 옵션\n */\nexport interface ReflectionOptions {\n readonly minConfidence?: number;\n readonly resolveConflicts?: boolean;\n readonly softDeleteOnConflict?: boolean;\n readonly maxAge?: number;\n}\n\n/**\n * Staging/Production 병합 결과\n */\nexport interface MergeResult {\n readonly mergeId: string;\n readonly timestamp: Date;\n readonly nodesPromoted: number;\n readonly nodesSkipped: number;\n readonly nodesFailed: number;\n readonly edgesPromoted: number;\n readonly edgesSkipped: number;\n readonly conflicts: readonly Conflict[];\n readonly duration: number;\n}\n\n/**\n * Production 승격 전용 Port 계약.\n * Reflector는 ProductionTKG 내부 맵에 직접 쓰지 않고 반드시 이 포트를 사용해야 합니다.\n */\nexport interface IProductionPromotionPort {\n promoteNode(node: TemporalNode, meta?: PromotionMeta): PromotionResult;\n promoteEdge(edge: TemporalEdge, meta?: PromotionMeta): PromotionResult;\n promoteBatch(payload: {\n nodes: readonly TemporalNode[];\n edges: readonly TemporalEdge[];\n meta?: PromotionMeta;\n }): MergeResult;\n}\n","/**\n * @module state-accessor\n * @description 상태 섹션 접근자\n */\n\nimport type { Blackboard } from \"../blackboard\";\nimport type { BoardPhase, StateSection } from \"../../types\";\nimport type { AgentStatus, AgentRole } from \"../../types\";\nimport { AgentStatusEnum } from \"../../types\";\nimport type { Task, TaskId, TaskError } from \"../../types\";\nimport { TaskStatus, TaskPriority } from \"../../types\";\nimport type { AgentId } from \"../../types\";\nimport { BlackboardError, BlackboardErrorCode, PathNotFoundError } from \"../blackboard\";\n\n/**\n * 상태 섹션 접근자\n * @description state 섹션에 대한 타입 안전한 접근 제공\n */\nexport class StateSectionAccessor {\n constructor(private readonly board: Blackboard) {}\n\n // === 단계 관리 ===\n\n /** 현재 단계 */\n get phase(): BoardPhase {\n return this.board.read<StateSection>(\"state\").phase;\n }\n\n set phase(value: BoardPhase) {\n const currentPhase = this.phase;\n if (currentPhase === value) {\n return; // No change, don't emit event\n }\n this.board.write(\"state.phase\", value);\n this.board.emit(\"state.phase.changed\", {\n type: \"state.phase.changed\",\n previousPhase: currentPhase,\n newPhase: value,\n });\n }\n\n /** 컨텍스트 데이터 */\n get context(): Record<string, unknown> {\n return this.board.read<StateSection>(\"state\").context;\n }\n\n setContext(key: string, value: unknown): void {\n this.board.write(`state.context.${key}`, value);\n }\n\n /**\n * 컨텍스트 값 조회 (기본값 포함)\n */\n getContext<T>(key: string, defaultValue?: T): T | undefined {\n try {\n const value = this.board.read<T>(`state.context.${key}`);\n return value !== undefined ? value : defaultValue;\n } catch (e) {\n if (e instanceof PathNotFoundError) {\n return defaultValue;\n }\n throw e;\n }\n }\n\n /**\n * 컨텍스트 값 조회 (기본값 포함) - 별칭 메서드\n */\n getContextValue<T>(key: string, defaultValue?: T): T | undefined {\n return this.getContext(key, defaultValue);\n }\n\n /**\n * 컨텍스트 항목 삭제\n */\n deleteContext(key: string): void {\n try {\n const state = this.board.read<StateSection>(\"state\");\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [key]: _, ...remaining } = state.context;\n this.board.write(\"state.context\", remaining);\n } catch (e) {\n if (e instanceof PathNotFoundError) {\n // 이미 존재하지 않는 키면 무시\n return;\n }\n throw e;\n }\n }\n\n /**\n * 컨텍스트 병합\n */\n mergeContext(partial: Record<string, unknown>): void {\n const state = this.board.read<StateSection>(\"state\");\n this.board.write(\"state.context\", { ...state.context, ...partial });\n }\n\n /**\n * 컨텍스트 초기화\n */\n clearContext(): void {\n this.board.write(\"state.context\", {});\n }\n\n // === 에이전트 관리 ===\n\n /**\n * 에이전트 등록\n * @param agent - 에이전트 상태 정보\n */\n registerAgent(agent: AgentStatus): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (state.agents.has(agent.id)) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENT_ALREADY_REGISTERED,\n `Agent ${agent.id} already registered`\n );\n }\n\n const updatedAgents = new Map(state.agents);\n updatedAgents.set(agent.id, agent);\n\n this.board.write(\"state.agents\", updatedAgents);\n this.board.emit(\"agent_joined\", { agentId: agent.id, agent });\n }\n\n /**\n * 에이전트 상태 업데이트\n * @param agentId - 에이전트 ID\n * @param updates - 업데이트할 필드\n */\n updateAgent(agentId: AgentId, updates: Partial<AgentStatus>): void {\n const state = this.board.read<StateSection>(\"state\");\n const agent = state.agents.get(agentId);\n\n if (!agent) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${agentId} not found`);\n }\n\n const updatedAgent = {\n ...agent,\n ...updates,\n updatedAt: new Date(),\n };\n\n const updatedAgents = new Map(state.agents);\n updatedAgents.set(agentId, updatedAgent);\n\n this.board.write(\"state.agents\", updatedAgents);\n\n if (updates.status !== undefined && updates.status !== agent.status) {\n this.board.emit(\"agent_status_changed\", {\n agentId,\n previousStatus: agent.status,\n newStatus: updates.status,\n });\n }\n }\n\n /**\n * 에이전트 제거\n * @param agentId - 에이전트 ID\n */\n removeAgent(agentId: AgentId): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (!state.agents.has(agentId)) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${agentId} not found`);\n }\n\n const updatedAgents = new Map(state.agents);\n updatedAgents.delete(agentId);\n\n this.board.write(\"state.agents\", updatedAgents);\n this.board.emit(\"agent_left\", { agentId });\n }\n\n /**\n * 에이전트 조회\n * @param agentId - 에이전트 ID\n */\n getAgent(agentId: AgentId): AgentStatus | undefined {\n const state = this.board.read<StateSection>(\"state\");\n return state.agents.get(agentId);\n }\n\n /**\n * 모든 에이전트 조회\n * @param filter - 필터 조건\n */\n getAgents(filter?: { role?: AgentRole; status?: AgentStatusEnum }): AgentStatus[] {\n const state = this.board.read<StateSection>(\"state\");\n const agents = Array.from(state.agents.values());\n\n if (!filter) {\n return agents;\n }\n\n return agents.filter((agent) => {\n if (filter.role !== undefined && agent.role !== filter.role) {\n return false;\n }\n if (filter.status !== undefined && agent.status !== filter.status) {\n return false;\n }\n return true;\n });\n }\n\n /**\n * 에이전트 수 조회 (getter)\n */\n get agentCount(): number {\n return this.board.read<StateSection>(\"state\").agents.size;\n }\n\n /**\n * 에이전트 수 조회 (호환성 메서드)\n */\n getAgentCount(): number {\n return this.agentCount;\n }\n\n /**\n * 에이전트 존재 여부 확인\n */\n hasAgent(id: AgentId): boolean {\n return this.board.read<StateSection>(\"state\").agents.has(id);\n }\n\n /**\n * 에이전트 하트비트 업데이트\n */\n updateAgentHeartbeat(id: AgentId): void {\n const agent = this.getAgent(id);\n if (!agent) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${id} not found`);\n }\n\n this.updateAgent(id, {\n lastHeartbeat: new Date(),\n });\n }\n\n /**\n * 활성 에이전트 수 조회 (BUSY 상태 에이전트)\n * @description 현재 작업을 수행 중인(BUSY 상태) 에이전트의 수를 반환합니다.\n * @deprecated 이름이 혼동스러울 수 있으므로 {@link getBusyAgentCount()} 사용 권장\n */\n getActiveAgentCount(): number {\n return this.getAgents({ status: AgentStatusEnum.BUSY }).length;\n }\n\n /**\n * BUSY 상태 에이전트 수 조회\n * @description 현재 작업을 수행 중인(BUSY 상태) 에이전트의 수를 반환합니다.\n */\n getBusyAgentCount(): number {\n return this.getAgents({ status: AgentStatusEnum.BUSY }).length;\n }\n\n // === 작업 관리 ===\n\n /**\n * 작업 추가\n */\n addTask(task: Task): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (state.tasks.has(task.id)) {\n throw new BlackboardError(\n BlackboardErrorCode.TASK_ALREADY_ASSIGNED,\n `Task ${task.id} already exists`\n );\n }\n\n const updatedTasks = new Map(state.tasks);\n updatedTasks.set(task.id, task);\n\n this.board.write(\"state.tasks\", updatedTasks);\n this.board.emit(\"task_created\", { taskId: task.id, task });\n }\n\n /**\n * 작업 업데이트\n */\n updateTask(taskId: TaskId, updates: Partial<Task>): void {\n const state = this.board.read<StateSection>(\"state\");\n const task = state.tasks.get(taskId);\n\n if (!task) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n\n const updatedTask = {\n ...task,\n ...updates,\n updatedAt: new Date(),\n version: task.version + 1,\n };\n\n const updatedTasks = new Map(state.tasks);\n updatedTasks.set(taskId, updatedTask);\n\n this.board.write(\"state.tasks\", updatedTasks);\n this.board.emit(\"task_updated\", { taskId, task: updatedTask });\n }\n\n /**\n * 작업 조회\n */\n getTask(taskId: TaskId): Task | undefined {\n const state = this.board.read<StateSection>(\"state\");\n return state.tasks.get(taskId);\n }\n\n /**\n * 작업 목록 조회\n */\n getTasks(filter?: {\n status?: TaskStatus;\n assignedTo?: AgentId;\n priority?: TaskPriority;\n }): Task[] {\n const state = this.board.read<StateSection>(\"state\");\n const tasks = Array.from(state.tasks.values());\n\n if (!filter) {\n return tasks;\n }\n\n return tasks.filter((task) => {\n if (filter.status !== undefined && task.status !== filter.status) {\n return false;\n }\n if (filter.assignedTo !== undefined && task.assignedTo !== filter.assignedTo) {\n return false;\n }\n if (filter.priority !== undefined && task.priority !== filter.priority) {\n return false;\n }\n return true;\n });\n }\n\n /**\n * 작업 삭제\n */\n removeTask(taskId: TaskId): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (!state.tasks.has(taskId)) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n\n const updatedTasks = new Map(state.tasks);\n updatedTasks.delete(taskId);\n\n this.board.write(\"state.tasks\", updatedTasks);\n }\n\n /**\n * 다음 실행 가능한 작업들\n * @param completedTasks - 완료된 작업 ID 목록\n */\n getNextTasks(completedTasks: Set<TaskId> = new Set()): Task[] {\n const tasks = this.getTasks({ status: TaskStatus.PENDING });\n\n return tasks\n .filter((task) => {\n // 모든 의존 작업이 완료되어야 함\n return task.dependsOn.every((depId) => completedTasks.has(depId));\n })\n .sort((a, b) => b.priority - a.priority); // 우선순위 내림차순\n }\n\n /**\n * 에이전트의 현재 작업 조회\n */\n getAgentCurrentTask(agentId: AgentId): Task | undefined {\n const tasks = this.getTasks({ assignedTo: agentId, status: TaskStatus.RUNNING });\n return tasks[0];\n }\n\n /**\n * 작업 수 조회 (getter)\n */\n get taskCount(): number {\n return this.board.read<StateSection>(\"state\").tasks.size;\n }\n\n /**\n * 작업 수 조회 (호환성 메서드)\n */\n getTaskCount(): number {\n return this.taskCount;\n }\n\n /**\n * 작업 존재 여부 확인\n */\n hasTask(id: TaskId): boolean {\n return this.board.read<StateSection>(\"state\").tasks.has(id);\n }\n\n /**\n * 작업 할당\n * @description 에이전트 존재 여부와 상태를 검증 후 작업을 할당합니다.\n * @param taskId - 할당할 작업 ID\n * @param agentId - 할당받을 에이전트 ID\n */\n assignTask(taskId: TaskId, agentId: AgentId): void {\n // 에이전트 존재 여부 확인\n const agent = this.getAgent(agentId);\n if (!agent) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${agentId} not found`);\n }\n\n // 에이전트 상태 확인 (BUSY 상태인 에이전트에는 할당하지 않음)\n if (agent.status === AgentStatusEnum.BUSY) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENT_NOT_AVAILABLE,\n `Agent ${agentId} is busy and cannot accept new tasks`\n );\n }\n\n // 작업 업데이트\n this.updateTask(taskId, {\n assignedTo: agentId,\n status: TaskStatus.RUNNING,\n startedAt: new Date(),\n });\n\n // 에이전트 상태도 BUSY로 변경\n this.updateAgent(agentId, {\n status: AgentStatusEnum.BUSY,\n currentTask: taskId,\n });\n }\n\n /**\n * 작업 할당 해제\n */\n unassignTask(taskId: TaskId): void {\n const task = this.getTask(taskId);\n if (!task) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n\n const agentId = task.assignedTo;\n\n this.updateTask(taskId, {\n assignedTo: null,\n status: TaskStatus.PENDING,\n startedAt: null,\n });\n\n // agent 상태 리셋 (에이전트가 존재하는 경우에만)\n if (agentId && this.hasAgent(agentId)) {\n this.updateAgent(agentId, {\n status: AgentStatusEnum.IDLE,\n currentTask: null,\n });\n }\n }\n\n /**\n * 작업 완료 처리\n */\n completeTask(taskId: TaskId, outputs: Record<string, unknown>): void {\n const task = this.getTask(taskId);\n if (!task) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n const agentId = task.assignedTo;\n\n this.updateTask(taskId, {\n status: TaskStatus.COMPLETED,\n outputs,\n completedAt: new Date(),\n });\n\n // agent 상태 리셋 (에이전트가 존재하는 경우에만)\n if (agentId && this.hasAgent(agentId)) {\n this.updateAgent(agentId, {\n status: AgentStatusEnum.IDLE,\n currentTask: null,\n });\n }\n }\n\n /**\n * 작업 실패 처리\n */\n failTask(taskId: TaskId, error: TaskError): void {\n const task = this.getTask(taskId);\n const agentId = task?.assignedTo;\n\n this.updateTask(taskId, {\n status: TaskStatus.FAILED,\n error,\n completedAt: new Date(),\n });\n\n // agent 상태 리셋 (에이전트가 존재하는 경우에만)\n if (agentId && this.hasAgent(agentId)) {\n this.updateAgent(agentId, {\n status: AgentStatusEnum.IDLE,\n currentTask: null,\n });\n }\n }\n\n /**\n * 실행 중인 작업 수 조회\n */\n getRunningTaskCount(): number {\n return this.getTasks({ status: TaskStatus.RUNNING }).length;\n }\n\n /**\n * 대기 중인 작업 수 조회\n */\n getPendingTaskCount(): number {\n return this.getTasks({ status: TaskStatus.PENDING }).length;\n }\n}\n","/**\n * @module knowledge-accessor\n * @description 지식 섹션 접근자\n */\n\nimport type { Blackboard } from '../blackboard';\nimport type { KnowledgeSection } from '../../types';\nimport type {\n Fact,\n FactCreateInput,\n Inference,\n InferenceCreateInput,\n Pattern,\n PatternCreateInput,\n KnowledgeQuery,\n InferenceQuery,\n PatternQuery,\n} from '../../types';\nimport type { AgentId } from '../../types';\nimport { BlackboardError, BlackboardErrorCode } from '../blackboard';\n\n/**\n * 지식 섹션 접근자\n * @description knowledge 섹션에 대한 타입 안전한 접근 제공\n */\nexport class KnowledgeSectionAccessor {\n constructor(private readonly board: Blackboard) {}\n\n // === 헬퍼 메서드 ===\n\n /**\n * confidence 값 검증\n * @private\n */\n private validateConfidence(value: number | undefined, fieldName = 'confidence'): void {\n if (value !== undefined) {\n if (typeof value !== 'number' || value < 0 || value > 1 || Number.isNaN(value)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n `${fieldName} must be a number between 0 and 1`\n );\n }\n }\n }\n\n // === Getters ===\n\n /**\n * 전체 사실 목록\n */\n get facts(): Fact[] {\n return this.board.read<KnowledgeSection>('knowledge').facts;\n }\n\n /**\n * 전체 추론 목록\n */\n get inferences(): Inference[] {\n return this.board.read<KnowledgeSection>('knowledge').inferences;\n }\n\n /**\n * 전체 패턴 목록\n */\n get patterns(): Pattern[] {\n return this.board.read<KnowledgeSection>('knowledge').patterns;\n }\n\n /**\n * 사실 수\n */\n get factCount(): number {\n return this.board.read<KnowledgeSection>('knowledge').facts.length;\n }\n\n /**\n * 추론 수\n */\n get inferenceCount(): number {\n return this.board.read<KnowledgeSection>('knowledge').inferences.length;\n }\n\n /**\n * 패턴 수\n */\n get patternCount(): number {\n return this.board.read<KnowledgeSection>('knowledge').patterns.length;\n }\n\n // === 사실 관리 ===\n\n /**\n * 사실 추가\n * @param factInput - 새 사실 입력\n */\n addFact(factInput: FactCreateInput): Fact {\n // 필수 필드 검증\n if (!factInput.content || factInput.content.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Fact content is required'\n );\n }\n if (!factInput.source) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Fact source is required'\n );\n }\n if (!factInput.category || factInput.category.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Fact category is required'\n );\n }\n this.validateConfidence(factInput.confidence, 'Fact confidence');\n\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const fact: Fact = {\n id: `fact-${crypto.randomUUID()}`,\n content: factInput.content,\n source: factInput.source,\n confidence: factInput.confidence,\n category: factInput.category,\n tags: factInput.tags || [],\n expiresAt: factInput.expiresAt ?? null,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedFacts = [...knowledge.facts, fact];\n this.board.write('knowledge.facts', updatedFacts);\n\n return fact;\n }\n\n /**\n * 사실 조회\n */\n getFact(factId: string): Fact | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.facts.find(f => f.id === factId);\n }\n\n /**\n * 사실 업데이트\n */\n updateFact(factId: string, updates: Partial<Omit<Fact, 'id' | 'createdAt'>>): Fact | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const factIndex = knowledge.facts.findIndex(f => f.id === factId);\n\n if (factIndex === -1) {\n return undefined;\n }\n\n const existingFact = knowledge.facts[factIndex];\n const updatedFact: Fact = {\n ...existingFact,\n ...updates,\n id: existingFact.id,\n createdAt: existingFact.createdAt,\n updatedAt: new Date(),\n };\n\n const updatedFacts = [...knowledge.facts];\n updatedFacts[factIndex] = updatedFact;\n this.board.write('knowledge.facts', updatedFacts);\n\n return updatedFact;\n }\n\n /**\n * 사실 검색\n */\n findFacts(query: KnowledgeQuery): Fact[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n return knowledge.facts.filter(fact => {\n // 유효 기간 필터\n if (query.validOnly && fact.expiresAt && fact.expiresAt < now) {\n return false;\n }\n\n // 카테고리 필터\n if (query.category !== undefined && fact.category !== query.category) {\n return false;\n }\n\n // 출처 필터\n if (query.source !== undefined && fact.source !== query.source) {\n return false;\n }\n\n // 최소 신뢰도 필터\n if (query.minConfidence !== undefined) {\n if (fact.confidence === undefined || fact.confidence < query.minConfidence) {\n return false;\n }\n }\n\n // 단일 태그 필터\n if (query.tag !== undefined && !fact.tags.includes(query.tag)) {\n return false;\n }\n\n // 태그 필터 (모든 태그가 포함되어야 함)\n if (query.tags && query.tags.length > 0) {\n const hasAllTags = query.tags.every(tag => fact.tags.includes(tag));\n if (!hasAllTags) {\n return false;\n }\n }\n\n // 텍스트 검색\n if (query.text && !fact.content.toLowerCase().includes(query.text.toLowerCase())) {\n return false;\n }\n\n return true;\n });\n }\n\n /**\n * 만료된 사실 정리\n */\n cleanupExpiredFacts(): number {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const validFacts = knowledge.facts.filter(\n fact => !fact.expiresAt || fact.expiresAt >= now\n );\n\n const removedCount = knowledge.facts.length - validFacts.length;\n\n if (removedCount > 0) {\n this.board.write('knowledge.facts', validFacts);\n }\n\n return removedCount;\n }\n\n /**\n * 사실 삭제\n */\n removeFact(factId: string): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const updatedFacts = knowledge.facts.filter(f => f.id !== factId);\n\n if (updatedFacts.length === knowledge.facts.length) {\n throw new BlackboardError(\n BlackboardErrorCode.FACT_NOT_FOUND,\n `Fact ${factId} not found`\n );\n }\n\n this.board.write('knowledge.facts', updatedFacts);\n }\n\n /**\n * 사실 수 조회 (deprecated: factCount getter 사용)\n */\n getFactCount(): number {\n return this.factCount;\n }\n\n // === 추론 관리 ===\n\n /**\n * 추론 추가\n */\n addInference(inferenceInput: InferenceCreateInput): Inference {\n // 필수 필드 검증\n if (!inferenceInput.conclusion || inferenceInput.conclusion.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Inference conclusion is required'\n );\n }\n if (!inferenceInput.source) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Inference source is required'\n );\n }\n if (!Array.isArray(inferenceInput.premises)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Inference premises must be an array'\n );\n }\n this.validateConfidence(inferenceInput.confidence, 'Inference confidence');\n\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const inference: Inference = {\n id: `inference-${crypto.randomUUID()}`,\n conclusion: inferenceInput.conclusion,\n premises: inferenceInput.premises,\n source: inferenceInput.source,\n method: inferenceInput.method,\n confidence: inferenceInput.confidence,\n tags: inferenceInput.tags || [],\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedInferences = [...knowledge.inferences, inference];\n this.board.write('knowledge.inferences', updatedInferences);\n\n return inference;\n }\n\n /**\n * 추론 조회\n */\n getInference(inferenceId: string): Inference | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.inferences.find(i => i.id === inferenceId);\n }\n\n /**\n * 추론 업데이트\n */\n updateInference(\n inferenceId: string,\n updates: Partial<Omit<Inference, 'id' | 'createdAt'>>\n ): Inference | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const inferenceIndex = knowledge.inferences.findIndex(i => i.id === inferenceId);\n\n if (inferenceIndex === -1) {\n return undefined;\n }\n\n const existingInference = knowledge.inferences[inferenceIndex];\n const updatedInference: Inference = {\n ...existingInference,\n ...updates,\n id: existingInference.id,\n createdAt: existingInference.createdAt,\n updatedAt: new Date(),\n };\n\n const updatedInferences = [...knowledge.inferences];\n updatedInferences[inferenceIndex] = updatedInference;\n this.board.write('knowledge.inferences', updatedInferences);\n\n return updatedInference;\n }\n\n /**\n * 추론 검색\n */\n findInferences(query: InferenceQuery): Inference[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n\n return knowledge.inferences.filter(inference => {\n // 출처 필터\n if (query.source !== undefined && inference.source !== query.source) {\n return false;\n }\n\n // 전제 필터 (모든 전제 포함)\n if (query.premises && query.premises.length > 0) {\n const hasAllPremises = query.premises.every(p => inference.premises.includes(p));\n if (!hasAllPremises) {\n return false;\n }\n }\n\n // 최소 신뢰도 필터\n if (query.minConfidence !== undefined) {\n if (inference.confidence === undefined || inference.confidence < query.minConfidence) {\n return false;\n }\n }\n\n return true;\n });\n }\n\n /**\n * 특정 사실을 전제로 하는 추론 찾기\n */\n findInferencesByPremise(factId: string): Inference[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.inferences.filter(i => i.premises.includes(factId));\n }\n\n /**\n * 에이전트별 추론 조회\n */\n findInferencesByAgent(agentId: AgentId): Inference[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.inferences.filter(i => i.source === agentId);\n }\n\n /**\n * 추론 삭제\n */\n removeInference(inferenceId: string): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const updatedInferences = knowledge.inferences.filter(i => i.id !== inferenceId);\n\n if (updatedInferences.length === knowledge.inferences.length) {\n throw new BlackboardError(\n BlackboardErrorCode.INFERENCE_NOT_FOUND,\n `Inference ${inferenceId} not found`\n );\n }\n\n this.board.write('knowledge.inferences', updatedInferences);\n }\n\n /**\n * 추론 수 조회 (deprecated: inferenceCount getter 사용)\n */\n getInferenceCount(): number {\n return this.inferenceCount;\n }\n\n // === 패턴 관리 ===\n\n /**\n * 패턴 추가\n */\n addPattern(patternInput: PatternCreateInput): Pattern {\n // 필수 필드 검증\n if (!patternInput.name || patternInput.name.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern name is required'\n );\n }\n if (!patternInput.description || patternInput.description.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern description is required'\n );\n }\n if (!Array.isArray(patternInput.conditions)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern conditions must be an array'\n );\n }\n if (!Array.isArray(patternInput.consequences)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern consequences must be an array'\n );\n }\n this.validateConfidence(patternInput.confidence, 'Pattern confidence');\n\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const pattern: Pattern = {\n id: `pattern-${crypto.randomUUID()}`,\n name: patternInput.name,\n description: patternInput.description,\n conditions: patternInput.conditions,\n consequences: patternInput.consequences,\n confidence: patternInput.confidence,\n tags: patternInput.tags || [],\n discoveredBy: patternInput.discoveredBy,\n usageCount: patternInput.usageCount ?? 0,\n successRate: patternInput.successRate ?? 0,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedPatterns = [...knowledge.patterns, pattern];\n this.board.write('knowledge.patterns', updatedPatterns);\n\n return pattern;\n }\n\n /**\n * 패턴 추가/업데이트\n */\n upsertPattern(patternInput: PatternCreateInput): Pattern {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n // 기존 패턴 확인 (같은 이름의 패턴)\n const existingPattern = knowledge.patterns.find(\n p => p.name === patternInput.name\n );\n\n if (existingPattern) {\n // 업데이트\n const updatedPattern: Pattern = {\n ...existingPattern,\n description: patternInput.description,\n conditions: patternInput.conditions,\n consequences: patternInput.consequences,\n confidence: patternInput.confidence,\n tags: patternInput.tags || existingPattern.tags,\n discoveredBy: patternInput.discoveredBy ?? existingPattern.discoveredBy,\n updatedAt: now,\n };\n\n const updatedPatterns = knowledge.patterns.map(p =>\n p.id === existingPattern.id ? updatedPattern : p\n );\n\n this.board.write('knowledge.patterns', updatedPatterns);\n return updatedPattern;\n }\n\n // 새 패턴 생성\n return this.addPattern(patternInput);\n }\n\n /**\n * 패턴 조회\n */\n getPattern(patternId: string): Pattern | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.patterns.find(p => p.id === patternId);\n }\n\n /**\n * 패턴 업데이트\n */\n updatePattern(\n patternId: string,\n updates: Partial<Omit<Pattern, 'id' | 'createdAt'>>\n ): Pattern | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const patternIndex = knowledge.patterns.findIndex(p => p.id === patternId);\n\n if (patternIndex === -1) {\n return undefined;\n }\n\n const existingPattern = knowledge.patterns[patternIndex];\n const updatedPattern: Pattern = {\n ...existingPattern,\n ...updates,\n id: existingPattern.id,\n createdAt: existingPattern.createdAt,\n updatedAt: new Date(),\n };\n\n const updatedPatterns = [...knowledge.patterns];\n updatedPatterns[patternIndex] = updatedPattern;\n this.board.write('knowledge.patterns', updatedPatterns);\n\n return updatedPattern;\n }\n\n /**\n * 패턴 검색\n */\n findPatterns(query: PatternQuery): Pattern[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n\n return knowledge.patterns.filter(pattern => {\n // 태그 필터\n if (query.tag !== undefined && !pattern.tags.includes(query.tag)) {\n return false;\n }\n\n // 최소 신뢰도 필터\n if (query.minConfidence !== undefined) {\n if (pattern.confidence === undefined || pattern.confidence < query.minConfidence) {\n return false;\n }\n }\n\n return true;\n });\n }\n\n /**\n * 에이전트가 발견한 패턴 조회\n */\n findPatternsByAgent(agentId: AgentId): Pattern[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.patterns.filter(p => p.discoveredBy === agentId);\n }\n\n /**\n * 패턴 사용 기록\n */\n recordPatternUsage(patternId: string, success: boolean): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const pattern = knowledge.patterns.find(p => p.id === patternId);\n\n if (!pattern) {\n throw new BlackboardError(\n BlackboardErrorCode.PATTERN_NOT_FOUND,\n `Pattern ${patternId} not found`\n );\n }\n\n const currentUsageCount = pattern.usageCount ?? 0;\n const currentSuccessRate = pattern.successRate ?? 0;\n const newUsageCount = currentUsageCount + 1;\n const newSuccessRate = (currentSuccessRate * currentUsageCount + (success ? 1 : 0)) / newUsageCount;\n\n const updatedPattern: Pattern = {\n ...pattern,\n usageCount: newUsageCount,\n successRate: newSuccessRate,\n updatedAt: new Date(),\n };\n\n const updatedPatterns = knowledge.patterns.map(p =>\n p.id === patternId ? updatedPattern : p\n );\n\n this.board.write('knowledge.patterns', updatedPatterns);\n }\n\n /**\n * 패턴 삭제\n */\n removePattern(patternId: string): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const updatedPatterns = knowledge.patterns.filter(p => p.id !== patternId);\n\n if (updatedPatterns.length === knowledge.patterns.length) {\n throw new BlackboardError(\n BlackboardErrorCode.PATTERN_NOT_FOUND,\n `Pattern ${patternId} not found`\n );\n }\n\n this.board.write('knowledge.patterns', updatedPatterns);\n }\n\n /**\n * 패턴 수 조회 (deprecated: patternCount getter 사용)\n */\n getPatternCount(): number {\n return this.patternCount;\n }\n\n // === 전체 관리 ===\n\n /**\n * 모든 지식 초기화\n */\n clearAll(): void {\n this.board.write('knowledge.facts', []);\n this.board.write('knowledge.inferences', []);\n this.board.write('knowledge.patterns', []);\n }\n\n // === 통계 ===\n\n /**\n * 지식 섹션 통계\n */\n getStats(): {\n facts: number;\n inferences: number;\n patterns: number;\n expiredFacts: number;\n } {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const expiredFacts = knowledge.facts.filter(\n f => f.expiresAt && f.expiresAt < now\n ).length;\n\n return {\n facts: knowledge.facts.length,\n inferences: knowledge.inferences.length,\n patterns: knowledge.patterns.length,\n expiredFacts,\n };\n }\n}\n","/**\n * @module decisions-accessor\n * @description 의사결정 섹션 접근자\n */\n\nimport type { Blackboard } from \"../blackboard\";\nimport type { DecisionsSection } from \"../../types\";\nimport type {\n Agenda,\n AgendaCreateInput,\n Opinion,\n OpinionCreateInput,\n Resolution,\n DecisionType,\n OpinionId,\n AgendaId,\n} from \"../../types\";\nimport type { AgentId } from \"../../types\";\nimport { AgendaStatus, createOpinionId, createAgendaId } from \"../../types\";\nimport { BlackboardError, BlackboardErrorCode } from \"../blackboard\";\n\n/**\n * 의사결정 섹션 접근자\n * @description decisions 섹션에 대한 타입 안전한 접근 제공\n */\nexport class DecisionsSectionAccessor {\n constructor(private readonly board: Blackboard) {}\n\n /**\n * 의견 키 생성 (agendaId + agentId 조합)\n * @private\n */\n private getOpinionKey(agendaId: AgendaId, agentId: AgentId): string {\n return `${agendaId}:${agentId}`;\n }\n\n /**\n * opinionId로 opinionKey 찾기\n * @private\n */\n private findOpinionKey(opinionId: OpinionId): string | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n for (const [key, opinion] of decisions.opinions.entries()) {\n if (opinion.id === opinionId) {\n return key;\n }\n }\n return undefined;\n }\n\n // === 안건 관리 ===\n\n /** 현재 안건 */\n get current(): Agenda | null {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.current;\n }\n\n /** 대기 중인 안건들 */\n get pending(): Agenda[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.pending.filter((a) => a.status === AgendaStatus.SUBMITTED);\n }\n\n /** 모든 대기 안건 */\n get allPending(): Agenda[] {\n return this.board.read<DecisionsSection>(\"decisions\").pending;\n }\n\n /** 결정 이력 전체 */\n get history(): Resolution[] {\n return this.board.read<DecisionsSection>(\"decisions\").history;\n }\n\n /** 대기 중인 안건 수 */\n get pendingCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").pending.length;\n }\n\n /** 결정 이력 수 */\n get historyCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").history.length;\n }\n\n /**\n * 안건 제출\n * @param agendaInput - 새 안건 입력\n */\n submitAgenda(agendaInput: AgendaCreateInput): Agenda {\n // 필수 필드 검증\n if (!agendaInput.title?.trim()) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Title is required\");\n }\n if (!agendaInput.description?.trim()) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Description is required\");\n }\n if (!agendaInput.proposer) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Proposer is required\");\n }\n\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n const agenda: Agenda = {\n id: createAgendaId(`agenda-${crypto.randomUUID()}`),\n title: agendaInput.title,\n description: agendaInput.description,\n proposer: agendaInput.proposer,\n status: AgendaStatus.SUBMITTED,\n deadline: agendaInput.deadline ?? null,\n requiredQuorum: agendaInput.requiredQuorum ?? 3,\n votingMethod: agendaInput.votingMethod ?? \"majority\",\n priority: agendaInput.priority ?? 1,\n tags: agendaInput.tags ?? [],\n attachments: agendaInput.attachments ?? [],\n createdAt: now,\n updatedAt: now,\n version: 1,\n };\n\n const updatedPending = [...decisions.pending, agenda];\n this.board.write(\"decisions.pending\", updatedPending);\n this.board.emit(\"agenda_submitted\", { agendaId: agenda.id, agenda });\n\n return agenda;\n }\n\n /**\n * 안건 상태 변경\n */\n updateAgendaStatus(agendaId: AgendaId, status: AgendaStatus): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // pending에서 찾기\n let targetIndex = -1;\n let targetPending = false;\n\n for (let i = 0; i < decisions.pending.length; i++) {\n if (decisions.pending[i].id === agendaId) {\n targetIndex = i;\n targetPending = true;\n break;\n }\n }\n\n if (targetIndex === -1 && decisions.current?.id === agendaId) {\n targetIndex = 0;\n targetPending = false;\n }\n\n if (targetIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n if (targetPending) {\n const updatedAgenda = {\n ...decisions.pending[targetIndex],\n status,\n updatedAt: new Date(),\n version: decisions.pending[targetIndex].version + 1,\n };\n\n const updatedPending = [...decisions.pending];\n updatedPending[targetIndex] = updatedAgenda;\n\n this.board.write(\"decisions.pending\", updatedPending);\n } else if (decisions.current) {\n const updatedAgenda = {\n ...decisions.current,\n status,\n updatedAt: new Date(),\n version: decisions.current.version + 1,\n };\n\n this.board.write(\"decisions.current\", updatedAgenda);\n }\n\n this.board.emit(\"agenda_updated\", { agendaId, status });\n }\n\n /**\n * 현재 안건 설정\n */\n setCurrentAgenda(agendaId: AgendaId): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // 현재 안건이 있으면 pending으로 이동\n const updatedPending = [...decisions.pending];\n if (decisions.current) {\n updatedPending.push(decisions.current);\n }\n\n // pending에서 해당 안건 찾기\n const agendaIndex = updatedPending.findIndex((a) => a.id === agendaId);\n if (agendaIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found in pending`\n );\n }\n\n const [agenda] = updatedPending.splice(agendaIndex, 1);\n\n // 안건 상태 업데이트\n const updatedAgenda: Agenda = {\n ...agenda,\n status: AgendaStatus.DISCUSSING,\n updatedAt: new Date(),\n version: agenda.version + 1,\n };\n\n this.board.write(\"decisions.current\", updatedAgenda);\n this.board.write(\"decisions.pending\", updatedPending);\n }\n\n /**\n * 안건 취소\n */\n cancelAgenda(agendaId: AgendaId, reason: string): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // current 안건인 경우\n if (decisions.current?.id === agendaId) {\n this.board.write(\"decisions.current\", null);\n this.board.emit(\"agenda_updated\", { agendaId, status: AgendaStatus.CANCELLED, reason });\n return;\n }\n\n // pending 안건인 경우\n const agendaIndex = decisions.pending.findIndex((a) => a.id === agendaId);\n if (agendaIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const updatedPending = decisions.pending.filter((a) => a.id !== agendaId);\n this.board.write(\"decisions.pending\", updatedPending);\n this.board.emit(\"agenda_updated\", { agendaId, status: AgendaStatus.CANCELLED, reason });\n }\n\n /**\n * 안건 조회\n */\n getAgenda(agendaId: AgendaId): Agenda | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n if (decisions.current?.id === agendaId) {\n return decisions.current;\n }\n\n const pendingAgenda = decisions.pending.find((a) => a.id === agendaId);\n if (pendingAgenda) {\n return pendingAgenda;\n }\n\n // 해결된 안건도 조회 (resolution에 연결된 agenda 정보)\n // 실제로는 agenda가 history에 저장되지 않으므로 null 반환\n return undefined;\n }\n\n /**\n * 모든 안건 조회\n */\n getAllAgendas(): Agenda[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const result: Agenda[] = [];\n\n if (decisions.current) {\n result.push(decisions.current);\n }\n\n result.push(...decisions.pending);\n return result;\n }\n\n // === 의견 관리 ===\n\n /**\n * 의견 제출\n * @param opinionInput - 의견 생성 입력 (agentId 포함)\n */\n submitOpinion(opinionInput: OpinionCreateInput & { agentId: AgentId }): Opinion {\n // 필수 필드 검증\n if (!opinionInput.stance) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Stance is required\");\n }\n if (\n opinionInput.confidence !== undefined &&\n (opinionInput.confidence < 0 ||\n opinionInput.confidence > 1 ||\n Number.isNaN(opinionInput.confidence))\n ) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n \"Confidence must be between 0 and 1\"\n );\n }\n\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n // 안건 확인\n const agenda = this.getAgenda(opinionInput.agendaId);\n if (!agenda) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${opinionInput.agendaId} not found`\n );\n }\n\n // 중복 의견 확인\n const opinionKey = this.getOpinionKey(opinionInput.agendaId, opinionInput.agentId);\n if (decisions.opinions.has(opinionKey)) {\n throw new BlackboardError(\n BlackboardErrorCode.DUPLICATE_OPINION,\n `Agent ${opinionInput.agentId} already submitted an opinion for agenda ${opinionInput.agendaId}`\n );\n }\n\n const fullOpinion: Opinion = {\n id: createOpinionId(`opinion-${crypto.randomUUID()}`),\n agentId: opinionInput.agentId,\n agendaId: opinionInput.agendaId,\n stance: opinionInput.stance,\n reason: opinionInput.reason,\n conditions: opinionInput.conditions ?? [],\n confidence: opinionInput.confidence ?? 0.5,\n references: opinionInput.references ?? [],\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedOpinions = new Map(decisions.opinions);\n updatedOpinions.set(opinionKey, fullOpinion);\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n this.board.emit(\"opinion_added\", { opinion: fullOpinion });\n\n return fullOpinion;\n }\n\n /**\n * 특정 안건의 모든 의견 조회\n */\n getOpinions(agendaId: AgendaId): Opinion[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const opinions: Opinion[] = [];\n\n for (const opinion of decisions.opinions.values()) {\n if (opinion.agendaId === agendaId) {\n opinions.push(opinion);\n }\n }\n\n return opinions;\n }\n\n /**\n * 에이전트의 의견 조회 (agendaId 먼저)\n * @deprecated getAgentOpinion() 사용 권장\n */\n getOpinionByAgent(agendaId: AgendaId, agentId: AgentId): Opinion | undefined {\n return this.getAgentOpinion(agentId, agendaId);\n }\n\n /**\n * 에이전트의 의견 조회\n * @param agentId - 에이전트 ID\n * @param agendaId - 안건 ID (필수)\n */\n getAgentOpinion(agentId: AgentId, agendaId: AgendaId): Opinion | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n // agendaId + agentId 조합으로 키 조회\n const opinionKey = this.getOpinionKey(agendaId, agentId);\n const opinion = decisions.opinions.get(opinionKey);\n\n return opinion;\n }\n\n /**\n * 의견 요약\n */\n summarizeOpinions(agendaId: AgendaId): {\n total: number;\n approve: number;\n reject: number;\n conditional: number;\n abstain: number;\n approvalRate: number;\n quorumReached: boolean;\n } {\n const opinions = this.getOpinions(agendaId);\n\n const summary = {\n total: opinions.length,\n approve: 0,\n reject: 0,\n conditional: 0,\n abstain: 0,\n approvalRate: 0,\n quorumReached: false,\n };\n\n // 유효한 stance 값인지 확인 후 처리\n const validStances: readonly string[] = [\"approve\", \"reject\", \"conditional\", \"abstain\"];\n\n for (const opinion of opinions) {\n if (validStances.includes(opinion.stance)) {\n summary[opinion.stance as keyof typeof summary]++;\n }\n }\n\n // 승인률 계산 (찬성 / 총 투표수)\n summary.approvalRate =\n summary.total > 0 ? (summary.approve + summary.conditional) / summary.total : 0;\n\n // 정족수 도달 여부 확인\n const agenda = this.getAgenda(agendaId);\n if (agenda) {\n summary.quorumReached = summary.total >= agenda.requiredQuorum;\n }\n\n return summary;\n }\n\n /**\n * 모든 의견 초기화 (재투표 시)\n */\n clearOpinions(agendaId: AgendaId): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const updatedOpinions = new Map(decisions.opinions);\n\n for (const [key, opinion] of decisions.opinions.entries()) {\n if (opinion.agendaId === agendaId) {\n updatedOpinions.delete(key);\n }\n }\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n }\n\n /**\n * 의견 업데이트\n */\n updateOpinion(opinionId: OpinionId, updates: Partial<Omit<Opinion, \"id\" | \"createdAt\">>): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const opinionKey = this.findOpinionKey(opinionId);\n\n if (!opinionKey) {\n throw new BlackboardError(\n BlackboardErrorCode.OPINION_NOT_FOUND,\n `Opinion ${opinionId} not found`\n );\n }\n\n const existingOpinion = decisions.opinions.get(opinionKey);\n if (!existingOpinion) {\n throw new BlackboardError(\n BlackboardErrorCode.OPINION_NOT_FOUND,\n `Opinion ${opinionId} not found`\n );\n }\n\n const updatedOpinion: Opinion = {\n ...existingOpinion,\n ...updates,\n id: existingOpinion.id, // ID 변경 불가\n createdAt: existingOpinion.createdAt, // 생성 시간 변경 불가\n updatedAt: new Date(),\n };\n\n const updatedOpinions = new Map(decisions.opinions);\n updatedOpinions.set(opinionKey, updatedOpinion);\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n this.board.emit(\"opinion_updated\", { opinion: updatedOpinion });\n }\n\n /**\n * 의견 삭제\n */\n removeOpinion(opinionId: OpinionId): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const opinionKey = this.findOpinionKey(opinionId);\n\n if (!opinionKey) {\n throw new BlackboardError(\n BlackboardErrorCode.OPINION_NOT_FOUND,\n `Opinion ${opinionId} not found`\n );\n }\n\n const updatedOpinions = new Map(decisions.opinions);\n updatedOpinions.delete(opinionKey);\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n this.board.emit(\"opinion_removed\", { opinionId });\n }\n\n // === 결정 관리 ===\n\n /**\n * 결정 기록 (안건 제거)\n * @description 새 결정을 기록하고 관련 안건을 제거합니다.\n * @warning closeAgenda()를 사용하면 안건이 RESOLVED 상태로 유지됩니다.\n * 이 메서드는 안건을 완전히 제거합니다.\n */\n recordResolution(\n resolutionInput: Omit<Resolution, \"id\" | \"createdAt\" | \"updatedAt\">\n ): Resolution {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n const resolution: Resolution = {\n id: `resolution-${crypto.randomUUID()}`,\n agendaId: resolutionInput.agendaId,\n decision: resolutionInput.decision,\n summary: resolutionInput.summary,\n voteSummary: resolutionInput.voteSummary,\n conditions: resolutionInput.conditions,\n dissent: resolutionInput.dissent,\n decidedBy: resolutionInput.decidedBy,\n nextActions: resolutionInput.nextActions,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedHistory = [...decisions.history, resolution];\n this.board.write(\"decisions.history\", updatedHistory);\n\n // 현재 안건 초기화\n if (decisions.current?.id === resolution.agendaId) {\n this.board.write(\"decisions.current\", null);\n } else {\n // pending에서 제거\n const updatedPending = decisions.pending.filter((a) => a.id !== resolution.agendaId);\n this.board.write(\"decisions.pending\", updatedPending);\n }\n\n this.board.emit(\"resolution_created\", { resolution });\n\n return resolution;\n }\n\n /**\n * 결정 기록 (안건 유지)\n * @description 안건을 제거하지 않고 결정만 기록합니다.\n * @private\n */\n private recordResolutionKeepAgenda(\n resolutionInput: Omit<Resolution, \"id\" | \"createdAt\" | \"updatedAt\">\n ): Resolution {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n const resolution: Resolution = {\n id: `resolution-${crypto.randomUUID()}`,\n agendaId: resolutionInput.agendaId,\n decision: resolutionInput.decision,\n summary: resolutionInput.summary,\n voteSummary: resolutionInput.voteSummary,\n conditions: resolutionInput.conditions,\n dissent: resolutionInput.dissent,\n decidedBy: resolutionInput.decidedBy,\n nextActions: resolutionInput.nextActions,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedHistory = [...decisions.history, resolution];\n this.board.write(\"decisions.history\", updatedHistory);\n this.board.emit(\"resolution_created\", { resolution });\n\n return resolution;\n }\n\n /**\n * 결정 이력 조회\n */\n getHistory(filter?: { agendaId?: AgendaId; decision?: DecisionType }): Resolution[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n let history = [...decisions.history];\n\n if (!filter) {\n return history;\n }\n\n if (filter.agendaId) {\n history = history.filter((r) => r.agendaId === filter.agendaId);\n }\n\n if (filter.decision) {\n history = history.filter((r) => r.decision === filter.decision);\n }\n\n return history;\n }\n\n /**\n * 최근 N개 결정 조회\n */\n getRecentResolutions(count: number): Resolution[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.history.slice(-count).reverse();\n }\n\n /**\n * 결정 조회\n */\n getResolution(resolutionId: string): Resolution | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.history.find((r) => r.id === resolutionId);\n }\n\n /**\n * 안건에 대한 결정 조회\n */\n getResolutionByAgenda(agendaId: AgendaId): Resolution | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.history.find((r) => r.agendaId === agendaId);\n }\n\n // === 통계 ===\n\n /**\n * 결정 수 조회\n */\n getResolutionCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").history.length;\n }\n\n /**\n * 안건 수 조회\n */\n getAgendaCount(): number {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n let count = decisions.current ? 1 : 0;\n count += decisions.pending.length;\n return count;\n }\n\n /**\n * 의견 수 조회\n */\n getOpinionCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").opinions.size;\n }\n\n // === 투표 ===\n\n /**\n * 투표 결과 확인\n * @note conditional은 승인으로 카운트됩니다 (찬성 = approve + conditional)\n */\n checkVotingResult(agendaId: AgendaId): {\n passed: boolean;\n method: \"majority\" | \"unanimous\" | \"weighted\" | \"supermajority\";\n summary: {\n total: number;\n approve: number;\n reject: number;\n conditional: number;\n abstain: number;\n approvalRate: number;\n quorumReached: boolean;\n };\n } {\n const agenda = this.getAgenda(agendaId);\n if (!agenda) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const summary = this.summarizeOpinions(agendaId);\n let passed = false;\n\n switch (agenda.votingMethod) {\n case \"unanimous\":\n // 전체 찬성 (반대 없음)\n passed = summary.reject === 0 && summary.total > 0;\n break;\n case \"majority\": {\n // 단순 과반수 (50% 초과)\n const approveCount = summary.approve + summary.conditional;\n passed = approveCount > summary.total / 2;\n break;\n }\n case \"supermajority\": {\n // 2/3 이상 찬성\n const superMajorityCount = summary.approve + summary.conditional;\n passed = superMajorityCount >= (summary.total * 2) / 3;\n break;\n }\n case \"weighted\": {\n // 가중치 투표 (현재는 과반수와 동일하게 처리)\n const weightedCount = summary.approve + summary.conditional;\n passed = weightedCount > summary.total / 2;\n break;\n }\n }\n\n return {\n passed: summary.quorumReached && passed,\n method: agenda.votingMethod,\n summary,\n };\n }\n\n // === 안건 관리 추가 ===\n\n /**\n * 안건 종료 (결정 기록)\n * @description 안건을 RESOLVED 상태로 변경하고 결정을 기록합니다.\n *\n * **정책:** 안건은 RESOLVED 상태로 변경 후에도 pending/current에 유지됩니다.\n * 이는 결정 이력 추적 및 후속 조치 관리를 위함입니다.\n * 안건을 완전히 제거하려면 {@link recordResolution()}을 직접 호출하세요.\n *\n * @param agendaId - 종료할 안건 ID\n * @param decision - 결정 유형 (기본: approved)\n */\n closeAgenda(\n agendaId: AgendaId,\n decision: \"approved\" | \"rejected\" | \"deferred\" = \"approved\"\n ): void {\n const agenda = this.getAgenda(agendaId);\n if (!agenda) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const summary = this.summarizeOpinions(agendaId);\n\n // 먼저 안건 상태 업데이트 (agenda를 찾을 수 있도록)\n this.updateAgendaStatus(agendaId, AgendaStatus.RESOLVED);\n\n // 결정 기록 생성 (안건 유지 - 정책에 따름)\n this.recordResolutionKeepAgenda({\n agendaId,\n decision: decision as DecisionType,\n summary: `Agenda ${agenda.title} ${decision}`,\n voteSummary: {\n total: summary.total,\n approve: summary.approve,\n reject: summary.reject,\n conditional: summary.conditional,\n abstain: summary.abstain,\n },\n conditions: [],\n dissent: [],\n decidedBy: agenda.proposer,\n nextActions: [],\n });\n }\n\n /**\n * 안건 업데이트\n */\n updateAgenda(agendaId: AgendaId, updates: Partial<Omit<Agenda, \"id\" | \"createdAt\">>): Agenda {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // current 안건 확인\n if (decisions.current?.id === agendaId) {\n const updatedAgenda: Agenda = {\n ...decisions.current,\n ...updates,\n id: decisions.current.id, // ID 변경 불가\n createdAt: decisions.current.createdAt, // 생성 시간 변경 불가\n updatedAt: new Date(),\n version: decisions.current.version + 1,\n };\n\n this.board.write(\"decisions.current\", updatedAgenda);\n this.board.emit(\"agenda_updated\", { agendaId, agenda: updatedAgenda });\n return updatedAgenda;\n }\n\n // pending 안건 확인\n const pendingIndex = decisions.pending.findIndex((a) => a.id === agendaId);\n if (pendingIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const existingAgenda = decisions.pending[pendingIndex];\n const updatedAgenda: Agenda = {\n ...existingAgenda,\n ...updates,\n id: existingAgenda.id, // ID 변경 불가\n createdAt: existingAgenda.createdAt, // 생성 시간 변경 불가\n updatedAt: new Date(),\n version: existingAgenda.version + 1,\n };\n\n const updatedPending = [...decisions.pending];\n updatedPending[pendingIndex] = updatedAgenda;\n\n this.board.write(\"decisions.pending\", updatedPending);\n this.board.emit(\"agenda_updated\", { agendaId, agenda: updatedAgenda });\n return updatedAgenda;\n }\n\n // === 초기화 ===\n\n /**\n * 모든 결정 초기화\n */\n clearAll(): void {\n this.board.write(\"decisions.current\", null);\n this.board.write(\"decisions.pending\", []);\n this.board.write(\"decisions.opinions\", new Map());\n this.board.write(\"decisions.history\", []);\n this.board.emit(\"decisions_cleared\", {});\n }\n}\n","/**\n * @module snapshot/types\n * @description 스냅샷 타입 정의\n */\n\nimport type { SessionId } from \"../types\";\n\n/**\n * 스냅샷 형식 버전\n * @description 역직렬화 시 호환성 체크에 사용\n */\nexport const SNAPSHOT_FORMAT_VERSION = \"1.0.0\";\n\n/**\n * 스냅샷 메타데이터\n */\nexport interface SnapshotMeta {\n /** 스냅샷 ID */\n readonly id: string;\n /** 스냅샷 형식 버전 */\n readonly formatVersion: string;\n /** 생성 시간 */\n readonly createdAt: Date;\n /** 원본 세션 ID */\n readonly sessionId: SessionId;\n /** 원본 상태 버전 */\n readonly stateVersion: number;\n /** 스냅샷 설명 (선택) */\n readonly description?: string;\n /** 스냅샷 태그 (선택) */\n readonly tags?: string[];\n /** 체크섬 (무결성 검증용) */\n readonly checksum: string;\n /** 압축 데이터 체크섬 */\n readonly compressedChecksum?: string;\n /** 압축 여부 */\n readonly compressed: boolean;\n /** 원본 크기 (바이트) */\n readonly originalSize: number;\n /** 압축 크기 (바이트, 압축 시) */\n readonly compressedSize?: number;\n}\n\n/**\n * 직렬화된 상태\n * @description Map, Date 등이 JSON 호환 형식으로 변환됨\n */\nexport interface SerializedState {\n meta: {\n version: number;\n lastUpdated: string; // ISO 8601\n sessionId: string;\n createdAt: string;\n };\n state: {\n phase: string;\n context: Record<string, unknown>;\n agents: Array<[string, unknown]>; // Map<AgentId, AgentStatus> entries\n tasks: Array<[string, unknown]>; // Map<TaskId, Task> entries\n };\n knowledge: {\n facts: unknown[]; // Fact[]\n inferences: unknown[]; // Inference[]\n patterns: unknown[]; // Pattern[]\n };\n decisions: {\n current: unknown | null; // Agenda | null\n pending: unknown[]; // Agenda[]\n opinions: Array<[string, unknown]>; // Map<string, Opinion> entries\n history: unknown[]; // Resolution[]\n voting?: Record<string, unknown>; // VotingSession map\n };\n}\n\n/**\n * 전체 스냅샷 구조\n */\nexport interface Snapshot {\n /** 메타데이터 */\n meta: SnapshotMeta;\n /** 직렬화된 상태 데이터 */\n data: SerializedState | string; // string when compressed\n}\n\n/**\n * 스냅샷 생성 옵션\n */\nexport interface CreateSnapshotOptions {\n /** 스냅샷 설명 */\n description?: string;\n /** 태그 */\n tags?: string[];\n /** 압축 사용 여부 (기본: false) */\n compress?: boolean;\n /** 특정 섹션만 포함 */\n includeSections?: (\"state\" | \"knowledge\" | \"decisions\")[];\n /** 메타만 포함 (상태 제외) */\n metaOnly?: boolean;\n /** 내부 저장소에 저장 여부 */\n store?: boolean;\n}\n\n/**\n * 스냅샷 복원 옵션\n */\nexport interface RestoreSnapshotOptions {\n /** 버전 체크 건너뛰기 */\n skipVersionCheck?: boolean;\n /** 구조적 검증 건너뛰기 (validateSync) */\n skipStructuralValidation?: boolean;\n /** 검증 건너뛰기 (별칭: skipStructuralValidation) */\n skipValidation?: boolean;\n /** 특정 섹션만 복원 */\n restoreSections?: (\"state\" | \"knowledge\" | \"decisions\")[];\n /** 복원 후 버전 리셋 여부 (기본: true) */\n resetVersion?: boolean;\n /** 새 세션 ID 발급 (기본: true) */\n newSessionId?: boolean;\n}\n\n/**\n * 스냅샷 검증 결과\n */\nexport interface SnapshotValidationResult {\n /** 유효 여부 */\n valid: boolean;\n /** 에러 목록 */\n errors: SnapshotValidationError[];\n /** 경고 목록 */\n warnings: SnapshotValidationWarning[];\n}\n\n/**\n * 검증 에러\n */\nexport interface SnapshotValidationError {\n code:\n | \"VERSION_MISMATCH\"\n | \"CHECKSUM_INVALID\"\n | \"DATA_CORRUPTED\"\n | \"FORMAT_INVALID\"\n | \"MISSING_FIELD\";\n message: string;\n details?: unknown;\n}\n\n/**\n * 검증 경고\n */\nexport interface SnapshotValidationWarning {\n code: \"DEPRECATED_FORMAT\" | \"UNKNOWN_FIELDS\" | \"PARTIAL_DATA\";\n message: string;\n details?: unknown;\n}\n\n/**\n * 스냅샷 마이그레이션 인터페이스\n * @description 스냅샷 데이터 버전 간 마이그레이션을 위한 인터페이스\n */\nexport interface SnapshotMigration {\n /** 원본 버전 */\n fromVersion: number;\n /** 대상 버전 */\n toVersion: number;\n /** 마이그레이션 함수 */\n migrate(data: unknown): unknown;\n}\n","/**\n * @module snapshot/id-utils\n * @description ID 생성 유틸리티 (브라우저/Node.js 호환)\n */\n\n/**\n * 기본 ID 생성 함수\n * @returns 고유 ID 문자열\n * @description Node.js 환경에서는 crypto.randomUUID(), 브라우저 환경에서는 fallback 사용\n */\nexport function createDefaultId(): string {\n // Node.js 환경\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n\n // 브라우저 환경 fallback\n return `snap-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * ID 생성자 타입\n */\nexport type IdGenerator = () => string;\n\n/**\n * 기본 ID 생성자 생성\n * @param customGenerator - 사용자 정의 ID 생성 함수 (선택)\n * @returns ID 생성 함수\n */\nexport function createIdGenerator(\n customGenerator?: IdGenerator\n): IdGenerator {\n return customGenerator ?? createDefaultId;\n}\n","/**\n * @module snapshot/compression\n * @description 압축 유틸리티 (브라우저/Node.js 호환)\n */\n\nimport { gzip, ungzip, type InflateFunctionOptions } from 'pako';\n\n/**\n * 압축 알고리즘\n * @note brotli는 pako에서 지원하지 않음\n */\nexport type CompressionAlgorithm = 'gzip' | 'none';\n\n/**\n * 압축 레벨 (테스트 호환 타입)\n */\nexport type CompressionLevel = 'none' | 'fast' | 'balanced' | 'max';\n\n/**\n * 내부 pako 압축 레벨 숫자 타입\n */\ntype PakoCompressionLevel = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n\n/**\n * 압축 옵션\n */\nexport interface CompressionOptions {\n /** 알고리즘 (기본: 'gzip') */\n algorithm?: CompressionAlgorithm;\n /** 압축 레벨 (기본: 'balanced') */\n level?: CompressionLevel | PakoCompressionLevel;\n /** 출력 형식 (기본: 'base64') */\n outputFormat?: 'base64' | 'buffer' | 'uint8array';\n /** 메타데이터 포함 여부 */\n includeMetadata?: boolean;\n}\n\n/**\n * 압축 해제 옵션\n */\nexport interface DecompressionOptions {\n /** 압축 알고리즘 */\n algorithm?: CompressionAlgorithm;\n /** 입력 형식 (기본: 'base64') */\n inputFormat?: 'base64' | 'buffer' | 'uint8array';\n /** 유효성 검사 건너뛰기 (algorithm='none'인 경우 자동 true) */\n skipValidation?: boolean;\n}\n\n/**\n * 압축 메타데이터\n */\nexport interface CompressionMetadata {\n /** 원본 크기 */\n originalSize: number;\n /** 압축된 크기 */\n compressedSize: number;\n /** 사용된 알고리즘 */\n algorithm: CompressionAlgorithm;\n /** 사용된 압축 레벨 */\n level: CompressionLevel | PakoCompressionLevel;\n /** 타임스탬프 */\n timestamp: string;\n}\n\n/**\n * 메타데이터가 포함된 압축 결과\n */\nexport interface CompressedWithMeta {\n /** 압축된 데이터 */\n data: string;\n /** 메타데이터 */\n metadata: CompressionMetadata;\n}\n\n/**\n * 압축 통계\n */\nexport interface CompressionStats {\n /** 원본 크기 */\n originalSize: number;\n /** 압축된 크기 */\n compressedSize: number;\n /** 압축 비율 (originalSize / compressedSize) */\n ratio: number;\n /** 절감된 크기 (bytes) */\n savings: number;\n /** 절감 비율 (%) */\n savingsPercent: number;\n}\n\n/**\n * Pako 압축 해제 옵션 타입 정의\n */\ninterface PakoUngzipOptions extends InflateFunctionOptions {\n windowBits?: number;\n}\n\n/**\n * 문자열 압축 레벨을 pako 레벨로 변환\n */\nfunction normalizeCompressionLevel(\n level?: CompressionLevel | PakoCompressionLevel\n): PakoCompressionLevel {\n if (level === undefined || level === 'balanced') {\n return 6;\n }\n if (level === 'none') {\n return 0;\n }\n if (level === 'fast') {\n return 1;\n }\n if (level === 'max') {\n return 9;\n }\n // 이미 숫자인 경우 (PakoCompressionLevel)\n return level as PakoCompressionLevel;\n}\n\n/**\n * 문자열을 Uint8Array로 변환\n */\nfunction stringToUint8Array(str: string): Uint8Array {\n const encoder = new TextEncoder();\n return encoder.encode(str);\n}\n\n/**\n * Uint8Array를 문자열로 변환\n */\nfunction uint8ArrayToString(bytes: Uint8Array): string {\n const decoder = new TextDecoder();\n return decoder.decode(bytes);\n}\n\n/**\n * Uint8Array를 Base64로 변환\n */\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n // Node.js 환경에서는 Buffer가 더 효율적\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64');\n }\n // 브라우저 환경\n let binary = '';\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Base64를 Uint8Array로 변환\n */\nfunction base64ToUint8Array(base64: string): Uint8Array {\n // Node.js 환경\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(base64, 'base64'));\n }\n // 브라우저 환경\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * 입력 데이터를 Uint8Array로 변환\n */\nfunction inputToUint8Array(data: string | Uint8Array | Buffer): Uint8Array {\n if (typeof data === 'string') {\n return stringToUint8Array(data);\n }\n if (data instanceof Uint8Array) {\n return data;\n }\n if (Buffer.isBuffer(data)) {\n return new Uint8Array(data);\n }\n throw new Error(`Unsupported input type: ${typeof data}`);\n}\n\n/**\n * 출력 데이터 변환\n */\nfunction formatOutput(\n data: Uint8Array,\n format: 'base64' | 'buffer' | 'uint8array'\n): string | Uint8Array | Buffer {\n if (format === 'base64') {\n return uint8ArrayToBase64(data);\n }\n if (format === 'buffer' && typeof Buffer !== 'undefined') {\n return Buffer.from(data);\n }\n return data;\n}\n\n/**\n * 입력 데이터를 Uint8Array로 변환 (decompression용)\n */\nfunction inputToUint8ArrayForDecompress(\n data: string | Uint8Array | Buffer,\n format?: 'base64' | 'buffer' | 'uint8array'\n): Uint8Array {\n // format이 지정된 경우 해당 형식으로 처리\n if (format === 'base64' && typeof data === 'string') {\n return base64ToUint8Array(data);\n }\n if (format === 'buffer' && Buffer.isBuffer(data)) {\n return new Uint8Array(data);\n }\n if (format === 'uint8array' && data instanceof Uint8Array) {\n return data;\n }\n\n // format이 지정되지 않은 경우 자동 감지\n if (typeof data === 'string') {\n // string이면 base64로 처리 (gzip 압축된 데이터는 항상 base64 인코딩됨)\n try {\n return base64ToUint8Array(data);\n } catch {\n // base64 디코딩 실패시 일반 문자열로 처리\n return stringToUint8Array(data);\n }\n }\n\n return inputToUint8Array(data);\n}\n\n/**\n * 체크섬 계산 (간단한 해시)\n */\nfunction calculateChecksum(data: string): string {\n let hash = 0;\n for (let i = 0; i < data.length; i++) {\n const char = data.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(16);\n}\n\n/**\n * 데이터 압축\n * @param data - 압축할 데이터 (string | Uint8Array | Buffer)\n * @param options - 압축 옵션\n * @returns 압축된 데이터 (string | Uint8Array | Buffer)\n */\nexport function compress(\n data: string | Uint8Array | Buffer,\n options?: CompressionOptions\n): string | Uint8Array | Buffer {\n // 빈 데이터 처리 - 빈 문자열은 허용\n if (data === null || data === undefined) {\n throw new Error('compress(): input data must not be null or undefined');\n }\n\n const algorithm = options?.algorithm ?? 'gzip';\n const outputFormat = options?.outputFormat ?? 'base64';\n const level = options?.level ?? 'balanced';\n\n // level: 'none'인 경우 압축하지 않음 - 원본 타입 유지\n if (level === 'none' || algorithm === 'none') {\n if (typeof data === 'string') {\n return data;\n }\n if (Buffer.isBuffer(data)) {\n return data;\n }\n if (data instanceof Uint8Array) {\n return data;\n }\n return data;\n }\n\n try {\n const input = inputToUint8Array(data);\n const normalizedLevel = normalizeCompressionLevel(level);\n\n // pako gzip 압축 옵션 (동기)\n const compressed = gzip(input, { level: normalizedLevel });\n\n // 원본 타입에 따라 반환 형식 결정 (outputFormat이 명시된 경우 제외)\n if (options?.outputFormat) {\n return formatOutput(compressed, outputFormat);\n }\n if (typeof data === 'string') {\n return uint8ArrayToBase64(compressed);\n }\n if (Buffer.isBuffer(data) && typeof Buffer !== 'undefined') {\n return Buffer.from(compressed);\n }\n return compressed;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`Failed to compress data: ${msg}`);\n }\n}\n\n/**\n * 데이터 압축 해제\n * @param compressed - 압축된 데이터\n * @param options - 압축 해제 옵션\n * @returns 원본 데이터\n * @throws {Error} 데이터 크기 제한 초과 시\n */\nexport function decompress(\n compressed: string | Uint8Array | Buffer,\n options?: DecompressionOptions\n): string | Uint8Array | Buffer {\n // 빈 데이터 처리\n if (compressed === null || compressed === undefined) {\n throw new Error('decompress(): input data must not be null or undefined');\n }\n\n const algorithm = options?.algorithm ?? 'gzip';\n const skipValidation = options?.skipValidation ?? false;\n\n // 빈 데이터 처리 (압축하지 않은 경우)\n if (\n (typeof compressed === 'string' && compressed === '') ||\n (Buffer.isBuffer(compressed) && compressed.length === 0) ||\n (compressed instanceof Uint8Array && compressed.length === 0)\n ) {\n return compressed;\n }\n\n // algorithm이 'none'인 경우 또는 skipValidation이 true인 경우\n if (algorithm === 'none' || skipValidation) {\n if (typeof compressed === 'string') {\n return compressed;\n }\n if (Buffer.isBuffer(compressed)) {\n return compressed;\n }\n return compressed;\n }\n\n try {\n const buffer = inputToUint8ArrayForDecompress(compressed, options?.inputFormat);\n\n // gzip 헤더 확인\n if (buffer.length >= 2) {\n if (!(buffer[0] === 0x1f && buffer[1] === 0x8b)) {\n // string 입력이고 gzip 헤더가 없으면 원본 반환 (level: 'none'으로 압축된 경우)\n if (typeof compressed === 'string') {\n return compressed;\n }\n // Buffer/Uint8Array 입력이고 gzip 헤더가 없으면 에러\n throw new Error('Invalid gzip header: data does not appear to be gzip-compressed');\n }\n }\n\n // pako gzip 압축 해제 옵션 (동기)\n const ungzipOptions: PakoUngzipOptions = {};\n const decompressed = ungzip(buffer, ungzipOptions);\n\n // 원본 타입에 따라 반환\n if (typeof compressed === 'string') {\n return uint8ArrayToString(decompressed);\n }\n if (Buffer.isBuffer(compressed) && typeof Buffer !== 'undefined') {\n return Buffer.from(decompressed);\n }\n return decompressed;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`Failed to decompress data: ${msg}`);\n }\n}\n\n/**\n * 압축 여부 감지\n * @param data - 검사할 데이터\n * @returns 압축 알고리즘 또는 null\n */\nexport function detectCompression(data: string): CompressionAlgorithm | null {\n // Base64 디코딩 시도\n try {\n const buffer = base64ToUint8Array(data);\n\n // 최소 2바이트 필요\n if (buffer.length < 2) {\n return null;\n }\n\n // Gzip magic number: 0x1f 0x8b\n if (buffer[0] === 0x1f && buffer[1] === 0x8b) {\n return 'gzip';\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * 체크섬 계산 (비동기)\n */\nexport async function calculateChecksumAsync(data: string): Promise<string> {\n return calculateChecksum(data);\n}\n\n/**\n * 체크섬 검증\n */\nexport async function verifyChecksum(\n data: string,\n expectedChecksum: string\n): Promise<boolean> {\n const checksum = await calculateChecksumAsync(data);\n return checksum === expectedChecksum;\n}\n\n/**\n * Compressor 클래스 - 상태 저장형 압축\n */\nexport class Compressor {\n private options: CompressionOptions;\n private history: CompressionStats[] = [];\n\n constructor(options?: CompressionOptions) {\n this.options = {\n algorithm: options?.algorithm ?? 'gzip',\n level: options?.level ?? 'balanced',\n outputFormat: options?.outputFormat ?? 'base64',\n includeMetadata: options?.includeMetadata ?? false,\n };\n }\n\n /**\n * 데이터 압축\n */\n compress(data: string | Uint8Array | Buffer): Uint8Array {\n const bytes = inputToUint8Array(data);\n const level = normalizeCompressionLevel(this.options.level);\n\n if (this.options.algorithm === 'none') {\n return bytes;\n }\n\n const compressed = gzip(bytes, { level });\n\n // 통계 기록\n const stats = this.calculateStatsInternal(bytes.length, compressed.length);\n this.history.push(stats);\n\n return compressed;\n }\n\n /**\n * 데이터 압축 해제\n */\n decompress(data: Uint8Array): string {\n if (this.options.algorithm === 'none') {\n return uint8ArrayToString(data);\n }\n\n const decompressed = ungzip(data);\n return uint8ArrayToString(decompressed);\n }\n\n /**\n * 비동기 압축\n */\n async compressAsync(data: string | Uint8Array | Buffer): Promise<Uint8Array> {\n return this.compress(data);\n }\n\n /**\n * 비동기 압축 해제\n */\n async decompressAsync(data: Uint8Array): Promise<string> {\n return this.decompress(data);\n }\n\n /**\n * 압축 비율 계산\n */\n ratio(originalSize: number, compressedSize: number): number {\n if (compressedSize === 0) {\n return originalSize === 0 ? 1 : Infinity;\n }\n return originalSize / compressedSize;\n }\n\n /**\n * 압축 통계 계산\n */\n stats(originalSize: number, compressedSize: number): CompressionStats {\n return this.calculateStatsInternal(originalSize, compressedSize);\n }\n\n /**\n * 내부 통계 계산\n */\n private calculateStatsInternal(\n originalSize: number,\n compressedSize: number\n ): CompressionStats {\n const ratio = this.ratio(originalSize, compressedSize);\n const savings = originalSize - compressedSize;\n const savingsPercent = originalSize > 0 ? (savings / originalSize) * 100 : 0;\n\n return {\n originalSize,\n compressedSize,\n ratio,\n savings,\n savingsPercent,\n };\n }\n\n /**\n * 메타데이터 포함 압축\n */\n compressWithMeta(data: string | Uint8Array | Buffer): CompressedWithMeta {\n const bytes = inputToUint8Array(data);\n const compressed = this.compress(bytes);\n\n const metadata: CompressionMetadata = {\n originalSize: bytes.length,\n compressedSize: compressed.length,\n algorithm: this.options.algorithm ?? 'gzip',\n level: this.options.level ?? 'balanced',\n timestamp: new Date().toISOString(),\n };\n\n // 메타데이터와 데이터를 결합하여 base64로 변환\n const metaJson = JSON.stringify(metadata);\n const metaBytes = stringToUint8Array(metaJson);\n\n // 포맷: [metaLength(4 bytes)][metadata][compressed data]\n const combined = new Uint8Array(4 + metaBytes.length + compressed.length);\n const view = new DataView(combined.buffer);\n\n view.setUint32(0, metaBytes.length, false); // big endian\n combined.set(metaBytes, 4);\n combined.set(compressed, 4 + metaBytes.length);\n\n return {\n data: uint8ArrayToBase64(combined),\n metadata,\n };\n }\n\n /**\n * 메타데이터 포함 압축 해제\n */\n decompressWithMeta(compressed: CompressedWithMeta | string): string {\n let base64Data: string;\n\n if (typeof compressed === 'string') {\n base64Data = compressed;\n } else {\n base64Data = compressed.data;\n }\n\n const combined = base64ToUint8Array(base64Data);\n const view = new DataView(combined.buffer);\n\n const metaLength = view.getUint32(0, false);\n const metaBytes = combined.slice(4, 4 + metaLength);\n const compressedData = combined.slice(4 + metaLength);\n\n // 메타데이터 파싱 (검증용)\n try {\n const metaJson = uint8ArrayToString(metaBytes);\n JSON.parse(metaJson);\n } catch {\n // 메타데이터 파싱 실패 시 무시하고 계속 진행\n }\n\n // 압축 해제\n return this.decompress(compressedData);\n }\n\n /**\n * 기록된 압축 통계 가져오기\n */\n getHistory(): CompressionStats[] {\n return [...this.history];\n }\n\n /**\n * 기록된 통계 지우기\n */\n clearHistory(): void {\n this.history = [];\n }\n\n /**\n * 옵션 업데이트\n */\n setOptions(options: Partial<CompressionOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * 현재 옵션 가져오기\n */\n getOptions(): CompressionOptions {\n return { ...this.options };\n }\n}\n","/**\n * @module snapshot/type-guards\n * @description 타입 가드 함수들 (중복 제거)\n */\n\nimport type { SerializedState } from './types';\n\n/**\n * 타입 가드: SerializedState 여부 확인\n * @description P1: 검증 범위 확대 - state/knowledge/decisions 필드 검증 추가\n * @param value - 확인할 값\n * @returns SerializedState 타입 여부\n */\nexport function isSerializedState(value: unknown): value is SerializedState {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Partial<SerializedState>;\n\n // meta 필드 필수 확인\n if (!obj.meta || typeof obj.meta !== 'object') {\n return false;\n }\n\n // meta의 필수 필드 확인\n const meta = obj.meta;\n if (!meta.sessionId || typeof meta.sessionId !== 'string') {\n return false;\n }\n if (typeof meta.version !== 'number') {\n return false;\n }\n\n // P1: state 섹션 필드 검증\n if (!obj.state || typeof obj.state !== 'object') {\n return false;\n }\n const state = obj.state;\n if (typeof state.phase !== 'string') {\n return false;\n }\n if (!state.context || typeof state.context !== 'object') {\n return false;\n }\n if (!Array.isArray(state.agents)) {\n return false;\n }\n if (!Array.isArray(state.tasks)) {\n return false;\n }\n\n // P1: knowledge 섹션 필드 검증\n if (!obj.knowledge || typeof obj.knowledge !== 'object') {\n return false;\n }\n const knowledge = obj.knowledge;\n if (!Array.isArray(knowledge.facts)) {\n return false;\n }\n if (!Array.isArray(knowledge.inferences)) {\n return false;\n }\n if (!Array.isArray(knowledge.patterns)) {\n return false;\n }\n\n // P1: decisions 섹션 필드 검증\n if (!obj.decisions || typeof obj.decisions !== 'object') {\n return false;\n }\n const decisions = obj.decisions;\n if (!Array.isArray(decisions.pending)) {\n return false;\n }\n if (!Array.isArray(decisions.opinions)) {\n return false;\n }\n if (!Array.isArray(decisions.history)) {\n return false;\n }\n\n return true;\n}\n","/**\n * @module snapshot/utils\n * @description 유틸리티 함수들 (중복 제거)\n */\n\nimport type { Snapshot, SerializedState } from \"./types\";\nimport { decompress, detectCompression } from \"./compression\";\nimport { isSerializedState } from \"./type-guards\";\n\n/**\n * JSON.stringify replacer for key sorting\n * @param key - Property key\n * @param value - Property value\n * @returns Value with sorted keys for objects\n */\nexport function sortedKeyReplacer(key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && !Array.isArray(value) && !(value instanceof Date)) {\n const sortedObj: Record<string, unknown> = {};\n Object.keys(value as Record<string, unknown>)\n .sort()\n .forEach((k) => {\n sortedObj[k] = (value as Record<string, unknown>)[k];\n });\n return sortedObj;\n }\n return value;\n}\n\n/**\n * 스냅샷 데이터 압축 해제 (공통 헬퍼)\n * @description P0: decompressData 로직 중복 제거를 위한 공통 함수\n * @param snapshot - 스냅샷\n * @returns 역직렬화된 상태 데이터\n * @throws {Error} 압축 해제 실패 또는 타입 불일치 시\n */\nexport function decompressSnapshotData(snapshot: Snapshot): SerializedState {\n if (!snapshot.meta.compressed) {\n if (!isSerializedState(snapshot.data)) {\n throw new Error(\"Invalid snapshot data: not a SerializedState\");\n }\n return snapshot.data;\n }\n\n if (typeof snapshot.data !== \"string\") {\n throw new Error(\"Invalid compressed data: expected string\");\n }\n\n const algorithm = detectCompression(snapshot.data) ?? \"gzip\";\n const json = decompress(snapshot.data, { algorithm }) as string;\n const parsed = JSON.parse(json);\n\n if (!isSerializedState(parsed)) {\n throw new Error(\"Invalid snapshot data: deserialized data is not a SerializedState\");\n }\n\n return parsed;\n}\n","/**\n * @module snapshot/serializer\n * @description 직렬화/역직렬화 (브라우저/Node.js 호환)\n */\n\nimport type {\n BlackboardState,\n AgentId,\n TaskId,\n SessionId,\n Fact,\n Inference,\n Pattern,\n Agenda,\n Opinion,\n Resolution,\n AgentStatus,\n Task,\n BoardPhase,\n VotingSession,\n} from \"../types\";\nimport type { SerializedState } from \"./types\";\nimport { sortedKeyReplacer } from \"./utils\";\n\n/**\n * 직렬화 옵션\n */\nexport interface SerializeOptions {\n /** 날짜 형식 (기본: 'iso') */\n dateFormat?: \"iso\" | \"timestamp\";\n /** 정렬된 키 (재현 가능한 출력용) */\n sortKeys?: boolean;\n /** 들여쓰기 (기본: 0 = 압축) */\n indent?: number;\n}\n\n/**\n * 섹션 데이터 유효성 검증 결과\n */\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Fact 구조 검증\n */\nfunction validateFactArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"facts must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`facts[${i}]: must be an object`);\n continue;\n }\n\n const fact = item as Record<string, unknown>;\n\n if (typeof fact.id !== \"string\") {\n errors.push(`facts[${i}].id: must be a string`);\n }\n\n if (typeof fact.content !== \"string\") {\n errors.push(`facts[${i}].content: must be a string`);\n }\n\n if (typeof fact.confidence !== \"number\" || fact.confidence < 0 || fact.confidence > 1) {\n errors.push(`facts[${i}].confidence: must be a number between 0 and 1`);\n }\n\n // createdAt은 문자열(ISO) 또는 Date 객체 허용\n if (typeof fact.createdAt !== \"string\" && !(fact.createdAt instanceof Date)) {\n errors.push(`facts[${i}].createdAt: must be a string or Date`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Inference 구조 검증\n */\nfunction validateInferenceArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"inferences must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`inferences[${i}]: must be an object`);\n continue;\n }\n\n const inference = item as Record<string, unknown>;\n\n if (typeof inference.id !== \"string\") {\n errors.push(`inferences[${i}].id: must be a string`);\n }\n\n if (typeof inference.conclusion !== \"string\") {\n errors.push(`inferences[${i}].conclusion: must be a string`);\n }\n\n if (\n typeof inference.confidence !== \"number\" ||\n inference.confidence < 0 ||\n inference.confidence > 1\n ) {\n errors.push(`inferences[${i}].confidence: must be a number between 0 and 1`);\n }\n\n // createdAt은 선택적 (문자열 또는 Date 객체)\n if (\n inference.createdAt !== undefined &&\n typeof inference.createdAt !== \"string\" &&\n !(inference.createdAt instanceof Date)\n ) {\n errors.push(`inferences[${i}].createdAt: must be a string, Date, or undefined`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Pattern 구조 검증\n */\nfunction validatePatternArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"patterns must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`patterns[${i}]: must be an object`);\n continue;\n }\n\n const pattern = item as Record<string, unknown>;\n\n if (typeof pattern.id !== \"string\") {\n errors.push(`patterns[${i}].id: must be a string`);\n }\n\n if (typeof pattern.name !== \"string\") {\n errors.push(`patterns[${i}].name: must be a string`);\n }\n\n // createdAt은 선택적 (문자열 또는 Date 객체)\n if (\n pattern.createdAt !== undefined &&\n typeof pattern.createdAt !== \"string\" &&\n !(pattern.createdAt instanceof Date)\n ) {\n errors.push(`patterns[${i}].createdAt: must be a string, Date, or undefined`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Resolution 구조 검증\n */\nfunction validateResolutionArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"history must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`history[${i}]: must be an object`);\n continue;\n }\n\n const resolution = item as Record<string, unknown>;\n\n if (typeof resolution.agendaId !== \"string\") {\n errors.push(`history[${i}].agendaId: must be a string`);\n }\n\n if (typeof resolution.decision !== \"string\") {\n errors.push(`history[${i}].decision: must be a string`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Agenda 구조 검증\n */\nfunction validateAgenda(value: unknown, fieldName: string): ValidationResult {\n const errors: string[] = [];\n\n if (value === null) {\n return { valid: true, errors };\n }\n\n if (!value || typeof value !== \"object\") {\n return { valid: false, errors: [`${fieldName}: must be an object or null`] };\n }\n\n const agenda = value as Record<string, unknown>;\n\n if (typeof agenda.id !== \"string\") {\n errors.push(`${fieldName}.id: must be a string`);\n }\n\n if (typeof agenda.title !== \"string\") {\n errors.push(`${fieldName}.title: must be a string`);\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * 상태 직렬화기\n * @description Map, Date 등을 JSON 호환 형식으로 변환\n */\nexport class StateSerializer {\n constructor(private options: SerializeOptions = {}) {}\n\n /**\n * BlackboardState → SerializedState\n * @param state - 원본 상태\n * @returns 직렬화된 상태\n */\n serialize(state: BlackboardState): SerializedState {\n return {\n meta: {\n version: state.meta.version,\n lastUpdated: this.serializeDate(state.meta.lastUpdated),\n sessionId: state.meta.sessionId,\n createdAt: this.serializeDate(state.meta.createdAt),\n },\n state: {\n phase: state.state.phase,\n context: state.state.context,\n agents: this.serializeMap(state.state.agents),\n tasks: this.serializeMap(state.state.tasks),\n },\n knowledge: {\n facts: state.knowledge.facts,\n inferences: state.knowledge.inferences,\n patterns: state.knowledge.patterns,\n },\n decisions: {\n current: state.decisions.current,\n pending: state.decisions.pending,\n opinions: this.serializeMap(state.decisions.opinions),\n history: state.decisions.history,\n voting: state.decisions.voting,\n },\n };\n }\n\n /**\n * 임의의 객체를 JSON 문자열로 직렬화\n * @param obj - 직렬화할 객체\n * @returns JSON 문자열\n * @description Date, Map, Set 등을 포함한 일반 객체 직렬화\n */\n serializeJSON(obj: unknown): string {\n const indent = this.options.indent ?? 0;\n const replacer = this.options.sortKeys\n ? (sortedKeyReplacer as (key: string, value: unknown) => unknown)\n : undefined;\n\n // JSON.stringify 직렬화\n return JSON.stringify(obj, replacer, indent);\n }\n\n /**\n * JSON 문자열을 객체로 역직렬화\n * @param json - JSON 문자열\n * @returns 역직렬화된 객체\n * @throws {Error} JSON 파싱 실패 시\n * @description JSON.parse를 사용한 기본 역직렬화\n */\n deserializeJSON<T = unknown>(json: string): T {\n try {\n return JSON.parse(json) as T;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Invalid JSON: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * SerializedState → BlackboardState\n * @param serialized - 직렬화된 상태\n * @returns 복원된 상태\n */\n deserialize(serialized: SerializedState): BlackboardState {\n // 구조 검증 (P1: 입력 검증 강화)\n if (!serialized || typeof serialized !== \"object\") {\n throw new Error(\"Invalid serialized state: must be an object\");\n }\n\n // 필수 필드 검증\n const requiredSections = [\"meta\", \"state\", \"knowledge\", \"decisions\"] as const;\n for (const section of requiredSections) {\n if (!serialized[section]) {\n throw new Error(`Invalid serialized state: missing section '${section}'`);\n }\n }\n\n // P1: 런타임 타입 검증 - facts\n const factsValidation = validateFactArray(serialized.knowledge.facts);\n if (!factsValidation.valid) {\n throw new Error(`Invalid facts data: ${factsValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - inferences\n const inferencesValidation = validateInferenceArray(serialized.knowledge.inferences);\n if (!inferencesValidation.valid) {\n throw new Error(`Invalid inferences data: ${inferencesValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - patterns\n const patternsValidation = validatePatternArray(serialized.knowledge.patterns);\n if (!patternsValidation.valid) {\n throw new Error(`Invalid patterns data: ${patternsValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - current\n const currentValidation = validateAgenda(serialized.decisions.current, \"decisions.current\");\n if (!currentValidation.valid) {\n throw new Error(`Invalid current agenda: ${currentValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - pending\n if (!Array.isArray(serialized.decisions.pending)) {\n throw new Error(\"Invalid pending agendas: must be an array\");\n }\n for (let i = 0; i < serialized.decisions.pending.length; i++) {\n const pendingValidation = validateAgenda(\n serialized.decisions.pending[i],\n `decisions.pending[${i}]`\n );\n if (!pendingValidation.valid) {\n throw new Error(\n `Invalid pending agenda at index ${i}: ${pendingValidation.errors.join(\", \")}`\n );\n }\n }\n\n // P1: 런타임 타입 검증 - history\n const historyValidation = validateResolutionArray(serialized.decisions.history);\n if (!historyValidation.valid) {\n throw new Error(`Invalid history data: ${historyValidation.errors.join(\", \")}`);\n }\n\n // 런타임 검증 완료 후 타입 어서션 사용 (TypeScript는 런타임 검증을 이해하지 못함)\n return {\n meta: {\n version: serialized.meta.version,\n lastUpdated: this.deserializeDate(serialized.meta.lastUpdated),\n sessionId: this.restoreIds<SessionId>(serialized.meta.sessionId),\n createdAt: this.deserializeDate(serialized.meta.createdAt),\n },\n state: {\n phase: serialized.state.phase as BoardPhase,\n context: serialized.state.context,\n agents: this.deserializeMap(serialized.state.agents as Array<[AgentId, AgentStatus]>),\n tasks: this.deserializeMap(serialized.state.tasks as Array<[TaskId, Task]>),\n },\n knowledge: {\n facts: serialized.knowledge.facts as Fact[],\n inferences: serialized.knowledge.inferences as Inference[],\n patterns: serialized.knowledge.patterns as Pattern[],\n },\n decisions: {\n current: serialized.decisions.current as Agenda | null,\n pending: serialized.decisions.pending as Agenda[],\n opinions: this.deserializeMap(serialized.decisions.opinions as Array<[string, Opinion]>),\n history: serialized.decisions.history as Resolution[],\n voting: (serialized.decisions.voting ?? {}) as Record<string, VotingSession>,\n },\n };\n }\n\n /**\n * JSON 문자열로 변환\n * @param state - 원본 상태\n * @returns JSON 문자열\n */\n toJSON(state: BlackboardState): string {\n const serialized = this.serialize(state);\n const indent = this.options.indent ?? 0;\n\n // P1: sortKeys 옵션 구현\n // Note: JSON.stringify는 null을 허용하지 않으므로 조건부 처리\n if (this.options.sortKeys) {\n return JSON.stringify(\n serialized,\n sortedKeyReplacer as (key: string, value: unknown) => unknown,\n indent\n );\n }\n return JSON.stringify(serialized, null, indent);\n }\n\n /**\n * JSON 문자열에서 복원\n * @param json - JSON 문자열\n * @returns 복원된 상태\n * @throws {Error} JSON 파싱 실패 시 명확한 에러 메시지 (P1: JSON.parse 에러 처리)\n */\n fromJSON(json: string): BlackboardState {\n try {\n const parsed = JSON.parse(json) as SerializedState | null | undefined;\n // P1: null/undefined 검증 추가 (parsed.meta 접근 전)\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Invalid serialized state: parsed data is null or undefined\");\n }\n return this.deserialize(parsed);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Invalid JSON in serialized state: ${error.message}`);\n }\n throw error;\n }\n }\n\n // === 내부 헬퍼 ===\n\n /**\n * Map → Array 변환\n */\n private serializeMap<K extends string, V>(map: Map<K, V>): Array<[K, V]> {\n return Array.from(map.entries());\n }\n\n /**\n * Array → Map 변환\n */\n private deserializeMap<K extends string, V>(entries: Array<[K, V]>): Map<K, V> {\n // P1: 입력 검증 강화\n if (!Array.isArray(entries)) {\n throw new Error(`Invalid map data: expected array, got ${typeof entries}`);\n }\n // 브랜드 타입으로 인한 타입 어서션 필요 (런타임 문자열 → 브랜드 타입)\n return new Map(entries) as Map<K, V>;\n }\n\n /**\n * Date → string 변환\n */\n private serializeDate(date: Date): string {\n if (this.options.dateFormat === \"timestamp\") {\n return date.getTime().toString();\n }\n return date.toISOString();\n }\n\n /**\n * string → Date 변환\n */\n private deserializeDate(str: string): Date {\n // P1: 입력 검증 강화\n if (typeof str !== \"string\") {\n throw new Error(`Invalid date value: expected string, got ${typeof str}`);\n }\n\n // P1: 빈 문자열 입력 검증 추가\n if (!str || str.trim() === \"\") {\n throw new Error(\"Invalid date value: string must not be empty or whitespace-only\");\n }\n\n const asNum = Number(str);\n if (!isNaN(asNum) && asNum > 1000000000) {\n return new Date(asNum);\n }\n const date = new Date(str);\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date value: \"${str}\"`);\n }\n return date;\n }\n\n /**\n * Branded ID 복원\n * @param obj - 원본 ID 값 (일반적으로 문자열)\n * @returns 브랜드 타입으로 캐스팅된 ID\n * @description 문자열 타입 안전성 검증 후 반환\n */\n private restoreIds<T extends string>(obj: unknown): T {\n if (typeof obj !== \"string\") {\n throw new TypeError(`Expected string ID, got ${typeof obj}`);\n }\n return obj as T;\n }\n}\n\n/**\n * Node.js crypto 모듈 fallback (WebCrypto 없는 환경)\n */\nasync function calculateChecksumNodeJS(data: string): Promise<string> {\n // P0: Node.js require → ESM import 변경\n if (typeof process === \"object\") {\n try {\n // Dynamic import for Node.js crypto module (ESM compatible)\n const { createHash } = await import(\"crypto\");\n return createHash(\"sha256\").update(data).digest(\"hex\");\n } catch {\n // Import 실패 시 fallback\n }\n }\n throw new Error(\n \"No crypto implementation available. Please use a browser environment or Node.js with crypto support.\"\n );\n}\n\n/**\n * Web Crypto API를 사용한 체크섬 계산 (비동기)\n * @param data - 대상 데이터\n * @returns SHA-256 해시\n */\nexport async function calculateChecksum(data: unknown): Promise<string> {\n let str: string;\n if (typeof data === \"string\") {\n str = data;\n } else {\n // 순서 독립적 체크섬 계산을 위해 키 정렬\n str = JSON.stringify(data, sortedKeyReplacer as (key: string, value: unknown) => unknown);\n }\n const encoder = new TextEncoder();\n const bytes = encoder.encode(str);\n\n // P1: crypto.subtle fallback - Web Crypto API 우선, Node.js fallback\n if (typeof crypto !== \"undefined\" && typeof crypto.subtle !== \"undefined\") {\n // Web Crypto API 사용 (브라우저/Node.js 호환)\n try {\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", bytes);\n\n // ArrayBuffer → hex string 변환\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\n return hashHex;\n } catch {\n // Web Crypto 실패 시 Node.js fallback 시도\n return calculateChecksumNodeJS(str);\n }\n } else {\n // Web Crypto 없는 환경에서 Node.js fallback\n return calculateChecksumNodeJS(str);\n }\n}\n\n/**\n * Web Crypto API를 사용한 체크섬 검증 (비동기)\n * @param data - 대상 데이터\n * @param expectedChecksum - 예상 체크섬\n * @returns 일치 여부\n */\nexport async function verifyChecksum(data: unknown, expectedChecksum: string): Promise<boolean> {\n const actualChecksum = await calculateChecksum(data);\n return actualChecksum === expectedChecksum;\n}\n\n/**\n * 동기 체크섬 계산 (Node.js 전용)\n * @param data - 대상 데이터\n * @returns SHA-256 해시\n * @description 테스트 환경 등에서 동기 체크섬이 필요한 경우 사용\n */\nexport function calculateChecksumSync(data: unknown): string {\n let str: string;\n if (typeof data === \"string\") {\n str = data;\n } else {\n // 순서 독립적 체크섬 계산을 위해 키 정렬\n str = JSON.stringify(data, sortedKeyReplacer as (key: string, value: unknown) => unknown);\n }\n\n // Node.js 환경에서 동기 해싱\n if (typeof process === \"object\") {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { createHash } = require(\"crypto\");\n return createHash(\"sha256\").update(str).digest(\"hex\");\n } catch {\n throw new Error(\n \"Failed to calculate checksum synchronously. Ensure Node.js crypto module is available.\"\n );\n }\n }\n\n throw new Error(\"Synchronous checksum calculation is only supported in Node.js environments.\");\n}\n\n/**\n * 동기 체크섬 검증 (Node.js 전용)\n * @param data - 대상 데이터\n * @param expectedChecksum - 예상 체크섬\n * @returns 일치 여부\n * @description 테스트 환경 등에서 동기 체크섬이 필요한 경우 사용\n */\nexport function verifyChecksumSync(data: unknown, expectedChecksum: string): boolean {\n const actualChecksum = calculateChecksumSync(data);\n return actualChecksum === expectedChecksum;\n}\n","/**\n * @module snapshot/snapshot-creator\n * @description 스냅샷 생성 담당\n */\n\nimport type { BlackboardState } from \"../types\";\nimport type { Snapshot, SnapshotMeta, CreateSnapshotOptions, SerializedState } from \"./types\";\nimport { StateSerializer, calculateChecksumSync } from \"./serializer\";\nimport { compress } from \"./compression\";\nimport { SNAPSHOT_FORMAT_VERSION } from \"./types\";\nimport { createIdGenerator, type IdGenerator } from \"./id-utils\";\n\n/**\n * 스냅샷 생성자 설정\n */\nexport interface SnapshotCreatorOptions {\n /** 자동 압축 임계값 (바이트, 기본: 10KB) */\n autoCompressThreshold?: number;\n /** 기본 압축 사용 */\n defaultCompress?: boolean;\n /** ID 생성 함수 */\n idGenerator?: IdGenerator;\n}\n\n/**\n * 스냅샷 생성자\n * @description 스냅샷 생성 전담 클래스\n */\nexport class SnapshotCreator {\n private serializer: StateSerializer;\n private options: Required<SnapshotCreatorOptions>;\n\n constructor(options: SnapshotCreatorOptions = {}) {\n this.options = this.normalizeOptions(options);\n this.serializer = new StateSerializer({ sortKeys: true });\n }\n\n /**\n * 옵션 정규화\n */\n private normalizeOptions(options: SnapshotCreatorOptions): Required<SnapshotCreatorOptions> {\n return {\n autoCompressThreshold: options.autoCompressThreshold ?? 10_240, // 10KB\n defaultCompress: options.defaultCompress ?? false,\n idGenerator: createIdGenerator(options.idGenerator),\n };\n }\n\n /**\n * ID 생성자 가져오기\n */\n getIdGenerator(): IdGenerator {\n return this.options.idGenerator;\n }\n\n /**\n * 스냅샷 생성 (동기)\n * @param state - 현재 Blackboard 상태\n * @param options - 생성 옵션\n * @returns 스냅샷\n */\n createSnapshot(state: BlackboardState, options?: CreateSnapshotOptions): Snapshot {\n const serialized = this.serializer.serialize(state);\n const metaOnly = options?.metaOnly ?? false;\n\n // P1: 섹션 필터링 타입 안전성 개선 - 명시적 구조 사용\n let stateData: SerializedState = serialized;\n\n if (options?.includeSections) {\n const sections = options.includeSections;\n // 명시적 구조로 타입 안전성 확보\n const filteredState: SerializedState = {\n meta: serialized.meta,\n state: sections.includes(\"state\")\n ? serialized.state\n : {\n phase: serialized.state.phase,\n context: serialized.state.context,\n agents: [],\n tasks: [],\n },\n knowledge: sections.includes(\"knowledge\")\n ? serialized.knowledge\n : {\n facts: [],\n inferences: [],\n patterns: [],\n },\n decisions: sections.includes(\"decisions\")\n ? serialized.decisions\n : {\n current: null,\n pending: [],\n opinions: [],\n history: [],\n },\n };\n stateData = filteredState;\n }\n\n // 압축 결정\n const shouldCompress = options?.compress ?? this.options.defaultCompress;\n const threshold = this.options.autoCompressThreshold;\n const originalSize = JSON.stringify(stateData, null, 0).length;\n const autoCompress = shouldCompress || originalSize >= threshold;\n\n let data: SerializedState | string;\n let compressedSize: number | undefined;\n let compressedChecksum: string | undefined;\n const compressed = autoCompress && !metaOnly;\n\n // 체크섬 계산 (metaOnly 모드에서는 빈 객체 기준)\n let checksum: string;\n try {\n if (metaOnly) {\n const emptyState: SerializedState = {\n meta: { version: 0, lastUpdated: \"\", sessionId: \"\", createdAt: \"\" },\n state: { phase: \"\", context: {}, agents: [], tasks: [] },\n knowledge: { facts: [], inferences: [], patterns: [] },\n decisions: { current: null, pending: [], opinions: [], history: [] },\n };\n checksum = calculateChecksumSync(emptyState);\n } else {\n checksum = calculateChecksumSync(stateData);\n }\n } catch (e) {\n throw new Error(\n `Failed to calculate checksum: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n\n if (metaOnly) {\n // metaOnly 모드에서는 데이터를 포함하지 않음\n data = {\n meta: { version: 0, lastUpdated: \"\", sessionId: \"\", createdAt: \"\" },\n state: { phase: \"\", context: {}, agents: [], tasks: [] },\n knowledge: { facts: [], inferences: [], patterns: [] },\n decisions: { current: null, pending: [], opinions: [], history: [] },\n };\n } else if (compressed) {\n const json = JSON.stringify(stateData);\n try {\n const compressedString = compress(json, { level: 6 }) as string;\n data = compressedString;\n compressedSize = compressedString.length;\n\n // 압축 데이터 체크섬 검증\n compressedChecksum = calculateChecksumSync(compressedString);\n } catch (e) {\n throw new Error(\n `Failed to compress snapshot data: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n } else {\n data = stateData;\n }\n\n // 메타데이터 생성\n const meta: SnapshotMeta = {\n id: this.options.idGenerator(),\n formatVersion: SNAPSHOT_FORMAT_VERSION,\n createdAt: new Date(),\n sessionId: state.meta.sessionId,\n stateVersion: state.meta.version,\n description: options?.description,\n tags: options?.tags,\n checksum,\n compressedChecksum,\n compressed,\n originalSize,\n compressedSize,\n };\n\n return { meta, data };\n }\n\n /**\n * 메타데이터만 포함된 스냅샷 생성 (동기)\n * @param state - 현재 상태\n * @param description - 설명\n * @returns 메타 전용 스냅샷\n */\n createMetaSnapshot(state: BlackboardState, description?: string): SnapshotMeta {\n const snapshot = this.createSnapshot(state, { metaOnly: true, description });\n return snapshot.meta;\n }\n}\n","/**\n * @module snapshot/snapshot-validator\n * @description 스냅샷 검증 담당\n */\n\nimport type {\n Snapshot,\n SnapshotValidationResult,\n SnapshotValidationError,\n SnapshotValidationWarning,\n SerializedState,\n} from \"./types\";\nimport { StateSerializer, verifyChecksum, verifyChecksumSync } from \"./serializer\";\nimport { decompress, detectCompression } from \"./compression\";\nimport { decompressSnapshotData } from \"./utils\";\nimport { SNAPSHOT_FORMAT_VERSION } from \"./types\";\nimport { isSerializedState } from \"./type-guards\";\n\n/**\n * 스냅샷 검증자\n * @description 스냅샷 검증 전담 클래스\n */\nexport class SnapshotValidator {\n private serializer: StateSerializer;\n\n constructor(serializer?: StateSerializer) {\n this.serializer = serializer ?? new StateSerializer({ sortKeys: true });\n }\n\n /**\n * 스냅샷 검증 (비동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n async validate(snapshot: Snapshot): Promise<SnapshotValidationResult> {\n const errors: SnapshotValidationError[] = [];\n const warnings: SnapshotValidationWarning[] = [];\n\n // 1. 기본 구조 검증\n if (!snapshot.meta || !snapshot.data) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot missing required fields (meta or data)\",\n });\n return { valid: false, errors, warnings };\n }\n\n // 2. 필수 메타데이터 필드 검증\n const { meta } = snapshot;\n if (!meta.id || !meta.formatVersion || !meta.sessionId || !meta.checksum) {\n errors.push({\n code: \"MISSING_FIELD\",\n message: \"Snapshot metadata missing required fields\",\n details: meta,\n });\n }\n\n // 3. 형식 버전 호환성 체크\n const versionCheck = this.checkVersionCompatibility(meta.formatVersion);\n if (!versionCheck.compatible) {\n if (versionCheck.migrationRequired) {\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n } else {\n // 미래 버전: 경고 + 에러 모두 추가\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} is from future version (current: ${versionCheck.current})`,\n });\n errors.push({\n code: \"VERSION_MISMATCH\",\n message: `Incompatible snapshot format: ${versionCheck.snapshot} (current: ${versionCheck.current})`,\n });\n }\n } else if (versionCheck.migrationRequired) {\n // 호환되지만 마이그레이션이 필요한 이전 버전\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n }\n\n // 4. 데이터 무결성 검증\n if (!meta.compressed && typeof snapshot.data === \"object\" && snapshot.data !== null) {\n const isValid = await verifyChecksum(snapshot.data, meta.checksum);\n if (!isValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Snapshot data checksum does not match metadata\",\n details: { expected: meta.checksum },\n });\n }\n }\n\n // 5. 압축 데이터 검증\n if (meta.compressed && typeof snapshot.data === \"string\") {\n try {\n const algorithm = detectCompression(snapshot.data);\n if (!algorithm) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot marked as compressed but data is not valid compressed format\",\n });\n }\n\n // 압축 데이터 체크섬 검증\n if (meta.compressedChecksum) {\n const checksumValid = await verifyChecksum(snapshot.data, meta.compressedChecksum);\n if (!checksumValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Compressed data checksum does not match metadata\",\n details: { expected: meta.compressedChecksum },\n });\n }\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to detect compression format\",\n details: e,\n });\n }\n }\n\n // 6. 런타임 검증 (P0: agents/tasks/opinions 구조 검증)\n if (errors.length === 0) {\n const runtimeValidation = this.validateRuntimeStructure(snapshot);\n if (!runtimeValidation.valid) {\n errors.push(...runtimeValidation.errors);\n warnings.push(...runtimeValidation.warnings);\n }\n }\n\n // 7. 역직렬화 테스트\n if (errors.length === 0) {\n try {\n const state = decompressSnapshotData(snapshot);\n\n if (!state.meta || !state.state) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Deserialized state is missing required fields\",\n });\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to deserialize snapshot data\",\n details: e,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * 스냅샷 검증 (동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n * @description 테스트 환경 등에서 동기 검증이 필요한 경우 사용\n */\n validateSync(snapshot: Snapshot): SnapshotValidationResult {\n const errors: SnapshotValidationError[] = [];\n const warnings: SnapshotValidationWarning[] = [];\n\n // 1. 기본 구조 검증\n if (!snapshot.meta || !snapshot.data) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot missing required fields (meta or data)\",\n });\n return { valid: false, errors, warnings };\n }\n\n // 2. 필수 메타데이터 필드 검증\n const { meta } = snapshot;\n if (!meta.id || !meta.formatVersion || !meta.sessionId || !meta.checksum) {\n errors.push({\n code: \"MISSING_FIELD\",\n message: \"Snapshot metadata missing required fields\",\n details: meta,\n });\n }\n\n // 3. 형식 버전 호환성 체크\n const versionCheck = this.checkVersionCompatibility(meta.formatVersion);\n if (!versionCheck.compatible) {\n if (versionCheck.migrationRequired) {\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n } else {\n // 미래 버전: 경고 + 에러 모두 추가\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} is from future version (current: ${versionCheck.current})`,\n });\n errors.push({\n code: \"VERSION_MISMATCH\",\n message: `Incompatible snapshot format: ${versionCheck.snapshot} (current: ${versionCheck.current})`,\n });\n }\n } else if (versionCheck.migrationRequired) {\n // 호환되지만 마이그레이션이 필요한 이전 버전\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n }\n\n // 4. 데이터 무결성 검증 (동기)\n if (!meta.compressed && typeof snapshot.data === \"object\" && snapshot.data !== null) {\n const isValid = verifyChecksumSync(snapshot.data, meta.checksum);\n if (!isValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Snapshot data checksum does not match metadata\",\n details: { expected: meta.checksum },\n });\n }\n }\n\n // 5. 압축 데이터 검증\n if (meta.compressed && typeof snapshot.data === \"string\") {\n try {\n const algorithm = detectCompression(snapshot.data);\n if (!algorithm) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot marked as compressed but data is not valid compressed format\",\n });\n }\n\n // 압축 데이터 체크섬 검증 (동기)\n if (meta.compressedChecksum) {\n const checksumValid = verifyChecksumSync(snapshot.data, meta.compressedChecksum);\n if (!checksumValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Compressed data checksum does not match metadata\",\n details: { expected: meta.compressedChecksum },\n });\n }\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to detect compression format\",\n details: e,\n });\n }\n }\n\n // 6. 런타임 검증 (P0: agents/tasks/opinions 구조 검증)\n if (errors.length === 0) {\n const runtimeValidation = this.validateRuntimeStructure(snapshot);\n if (!runtimeValidation.valid) {\n errors.push(...runtimeValidation.errors);\n warnings.push(...runtimeValidation.warnings);\n }\n }\n\n // 7. 역직렬화 테스트\n if (errors.length === 0) {\n try {\n const state = decompressSnapshotData(snapshot);\n\n if (!state.meta || !state.state) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Deserialized state is missing required fields\",\n });\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to deserialize snapshot data\",\n details: e,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * 버전 호환성 체크\n * @param formatVersion - 스냅샷 형식 버전\n * @returns 호환 여부 및 상세 정보\n */\n checkVersionCompatibility(formatVersion: string): {\n compatible: boolean;\n current: string;\n snapshot: string;\n migrationRequired: boolean;\n } {\n const current = SNAPSHOT_FORMAT_VERSION;\n const snapshot = formatVersion;\n\n // 동일 버전\n if (current === snapshot) {\n return { compatible: true, current, snapshot, migrationRequired: false };\n }\n\n // 메이저 버전 체크 (semver 간단 구현)\n const currentMajor = parseInt(current.split(\".\")[0], 10);\n const snapshotMajor = parseInt(snapshot.split(\".\")[0], 10);\n\n if (snapshotMajor > currentMajor) {\n // 미래 버전 - 호환 불가\n return { compatible: false, current, snapshot, migrationRequired: false };\n }\n\n // 이전 버전 - 마이그레이션 필요 (현재는 미구현)\n return { compatible: true, current, snapshot, migrationRequired: true };\n }\n\n /**\n * 동기 체크섬 검증 (구조적 검증만, 체크섬 제외)\n * @description restore()에서 사용하는 동기 검증 메서드\n * 체크섬 검증은 비동기이므로 validate()에서 수행해야 함\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n validateSyncStructure(snapshot: Snapshot): {\n valid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n // 1. 기본 구조 검증\n if (!snapshot.meta || !snapshot.data) {\n errors.push(\"Snapshot missing required fields (meta or data)\");\n return { valid: false, errors };\n }\n\n // 2. 필수 메타데이터 필드 검증\n const { meta } = snapshot;\n if (!meta.id || !meta.formatVersion || !meta.sessionId || !meta.checksum) {\n errors.push(\"Snapshot metadata missing required fields\");\n }\n\n // 3. 형식 버전 호환성 체크\n const versionCheck = this.checkVersionCompatibility(meta.formatVersion);\n if (!versionCheck.compatible) {\n errors.push(\n `Incompatible snapshot format: ${versionCheck.snapshot} (current: ${versionCheck.current})`\n );\n }\n\n // 4. 데이터 타입 검증\n if (!meta.compressed && typeof snapshot.data !== \"object\") {\n errors.push(\"Snapshot data must be an object when not compressed\");\n }\n\n if (meta.compressed && typeof snapshot.data !== \"string\") {\n errors.push(\"Snapshot data must be a string when compressed\");\n }\n\n // 5. 압축 데이터 형식 검증\n if (meta.compressed && typeof snapshot.data === \"string\") {\n try {\n const algorithm = detectCompression(snapshot.data);\n if (!algorithm) {\n errors.push(\"Snapshot marked as compressed but data is not valid compressed format\");\n }\n } catch {\n errors.push(\"Failed to detect compression format\");\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * 런타임 구조 검증 (P0: agents/tasks/opinions)\n * @description 역직렬화 후 실제 데이터 구조 검증\n * P1: 에러 수집 모드 (break 제거)\n */\n private validateRuntimeStructure(snapshot: Snapshot): {\n valid: boolean;\n errors: SnapshotValidationError[];\n warnings: SnapshotValidationWarning[];\n } {\n const errors: SnapshotValidationError[] = [];\n const warnings: SnapshotValidationWarning[] = [];\n\n try {\n let serializedState: SerializedState | undefined;\n\n // 압축 데이터 처리\n if (snapshot.meta.compressed && typeof snapshot.data === \"string\") {\n const algorithm = detectCompression(snapshot.data) ?? \"gzip\";\n const json = decompress(snapshot.data, { algorithm }) as string;\n const parsed = JSON.parse(json);\n serializedState = isSerializedState(parsed) ? parsed : undefined;\n } else if (typeof snapshot.data === \"object\" && isSerializedState(snapshot.data)) {\n serializedState = snapshot.data;\n }\n\n // 타입 가드 실패 시 에러 반환\n if (!serializedState) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to parse serialized state data\",\n });\n return { valid: false, errors, warnings };\n }\n\n // state 섹션 검증\n if (serializedState.state) {\n const stateSection = serializedState.state;\n\n // agents 검증: Array<[string, unknown]> 형식\n if (stateSection.agents) {\n if (!Array.isArray(stateSection.agents)) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"state.agents must be an array of [id, data] tuples\",\n });\n } else {\n for (let i = 0; i < stateSection.agents.length; i++) {\n const item = stateSection.agents[i];\n if (!Array.isArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: `state.agents[${i}] must be a [string, unknown] tuple`,\n });\n // P1: break 제거 - 전체 에러 수집\n }\n }\n }\n }\n\n // tasks 검증: Array<[string, unknown]> 형식\n if (stateSection.tasks) {\n if (!Array.isArray(stateSection.tasks)) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"state.tasks must be an array of [id, data] tuples\",\n });\n } else {\n for (let i = 0; i < stateSection.tasks.length; i++) {\n const item = stateSection.tasks[i];\n if (!Array.isArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: `state.tasks[${i}] must be a [string, unknown] tuple`,\n });\n // P1: break 제거 - 전체 에러 수집\n }\n }\n }\n }\n }\n\n // decisions 섹션 검증\n if (serializedState?.decisions) {\n const decisionsSection = serializedState.decisions;\n\n // opinions 검증: Array<[string, unknown]> 형식\n if (decisionsSection.opinions) {\n if (!Array.isArray(decisionsSection.opinions)) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"decisions.opinions must be an array of [id, data] tuples\",\n });\n } else {\n for (let i = 0; i < decisionsSection.opinions.length; i++) {\n const item = decisionsSection.opinions[i];\n if (!Array.isArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: `decisions.opinions[${i}] must be a [string, unknown] tuple`,\n });\n // P1: break 제거 - 전체 에러 수집\n }\n }\n }\n }\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to validate runtime structure\",\n details: e,\n });\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n}\n","/**\n * @module snapshot/snapshot-restorer\n * @description 스냅샷 복원 담당\n */\n\nimport type { BlackboardState, SessionId } from '../types';\nimport type {\n Snapshot,\n RestoreSnapshotOptions,\n} from './types';\nimport type { SerializedState } from './types';\nimport { StateSerializer } from './serializer';\nimport { decompressSnapshotData } from './utils';\nimport { SnapshotValidator } from './snapshot-validator';\nimport { createIdGenerator, type IdGenerator } from './id-utils';\n\n/**\n * 스냅샷 복원 에러\n */\nexport class SnapshotRestoreError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = 'SnapshotRestoreError';\n }\n}\n\n/**\n * 스냅샷 복원자 설정\n */\nexport interface SnapshotRestorerOptions {\n /** ID 생성 함수 */\n idGenerator?: () => string;\n}\n\n/**\n * 스냅샷 복원자\n * @description 스냅샷 복원 전담 클래스\n */\nexport class SnapshotRestorer {\n private serializer: StateSerializer;\n private validator: SnapshotValidator;\n private idGenerator: IdGenerator;\n\n constructor(options: SnapshotRestorerOptions = {}) {\n this.serializer = new StateSerializer({ sortKeys: true });\n this.validator = new SnapshotValidator(this.serializer);\n this.idGenerator = createIdGenerator(options.idGenerator);\n }\n\n /**\n * 스냅샷에서 상태 복원\n * @param snapshot - 스냅샷\n * @param options - 복원 옵션\n * @returns 복원된 상태\n * @throws {SnapshotRestoreError} 복원 실패 시\n * @description\n * **옵션 동작:**\n * - `skipVersionCheck`: 포맷 버전 호환성 검사 건너뜀\n * - `skipStructuralValidation`: 구조적 검증 건너뜀 (validateSync)\n * - 참고: 체크섬 검증은 validate()에서 수행됨\n * - `resetVersion`: 상태 버전 0으로 초기화 (기본: true)\n * - `newSessionId`: 새 세션 ID 생성 (기본: true)\n */\n restore(\n snapshot: Snapshot,\n options?: RestoreSnapshotOptions\n ): BlackboardState {\n const opts = options ?? {};\n\n // skipValidation은 skipStructuralValidation의 별칭\n const shouldSkipStructuralValidation =\n opts.skipValidation || opts.skipStructuralValidation;\n\n // 1. 버전 호환성 체크\n if (!opts.skipVersionCheck) {\n const versionCheck = this.validator.checkVersionCompatibility(snapshot.meta.formatVersion);\n if (!versionCheck.compatible) {\n throw new SnapshotRestoreError(\n `Incompatible snapshot format: ${versionCheck.snapshot}`,\n 'VERSION_MISMATCH',\n { current: versionCheck.current, snapshot: versionCheck.snapshot }\n );\n }\n }\n\n // 2. 구조/타입 검증 (체크섬 X)\n if (!shouldSkipStructuralValidation) {\n const syncValidation = this.validator.validateSyncStructure(snapshot);\n if (!syncValidation.valid) {\n throw new SnapshotRestoreError(\n `Snapshot validation failed: ${syncValidation.errors.join(', ')}`,\n 'VALIDATION_FAILED',\n syncValidation.errors\n );\n }\n }\n\n // 3. 체크섬 검증 (skipValidation이 false일 때만)\n if (!shouldSkipStructuralValidation) {\n const fullValidation = this.validator.validateSync(snapshot);\n if (!fullValidation.valid) {\n throw new SnapshotRestoreError(\n `Snapshot checksum validation failed: ${fullValidation.errors.map(e => e.message).join(', ')}`,\n 'CHECKSUM_INVALID',\n fullValidation.errors\n );\n }\n }\n\n // 4. 데이터 역직렬화\n let serialized: SerializedState;\n\n try {\n serialized = decompressSnapshotData(snapshot);\n } catch (e) {\n // P2: catch 블록 타입 명시\n const error = e instanceof Error ? e : new Error(String(e));\n throw new SnapshotRestoreError(\n `Failed to deserialize snapshot data: ${error.message}`,\n 'DATA_CORRUPTED',\n error\n );\n }\n\n // 4. State 역직렬화\n const state = this.serializer.deserialize(serialized);\n\n // 5. 버전/세션 ID 처리\n if (opts.resetVersion !== false) {\n state.meta.version = 0;\n state.meta.lastUpdated = new Date();\n }\n\n if (opts.newSessionId !== false) {\n const newId = this.idGenerator();\n if (typeof newId !== 'string') {\n throw new SnapshotRestoreError(\n 'idGenerator must return a string',\n 'INVALID_SESSION_ID'\n );\n }\n state.meta.sessionId = newId as SessionId;\n }\n\n return state;\n }\n\n /**\n * 부분 복원 (특정 섹션만)\n * @param snapshot - 스냅샷\n * @param currentState - 현재 상태\n * @param sections - 복원할 섹션\n * @returns 병합된 상태\n */\n partialRestore(\n snapshot: Snapshot,\n currentState: BlackboardState,\n sections: ('state' | 'knowledge' | 'decisions')[]\n ): BlackboardState {\n // 스냅샷 복원\n const snapshotState = this.restore(snapshot, {\n skipVersionCheck: true,\n skipStructuralValidation: true,\n resetVersion: false,\n newSessionId: false,\n });\n\n // 깊은 복사\n const result: BlackboardState = structuredClone(currentState);\n\n // 섹션별 병합\n if (sections.includes('state') && snapshotState.state) {\n result.state = snapshotState.state;\n result.meta.version = snapshotState.meta.version;\n result.meta.lastUpdated = snapshotState.meta.lastUpdated;\n }\n\n if (sections.includes('knowledge') && snapshotState.knowledge) {\n result.knowledge = snapshotState.knowledge;\n }\n\n if (sections.includes('decisions') && snapshotState.decisions) {\n result.decisions = snapshotState.decisions;\n }\n\n return result;\n }\n}\n","/**\n * @module snapshot/snapshot-serializer\n * @description 스냅샷 직렬화 담당\n */\n\nimport type { Snapshot } from './types';\n\n/**\n * 스냅샷 직렬화 옵션\n */\nexport interface SnapshotSerializeOptions {\n /** 예쁜 출력 여부 */\n pretty?: boolean;\n}\n\n/**\n * 스냅샷 직렬화자\n * @description 스냅샷 직렬화/역직렬화 전담 클래스\n */\nexport class SnapshotSerializer {\n /**\n * 스냅샷 → JSON 문자열\n * @param snapshot - 스냅샷\n * @param pretty - 예쁜 출력 여부\n * @returns JSON 문자열\n */\n toJSON(snapshot: Snapshot, pretty: boolean = false): string {\n // Date 객체 직렬화 처리\n const json = JSON.stringify(snapshot, (key, value) => {\n if (value instanceof Date) {\n return value.toISOString();\n }\n return value;\n }, pretty ? 2 : 0);\n\n return json;\n }\n\n /**\n * JSON 문자열 → 스냅샷\n * @param json - JSON 문자열\n * @returns 스냅샷\n * @throws {Error} JSON 파싱 실패 시 명확한 에러 메시지\n */\n fromJSON(json: string): Snapshot {\n // P1: 빈 문자열 입력 검증 추가\n if (!json || json.trim() === '') {\n throw new Error('fromJSON(): input JSON must not be empty or whitespace-only');\n }\n\n try {\n const parsed = JSON.parse(json);\n\n // Date 역직렬화\n const snapshot: Snapshot = {\n meta: {\n ...parsed.meta,\n createdAt: new Date(parsed.meta.createdAt),\n },\n data: parsed.data,\n };\n\n return snapshot;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Invalid JSON in snapshot: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * 스냅샷 → Uint8Array (바이너리)\n * @param snapshot - 스냅샷\n * @returns Uint8Array\n */\n toUint8Array(snapshot: Snapshot): Uint8Array {\n const json = this.toJSON(snapshot);\n const encoder = new TextEncoder();\n return encoder.encode(json);\n }\n\n /**\n * Uint8Array → 스냅샷\n * @param bytes - 바이트 배열\n * @returns 스냅샷\n * @throws {Error} 디코딩 실패 시 명확한 에러 메시지\n */\n fromUint8Array(bytes: Uint8Array): Snapshot {\n try {\n const decoder = new TextDecoder();\n const json = decoder.decode(bytes);\n return this.fromJSON(json);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to decode Uint8Array to snapshot: ${error.message}`);\n }\n throw error;\n }\n }\n}\n","/**\n * @module snapshot/snapshot-comparer\n * @description 스냅샷 비교 담당\n */\n\nimport type { Snapshot } from './types';\nimport { sortedKeyReplacer, decompressSnapshotData } from './utils';\nimport type { SerializedState } from './types';\n\n/**\n * 스냅샷 차이점\n */\nexport interface SnapshotDiff {\n /** 메타데이터 차이 */\n meta: {\n versionDiff: number;\n timeDiff: number;\n };\n /** 섹션별 차이 */\n sections: {\n state: SectionDiff;\n knowledge: SectionDiff;\n decisions: SectionDiff;\n };\n /** 차이점 존재 여부 */\n hasDifferences: boolean;\n /** 상세 변경 정보 */\n details?: {\n phase?: { before: unknown; after: unknown };\n [key: string]: unknown;\n };\n}\n\n/**\n * 섹션 데이터 타입\n */\nexport type SectionData = Record<string, unknown>;\n\n/**\n * 섹션 차이점\n */\nexport interface SectionDiff {\n /** 추가된 항목 수 */\n added: number;\n /** 제거된 항목 수 */\n removed: number;\n /** 변경된 항목 수 */\n modified: number;\n /** 상세 변경 목록 (경로 → [이전, 이후]) */\n changes: Map<string, [unknown, unknown]>;\n}\n\n/**\n * 스냅샷 비교자\n * @description 스냅샷 비교 전담 클래스\n */\nexport class SnapshotComparer {\n /**\n * Optional logger for error reporting\n * If not provided, errors are silently ignored (fail-safe)\n */\n private logger?: (msg: string, error?: string) => void;\n\n /**\n * Set the logger for error reporting\n */\n setLogger(logger: (msg: string, error?: string) => void): void {\n this.logger = logger;\n }\n\n /**\n * 스냅샷 비교\n * @param a - 첫 번째 스냅샷\n * @param b - 두 번째 스냅샷\n * @returns 차이점 목록\n */\n compare(a: Snapshot, b: Snapshot): SnapshotDiff {\n const metaDiff = {\n versionDiff: b.meta.stateVersion - a.meta.stateVersion,\n timeDiff: b.meta.createdAt.getTime() - a.meta.createdAt.getTime(),\n };\n\n // 섹션별 비교\n const stateSection = this.createSectionDiff(\n this.extractStateData(a),\n this.extractStateData(b)\n );\n\n const knowledgeSection = this.createSectionDiff(\n this.extractKnowledgeData(a),\n this.extractKnowledgeData(b)\n );\n\n const decisionsSection = this.createSectionDiff(\n this.extractDecisionsData(a),\n this.extractDecisionsData(b)\n );\n\n // 차이점 존재 여부 계산\n const hasDifferences =\n metaDiff.versionDiff !== 0 ||\n stateSection.added > 0 ||\n stateSection.removed > 0 ||\n stateSection.modified > 0 ||\n knowledgeSection.added > 0 ||\n knowledgeSection.removed > 0 ||\n knowledgeSection.modified > 0 ||\n decisionsSection.added > 0 ||\n decisionsSection.removed > 0 ||\n decisionsSection.modified > 0;\n\n // 상세 변경 정보 추출\n const details: Record<string, unknown> = {};\n for (const [key, [before, after]] of stateSection.changes.entries()) {\n details[key] = { before, after };\n }\n\n return {\n meta: metaDiff,\n sections: {\n state: stateSection,\n knowledge: knowledgeSection,\n decisions: decisionsSection,\n },\n hasDifferences,\n details: Object.keys(details).length > 0 ? details : undefined,\n };\n }\n\n /**\n * 섹션 차이점 생성\n * @param data1 - 첫 번째 데이터\n * @param data2 - 두 번째 데이터\n * @returns 섹션 차이점\n */\n createSectionDiff(data1: SectionData, data2: SectionData): SectionDiff {\n const changes = new Map<string, [unknown, unknown]>();\n const keys1 = new Set(Object.keys(data1 ?? {}));\n const keys2 = new Set(Object.keys(data2 ?? {}));\n\n let added = 0;\n let removed = 0;\n let modified = 0;\n\n // 추가/변경된 항목\n for (const key of keys2) {\n if (!keys1.has(key)) {\n added++;\n changes.set(key, [undefined, data2[key]]);\n } else {\n // JSON.stringify 순서 독립적 비교 (sortedKeyReplacer 사용)\n const json1 = JSON.stringify(data1[key], sortedKeyReplacer);\n const json2 = JSON.stringify(data2[key], sortedKeyReplacer);\n if (json1 !== json2) {\n modified++;\n changes.set(key, [data1[key], data2[key]]);\n }\n }\n }\n\n // 제거된 항목\n for (const key of keys1) {\n if (!keys2.has(key)) {\n removed++;\n changes.set(key, [data1[key], undefined]);\n }\n }\n\n return { added, removed, modified, changes };\n }\n\n /**\n * Generic section data extraction\n * @param snapshot - 스냅샷\n * @param section - 섹션 이름\n * @returns 섹션 데이터\n */\n private extractSection<T>(snapshot: Snapshot, section: keyof SerializedState): T {\n try {\n const serialized = decompressSnapshotData(snapshot);\n return (serialized?.[section] as T) ?? ({} as T);\n } catch (error) {\n // Safe error handling: only log error.message to avoid exposing sensitive info\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger?.(`[SnapshotComparer] extractSection (${section}) failed: ${errorMessage}`);\n return {} as T;\n }\n }\n\n /**\n * 상태 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 상태 데이터\n */\n extractStateData(snapshot: Snapshot): SectionData {\n return this.extractSection<SectionData>(snapshot, 'state');\n }\n\n /**\n * 지식 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 지식 데이터\n */\n extractKnowledgeData(snapshot: Snapshot): SectionData {\n return this.extractSection<SectionData>(snapshot, 'knowledge');\n }\n\n /**\n * 의사결정 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 의사결정 데이터\n */\n extractDecisionsData(snapshot: Snapshot): SectionData {\n return this.extractSection<SectionData>(snapshot, 'decisions');\n }\n}\n","/**\n * @module snapshot/snapshot-manager\n * @description 스냅샷 관리자 (파사드 패턴)\n */\n\nimport type { BlackboardState } from '../types';\nimport type {\n Snapshot,\n SnapshotMeta,\n CreateSnapshotOptions,\n RestoreSnapshotOptions,\n SnapshotValidationResult,\n} from './types';\nimport type {\n SnapshotCreatorOptions,\n} from './snapshot-creator';\nimport type {\n SnapshotRestorerOptions,\n} from './snapshot-restorer';\nimport type {\n SnapshotDiff,\n SectionDiff,\n SectionData,\n} from './snapshot-comparer';\n\nimport { SnapshotCreator } from './snapshot-creator';\nimport { SnapshotValidator } from './snapshot-validator';\nimport {\n SnapshotRestorer,\n SnapshotRestoreError,\n} from './snapshot-restorer';\nimport { SnapshotSerializer } from './snapshot-serializer';\nimport {\n SnapshotComparer,\n} from './snapshot-comparer';\n\n/**\n * 스냅샷 목록 필터 옵션\n */\nexport interface ListSnapshotOptions {\n /** 태그로 필터링 */\n tags?: string[];\n /** 세션 ID로 필터링 */\n sessionId?: string;\n /** 정렬 기준 */\n sortBy?: 'date' | 'id';\n /** 정렬 순서 */\n order?: 'asc' | 'desc';\n}\n\n/**\n * 스냅샷 관리자 설정\n */\nexport interface SnapshotManagerOptions extends SnapshotCreatorOptions, SnapshotRestorerOptions {\n /** 자동 압축 임계값 (바이트, 기본: 10KB) */\n autoCompressThreshold?: number;\n /** 기본 압축 사용 */\n defaultCompress?: boolean;\n /** ID 생성 함수 */\n idGenerator?: () => string;\n}\n\n/**\n * 스냅샷 복원 에러\n */\nexport { SnapshotRestoreError };\n\n/**\n * 스냅샷 관리자\n * @description Blackboard 상태의 스냅샷 생성, 검증, 복원 담당\n *\n * 파사드 패턴으로 각 전문 클래스를 조합하여 기존 API 유지\n *\n * @example\n * ```typescript\n * const manager = new SnapshotManager();\n *\n * // 스냅샷 생성\n * const snapshot = await manager.createSnapshot(board.getState(), {\n * description: 'Before major decision',\n * tags: ['checkpoint', 'decision-001'],\n * compress: true,\n * });\n *\n * // JSON으로 저장\n * const json = manager.toJSON(snapshot);\n * fs.writeFileSync('snapshot.json', json);\n *\n * // JSON에서 로드\n * const loaded = manager.fromJSON(fs.readFileSync('snapshot.json', 'utf-8'));\n *\n * // 검증\n * const validation = await manager.validate(loaded);\n * if (!validation.valid) {\n * console.error('Invalid snapshot:', validation.errors);\n * }\n *\n * // 복원\n * const restoredState = manager.restore(loaded, {\n * newSessionId: true,\n * });\n * board.replaceState(restoredState);\n * ```\n */\nexport class SnapshotManager {\n private creator: SnapshotCreator;\n private validator: SnapshotValidator;\n private restorer: SnapshotRestorer;\n private serializer: SnapshotSerializer;\n private comparer: SnapshotComparer;\n private storage: Map<string, Snapshot> = new Map();\n\n constructor(options: SnapshotManagerOptions = {}) {\n // 각 전문 클래스 초기화\n this.creator = new SnapshotCreator(options);\n this.validator = new SnapshotValidator();\n this.restorer = new SnapshotRestorer(options);\n this.serializer = new SnapshotSerializer();\n this.comparer = new SnapshotComparer();\n }\n\n // === 내부 저장소 관리 ===\n\n /**\n * 스냅샷 저장 (내부)\n */\n private storeSnapshot(snapshot: Snapshot): void {\n this.storage.set(snapshot.meta.id, snapshot);\n }\n\n /**\n * 저장된 스냅샷 목록 조회\n * @param options - 필터 및 정렬 옵션\n * @returns 스냅샷 목록\n */\n list(options?: ListSnapshotOptions): Snapshot[] {\n let snapshots = Array.from(this.storage.values());\n\n // 필터링\n if (options?.tags && options.tags.length > 0) {\n snapshots = snapshots.filter(snapshot =>\n options.tags!.some(tag =>\n snapshot.meta.tags?.includes(tag)\n )\n );\n }\n\n if (options?.sessionId) {\n snapshots = snapshots.filter(snapshot =>\n snapshot.meta.sessionId === options.sessionId\n );\n }\n\n // 정렬\n if (options?.sortBy) {\n snapshots.sort((a, b) => {\n let comparison = 0;\n\n if (options.sortBy === 'date') {\n comparison = a.meta.createdAt.getTime() - b.meta.createdAt.getTime();\n } else if (options.sortBy === 'id') {\n comparison = a.meta.id.localeCompare(b.meta.id);\n }\n\n return options.order === 'desc' ? -comparison : comparison;\n });\n }\n\n return snapshots;\n }\n\n /**\n * ID로 스냅샷 조회\n * @param id - 스냅샷 ID\n * @returns 스냅샷 또는 undefined\n */\n get(id: string): Snapshot | undefined {\n return this.storage.get(id);\n }\n\n /**\n * ID로 스냅샷 삭제\n * @param id - 스냅샷 ID\n * @returns 삭제 성공 여부\n */\n delete(id: string): boolean {\n return this.storage.delete(id);\n }\n\n // === 생성 (SnapshotCreator 위임) ===\n\n /**\n * 스냅샷 생성 (동기)\n * @param state - 현재 Blackboard 상태\n * @param options - 생성 옵션\n * @returns 스냅샷\n */\n createSnapshot(\n state: BlackboardState,\n options?: CreateSnapshotOptions\n ): Snapshot {\n const snapshot = this.creator.createSnapshot(state, options);\n\n // store 옵션이 true면 내부 저장소에 저장\n if (options?.store === true) {\n this.storeSnapshot(snapshot);\n }\n\n return snapshot;\n }\n\n /**\n * 메타데이터만 포함된 스냅샷 생성 (동기)\n * @param state - 현재 상태\n * @param description - 설명\n * @returns 메타 전용 스냅샷\n */\n createMetaSnapshot(\n state: BlackboardState,\n description?: string\n ): SnapshotMeta {\n return this.creator.createMetaSnapshot(state, description);\n }\n\n // === 검증 (SnapshotValidator 위임) ===\n\n /**\n * 스냅샷 검증 (동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n validate(snapshot: Snapshot): SnapshotValidationResult {\n return this.validator.validateSync(snapshot);\n }\n\n /**\n * 스냅샷 검증 (비동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n async validateAsync(snapshot: Snapshot): Promise<SnapshotValidationResult> {\n return this.validator.validate(snapshot);\n }\n\n /**\n * 버전 호환성 체크\n * @param formatVersion - 스냅샷 형식 버전\n * @returns 호환 여부 및 상세 정보\n */\n checkVersionCompatibility(formatVersion: string): {\n compatible: boolean;\n current: string;\n snapshot: string;\n migrationRequired: boolean;\n } {\n return this.validator.checkVersionCompatibility(formatVersion);\n }\n\n /**\n * 동기 체크섬 검증 (구조적 검증만, 체크섬 제외)\n * @description restore()에서 사용하는 동기 검증 메서드\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n validateSyncStructure(snapshot: Snapshot): {\n valid: boolean;\n errors: string[];\n } {\n return this.validator.validateSyncStructure(snapshot);\n }\n\n // === 복원 (SnapshotRestorer 위임) ===\n\n /**\n * 스냅샷에서 상태 복원\n * @param snapshot - 스냅샷\n * @param options - 복원 옵션\n * @returns 복원된 상태\n * @throws {SnapshotRestoreError} 복원 실패 시\n * @description\n * **옵션 동작:**\n * - `skipVersionCheck`: 포맷 버전 호환성 검사 건너뜀\n * - `skipStructuralValidation`: 구조적 검증 건너뜀 (validateSync)\n * - `resetVersion`: 상태 버전 0으로 초기화 (기본: true)\n * - `newSessionId`: 새 세션 ID 생성 (기본: true)\n */\n restore(\n snapshot: Snapshot,\n options?: RestoreSnapshotOptions\n ): BlackboardState {\n return this.restorer.restore(snapshot, options);\n }\n\n /**\n * 부분 복원 (특정 섹션만)\n * @param snapshot - 스냅샷\n * @param currentState - 현재 상태\n * @param sections - 복원할 섹션\n * @returns 병합된 상태\n */\n partialRestore(\n snapshot: Snapshot,\n currentState: BlackboardState,\n sections: ('state' | 'knowledge' | 'decisions')[]\n ): BlackboardState {\n return this.restorer.partialRestore(snapshot, currentState, sections);\n }\n\n // === 직렬화 (SnapshotSerializer 위임) ===\n\n /**\n * 스냅샷 → JSON 문자열\n * @param snapshot - 스냅샷\n * @param pretty - 예쁜 출력 여부\n * @returns JSON 문자열\n */\n toJSON(snapshot: Snapshot, pretty = false): string {\n return this.serializer.toJSON(snapshot, pretty);\n }\n\n /**\n * JSON 문자열 → 스냅샷\n * @param json - JSON 문자열\n * @returns 스냅샷\n * @throws {Error} JSON 파싱 실패 시 명확한 에러 메시지\n */\n fromJSON(json: string): Snapshot {\n return this.serializer.fromJSON(json);\n }\n\n /**\n * 스냅샷 → Uint8Array (바이너리)\n * @param snapshot - 스냅샷\n * @returns Uint8Array\n */\n toUint8Array(snapshot: Snapshot): Uint8Array {\n return this.serializer.toUint8Array(snapshot);\n }\n\n /**\n * Uint8Array → 스냅샷\n * @param bytes - 바이트 배열\n * @returns 스냅샷\n * @throws {Error} 디코딩 실패 시 명확한 에러 메시지\n */\n fromUint8Array(bytes: Uint8Array): Snapshot {\n return this.serializer.fromUint8Array(bytes);\n }\n\n // === 비교 (SnapshotComparer 위임) ===\n\n /**\n * 스냅샷 비교\n * @param a - 첫 번째 스냅샷\n * @param b - 두 번째 스냅샷\n * @returns 차이점 목록\n */\n compare(a: Snapshot, b: Snapshot): SnapshotDiff {\n return this.comparer.compare(a, b);\n }\n\n /**\n * 섹션 차이점 생성\n * @param data1 - 첫 번째 데이터\n * @param data2 - 두 번째 데이터\n * @returns 섹션 차이점\n */\n createSectionDiff(data1: SectionData, data2: SectionData): SectionDiff {\n return this.comparer.createSectionDiff(data1, data2);\n }\n\n /**\n * 상태 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 상태 데이터\n */\n extractStateData(snapshot: Snapshot): SectionData {\n return this.comparer.extractStateData(snapshot);\n }\n\n /**\n * 지식 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 지식 데이터\n */\n extractKnowledgeData(snapshot: Snapshot): SectionData {\n return this.comparer.extractKnowledgeData(snapshot);\n }\n\n /**\n * 의사결정 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 의사결정 데이터\n */\n extractDecisionsData(snapshot: Snapshot): SectionData {\n return this.comparer.extractDecisionsData(snapshot);\n }\n\n // === 유틸리티 ===\n\n /**\n * 스냅샷 메타데이터만 추출\n */\n extractMeta(snapshot: Snapshot): SnapshotMeta {\n return snapshot.meta;\n }\n\n /**\n * 스냅샷 크기 계산 (숫자)\n * @param snapshot - 스냅샷\n * @returns 바이트 크기\n */\n size(snapshot: Snapshot): number {\n const metaSize = JSON.stringify(snapshot.meta).length;\n const dataSize =\n typeof snapshot.data === 'string'\n ? snapshot.data.length\n : JSON.stringify(snapshot.data).length;\n\n return metaSize + dataSize;\n }\n\n /**\n * 스냅샷 크기 계산 (상세)\n */\n calculateSize(snapshot: Snapshot): {\n total: number;\n data: number;\n meta: number;\n compressed: boolean;\n } {\n const metaSize = JSON.stringify(snapshot.meta).length;\n const dataSize =\n typeof snapshot.data === 'string'\n ? snapshot.data.length\n : JSON.stringify(snapshot.data).length;\n\n return {\n total: metaSize + dataSize,\n data: dataSize,\n meta: metaSize,\n compressed: snapshot.meta.compressed,\n };\n }\n}\n","/**\n * @module blackboard\n * @description 메인 Blackboard 클래스\n */\n\nimport type {\n BlackboardState,\n BlackboardMeta,\n KnowledgeSection,\n BoardPhase,\n SessionId,\n} from \"../types\";\nimport { createSessionId } from \"../types/base\";\n\nimport { VersionManager, VersionConflictError } from \"./versioning\";\nimport { getByPath, setByPath, deleteByPath, isValidPath } from \"./path-utils\";\nimport { deepClone, mapToObject, objectToMap } from \"./immutable\";\n\nimport { StateSectionAccessor } from \"./accessors/state-accessor\";\nimport { KnowledgeSectionAccessor } from \"./accessors/knowledge-accessor\";\nimport { DecisionsSectionAccessor } from \"./accessors/decisions-accessor\";\n\n// Snapshot imports\nimport { SnapshotManager } from \"../snapshot\";\nimport type {\n Snapshot,\n CreateSnapshotOptions,\n RestoreSnapshotOptions,\n SnapshotValidationResult,\n} from \"../snapshot\";\n\n// Re-export types for convenience\nexport { BoardPhase };\n\n/**\n * 간단한 EventEmitter 구현\n */\ntype EventListener = (...args: unknown[]) => void;\n\nclass SimpleEventEmitter {\n private _listeners: Map<string, EventListener[]> = new Map();\n\n on(event: string, listener: EventListener): this {\n const listeners = this._listeners.get(event) ?? [];\n listeners.push(listener);\n this._listeners.set(event, listeners);\n return this;\n }\n\n off(event: string, listener: EventListener): this {\n const listeners = this._listeners.get(event) ?? [];\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n return this;\n }\n\n once(event: string, listener: EventListener): this {\n const onceWrapper = (...args: unknown[]) => {\n this.off(event, onceWrapper);\n listener(...args);\n };\n return this.on(event, onceWrapper);\n }\n\n emit(event: string, ...args: unknown[]): boolean {\n const listeners = this._listeners.get(event) ?? [];\n for (const listener of listeners) {\n listener(...args);\n }\n\n // 와일드카드 지원 (예: 'state.*' -> 'state.updated' 매칭)\n for (const [pattern, wildcardListeners] of this._listeners.entries()) {\n if (pattern.endsWith(\"*\") && event.startsWith(pattern.slice(0, -1))) {\n for (const listener of wildcardListeners) {\n listener(...args);\n }\n }\n }\n\n return listeners.length > 0;\n }\n\n removeAllListeners(event?: string): this {\n if (event) {\n this._listeners.delete(event);\n } else {\n this._listeners.clear();\n }\n return this;\n }\n\n listenerCount(event: string): number {\n return this._listeners.get(event)?.length ?? 0;\n }\n}\n\n/**\n * Blackboard 설정 옵션\n */\nexport interface BlackboardOptions {\n /** 세션 ID (자동 생성되지 않으면 필수) */\n sessionId?: SessionId;\n /** 초기 상태 (스냅샷 복원 시 사용) */\n initialState?: Partial<BlackboardState>;\n /** 버전 충돌 시 재시도 횟수 */\n maxRetries?: number;\n /** 재시도 간격 (ms) */\n retryDelay?: number;\n /** 이벤트 리스너 */\n onEvent?: (event: { type: string; timestamp: Date }) => void;\n}\n\n/**\n * 쿼리 옵션\n */\nexport interface QueryOptions {\n /** 깊은 복사 반환 여부 (기본: true) */\n deep?: boolean;\n /** 필터 조건 */\n filter?: Record<string, unknown>;\n /** 정렬 기준 */\n sort?: { field: string; order: \"asc\" | \"desc\" };\n /** 결과 제한 */\n limit?: number;\n /** 오프셋 */\n offset?: number;\n}\n\n/**\n * 쓰기 결과\n */\nexport interface WriteResult {\n /** 성공 여부 */\n success: boolean;\n /** 새 버전 */\n version: number;\n /** 변경된 경로 */\n path: string;\n /** 이전 값 */\n previousValue: unknown;\n /** 에러 (실패 시) */\n error?: Error;\n}\n\n/**\n * 트랜잭션 연산\n */\nexport interface Operation {\n /** 연산 타입 */\n type: \"read\" | \"write\" | \"delete\";\n /** 섹션 */\n section: string;\n /** 키/경로 */\n key: string;\n /** 값 (write 연산 시) */\n value?: unknown;\n}\n\n/**\n * Blackboard 에러 코드\n */\nexport enum BlackboardErrorCode {\n UNKNOWN_ERROR = 1000,\n INVALID_INPUT = 1001,\n NOT_IMPLEMENTED = 1002,\n PATH_NOT_FOUND = 1003,\n INVALID_PATH = 1004,\n\n SLOT_NOT_FOUND = 2000,\n SLOT_ALREADY_EXISTS = 2001,\n SLOT_TYPE_MISMATCH = 2002,\n SLOT_VERSION_CONFLICT = 2003,\n\n ENTRY_NOT_FOUND = 2100,\n ENTRY_ALREADY_EXISTS = 2101,\n ENTRY_LOCKED = 2102,\n\n AGENT_NOT_FOUND = 3000,\n AGENT_ALREADY_REGISTERED = 3001,\n AGENT_NOT_AVAILABLE = 3002,\n TASK_NOT_FOUND = 3003,\n TASK_ALREADY_ASSIGNED = 3004,\n TASK_IN_PROGRESS = 3005,\n\n FACT_NOT_FOUND = 4000,\n INFERENCE_NOT_FOUND = 4001,\n PATTERN_NOT_FOUND = 4002,\n INVALID_PREMISES = 4003,\n\n AGENDA_NOT_FOUND = 5000,\n AGENDA_ALREADY_IN_PROGRESS = 5001,\n AGENDA_ALREADY_RESOLVED = 5002,\n VOTING_NOT_STARTED = 5003,\n VOTING_ALREADY_ENDED = 5004,\n QUORUM_NOT_REACHED = 5005,\n ALREADY_VOTED = 5006,\n CONSENSUS_NOT_REACHED = 5007,\n DUPLICATE_OPINION = 5008,\n OPINION_NOT_FOUND = 5009,\n\n SNAPSHOT_NOT_FOUND = 6000,\n SNAPSHOT_CORRUPTED = 6001,\n SNAPSHOT_VERSION_MISMATCH = 6002,\n\n EVENT_HANDLER_ERROR = 7000,\n SUBSCRIPTION_NOT_FOUND = 7001,\n}\n\n/**\n * 경로 에러\n */\nexport class PathNotFoundError extends Error {\n public readonly code = BlackboardErrorCode.PATH_NOT_FOUND;\n\n constructor(public readonly path: string) {\n super(`Path not found: ${path}`);\n this.name = \"PathNotFoundError\";\n }\n}\n\n/**\n * Blackboard 에러 클래스\n */\nexport class BlackboardError extends Error {\n constructor(\n public readonly code: BlackboardErrorCode,\n message: string,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"BlackboardError\";\n }\n}\n\n/**\n * Blackboard 메인 클래스\n * @description 시스템의 단일 진실 소스(SSOT)를 관리하는 핵심 클래스\n *\n * @example\n * ```typescript\n * const board = new Blackboard({ sessionId: createSessionId('session-001') });\n *\n * // 읽기\n * const phase = board.read('state.phase');\n *\n * // 쓰기 (버전 관리 포함)\n * const result = board.write('state.phase', 'discussion');\n *\n * // 섹션 접근\n * const stateSection = board.state;\n * const knowledgeSection = board.knowledge;\n * const decisionsSection = board.decisions;\n * ```\n */\nexport class Blackboard extends SimpleEventEmitter {\n private _state: BlackboardState;\n private readonly versionManager: VersionManager;\n private readonly options: Required<Omit<BlackboardOptions, \"onEvent\">> &\n Pick<BlackboardOptions, \"onEvent\">;\n private _snapshotManager: SnapshotManager;\n\n // 섹션 접근자\n private _stateAccessor?: StateSectionAccessor;\n private _knowledgeAccessor?: KnowledgeSectionAccessor;\n private _decisionsAccessor?: DecisionsSectionAccessor;\n\n constructor(options: BlackboardOptions = {}) {\n super();\n this.options = this.normalizeOptions(options);\n this._state = this.createInitialState();\n this.versionManager = new VersionManager({\n maxRetries: this.options.maxRetries,\n retryDelay: this.options.retryDelay,\n exponentialBackoff: true,\n });\n this._snapshotManager = new SnapshotManager();\n\n // 접근자 초기화\n this._stateAccessor = new StateSectionAccessor(this);\n this._knowledgeAccessor = new KnowledgeSectionAccessor(this);\n this._decisionsAccessor = new DecisionsSectionAccessor(this);\n\n // state.initialized 이벤트 발생 (onEvent 옵션이 있는 경우)\n if (options.onEvent) {\n options.onEvent({ type: \"state.initialized\", timestamp: new Date() });\n }\n }\n\n /**\n * 옵션 정규화\n */\n private normalizeOptions(\n options: BlackboardOptions\n ): Required<Omit<BlackboardOptions, \"onEvent\">> & Pick<BlackboardOptions, \"onEvent\"> {\n return {\n sessionId: options.sessionId ?? createSessionId(`session-${Date.now()}`),\n initialState: options.initialState ?? {},\n maxRetries: options.maxRetries ?? 3,\n retryDelay: options.retryDelay ?? 100,\n onEvent: options.onEvent,\n };\n }\n\n /**\n * 초기 상태 생성\n */\n private createInitialState(): BlackboardState {\n const now = new Date();\n const sessionId = this.options.sessionId;\n\n // 초기 상태 복원\n if (this.options.initialState.meta) {\n return {\n meta: {\n version: this.options.initialState.meta?.version ?? 1,\n lastUpdated: this.options.initialState.meta?.lastUpdated ?? now,\n sessionId: this.options.initialState.meta?.sessionId ?? sessionId,\n createdAt: this.options.initialState.meta?.createdAt ?? now,\n },\n state: this.options.initialState.state ?? {\n phase: \"idle\",\n context: {},\n agents: new Map(),\n tasks: new Map(),\n },\n knowledge: this.options.initialState.knowledge ?? {\n facts: [],\n inferences: [],\n patterns: [],\n },\n decisions: this.options.initialState.decisions ?? {\n current: null,\n pending: [],\n opinions: new Map(),\n history: [],\n voting: {},\n },\n };\n }\n\n // 새 상태 생성\n return {\n meta: {\n version: 1,\n lastUpdated: now,\n sessionId,\n createdAt: now,\n },\n state: {\n phase: \"idle\",\n context: {},\n agents: new Map(),\n tasks: new Map(),\n },\n knowledge: {\n facts: [],\n inferences: [],\n patterns: [],\n },\n decisions: {\n current: null,\n pending: [],\n opinions: new Map(),\n history: [],\n voting: {},\n },\n };\n }\n\n // === Getters for sections ===\n\n /** 메타데이터 섹션 (읽기 전용) */\n get meta(): Readonly<BlackboardMeta> {\n return {\n version: this._state.meta.version,\n lastUpdated: new Date(this._state.meta.lastUpdated.getTime()),\n sessionId: this._state.meta.sessionId,\n createdAt: new Date(this._state.meta.createdAt.getTime()),\n };\n }\n\n /** 상태 섹션 접근자 */\n get state(): StateSectionAccessor {\n if (!this._stateAccessor) {\n this._stateAccessor = new StateSectionAccessor(this);\n }\n return this._stateAccessor;\n }\n\n /** 지식 섹션 접근자 */\n get knowledge(): KnowledgeSectionAccessor {\n if (!this._knowledgeAccessor) {\n this._knowledgeAccessor = new KnowledgeSectionAccessor(this);\n }\n return this._knowledgeAccessor;\n }\n\n /** 의사결정 섹션 접근자 */\n get decisions(): DecisionsSectionAccessor {\n if (!this._decisionsAccessor) {\n this._decisionsAccessor = new DecisionsSectionAccessor(this);\n }\n return this._decisionsAccessor;\n }\n\n /** 현재 버전 */\n get version(): number {\n return this._state.meta.version;\n }\n\n /** 세션 ID */\n get sessionId(): SessionId {\n return this._state.meta.sessionId;\n }\n\n /** 스냅샷 관리자 (public) */\n get snapshotManager(): SnapshotManager {\n return this._snapshotManager;\n }\n\n // === Core API ===\n\n /**\n * 현재 전체 상태 조회\n * @returns 현재 Blackboard 상태 (스냅샷용)\n */\n getState(): BlackboardState {\n return {\n meta: {\n version: this._state.meta.version,\n lastUpdated: new Date(this._state.meta.lastUpdated.getTime()),\n sessionId: this._state.meta.sessionId,\n createdAt: new Date(this._state.meta.createdAt.getTime()),\n },\n state: {\n phase: this._state.state.phase,\n context: deepClone(this._state.state.context),\n agents: new Map(this._state.state.agents.entries()),\n tasks: new Map(this._state.state.tasks.entries()),\n },\n knowledge: {\n facts: this._state.knowledge.facts.map((f) => deepClone(f)),\n inferences: this._state.knowledge.inferences.map((i) => deepClone(i)),\n patterns: this._state.knowledge.patterns.map((p) => deepClone(p)),\n },\n decisions: {\n current: this._state.decisions.current ? deepClone(this._state.decisions.current) : null,\n pending: this._state.decisions.pending.map((d) => deepClone(d)),\n opinions: new Map(this._state.decisions.opinions.entries()),\n history: this._state.decisions.history.map((h) => deepClone(h)),\n voting: deepClone(this._state.decisions.voting),\n },\n };\n }\n\n /**\n * 경로 기반 읽기\n * @param path - 점(.)으로 구분된 경로 (예: 'state.phase', 'decisions.current')\n * @param options - 쿼리 옵션\n * @returns 해당 경로의 값\n */\n read<T = unknown>(path: string, options?: QueryOptions & { strict?: boolean }): T {\n const shouldDeepClone = options?.deep !== false;\n const strict = options?.strict !== false;\n const value = getByPath(this._state, path);\n\n if (value === undefined && strict) {\n throw new PathNotFoundError(path);\n }\n\n return (shouldDeepClone ? deepClone(value) : value) as T;\n }\n\n /**\n * 경로 기반 쓰기 (동기)\n * @param path - 점(.)으로 구분된 경로\n * @param value - 새 값\n * @param options - 쓰기 옵션 (expectedVersion 포함)\n * @returns 쓰기 결과\n */\n write(path: string, value: unknown, options?: { expectedVersion?: number }): WriteResult {\n // 경로 검증\n if (!isValidPath(path)) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_PATH, `Invalid path: ${path}`);\n }\n\n // 버전 검증\n if (options?.expectedVersion !== undefined) {\n this.versionManager.validateVersion(this.version, options.expectedVersion, path);\n }\n\n const previousValue = getByPath(this._state, path);\n\n const newState = setByPath(this._state, path, value);\n this._state = newState;\n\n // 메타데이터 업데이트\n const newVersion = this.versionManager.incrementVersion(this.version);\n this._state.meta.version = newVersion;\n this._state.meta.lastUpdated = new Date();\n\n // state.updated 이벤트 발생\n this.emit(\"state.updated\", { type: \"state.updated\", path, value, timestamp: new Date() });\n\n return {\n success: true,\n version: newVersion,\n path,\n previousValue,\n };\n }\n\n /**\n * 경로 기반 삭제\n * @param path - 삭제할 경로\n * @param options - 삭제 옵션\n * @returns 삭제 결과\n */\n delete(path: string, options?: { expectedVersion?: number; strict?: boolean }): WriteResult {\n // 경로 검증\n if (!isValidPath(path)) {\n return {\n success: false,\n version: this.version,\n path,\n previousValue: undefined,\n error: new BlackboardError(BlackboardErrorCode.INVALID_PATH, `Invalid path: ${path}`),\n };\n }\n\n // 경로가 존재하는지 확인\n const previousValue = getByPath(this._state, path);\n if (previousValue === undefined) {\n if (options?.strict !== false) {\n throw new PathNotFoundError(path);\n }\n return {\n success: false,\n version: this.version,\n path,\n previousValue: undefined,\n };\n }\n\n // 버전 검증\n if (options?.expectedVersion !== undefined) {\n try {\n this.versionManager.validateVersion(this.version, options.expectedVersion, path);\n } catch (error) {\n return {\n success: false,\n version: this.version,\n path,\n previousValue,\n error: error as Error,\n };\n }\n }\n\n try {\n const newState = deleteByPath(this._state, path);\n this._state = newState;\n\n // 메타데이터 업데이트\n const newVersion = this.versionManager.incrementVersion(this.version);\n this._state.meta.version = newVersion;\n this._state.meta.lastUpdated = new Date();\n\n return {\n success: true,\n version: newVersion,\n path,\n previousValue,\n };\n } catch (error) {\n return {\n success: false,\n version: this.version,\n path,\n previousValue,\n error: error as Error,\n };\n }\n }\n\n /**\n * 경로 존재 여부 확인\n * @param path - 확인할 경로\n */\n exists(path: string): boolean {\n return getByPath(this._state, path) !== undefined;\n }\n\n /**\n * 트랜잭션 실행\n * @description 여러 쓰기를 원자적으로 실행\n * @param operations - 실행할 연산 목록\n * @returns 전체 트랜잭션 결과\n */\n transaction(\n operations: Array<{\n type: \"write\" | \"delete\";\n path: string;\n value?: unknown;\n expectedVersion?: number;\n }>\n ): WriteResult[] {\n const originalVersion = this._state.meta.version;\n const results: WriteResult[] = [];\n const backup = {\n meta: {\n version: this._state.meta.version,\n lastUpdated: new Date(this._state.meta.lastUpdated.getTime()),\n sessionId: this._state.meta.sessionId,\n createdAt: new Date(this._state.meta.createdAt.getTime()),\n },\n state: {\n phase: this._state.state.phase,\n context: deepClone(this._state.state.context),\n agents: new Map(this._state.state.agents.entries()),\n tasks: new Map(this._state.state.tasks.entries()),\n },\n knowledge: {\n facts: this._state.knowledge.facts.map((f) => deepClone(f)),\n inferences: this._state.knowledge.inferences.map((i) => deepClone(i)),\n patterns: this._state.knowledge.patterns.map((p) => deepClone(p)),\n },\n decisions: {\n current: this._state.decisions.current ? deepClone(this._state.decisions.current) : null,\n pending: this._state.decisions.pending.map((d) => deepClone(d)),\n opinions: new Map(this._state.decisions.opinions.entries()),\n history: this._state.decisions.history.map((h) => deepClone(h)),\n voting: deepClone(this._state.decisions.voting),\n },\n };\n\n try {\n // 버전 검증 (모든 연산 전에 수행)\n for (const op of operations) {\n if (op.expectedVersion !== undefined) {\n this.versionManager.validateVersion(originalVersion, op.expectedVersion, op.path);\n }\n }\n\n // 모든 연산 실행 (버전 증가 없이)\n for (const op of operations) {\n // 내�的方法를 사용하여 버전 증가 없이 쓰기/삭제 수행\n if (op.type === \"write\") {\n const previousValue = getByPath(this._state, op.path);\n this._state = setByPath(this._state, op.path, op.value);\n results.push({\n success: true,\n version: originalVersion, // 아직 버전 증가 안 함\n path: op.path,\n previousValue,\n });\n } else {\n const previousValue = getByPath(this._state, op.path);\n this._state = deleteByPath(this._state, op.path);\n results.push({\n success: true,\n version: originalVersion, // 아직 버전 증가 안 함\n path: op.path,\n previousValue,\n });\n }\n }\n\n // 모든 성공 시 한 번만 버전 증가\n this._state.meta.version = originalVersion + 1;\n this._state.meta.lastUpdated = new Date();\n\n // 결과에 최종 버전 업데이트\n return results.map((r) => ({ ...r, version: this._state.meta.version }));\n } catch (error) {\n // 롤백: 상태 복원 및 버전 복원\n this._state = backup;\n this._state.meta.version = originalVersion;\n\n return operations.map(() => ({\n success: false,\n version: originalVersion,\n path: \"\",\n previousValue: undefined,\n error: error as Error,\n }));\n }\n }\n\n // === Snapshot Methods ===\n\n /**\n * 현재 상태 스냅샷 생성 (비동기)\n * @param options - 스냅샷 옵션\n * @returns 스냅샷\n */\n async createSnapshot(options?: CreateSnapshotOptions): Promise<Snapshot> {\n const state = this.getState();\n return this._snapshotManager.createSnapshot(state, options);\n }\n\n /**\n * 스냅샷에서 상태 복원\n * @param snapshot - 복원할 스냅샷\n * @param options - 복원 옵션\n */\n restoreSnapshot(snapshot: Snapshot, options?: RestoreSnapshotOptions): void {\n const restoredState = this._snapshotManager.restore(snapshot, options);\n this.replaceState(restoredState);\n }\n\n /**\n * 스냅샷 검증 (비동기)\n * @param snapshot - 검증할 스냅샷\n */\n async validateSnapshot(snapshot: Snapshot): Promise<SnapshotValidationResult> {\n return this._snapshotManager.validate(snapshot);\n }\n\n /**\n * 전체 상태 교체 (내부용)\n * @param newState - 새 상태\n */\n private replaceState(newState: BlackboardState): void {\n this._state = deepClone(newState);\n\n // 접근자 재초기화\n this._stateAccessor = new StateSectionAccessor(this);\n this._knowledgeAccessor = new KnowledgeSectionAccessor(this);\n this._decisionsAccessor = new DecisionsSectionAccessor(this);\n }\n\n /**\n * 스냅샷 생성 (JSON 직렬화용) - 하위 호환성 유지\n */\n toJSON(): unknown {\n return {\n meta: this._state.meta,\n state: {\n phase: this._state.state.phase,\n context: this._state.state.context,\n agents: mapToObject(this._state.state.agents),\n tasks: mapToObject(this._state.state.tasks),\n },\n knowledge: this._state.knowledge,\n decisions: {\n current: this._state.decisions.current,\n pending: this._state.decisions.pending,\n opinions: mapToObject(this._state.decisions.opinions),\n history: this._state.decisions.history,\n voting: this._state.decisions.voting,\n },\n };\n }\n\n /**\n * 스냅샷에서 복원 - 하위 호환성 유지\n */\n static fromJSON(json: {\n meta?: unknown;\n state?: unknown;\n knowledge?: unknown;\n decisions?: unknown;\n }): Blackboard {\n const state: Partial<BlackboardState> = {\n meta: json.meta as BlackboardMeta,\n state: json.state\n ? {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...(json.state as any),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n agents: objectToMap((json.state as any).agents ?? {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tasks: objectToMap((json.state as any).tasks ?? {}),\n }\n : undefined,\n knowledge: json.knowledge as KnowledgeSection,\n decisions: json.decisions\n ? {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ...(json.decisions as any),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n opinions: objectToMap((json.decisions as any).opinions ?? {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n voting: (json.decisions as any).voting ?? {},\n }\n : undefined,\n };\n\n return new Blackboard({ initialState: state });\n }\n}\n\n// Re-export error classes\nexport { VersionConflictError };\n","import type { AuditRecorder } from \"../audit/AuditTrail.js\";\nimport type { CellResult } from \"../cell/types.js\";\n\nexport interface StateBinding {\n source: string;\n target: string;\n transform?: string;\n condition?: string;\n}\n\nexport interface StateBinder {\n bind(cellResult: CellResult, bindings: StateBinding[]): Promise<void>;\n}\n\nexport interface StateStore {\n read(path: string): unknown;\n write(path: string, value: unknown): unknown;\n}\n\nexport type TransformFn = (value: unknown, cellResult: CellResult, binding: StateBinding) => unknown;\n\nexport interface StateBinderOptions {\n transforms?: Record<string, TransformFn>;\n evaluateCondition?: (condition: string, value: unknown, cellResult: CellResult, binding: StateBinding) => boolean;\n auditRecorder?: Pick<AuditRecorder, \"recordStateChange\">;\n}\n\nconst PATH_SEGMENT_PATTERN = /[^.[\\]]+|\\[(\\d+)\\]/g;\n\nfunction parsePath(path: string): string[] {\n return path.match(PATH_SEGMENT_PATTERN)?.map((segment) => segment.replace(/^\\[(\\d+)\\]$/, \"$1\")) ?? [];\n}\n\nfunction getByPath(source: unknown, path: string): unknown {\n if (path.trim() === \"\") {\n return source;\n }\n\n const segments = parsePath(path);\n let current: unknown = source;\n\n for (const segment of segments) {\n if (current === null || current === undefined) {\n return undefined;\n }\n\n if (Array.isArray(current)) {\n const index = Number(segment);\n current = Number.isInteger(index) ? current[index] : undefined;\n continue;\n }\n\n if (typeof current === \"object\") {\n current = (current as Record<string, unknown>)[segment];\n continue;\n }\n\n return undefined;\n }\n\n return current;\n}\n\nfunction resolvePathFunction(path: string): unknown {\n const segments = path.split(\".\").map((segment) => segment.trim()).filter(Boolean);\n let current: unknown = globalThis;\n\n for (const segment of segments) {\n if (current === null || current === undefined || (typeof current !== \"object\" && typeof current !== \"function\")) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current;\n}\n\ntype ConditionTokenType =\n | \"identifier\"\n | \"number\"\n | \"string\"\n | \"boolean\"\n | \"null\"\n | \"operator\"\n | \"paren\";\n\ninterface ConditionToken {\n type: ConditionTokenType;\n value: string;\n}\n\nfunction tokenizeCondition(condition: string): ConditionToken[] {\n const tokens: ConditionToken[] = [];\n let index = 0;\n\n const push = (type: ConditionTokenType, value: string) => {\n tokens.push({ type, value });\n };\n\n while (index < condition.length) {\n const char = condition[index] ?? \"\";\n\n if (/\\s/.test(char)) {\n index += 1;\n continue;\n }\n\n const twoChar = condition.slice(index, index + 2);\n if ([\"&&\", \"||\", \"==\", \"!=\", \">=\", \"<=\"].includes(twoChar)) {\n push(\"operator\", twoChar);\n index += 2;\n continue;\n }\n\n if ([\">\", \"<\", \"!\"].includes(char)) {\n push(\"operator\", char);\n index += 1;\n continue;\n }\n\n if (char === \"(\" || char === \")\") {\n push(\"paren\", char);\n index += 1;\n continue;\n }\n\n if (char === \"\\\"\" || char === \"'\") {\n const quote = char;\n let cursor = index + 1;\n let value = \"\";\n while (cursor < condition.length) {\n const current = condition[cursor] ?? \"\";\n if (current === \"\\\\\") {\n value += condition[cursor + 1] ?? \"\";\n cursor += 2;\n continue;\n }\n if (current === quote) {\n break;\n }\n value += current;\n cursor += 1;\n }\n if (condition[cursor] !== quote) {\n throw new Error(\"Unterminated string literal in condition\");\n }\n push(\"string\", value);\n index = cursor + 1;\n continue;\n }\n\n const numberMatch = condition.slice(index).match(/^-?\\d+(?:\\.\\d+)?/);\n if (numberMatch) {\n push(\"number\", numberMatch[0]);\n index += numberMatch[0].length;\n continue;\n }\n\n const identifierMatch = condition.slice(index).match(/^[A-Za-z_$][\\w$.]*/);\n if (identifierMatch) {\n const value = identifierMatch[0];\n if (value === \"true\" || value === \"false\") {\n push(\"boolean\", value);\n } else if (value === \"null\") {\n push(\"null\", value);\n } else {\n push(\"identifier\", value);\n }\n index += value.length;\n continue;\n }\n\n throw new Error(`Unsupported token in condition near '${condition.slice(index)}'`);\n }\n\n return tokens;\n}\n\nfunction resolveConditionIdentifier(name: string, scope: Record<string, unknown>): unknown {\n const segments = name.split(\".\").filter(Boolean);\n let current: unknown = scope;\n for (const segment of segments) {\n if (typeof current !== \"object\" || current === null) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\nfunction evaluateConditionExpression(\n condition: string,\n value: unknown,\n cellResult: CellResult,\n binding: StateBinding\n): boolean {\n const tokens = tokenizeCondition(condition);\n let cursor = 0;\n const scope = { value, cellResult, binding } as Record<string, unknown>;\n\n const peek = () => tokens[cursor];\n const consume = () => tokens[cursor++];\n const matchOperator = (...operators: string[]) => {\n const token = peek();\n if (token?.type === \"operator\" && operators.includes(token.value)) {\n consume();\n return token.value;\n }\n return undefined;\n };\n\n const parsePrimary = (): unknown => {\n const token = consume();\n if (!token) {\n throw new Error(\"Unexpected end of condition\");\n }\n\n if (token.type === \"paren\" && token.value === \"(\") {\n const result = parseOr();\n const closing = consume();\n if (!closing || closing.type !== \"paren\" || closing.value !== \")\") {\n throw new Error(\"Missing closing ')' in condition\");\n }\n return result;\n }\n\n if (token.type === \"number\") {\n return Number(token.value);\n }\n if (token.type === \"string\") {\n return token.value;\n }\n if (token.type === \"boolean\") {\n return token.value === \"true\";\n }\n if (token.type === \"null\") {\n return null;\n }\n if (token.type === \"identifier\") {\n return resolveConditionIdentifier(token.value, scope);\n }\n\n throw new Error(`Unexpected token '${token.value}' in condition`);\n };\n\n const parseUnary = (): unknown => {\n if (matchOperator(\"!\")) {\n return !Boolean(parseUnary());\n }\n return parsePrimary();\n };\n\n const parseComparison = (): unknown => {\n let left = parseUnary();\n while (true) {\n const operator = matchOperator(\"==\", \"!=\", \">\", \"<\", \">=\", \"<=\");\n if (!operator) {\n return left;\n }\n const right = parseUnary();\n switch (operator) {\n case \"==\": left = left == right; break;\n case \"!=\": left = left != right; break;\n case \">\": left = Number(left) > Number(right); break;\n case \"<\": left = Number(left) < Number(right); break;\n case \">=\": left = Number(left) >= Number(right); break;\n case \"<=\": left = Number(left) <= Number(right); break;\n }\n }\n };\n\n const parseAnd = (): unknown => {\n let left = parseComparison();\n while (matchOperator(\"&&\")) {\n const right = parseComparison();\n left = Boolean(left) && Boolean(right);\n }\n return left;\n };\n\n const parseOr = (): unknown => {\n let left = parseAnd();\n while (matchOperator(\"||\")) {\n const right = parseAnd();\n left = Boolean(left) || Boolean(right);\n }\n return left;\n };\n\n const result = parseOr();\n if (cursor < tokens.length) {\n throw new Error(`Unexpected trailing token '${tokens[cursor]?.value ?? \"\"}' in condition`);\n }\n\n return Boolean(result);\n}\n\nexport class DefaultStateBinder implements StateBinder {\n private readonly transforms: Record<string, TransformFn>;\n private readonly evaluateCondition: NonNullable<StateBinderOptions[\"evaluateCondition\"]>;\n private readonly auditRecorder?: Pick<AuditRecorder, \"recordStateChange\">;\n\n constructor(\n private readonly stateStore: StateStore,\n options: StateBinderOptions = {}\n ) {\n this.transforms = options.transforms ?? {};\n this.evaluateCondition = options.evaluateCondition ?? evaluateConditionExpression;\n this.auditRecorder = options.auditRecorder;\n }\n\n async bind(cellResult: CellResult, bindings: StateBinding[]): Promise<void> {\n for (const binding of bindings) {\n const sourceValue = getByPath(cellResult, binding.source);\n\n if (binding.condition && !this.evaluateCondition(binding.condition, sourceValue, cellResult, binding)) {\n continue;\n }\n\n const targetValue = binding.transform\n ? this.applyTransform(binding.transform, sourceValue, cellResult, binding)\n : sourceValue;\n\n const oldValue = this.readSafely(binding.target);\n this.stateStore.write(binding.target, targetValue);\n await this.auditRecorder?.recordStateChange(binding.target, oldValue, targetValue);\n }\n }\n\n private readSafely(path: string): unknown {\n try {\n return this.stateStore.read(path);\n } catch {\n return undefined;\n }\n }\n\n private applyTransform(\n transformName: string,\n value: unknown,\n cellResult: CellResult,\n binding: StateBinding\n ): unknown {\n const registeredTransform = this.transforms[transformName];\n if (registeredTransform) {\n return registeredTransform(value, cellResult, binding);\n }\n\n const resolved = resolvePathFunction(transformName);\n if (typeof resolved === \"function\") {\n return (resolved as (input: unknown) => unknown)(value);\n }\n\n throw new Error(`Unknown transform: ${transformName}`);\n }\n}\n\nexport const __internal = {\n getByPath,\n parsePath,\n resolvePathFunction,\n};\n","export function parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)([smhd])$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}`);\n }\n\n const value = Number.parseInt(match[1], 10);\n const unit = match[2];\n const multipliers: Record<string, number> = {\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n };\n\n return value * multipliers[unit];\n}\n\nexport function deepFreeze<T>(value: T): Readonly<T> {\n if (value === null || typeof value !== \"object\") {\n return value as Readonly<T>;\n }\n\n if (Object.isFrozen(value)) {\n return value as Readonly<T>;\n }\n\n const target = value as Record<string | symbol, unknown>;\n\n for (const key of Reflect.ownKeys(target)) {\n const child = target[key];\n if (child !== null && typeof child === \"object\") {\n deepFreeze(child);\n }\n }\n\n return Object.freeze(value) as Readonly<T>;\n}\n","import { deepFreeze } from \"./utils.js\";\nimport type { StepErrorMetadata } from \"./types.js\";\n\nexport interface StepRuntimeRecord {\n success: boolean;\n output: string | null;\n error: string | null;\n errorMeta?: StepErrorMetadata | null;\n diagnosisCode: string | null;\n completedAt: string | null;\n failedAt: string | null;\n}\n\nexport interface RuntimeState {\n state: {\n context: {\n workflow?: Record<string, unknown>;\n steps: Record<string, StepRuntimeRecord>;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\nexport class Blackboard {\n #state: RuntimeState;\n #version = 1;\n\n constructor(initialState?: Partial<RuntimeState>) {\n this.#state = {\n state: {\n context: {\n steps: {},\n },\n },\n };\n\n if (initialState) {\n this.#state = {\n ...this.#state,\n ...structuredClone(initialState),\n state: {\n ...this.#state.state,\n ...structuredClone(initialState.state ?? {}),\n context: {\n ...this.#state.state.context,\n ...structuredClone(initialState.state?.context ?? {}),\n steps: {\n ...this.#state.state.context.steps,\n ...(structuredClone(initialState.state?.context?.steps ?? {}) as Record<\n string,\n StepRuntimeRecord\n >),\n },\n },\n },\n };\n }\n }\n\n get version(): number {\n return this.#version;\n }\n\n #write(path: string, value: unknown): void {\n const parts = path.split(\".\");\n let cursor: Record<string, unknown> = this.#state as Record<string, unknown>;\n for (let i = 0; i < parts.length - 1; i++) {\n const key = parts[i];\n const next = cursor[key];\n if (next == null || typeof next !== \"object\") {\n cursor[key] = {};\n }\n cursor = cursor[key] as Record<string, unknown>;\n }\n cursor[parts[parts.length - 1]] = structuredClone(value);\n this.#version += 1;\n }\n\n read<T = unknown>(path: string, options?: { strict?: boolean }): T {\n const parts = path.split(\".\");\n let cursor: unknown = this.#state;\n for (const key of parts) {\n if (cursor == null || typeof cursor !== \"object\" || !(key in (cursor as object))) {\n if (options?.strict === false) {\n return undefined as T;\n }\n throw new Error(`Path not found: ${path}`);\n }\n cursor = (cursor as Record<string, unknown>)[key];\n }\n return structuredClone(cursor) as T;\n }\n\n exists(path: string): boolean {\n return this.read(path, { strict: false }) !== undefined;\n }\n\n\n on(_event: string, _listener: (...args: unknown[]) => void): this {\n return this;\n }\n\n off(_event: string, _listener: (...args: unknown[]) => void): this {\n return this;\n }\n\n once(_event: string, _listener: (...args: unknown[]) => void): this {\n return this;\n }\n\n emit(_event: string, ..._args: unknown[]): boolean {\n return false;\n }\n\n removeAllListeners(_event?: string): this {\n return this;\n }\n\n listenerCount(_event: string): number {\n return 0;\n }\n recordStepResult(name: string, result: StepRuntimeRecord): void {\n this.#write(`state.context.steps.${name}`, result);\n }\n\n recordStepError(\n name: string,\n error: Omit<StepErrorMetadata, \"code\"> & { code?: StepErrorMetadata[\"code\"] },\n ): void {\n this.#write(`state.context.steps.${name}`, {\n success: false,\n output: null,\n error: error.message,\n errorMeta: error.code ? (error as StepErrorMetadata) : null,\n diagnosisCode: error.code ?? null,\n completedAt: null,\n failedAt: error.failedAt ?? new Date().toISOString(),\n } satisfies StepRuntimeRecord);\n }\n\n getSnapshot(): Readonly<RuntimeState> {\n return deepFreeze(structuredClone(this.#state));\n }\n}\n","import type { TallyResult } from '../voting';\nimport type {\n ConsensusCondition,\n ConsensusEscalation,\n ConsensusResult,\n VotingSessionSnapshot,\n} from './types';\n\nexport type ConsensusMethod = VotingSessionSnapshot['policy'] | 'supermajority';\n\nexport interface EvaluateConsensusOptions {\n method?: ConsensusMethod;\n supermajorityThreshold?: number;\n conditionalCodes?: string[];\n escalation?: ConsensusEscalation;\n summary?: string;\n}\n\nfunction getApprovedByMethod(\n method: ConsensusMethod,\n tally: TallyResult,\n supermajorityThreshold: number,\n): boolean {\n if (!tally.quorumMet) {\n return false;\n }\n\n switch (method) {\n case 'majority':\n case 'weighted':\n return tally.passed;\n case 'unanimous':\n // 기권(abstains)은 투표 수에 포함하나 거부가 없으면 만장일치로 간주\n return tally.totalVotes > 0 && tally.rejects === 0 && tally.approves === tally.totalVotes - tally.abstains;\n case 'supermajority': {\n const supportRatio = tally.totalVotes === 0 ? 0 : tally.approves / tally.totalVotes;\n return supportRatio >= supermajorityThreshold;\n }\n default: {\n const _exhaustive: never = method;\n return false;\n }\n }\n}\n\nfunction toConditions(codes?: string[]): ConsensusCondition[] | undefined {\n if (!codes || codes.length === 0) {\n return undefined;\n }\n\n // 중복 제거, 빈 문자열 제거, trim\n const normalized = [...new Set(codes.map((c) => c.trim()).filter(Boolean))];\n\n if (normalized.length === 0) {\n return undefined;\n }\n\n return normalized.map((code) => ({\n code,\n description: code,\n }));\n}\n\nexport function evaluateConsensus(\n snapshot: VotingSessionSnapshot,\n options: EvaluateConsensusOptions = {},\n): ConsensusResult {\n const method = options.method ?? snapshot.policy;\n\n // supermajorityThreshold 검증: 유효한 숫자이고 [0, 1] 범위여야 함\n let threshold = options.supermajorityThreshold ?? 2 / 3;\n if (!Number.isFinite(threshold) || threshold < 0 || threshold > 1) {\n threshold = 2 / 3; // 안전한 기본값으로 대체\n }\n\n const conditions = toConditions(options.conditionalCodes);\n\n const approved = getApprovedByMethod(method, snapshot.tally, threshold);\n\n const status = options.escalation\n ? 'ESCALATED'\n : conditions && conditions.length > 0\n ? 'CONDITIONAL'\n : approved\n ? 'APPROVED'\n : 'REJECTED';\n\n return {\n sessionId: snapshot.sessionId,\n status,\n approved,\n summary: options.summary ?? `${method} rule evaluated`,\n snapshot,\n ...(conditions ? { conditions } : {}),\n ...(options.escalation ? { escalation: options.escalation } : {}),\n };\n}\n","import type { VotingPolicy, TallyResult, VotingSessionId } from '../voting';\n\nexport const CONSENSUS_STATUSES = ['APPROVED', 'REJECTED', 'CONDITIONAL', 'ESCALATED'] as const;\nexport type ConsensusStatus = (typeof CONSENSUS_STATUSES)[number];\n\nexport interface VotingSessionSnapshot {\n sessionId: VotingSessionId;\n policy: VotingPolicy;\n tally: TallyResult;\n}\n\nexport interface ConsensusCondition {\n code: string;\n description: string;\n}\n\nexport interface ConsensusEscalation {\n reason: string;\n requiredRoles: string[];\n}\n\nexport interface ConsensusResult {\n sessionId: VotingSessionId;\n status: ConsensusStatus;\n approved: boolean;\n summary: string;\n snapshot: VotingSessionSnapshot;\n conditions?: ConsensusCondition[];\n escalation?: ConsensusEscalation;\n dissentingVoterIds?: string[];\n}\n\nexport function isConsensusResult(value: unknown): value is ConsensusResult {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const candidate = value as Partial<ConsensusResult>;\n\n // 기본 필드 검증\n if (!candidate.sessionId || typeof candidate.sessionId !== 'string') {\n return false;\n }\n\n if (!candidate.status || !CONSENSUS_STATUSES.includes(candidate.status as ConsensusStatus)) {\n return false;\n }\n\n if (typeof candidate.approved !== 'boolean' || typeof candidate.summary !== 'string') {\n return false;\n }\n\n const snapshot = candidate.snapshot as Partial<VotingSessionSnapshot> | undefined;\n\n if (!snapshot || typeof snapshot.sessionId !== 'string') {\n return false;\n }\n\n // tally 필드 구조 검증\n const tally = snapshot.tally as Partial<TallyResult> | undefined;\n if (!tally || typeof tally.sessionId !== 'string') {\n return false;\n }\n\n // 숫자 필드 검증\n if (typeof tally.totalVotes !== 'number' || typeof tally.approves !== 'number' ||\n typeof tally.rejects !== 'number' || typeof tally.abstains !== 'number') {\n return false;\n }\n\n // 불리언 필드 검증\n if (typeof tally.passed !== 'boolean' || typeof tally.quorumMet !== 'boolean') {\n return false;\n }\n\n // conditions 배열 검증 (존재 시)\n if (candidate.conditions) {\n if (!Array.isArray(candidate.conditions) || candidate.conditions.length === 0) {\n return false;\n }\n for (const cond of candidate.conditions) {\n if (!cond || typeof cond.code !== 'string' || typeof cond.description !== 'string') {\n return false;\n }\n }\n }\n\n // escalation 객체 검증 (존재 시)\n if (candidate.escalation) {\n if (!candidate.escalation || typeof candidate.escalation.reason !== 'string' ||\n !Array.isArray(candidate.escalation.requiredRoles)) {\n return false;\n }\n for (const role of candidate.escalation.requiredRoles) {\n if (typeof role !== 'string') {\n return false;\n }\n }\n }\n\n return true;\n}\n","import { createSessionId } from '../../types';\nimport { VotingSession, Vote, TallyResult } from './types';\n\nexport class VotingSessionStore {\n private sessions: Map<string, VotingSession> = new Map();\n private votes: Map<string, Vote[]> = new Map();\n\n create(params: Omit<VotingSession, 'id' | 'createdAt' | 'status'>): VotingSession {\n const session: VotingSession = {\n ...params,\n id: createSessionId(crypto.randomUUID()),\n status: 'PENDING',\n createdAt: new Date(),\n };\n this.sessions.set(session.id, session);\n this.votes.set(session.id, []);\n return session;\n }\n\n get(id: string): VotingSession | undefined {\n return this.sessions.get(id);\n }\n\n getByAgendaId(agendaId: string): VotingSession[] {\n return Array.from(this.sessions.values()).filter((s) => s.agendaId === agendaId);\n }\n\n open(id: string): VotingSession | undefined {\n const session = this.sessions.get(id);\n if (!session || session.status !== 'PENDING') {\n return undefined;\n }\n session.status = 'OPEN';\n session.openedAt = new Date();\n return session;\n }\n\n close(id: string): VotingSession | undefined {\n const session = this.sessions.get(id);\n if (!session || session.status !== 'OPEN') {\n return undefined;\n }\n session.status = 'CLOSED';\n session.closedAt = new Date();\n return session;\n }\n\n addVote(vote: Omit<Vote, 'timestamp'>): Vote | null {\n const session = this.sessions.get(vote.sessionId);\n if (!session || session.status !== 'OPEN') {\n return null;\n }\n\n const votes = this.votes.get(vote.sessionId) || [];\n // 중복 투표 체크 (같은 유저가 다시 투표하면 기존 투표를 대체)\n const existingIndex = votes.findIndex((v) => v.voterId === vote.voterId);\n\n const newVote: Vote = {\n ...vote,\n timestamp: new Date(),\n };\n\n if (existingIndex >= 0) {\n votes[existingIndex] = newVote;\n } else {\n votes.push(newVote);\n }\n\n this.votes.set(vote.sessionId, votes);\n return newVote;\n }\n\n getVotes(sessionId: string): Vote[] {\n return this.votes.get(sessionId) || [];\n }\n\n getTally(sessionId: string): TallyResult | null {\n const session = this.sessions.get(sessionId);\n if (!session) {\n return null;\n }\n\n const votes = this.getVotes(sessionId);\n const approves = votes.filter((v) => v.option === 'approve').length;\n const rejects = votes.filter((v) => v.option === 'reject').length;\n const abstains = votes.filter((v) => v.option === 'abstain').length;\n const totalVotes = votes.length;\n\n let passed = false;\n\n switch (session.policy) {\n case 'majority':\n // 과반수 승인 (기권 제외)\n const majorityVotes = totalVotes - abstains;\n passed = majorityVotes > 0 && approves > majorityVotes / 2;\n break;\n case 'unanimous':\n // 만장일치 (반대 없고 기권 포함 전체 동의)\n passed = rejects === 0;\n break;\n case 'weighted':\n // 가중치 기반\n const approveWeight = votes\n .filter((v) => v.option === 'approve')\n .reduce((sum, v) => sum + (v.weight || 1), 0);\n const totalWeight = votes.reduce((sum, v) => sum + (v.weight || 1), 0);\n passed = totalWeight > 0 && approveWeight > totalWeight / 2;\n break;\n }\n\n // 정족수 체크\n const quorumMet = totalVotes >= session.quorum;\n\n return {\n sessionId: session.id,\n totalVotes,\n approves,\n rejects,\n abstains,\n passed,\n quorumMet,\n };\n }\n\n delete(id: string): boolean {\n const deleted = this.sessions.delete(id);\n this.votes.delete(id);\n return deleted;\n }\n}\n","import type { AuditTrail } from \"../audit/AuditTrail.js\";\nimport { VotingSessionStore } from \"./voting/VotingSessionStore.js\";\n\nexport interface ConsensusVoterSpec {\n id: string;\n weight?: number;\n}\n\nexport interface ConsensusIssue {\n severity: \"P0\" | \"P1\" | \"P2\";\n description: string;\n}\n\nexport interface ConsensusVoteInput {\n voterId: string;\n score?: number;\n approved: boolean;\n issues?: ConsensusIssue[];\n timestamp?: Date;\n}\n\nexport interface ConsensusVote {\n voterId: string;\n score?: number;\n approved: boolean;\n issues?: ConsensusIssue[];\n timestamp: Date;\n}\n\nexport interface ConsensusConfig {\n type: \"majority\" | \"unanimous\" | \"weighted\" | \"score-threshold\" | \"custom\";\n voters: ConsensusVoterSpec[];\n minRequired: number;\n threshold?: number;\n timeout?: string;\n bestEffort?: string[];\n customEvaluate?: (votes: ConsensusVote[]) => GateConsensusResult;\n}\n\nexport interface ConsensusSession {\n id: string;\n config: ConsensusConfig;\n startedAt: Date;\n bestEffortMarked: string[];\n}\n\nexport type GateConsensusResult =\n | { status: \"pass\"; votes: ConsensusVote[] }\n | { status: \"fail\"; reason: string; votes: ConsensusVote[] }\n | { status: \"pending\"; received: number; required: number }\n | { status: \"timeout\"; partial: ConsensusVote[] };\n\nexport interface ConsensusGate {\n setup(config: ConsensusConfig): ConsensusSession;\n registerVote(sessionId: string, vote: ConsensusVoteInput): void;\n evaluate(sessionId: string): GateConsensusResult;\n onTimeout(sessionId: string): GateConsensusResult;\n markBestEffort(sessionId: string, voterId: string): void;\n}\n\ninterface SessionState {\n session: ConsensusSession;\n votes: Map<string, ConsensusVote>;\n}\n\nconst parseTimeoutToMs = (timeout?: string): number | undefined => {\n if (!timeout) {\n return undefined;\n }\n\n const match = timeout.trim().match(/^(\\d+)(ms|s|m|h)$/);\n if (!match) {\n return undefined;\n }\n\n const value = Number(match[1]);\n const unit = match[2];\n if (unit === \"ms\") return value;\n if (unit === \"s\") return value * 1_000;\n if (unit === \"m\") return value * 60_000;\n return value * 3_600_000;\n};\n\n/** Clamp a score value to [0, 1]. Undefined scores pass through unchanged. */\nconst clampScore = (score: number | undefined): number | undefined =>\n score === undefined ? undefined : Math.max(0, Math.min(1, score));\nconst cloneVotes = (votes: Iterable<ConsensusVote>): ConsensusVote[] =>\n Array.from(votes).map((vote) => ({ ...vote, timestamp: new Date(vote.timestamp) }));\n\nexport class DefaultConsensusGate implements ConsensusGate {\n private readonly sessions = new Map<string, SessionState>();\n private readonly votingSessionStore: VotingSessionStore;\n\n constructor(\n private readonly options: {\n executionId: string;\n auditTrail?: AuditTrail;\n votingSessionStore?: VotingSessionStore;\n now?: () => Date;\n sessionIdFactory?: () => string;\n }\n ) {\n this.votingSessionStore = options.votingSessionStore ?? new VotingSessionStore();\n }\n\n setup(config: ConsensusConfig): ConsensusSession {\n if (config.minRequired <= 0) {\n throw new Error(\"ConsensusConfig.minRequired must be greater than 0\");\n }\n\n const voterIds = new Set(config.voters.map((voter) => voter.id));\n if (voterIds.size !== config.voters.length) {\n throw new Error(\"ConsensusConfig.voters must be unique\");\n }\n\n const sessionId = this.options.sessionIdFactory?.() ?? crypto.randomUUID();\n const startedAt = this.options.now?.() ?? new Date();\n const session: ConsensusSession = {\n id: sessionId,\n config: {\n ...config,\n bestEffort: config.bestEffort ?? [],\n },\n startedAt,\n bestEffortMarked: [],\n };\n\n const internalSession = this.votingSessionStore.create({\n agendaId: `consensus:${sessionId}`,\n policy:\n config.type === \"score-threshold\" || config.type === \"custom\"\n ? \"majority\"\n : config.type,\n quorum: config.minRequired,\n createdBy: \"runtime:consensus-gate\",\n });\n this.votingSessionStore.open(internalSession.id);\n\n this.sessions.set(sessionId, {\n session,\n votes: new Map<string, ConsensusVote>(),\n });\n\n return { ...session, startedAt: new Date(startedAt), bestEffortMarked: [...session.bestEffortMarked] };\n }\n\n registerVote(sessionId: string, vote: ConsensusVoteInput): void {\n const state = this.requireState(sessionId);\n const timestamp = vote.timestamp ?? (this.options.now?.() ?? new Date());\n const resolvedVote: ConsensusVote = {\n voterId: vote.voterId,\n score: clampScore(vote.score),\n approved: vote.approved,\n issues: vote.issues,\n timestamp,\n };\n\n state.votes.set(vote.voterId, resolvedVote);\n\n this.votingSessionStore.addVote({\n sessionId: this.findVotingSessionId(sessionId),\n voterId: vote.voterId,\n option: vote.approved ? \"approve\" : \"reject\",\n weight: state.session.config.voters.find((v) => v.id === vote.voterId)?.weight,\n });\n\n void this.options.auditTrail?.record({\n id: crypto.randomUUID(),\n executionId: this.options.executionId,\n timestamp: new Date(timestamp),\n type: \"consensus_vote\",\n data: {\n sessionId,\n vote: resolvedVote,\n },\n });\n }\n\n evaluate(sessionId: string): GateConsensusResult {\n const state = this.requireState(sessionId);\n const result = this.evaluateInternal(state, false);\n this.recordConsensusResult(sessionId, result);\n return result;\n }\n\n onTimeout(sessionId: string): GateConsensusResult {\n const state = this.requireState(sessionId);\n const result: GateConsensusResult = {\n status: \"timeout\",\n partial: cloneVotes(state.votes.values()),\n };\n this.recordConsensusResult(sessionId, result);\n return result;\n }\n\n markBestEffort(sessionId: string, voterId: string): void {\n const state = this.requireState(sessionId);\n if (!state.session.bestEffortMarked.includes(voterId)) {\n state.session.bestEffortMarked.push(voterId);\n }\n }\n\n private evaluateInternal(state: SessionState, timedOut: boolean): GateConsensusResult {\n if (timedOut) {\n return {\n status: \"timeout\",\n partial: cloneVotes(state.votes.values()),\n };\n }\n\n const timeoutMs = parseTimeoutToMs(state.session.config.timeout);\n if (timeoutMs) {\n const now = this.options.now?.() ?? new Date();\n if (now.getTime() - state.session.startedAt.getTime() > timeoutMs) {\n return {\n status: \"timeout\",\n partial: cloneVotes(state.votes.values()),\n };\n }\n }\n\n const votes = cloneVotes(state.votes.values());\n const effectiveMinRequired = Math.max(\n 0,\n state.session.config.minRequired - state.session.bestEffortMarked.length,\n );\n\n if (votes.length < effectiveMinRequired) {\n return {\n status: \"pending\",\n received: votes.length,\n required: effectiveMinRequired,\n };\n }\n\n if (state.session.config.type === \"custom\" && state.session.config.customEvaluate) {\n return state.session.config.customEvaluate(votes);\n }\n\n // M2-03A: only required voters (not best_effort-marked) influence pass/fail verdict\n const bestEffortSet = new Set([\n ...(state.session.config.bestEffort ?? []),\n ...state.session.bestEffortMarked,\n ]);\n const requiredVotes = votes.filter((vote) => !bestEffortSet.has(vote.voterId));\n\n const rejectVote = requiredVotes.find((vote) => vote.approved === false);\n const approvalCount = requiredVotes.filter((vote) => vote.approved).length;\n\n if (state.session.config.type === \"unanimous\") {\n if (rejectVote) {\n return { status: \"fail\", reason: \"unanimous consensus rejected\", votes };\n }\n return { status: \"pass\", votes };\n }\n\n if (state.session.config.type === \"score-threshold\") {\n const threshold = state.session.config.threshold ?? 0;\n const scoredVotes = requiredVotes.filter((vote) => typeof vote.score === \"number\");\n if (scoredVotes.length === 0) {\n return { status: \"fail\", reason: \"no scored votes provided\", votes };\n }\n const averageScore =\n scoredVotes.reduce((sum, vote) => sum + (vote.score ?? 0), 0) / scoredVotes.length;\n if (averageScore >= threshold) {\n return { status: \"pass\", votes };\n }\n return { status: \"fail\", reason: `score threshold not met: ${averageScore} < ${threshold}`, votes };\n }\n\n if (state.session.config.type === \"weighted\") {\n const approveWeight = requiredVotes\n .filter((vote) => vote.approved)\n .reduce((sum, vote) => sum + (this.findWeight(state, vote.voterId) ?? 1), 0);\n const totalWeight = requiredVotes.reduce(\n (sum, vote) => sum + (this.findWeight(state, vote.voterId) ?? 1),\n 0,\n );\n if (totalWeight <= 0) {\n return { status: \"fail\", reason: \"invalid total vote weight\", votes };\n }\n if (approveWeight > totalWeight / 2) {\n return { status: \"pass\", votes };\n }\n return { status: \"fail\", reason: \"weighted majority not reached\", votes };\n }\n\n if (approvalCount > requiredVotes.length / 2) {\n return { status: \"pass\", votes };\n }\n\n return { status: \"fail\", reason: \"majority not reached\", votes };\n }\n\n private findVotingSessionId(consensusSessionId: string): string {\n const sessions = this.votingSessionStore.getByAgendaId(`consensus:${consensusSessionId}`);\n const latest = sessions[sessions.length - 1];\n if (!latest) {\n throw new Error(`VotingSession is not initialized for consensus session: ${consensusSessionId}`);\n }\n return latest.id;\n }\n\n private findWeight(state: SessionState, voterId: string): number | undefined {\n return state.session.config.voters.find((voter) => voter.id === voterId)?.weight;\n }\n\n private requireState(sessionId: string): SessionState {\n const state = this.sessions.get(sessionId);\n if (!state) {\n throw new Error(`Consensus session not found: ${sessionId}`);\n }\n return state;\n }\n\n private recordConsensusResult(sessionId: string, result: GateConsensusResult): void {\n void this.options.auditTrail?.record({\n id: crypto.randomUUID(),\n executionId: this.options.executionId,\n timestamp: this.options.now?.() ?? new Date(),\n type: \"consensus_result\",\n data: {\n sessionId,\n result,\n },\n });\n }\n}\n","import { evaluateExpression } from \"../policy/expressions/ExpressionEvaluator.js\";\nimport { parseExpression } from \"../policy/expressions/ExpressionParser.js\";\n\nexport type GateFallback = \"fail\" | \"escalate\" | \"auto-approve\";\n\nexport type HITLAuditEventType =\n | \"gate_assignment_created\"\n | \"gate_assignment_reassigned\"\n | \"gate_assignment_expired\"\n | \"gate_approval_decision\"\n | \"gate_sla_warning\"\n | \"gate_sla_expired\";\n\nexport interface GateAuditEvent {\n type: HITLAuditEventType;\n payload: Record<string, unknown>;\n}\n\nexport interface GateRuntimeContext {\n emit?: (event: GateAuditEvent) => Promise<void> | void;\n now?: () => Date;\n conditionContext?: Record<string, unknown>;\n}\n\nexport function parseDurationToMs(duration?: string): number | undefined {\n if (!duration) {\n return undefined;\n }\n\n const match = duration.trim().match(/^(\\d+)(ms|s|m|h|d)$/);\n if (!match) {\n return undefined;\n }\n\n const value = Number(match[1]);\n const unit = match[2];\n\n if (unit === \"ms\") return value;\n if (unit === \"s\") return value * 1_000;\n if (unit === \"m\") return value * 60_000;\n if (unit === \"h\") return value * 3_600_000;\n return value * 86_400_000;\n}\n\n/**\n * Evaluate a gate condition expression.\n *\n * @throws {Error} When parsing or evaluation fails. Callers must handle this\n * as a fail-closed error path (stage failure), not as a skipped stage.\n */\nexport function evaluateGateCondition(condition: string | undefined, context: Record<string, unknown>): boolean {\n if (!condition) {\n return true;\n }\n\n const ast = parseExpression(condition);\n return evaluateExpression(ast, {\n action: { type: \"step_start\", name: \"gate-condition\" },\n context,\n });\n}\n","import { evaluateGateCondition, type GateFallback, type GateRuntimeContext } from \"./types.js\";\n\nexport interface ApprovalStage {\n name: string;\n approvers: string[];\n required: number;\n timeout?: string;\n fallback?: GateFallback;\n escalation_to?: string;\n condition?: string;\n}\n\nexport interface MultiStageGateConfig {\n stages: ApprovalStage[];\n on_reject?: \"fail\" | \"restart\" | \"reassign\";\n allow_comments?: boolean;\n track_history?: boolean;\n}\n\nexport interface ApprovalDecision {\n stageIndex: number;\n stageName: string;\n approver: string;\n decision: \"approved\" | \"rejected\" | \"abstained\";\n comment?: string;\n timestamp: Date;\n}\n\nexport interface MultiStageApprovalResult {\n approved: boolean;\n stages: Array<{\n name: string;\n status: \"approved\" | \"rejected\" | \"pending\" | \"skipped\" | \"timeout\";\n decisions: ApprovalDecision[];\n }>;\n reason?: string;\n /**\n * Signals the distinct on_reject action the caller should take:\n * - \"fail\": terminal rejection, no retry.\n * - \"restart\": caller should reset all stages and re-collect decisions from stage 0.\n * - \"reassign\": caller should reassign the rejecting stage to a different approver.\n * Only set when a rejection occurs.\n */\n action?: \"fail\" | \"restart\" | \"reassign\";\n /** When action=\"reassign\", identifies the stage index to reassign. */\n reassignStageIndex?: number;\n}\n\n/**\n * Stage-level timeout/fallback/escalation_to mapping to SLAManager:\n *\n * Each ApprovalStage may declare `timeout`, `fallback`, and `escalation_to`.\n * These fields map to SLAManager.checkSLA() as follows:\n * - stage.timeout → SLAConfig.timeout\n * - stage.fallback → SLAConfig.fallback (defaults to \"fail\")\n * - stage.escalation_to → SLAConfig.escalation_chain[0]\n *\n * The caller is responsible for constructing an SLAConfig from stage fields\n * and invoking SLAManager.checkSLA() with the relevant GateAssignment.\n * Use `buildSLAConfigFromStage()` below for the canonical mapping.\n */\n\nexport interface StageSLAConfig {\n timeout: string;\n fallback: GateFallback;\n escalation_chain?: string[];\n}\n\n/**\n * Build an SLAConfig from stage-level timeout/fallback/escalation_to fields.\n * Returns undefined if the stage has no timeout configured.\n */\nexport function buildSLAConfigFromStage(stage: ApprovalStage): StageSLAConfig | undefined {\n if (!stage.timeout) return undefined;\n return {\n timeout: stage.timeout,\n fallback: stage.fallback ?? \"fail\",\n escalation_chain: stage.escalation_to ? [stage.escalation_to] : undefined,\n };\n}\n\nexport class MultiStageApprovalGate {\n constructor(\n private readonly config: MultiStageGateConfig,\n private readonly context: GateRuntimeContext = {}\n ) {}\n\n async evaluate(decisions: ApprovalDecision[]): Promise<MultiStageApprovalResult> {\n const normalized = this.normalizeDecisions(decisions);\n const stageResults: MultiStageApprovalResult[\"stages\"] = [];\n const trackHistory = this.config.track_history ?? true;\n const onReject = this.config.on_reject ?? \"fail\";\n\n for (let stageIndex = 0; stageIndex < this.config.stages.length; stageIndex += 1) {\n const stage = this.config.stages[stageIndex]!;\n let allowed = false;\n try {\n allowed = evaluateGateCondition(stage.condition, {\n ...(this.context.conditionContext ?? {}),\n stageIndex,\n stageName: stage.name,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n stageResults.push({\n name: stage.name,\n status: \"rejected\",\n decisions: [],\n });\n return {\n approved: false,\n stages: stageResults,\n reason: `condition_evaluation_error: ${message}`,\n action: \"fail\",\n };\n }\n\n if (!allowed) {\n stageResults.push({ name: stage.name, status: \"skipped\", decisions: [] });\n continue;\n }\n\n const stageDecisions = this.pickStageDecisions(normalized, stageIndex, stage.name, stage.approvers);\n const approvals = stageDecisions.filter((entry) => entry.decision === \"approved\").length;\n const rejections = stageDecisions.filter((entry) => entry.decision === \"rejected\");\n\n if (rejections.length > 0) {\n for (const rejection of rejections) {\n await this.context.emit?.({\n type: \"gate_approval_decision\",\n payload: {\n stageIndex,\n stageName: stage.name,\n approver: rejection.approver,\n decision: rejection.decision,\n comment: rejection.comment,\n timestamp: rejection.timestamp.toISOString(),\n },\n });\n }\n\n stageResults.push({\n name: stage.name,\n status: \"rejected\",\n decisions: trackHistory ? stageDecisions : [],\n });\n\n const result: MultiStageApprovalResult = {\n approved: false,\n stages: stageResults,\n reason: `Rejected at stage '${stage.name}' (${onReject})`,\n action: onReject,\n };\n\n // For \"reassign\", indicate which stage needs reassignment\n if (onReject === \"reassign\") {\n result.reassignStageIndex = stageIndex;\n }\n\n return result;\n }\n\n for (const stageDecision of stageDecisions) {\n await this.context.emit?.({\n type: \"gate_approval_decision\",\n payload: {\n stageIndex,\n stageName: stage.name,\n approver: stageDecision.approver,\n decision: stageDecision.decision,\n comment: stageDecision.comment,\n timestamp: stageDecision.timestamp.toISOString(),\n },\n });\n }\n\n if (approvals >= stage.required) {\n stageResults.push({\n name: stage.name,\n status: \"approved\",\n decisions: trackHistory ? stageDecisions : [],\n });\n continue;\n }\n\n stageResults.push({\n name: stage.name,\n status: \"pending\",\n decisions: trackHistory ? stageDecisions : [],\n });\n\n return {\n approved: false,\n stages: stageResults,\n reason: `Stage '${stage.name}' requires ${stage.required} approvals (${approvals} received)`,\n };\n }\n\n return {\n approved: true,\n stages: stageResults,\n };\n }\n\n private normalizeDecisions(decisions: ApprovalDecision[]): ApprovalDecision[] {\n return [...decisions].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n }\n\n private pickStageDecisions(\n decisions: ApprovalDecision[],\n stageIndex: number,\n stageName: string,\n allowedApprovers: string[]\n ): ApprovalDecision[] {\n const latestByApprover = new Map<string, ApprovalDecision>();\n\n for (const decision of decisions) {\n if (decision.stageIndex !== stageIndex && decision.stageName !== stageName) {\n continue;\n }\n if (!allowedApprovers.includes(decision.approver)) {\n continue;\n }\n\n const normalizedDecision = this.config.allow_comments === false\n ? { ...decision, comment: undefined }\n : decision;\n latestByApprover.set(decision.approver, normalizedDecision);\n }\n\n return [...latestByApprover.values()].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n }\n}\n","import { parseDurationToMs, type GateRuntimeContext } from \"./types.js\";\n\nexport interface GateAssignment {\n gateId: string;\n stepName: string;\n assignedTo: string;\n assignedAt: Date;\n expiresAt?: Date;\n status: \"pending\" | \"completed\" | \"expired\" | \"reassigned\";\n reassignedFrom?: string;\n reassignmentReason?: string;\n}\n\nexport class GateAssignmentManager {\n private readonly assignments = new Map<string, GateAssignment>();\n\n constructor(private readonly context: GateRuntimeContext = {}) {}\n\n assign(gateId: string, stepName: string, assignee: string, timeout?: string): GateAssignment {\n const assignedAt = this.now();\n const timeoutMs = parseDurationToMs(timeout);\n const assignment: GateAssignment = {\n gateId,\n stepName,\n assignedTo: assignee,\n assignedAt,\n expiresAt: timeoutMs !== undefined ? new Date(assignedAt.getTime() + timeoutMs) : undefined,\n status: \"pending\",\n };\n\n this.assignments.set(gateId, assignment);\n void this.context.emit?.({\n type: \"gate_assignment_created\",\n payload: {\n gateId,\n stepName,\n assignedTo: assignee,\n assignedAt: assignedAt.toISOString(),\n expiresAt: assignment.expiresAt?.toISOString(),\n },\n });\n\n return structuredClone(assignment);\n }\n\n /**\n * Reassign a gate to a new assignee. The expiresAt is refreshed:\n * - If an explicit `timeout` is provided, use it from now.\n * - Otherwise, preserve the original timeout duration relative to new assignedAt.\n * - If the original had no timeout, expiresAt remains undefined.\n */\n reassign(gateId: string, newAssignee: string, reason: string, timeout?: string): GateAssignment {\n const current = this.assignments.get(gateId);\n if (!current) {\n throw new Error(`Gate assignment not found: ${gateId}`);\n }\n\n current.status = \"reassigned\";\n this.assignments.set(gateId, current);\n\n const reassignedAt = this.now();\n\n // Refresh expiresAt\n let newExpiresAt: Date | undefined;\n if (timeout) {\n const timeoutMs = parseDurationToMs(timeout);\n newExpiresAt = timeoutMs !== undefined ? new Date(reassignedAt.getTime() + timeoutMs) : undefined;\n } else if (current.expiresAt && current.assignedAt) {\n const originalDurationMs = current.expiresAt.getTime() - current.assignedAt.getTime();\n newExpiresAt = new Date(reassignedAt.getTime() + originalDurationMs);\n }\n\n const reassigned: GateAssignment = {\n ...current,\n assignedTo: newAssignee,\n assignedAt: reassignedAt,\n expiresAt: newExpiresAt,\n status: \"pending\",\n reassignedFrom: current.assignedTo,\n reassignmentReason: reason,\n };\n\n this.assignments.set(gateId, reassigned);\n void this.context.emit?.({\n type: \"gate_assignment_reassigned\",\n payload: {\n gateId,\n stepName: reassigned.stepName,\n from: reassigned.reassignedFrom,\n to: newAssignee,\n reason,\n expiresAt: reassigned.expiresAt?.toISOString(),\n },\n });\n\n return structuredClone(reassigned);\n }\n\n expire(gateId: string): GateAssignment {\n const current = this.assignments.get(gateId);\n if (!current) {\n throw new Error(`Gate assignment not found: ${gateId}`);\n }\n\n const expired: GateAssignment = {\n ...current,\n status: \"expired\",\n };\n this.assignments.set(gateId, expired);\n\n void this.context.emit?.({\n type: \"gate_assignment_expired\",\n payload: {\n gateId,\n stepName: expired.stepName,\n assignedTo: expired.assignedTo,\n expiredAt: this.now().toISOString(),\n },\n });\n\n return structuredClone(expired);\n }\n\n getAssignment(gateId: string): GateAssignment | undefined {\n const assignment = this.assignments.get(gateId);\n return assignment ? structuredClone(assignment) : undefined;\n }\n\n getActiveAssignments(): GateAssignment[] {\n return [...this.assignments.values()]\n .filter((assignment) => assignment.status === \"pending\")\n .map((assignment) => structuredClone(assignment));\n }\n\n private now(): Date {\n return this.context.now ? this.context.now() : new Date();\n }\n}\n","import type { GateAssignment } from \"./GateAssignment.js\";\nimport { parseDurationToMs, type GateFallback, type GateRuntimeContext } from \"./types.js\";\n\nexport interface SLAConfig {\n timeout: string;\n warning_at?: string;\n fallback: GateFallback;\n escalation_chain?: string[];\n}\n\nexport interface SLACheckResult {\n status: \"ok\" | \"warning\" | \"expired\";\n remainingMs?: number;\n action?: \"none\" | \"warn\" | \"escalate\" | \"auto-approve\" | \"fail\";\n escalationTarget?: string;\n}\n\nexport class SLAManager {\n constructor(private readonly context: GateRuntimeContext = {}) {}\n\n checkSLA(assignment: GateAssignment, config: SLAConfig): SLACheckResult {\n const now = this.now();\n const timeoutMs = parseDurationToMs(config.timeout);\n if (timeoutMs === undefined) {\n return { status: \"ok\", action: \"none\" };\n }\n\n const deadline = assignment.expiresAt ?? new Date(assignment.assignedAt.getTime() + timeoutMs);\n const remainingMs = deadline.getTime() - now.getTime();\n\n if (remainingMs <= 0) {\n const expired = this.resolveExpired(config);\n void this.context.emit?.({\n type: \"gate_sla_expired\",\n payload: {\n gateId: assignment.gateId,\n stepName: assignment.stepName,\n assignedTo: assignment.assignedTo,\n fallback: config.fallback,\n escalationTarget: expired.escalationTarget,\n },\n });\n return {\n status: \"expired\",\n remainingMs: 0,\n action: expired.action,\n escalationTarget: expired.escalationTarget,\n };\n }\n\n const warningMs = parseDurationToMs(config.warning_at);\n if (warningMs !== undefined && remainingMs <= warningMs) {\n void this.context.emit?.({\n type: \"gate_sla_warning\",\n payload: {\n gateId: assignment.gateId,\n stepName: assignment.stepName,\n assignedTo: assignment.assignedTo,\n remainingMs,\n },\n });\n return { status: \"warning\", remainingMs, action: \"warn\" };\n }\n\n return { status: \"ok\", remainingMs, action: \"none\" };\n }\n\n private resolveExpired(config: SLAConfig): { action: \"escalate\" | \"auto-approve\" | \"fail\"; escalationTarget?: string } {\n if (config.fallback === \"escalate\") {\n return {\n action: \"escalate\",\n escalationTarget: config.escalation_chain?.[0],\n };\n }\n\n if (config.fallback === \"auto-approve\") {\n return { action: \"auto-approve\" };\n }\n\n return { action: \"fail\" };\n }\n\n private now(): Date {\n return this.context.now ? this.context.now() : new Date();\n }\n}\n","import type { AuditTrail, ReplayOptions, ReplayResult } from \"./AuditTrail.js\";\nimport type { AuditEvent, AuditEventType, AuditFilter } from \"./types.js\";\n\nfunction cloneEvent(event: AuditEvent): AuditEvent {\n return {\n ...event,\n timestamp: new Date(event.timestamp),\n };\n}\n\nfunction escapeCsv(value: unknown): string {\n if (value === null || value === undefined) {\n return \"\";\n }\n\n const raw = typeof value === \"string\" ? value : JSON.stringify(value);\n const escaped = raw.replaceAll('\"', '\"\"');\n return `\"${escaped}\"`;\n}\n\nfunction sleep(ms: number): Promise<void> {\n if (ms <= 0) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nexport class InMemoryAuditStore implements AuditTrail {\n private events: AuditEvent[] = [];\n\n async record(event: AuditEvent): Promise<void> {\n this.events.push(cloneEvent(event));\n }\n\n async query(filter: AuditFilter = {}): Promise<AuditEvent[]> {\n const requestedTypes = Array.isArray(filter.type)\n ? new Set<AuditEventType>(filter.type)\n : filter.type\n ? new Set<AuditEventType>([filter.type])\n : undefined;\n\n let result = this.events.filter((event) => {\n if (filter.executionId && event.executionId !== filter.executionId) {\n return false;\n }\n\n if (filter.cellId && event.cellId !== filter.cellId) {\n return false;\n }\n\n if (requestedTypes && !requestedTypes.has(event.type)) {\n return false;\n }\n\n if (filter.from && event.timestamp < filter.from) {\n return false;\n }\n\n if (filter.to && event.timestamp > filter.to) {\n return false;\n }\n\n return true;\n });\n\n result = [...result].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());\n\n if (filter.limit && filter.limit > 0) {\n result = result.slice(0, filter.limit);\n }\n\n return result.map(cloneEvent);\n }\n\n async replay(options: ReplayOptions): Promise<ReplayResult> {\n const mode = options.mode ?? \"event-playback\";\n if (mode !== \"event-playback\") {\n throw new Error(`Replay mode '${mode}' is not supported in M1`);\n }\n\n const speed = options.speed ?? 1;\n if (!Number.isFinite(speed) || speed <= 0) {\n throw new Error(\"Replay speed must be a positive finite number\");\n }\n\n const sequence = await this.query({ executionId: options.executionId });\n const startedAt = new Date();\n\n for (let index = 0; index < sequence.length; index += 1) {\n const current = sequence[index];\n const next = sequence[index + 1];\n\n if (options.onEvent) {\n await options.onEvent(cloneEvent(current), index);\n }\n\n if (next) {\n const deltaMs = next.timestamp.getTime() - current.timestamp.getTime();\n if (deltaMs > 0) {\n await sleep(deltaMs / speed);\n }\n }\n }\n\n const completedAt = new Date();\n\n return {\n mode: \"event-playback\",\n executionId: options.executionId,\n totalEvents: sequence.length,\n startedAt,\n completedAt,\n durationMs: completedAt.getTime() - startedAt.getTime(),\n sequence,\n };\n }\n\n async export(executionId: string, format: \"json\" | \"csv\"): Promise<string> {\n const events = await this.query({ executionId });\n\n if (format === \"json\") {\n return JSON.stringify(events, null, 2);\n }\n\n const header = [\n \"id\",\n \"executionId\",\n \"cellId\",\n \"timestamp\",\n \"type\",\n \"data\",\n \"metadata\",\n ].join(\",\");\n\n const rows = events.map((event) =>\n [\n escapeCsv(event.id),\n escapeCsv(event.executionId),\n escapeCsv(event.cellId ?? \"\"),\n escapeCsv(event.timestamp.toISOString()),\n escapeCsv(event.type),\n escapeCsv(event.data),\n escapeCsv(event.metadata ?? \"\"),\n ].join(\",\"),\n );\n\n return [header, ...rows].join(\"\\n\");\n }\n}\n","import type { AuditRecorder, AuditTrail } from \"./AuditTrail.js\";\n\nexport class DefaultAuditRecorder implements AuditRecorder {\n constructor(\n private readonly trail: AuditTrail,\n private readonly executionId: string,\n private readonly cellId: string,\n ) {}\n\n async recordToolCall(\n toolName: string,\n params: unknown,\n result: unknown,\n durationMs: number,\n ): Promise<void> {\n const now = new Date();\n\n await this.trail.record({\n id: crypto.randomUUID(),\n executionId: this.executionId,\n cellId: this.cellId,\n timestamp: now,\n type: \"tool_call\",\n data: {\n toolName,\n params,\n },\n });\n\n await this.trail.record({\n id: crypto.randomUUID(),\n executionId: this.executionId,\n cellId: this.cellId,\n timestamp: new Date(),\n type: \"tool_result\",\n data: {\n toolName,\n result,\n },\n metadata: {\n durationMs,\n },\n });\n }\n\n async recordStateChange(path: string, oldValue: unknown, newValue: unknown): Promise<void> {\n await this.trail.record({\n id: crypto.randomUUID(),\n executionId: this.executionId,\n cellId: this.cellId,\n timestamp: new Date(),\n type: \"state_change\",\n data: {\n path,\n oldValue,\n newValue,\n },\n });\n }\n\n async recordError(code: string, message: string, context?: unknown): Promise<void> {\n await this.trail.record({\n id: crypto.randomUUID(),\n executionId: this.executionId,\n cellId: this.cellId,\n timestamp: new Date(),\n type: \"error\",\n data: {\n code,\n message,\n context,\n },\n });\n }\n}\n","import type { AuditTrail } from \"./AuditTrail.js\";\nimport { EventBus } from \"./event-bus.js\";\nimport type { AuditEvent, AuditEventType } from \"./types.js\";\n\ninterface EventBusMessage {\n id: string;\n type: string;\n timestamp: Date;\n source: string;\n correlationId?: string;\n payload: unknown;\n}\n\nconst EVENT_TYPE_MAP: Record<string, AuditEventType> = {\n \"task.started\": \"step_start\",\n \"task.completed\": \"step_end\",\n \"task.failed\": \"error\",\n \"state.context.updated\": \"state_change\",\n \"state.task.completed\": \"step_end\",\n \"state.task.failed\": \"error\",\n \"decision.vote.requested\": \"consensus_vote\",\n \"decision.consensus.reached\": \"consensus_result\",\n \"snapshot.created\": \"snapshot_create\",\n \"snapshot.restored\": \"snapshot_restore\",\n \"system.error\": \"error\",\n};\n\nexport class EventBusAdapter {\n private unsubscribe?: () => void;\n\n constructor(\n private readonly eventBus: EventBus,\n private readonly trail: AuditTrail,\n private readonly fallbackExecutionId: string = \"event-bus\",\n ) {}\n\n start(): void {\n this.unsubscribe = this.eventBus.subscribe(\"*\", (event) => {\n void this.handleEvent(event);\n });\n }\n\n stop(): void {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n }\n\n private async handleEvent(event: EventBusMessage): Promise<void> {\n const auditType = EVENT_TYPE_MAP[event.type];\n\n if (!auditType) {\n return;\n }\n\n const payload = event.payload as Record<string, unknown>;\n const auditEvent: AuditEvent = {\n id: event.id,\n executionId: event.correlationId ?? this.fallbackExecutionId,\n cellId: typeof payload?.taskId === \"string\" ? payload.taskId : undefined,\n timestamp: event.timestamp,\n type: auditType,\n data: {\n sourceType: event.type,\n source: event.source,\n payload: event.payload,\n },\n };\n\n await this.trail.record(auditEvent);\n }\n}\n","import type { AuditTrail } from \"./AuditTrail.js\";\nimport type { AuditEvent } from \"./types.js\";\n\nexport interface ReExecutionPlan {\n executionId: string;\n originalWorkflow: string;\n workflowVersion?: string;\n snapshotRef?: string;\n mode: \"full\" | \"from_checkpoint\";\n startFromStep?: string;\n restoredState?: Record<string, unknown>;\n stepsToRerun: string[];\n stepsToSkip: string[];\n nonDeterminismWarnings: NonDeterminismWarning[];\n createdAt: Date;\n}\n\nexport interface NonDeterminismWarning {\n type: \"model_change\" | \"time_drift\" | \"policy_change\" | \"state_external\" | \"tool_output\";\n description: string;\n stepName?: string;\n severity: \"info\" | \"warning\" | \"critical\";\n}\n\nexport interface ReExecutionPlannerOptions {\n mode: \"full\" | \"from_checkpoint\";\n checkpointStep?: string;\n detectNonDeterminism?: boolean;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction getStepName(event: AuditEvent): string | undefined {\n if (!isObject(event.data)) {\n return undefined;\n }\n\n return asString(event.data.stepName);\n}\n\nfunction getWorkflowName(events: AuditEvent[]): string {\n const executionStart = events.find((event) => event.type === \"execution_start\");\n if (!executionStart || !isObject(executionStart.data)) {\n return \"unknown\";\n }\n\n const workflowName = asString(executionStart.data.workflowName);\n return workflowName ?? \"unknown\";\n}\n\nfunction getWorkflowVersion(events: AuditEvent[]): string | undefined {\n const executionStart = events.find((event) => event.type === \"execution_start\");\n if (!executionStart || !isObject(executionStart.data)) {\n return undefined;\n }\n return asString(executionStart.data.workflowVersion) ?? asString(executionStart.data.contractVersion);\n}\n\nfunction getSnapshotRef(events: AuditEvent[], mode: \"full\" | \"from_checkpoint\", checkpointStep?: string): string | undefined {\n if (mode === \"from_checkpoint\" && checkpointStep) {\n // Prefer snapshot events whose stepName or checkpointStep matches the checkpoint\n let fallbackRef: string | undefined;\n for (const event of events) {\n if ((event.type === \"snapshot_create\" || event.type === \"snapshot_restore\") && isObject(event.data)) {\n const ref = asString(event.data.snapshotId) ?? asString(event.data.snapshotRef);\n if (!ref) continue;\n const eventStep = asString(event.data.stepName) ?? asString(event.data.checkpointStep);\n if (eventStep === checkpointStep) return ref;\n if (!fallbackRef) fallbackRef = ref;\n }\n }\n if (fallbackRef) return fallbackRef;\n } else if (mode === \"from_checkpoint\") {\n // No checkpointStep specified, pick first snapshot\n for (const event of events) {\n if ((event.type === \"snapshot_create\" || event.type === \"snapshot_restore\") && isObject(event.data)) {\n const ref = asString(event.data.snapshotId) ?? asString(event.data.snapshotRef);\n if (ref) return ref;\n }\n }\n }\n // Fallback: check execution_start for a snapshotRef\n const executionStart = events.find((event) => event.type === \"execution_start\");\n if (executionStart && isObject(executionStart.data)) {\n return asString(executionStart.data.snapshotRef) ?? asString(executionStart.data.snapshotId);\n }\n return undefined;\n}\n\nfunction getStepOrder(events: AuditEvent[]): string[] {\n const executionStart = events.find((event) => event.type === \"execution_start\");\n if (executionStart && isObject(executionStart.data) && Array.isArray(executionStart.data.stepOrder)) {\n const fromStart = executionStart.data.stepOrder.filter((v): v is string => typeof v === \"string\");\n if (fromStart.length > 0) {\n return [...new Set(fromStart)];\n }\n }\n\n const seen = new Set<string>();\n const order: string[] = [];\n for (const event of events) {\n if (event.type !== \"step_start\") {\n continue;\n }\n const stepName = getStepName(event);\n if (!stepName || seen.has(stepName)) {\n continue;\n }\n seen.add(stepName);\n order.push(stepName);\n }\n return order;\n}\n\nfunction reconstructStateAtCheckpoint(events: AuditEvent[], checkpointStep: string): Record<string, unknown> {\n const state: Record<string, unknown> = {};\n\n for (const event of events) {\n if (event.type === \"step_start\" && getStepName(event) === checkpointStep) {\n break;\n }\n\n if (event.type !== \"state_change\" || !isObject(event.data)) {\n continue;\n }\n\n const path = asString(event.data.path);\n if (!path) {\n continue;\n }\n\n state[path] = event.data.newValue;\n }\n\n return state;\n}\n\nfunction detectNonDeterminismWarnings(events: AuditEvent[]): NonDeterminismWarning[] {\n const warnings: NonDeterminismWarning[] = [];\n\n const models = new Set<string>();\n for (const event of events) {\n if (event.metadata?.model) {\n models.add(event.metadata.model);\n }\n\n if (event.type === \"llm_request\" || event.type === \"llm_response\") {\n if (isObject(event.data) && asString(event.data.model)) {\n models.add(asString(event.data.model)!);\n }\n }\n }\n\n const currentModel = process.env.OBORA_MODEL ?? process.env.MODEL;\n if (currentModel && models.size > 0 && !models.has(currentModel)) {\n warnings.push({\n type: \"model_change\",\n severity: \"warning\",\n description: `Original execution used model(s): ${[...models].join(\", \")}, current model is '${currentModel}'.`,\n });\n }\n\n const startedAt = events.find((event) => event.type === \"execution_start\")?.timestamp;\n if (startedAt) {\n const driftMs = Date.now() - startedAt.getTime();\n if (driftMs > 24 * 60 * 60 * 1000) {\n warnings.push({\n type: \"time_drift\",\n severity: \"warning\",\n description: `Original execution started ${Math.floor(driftMs / (60 * 60 * 1000))}h ago; re-execution may diverge.`,\n });\n }\n }\n\n const policyVersions = new Set<string>();\n for (const event of events) {\n if (!isObject(event.data)) {\n continue;\n }\n\n if (event.type === \"execution_start\") {\n const policyVersion = asString(event.data.policyVersion);\n if (policyVersion) {\n policyVersions.add(policyVersion);\n }\n }\n\n if (event.type === \"policy_check\") {\n const policyVersion = asString(event.data.policyVersion);\n if (policyVersion) {\n policyVersions.add(policyVersion);\n }\n }\n }\n\n const currentPolicyVersion = process.env.OBORA_POLICY_VERSION;\n if (currentPolicyVersion && policyVersions.size > 0 && !policyVersions.has(currentPolicyVersion)) {\n warnings.push({\n type: \"policy_change\",\n severity: \"warning\",\n description: `Original execution used policy version(s): ${[...policyVersions].join(\", \")}, current policy is '${currentPolicyVersion}'.`,\n });\n }\n\n for (const event of events) {\n if (event.type === \"state_change\" && isObject(event.data)) {\n const path = asString(event.data.path);\n if (path && (path.startsWith(\"external.\") || path.includes(\"api\") || path.includes(\"cache\"))) {\n warnings.push({\n type: \"state_external\",\n severity: \"info\",\n stepName: getStepName(event),\n description: `State path '${path}' may depend on mutable external systems.`,\n });\n }\n }\n\n if ((event.type === \"tool_call\" || event.type === \"tool_result\") && isObject(event.data)) {\n const toolName = asString(event.data.toolName)?.toLowerCase();\n if (toolName && [\"date_now\", \"clock\", \"time\", \"random\", \"uuid\"].some((token) => toolName.includes(token))) {\n warnings.push({\n type: \"tool_output\",\n severity: \"warning\",\n stepName: getStepName(event),\n description: `Tool '${toolName}' may produce time-dependent or random output.`,\n });\n }\n }\n }\n\n return warnings;\n}\n\nexport class ReExecutionPlanner {\n constructor(private readonly auditTrail: AuditTrail) {}\n\n async createPlan(executionId: string, options: ReExecutionPlannerOptions): Promise<ReExecutionPlan> {\n const events = await this.auditTrail.query({ executionId });\n\n if (events.length === 0) {\n throw new Error(`No audit events found for execution: ${executionId}`);\n }\n\n if (!events.some((event) => event.type === \"execution_start\")) {\n throw new Error(`Invalid audit log for execution '${executionId}': missing execution_start event`);\n }\n\n const originalWorkflow = getWorkflowName(events);\n const stepOrder = getStepOrder(events);\n if (stepOrder.length === 0) {\n throw new Error(`Execution '${executionId}' has no step sequence in audit events`);\n }\n\n const detectNonDeterminism = options.detectNonDeterminism ?? true;\n\n const workflowVersion = getWorkflowVersion(events);\n const snapshotRef = getSnapshotRef(events, options.mode, options.checkpointStep);\n\n if (options.mode === \"full\") {\n return {\n executionId,\n originalWorkflow,\n ...(workflowVersion ? { workflowVersion } : {}),\n ...(snapshotRef ? { snapshotRef } : {}),\n mode: \"full\",\n stepsToRerun: stepOrder,\n stepsToSkip: [],\n nonDeterminismWarnings: detectNonDeterminism ? detectNonDeterminismWarnings(events) : [],\n createdAt: new Date(),\n };\n }\n\n if (!options.checkpointStep) {\n throw new Error(\"checkpointStep is required when mode is 'from_checkpoint'\");\n }\n\n const checkpointIndex = stepOrder.indexOf(options.checkpointStep);\n if (checkpointIndex < 0) {\n throw new Error(`Checkpoint step not found: ${options.checkpointStep}`);\n }\n\n const stepsToSkip = stepOrder.slice(0, checkpointIndex);\n const stepsToRerun = stepOrder.slice(checkpointIndex);\n const restoredState = reconstructStateAtCheckpoint(events, options.checkpointStep);\n\n return {\n executionId,\n originalWorkflow,\n ...(workflowVersion ? { workflowVersion } : {}),\n ...(snapshotRef ? { snapshotRef } : {}),\n mode: \"from_checkpoint\",\n startFromStep: options.checkpointStep,\n restoredState,\n stepsToRerun,\n stepsToSkip,\n nonDeterminismWarnings: detectNonDeterminism ? detectNonDeterminismWarnings(events) : [],\n createdAt: new Date(),\n };\n }\n}\n","import type { AuditEvent } from \"./types.js\";\nimport type { ReExecutionPlan } from \"./ReExecutionPlanner.js\";\n\nexport interface ReExecutionDiffReport {\n executionId: string;\n reExecutionId?: string;\n plan: ReExecutionPlan;\n differences: StepDiff[];\n summary: { total_steps: number; changed: number; unchanged: number; skipped: number; new: number; removed: number };\n}\n\nexport interface StepDiff {\n stepName: string;\n status: \"unchanged\" | \"changed\" | \"new\" | \"removed\" | \"skipped\";\n originalOutput?: unknown;\n reExecutionOutput?: unknown;\n diffDetails?: string;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getStepName(event: AuditEvent): string | undefined {\n if (!isObject(event.data)) {\n return undefined;\n }\n\n const stepName = event.data.stepName;\n return typeof stepName === \"string\" && stepName.length > 0 ? stepName : undefined;\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map((v) => stableStringify(v)).join(\",\")}]`;\n }\n\n if (isObject(value)) {\n const entries = Object.entries(value).sort(([a], [b]) => a.localeCompare(b));\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`).join(\",\")}}`;\n }\n\n return JSON.stringify(value);\n}\n\nfunction outputsByStep(events: AuditEvent[]): Map<string, unknown> {\n const map = new Map<string, unknown>();\n\n for (const event of events) {\n if (event.type !== \"cell_end\") {\n continue;\n }\n\n const stepName = getStepName(event);\n if (!stepName || !isObject(event.data)) {\n continue;\n }\n\n if (\"output\" in event.data) {\n map.set(stepName, event.data.output);\n continue;\n }\n\n if (\"metrics\" in event.data) {\n map.set(stepName, event.data.metrics);\n }\n }\n\n return map;\n}\n\nexport function createDiffReport(\n plan: ReExecutionPlan,\n originalEvents: AuditEvent[],\n reExecutionEvents?: AuditEvent[]\n): ReExecutionDiffReport {\n const originalOutputs = outputsByStep(originalEvents);\n const reExecutionOutputs = outputsByStep(reExecutionEvents ?? []);\n\n const allSteps = new Set<string>([\n ...originalOutputs.keys(),\n ...reExecutionOutputs.keys(),\n ...plan.stepsToRerun,\n ...plan.stepsToSkip,\n ]);\n\n const differences: StepDiff[] = [];\n\n for (const stepName of allSteps) {\n if (plan.stepsToSkip.includes(stepName)) {\n differences.push({ stepName, status: \"skipped\", originalOutput: originalOutputs.get(stepName) });\n continue;\n }\n\n const originalOutput = originalOutputs.get(stepName);\n const reExecutionOutput = reExecutionOutputs.get(stepName);\n\n if (originalOutput === undefined && reExecutionOutput !== undefined) {\n differences.push({\n stepName,\n status: \"new\",\n originalOutput,\n reExecutionOutput,\n diffDetails: \"Step exists only in re-execution output.\",\n });\n continue;\n }\n\n if (originalOutput !== undefined && reExecutionOutput === undefined) {\n differences.push({\n stepName,\n status: \"removed\",\n originalOutput,\n reExecutionOutput,\n diffDetails: \"Step output missing in re-execution.\",\n });\n continue;\n }\n\n const originalDigest = stableStringify(originalOutput);\n const reExecutionDigest = stableStringify(reExecutionOutput);\n\n if (originalDigest === reExecutionDigest) {\n differences.push({ stepName, status: \"unchanged\", originalOutput, reExecutionOutput });\n } else {\n differences.push({\n stepName,\n status: \"changed\",\n originalOutput,\n reExecutionOutput,\n diffDetails: \"Output payload differs between original execution and re-execution.\",\n });\n }\n }\n\n const summary = differences.reduce(\n (acc, diff) => {\n if (diff.status === \"changed\") {\n acc.changed += 1;\n }\n if (diff.status === \"unchanged\") {\n acc.unchanged += 1;\n }\n if (diff.status === \"skipped\") {\n acc.skipped += 1;\n }\n if (diff.status === \"new\") {\n acc.new += 1;\n }\n if (diff.status === \"removed\") {\n acc.removed += 1;\n }\n return acc;\n },\n { total_steps: differences.length, changed: 0, unchanged: 0, skipped: 0, new: 0, removed: 0 }\n );\n\n const reExecutionId = reExecutionEvents?.find((event) => event.type === \"execution_start\")?.executionId;\n\n return {\n executionId: plan.executionId,\n reExecutionId,\n plan,\n differences,\n summary,\n };\n}\n","import type { AuditTrail } from \"./AuditTrail.js\";\nimport { createDiffReport, type ReExecutionDiffReport } from \"./ReExecutionDiffReport.js\";\nimport { type ReExecutionPlan, ReExecutionPlanner } from \"./ReExecutionPlanner.js\";\nimport type { AuditEvent } from \"./types.js\";\n\nexport interface ReExecutionOptions {\n executionId: string;\n mode: \"full\" | \"from_checkpoint\";\n checkpointStep?: string;\n detectNonDeterminism?: boolean;\n dryRun?: boolean;\n onStepComplete?: (stepName: string, result: StepReExecutionResult) => void | Promise<void>;\n}\n\nexport interface StepReExecutionResult {\n stepName: string;\n status: \"done\" | \"failed\" | \"skipped\";\n output?: unknown;\n matchesOriginal?: boolean;\n diff?: string;\n}\n\nexport interface ReExecutionResult {\n reExecutionId: string;\n originalExecutionId: string;\n workflowVersion?: string;\n snapshotRef?: string;\n plan: ReExecutionPlan;\n stepResults: StepReExecutionResult[];\n diffReport: ReExecutionDiffReport;\n success: boolean;\n completedAt: Date;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction extractLatestStepOutputs(events: AuditEvent[]): Map<string, unknown> {\n const outputs = new Map<string, unknown>();\n\n for (const event of events) {\n if (event.type !== \"cell_end\" || !isObject(event.data)) {\n continue;\n }\n\n const stepName = event.data.stepName;\n if (typeof stepName !== \"string\" || stepName.length === 0) {\n continue;\n }\n\n if (\"output\" in event.data) {\n outputs.set(stepName, event.data.output);\n continue;\n }\n\n if (\"metrics\" in event.data) {\n outputs.set(stepName, event.data.metrics);\n }\n }\n\n return outputs;\n}\n\nfunction now(): Date {\n return new Date();\n}\n\nexport class ReExecutionRuntime {\n constructor(\n private readonly auditTrail: AuditTrail,\n private readonly planner: ReExecutionPlanner\n ) {}\n\n async reexecute(options: ReExecutionOptions): Promise<ReExecutionResult> {\n const reExecutionId = `reexec-${crypto.randomUUID()}`;\n const originalEvents = await this.auditTrail.query({ executionId: options.executionId });\n\n const plan = await this.planner.createPlan(options.executionId, {\n mode: options.mode,\n checkpointStep: options.checkpointStep,\n detectNonDeterminism: options.detectNonDeterminism,\n });\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_start\",\n data: {\n originalExecutionId: options.executionId,\n reExecutionId,\n mode: plan.mode,\n plan,\n simulation: true,\n dryRun: options.dryRun ?? false,\n },\n });\n\n if (options.dryRun) {\n const diffReport: ReExecutionDiffReport = {\n executionId: plan.executionId,\n reExecutionId,\n plan,\n differences: [],\n summary: {\n total_steps: plan.stepsToRerun.length + plan.stepsToSkip.length,\n changed: 0,\n unchanged: 0,\n skipped: plan.stepsToSkip.length,\n new: 0,\n removed: 0,\n },\n };\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_end\",\n data: {\n reExecutionId,\n success: true,\n diffSummary: diffReport.summary,\n simulation: true,\n dryRun: true,\n },\n });\n\n return {\n reExecutionId,\n originalExecutionId: options.executionId,\n ...(plan.workflowVersion ? { workflowVersion: plan.workflowVersion } : {}),\n ...(plan.snapshotRef ? { snapshotRef: plan.snapshotRef } : {}),\n plan,\n stepResults: [],\n diffReport,\n success: true,\n completedAt: now(),\n };\n }\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"execution_start\",\n data: {\n workflowName: plan.originalWorkflow,\n ...(plan.workflowVersion ? { workflowVersion: plan.workflowVersion } : {}),\n originalExecutionId: options.executionId,\n mode: \"reexecution\",\n simulation: true,\n },\n });\n\n if (plan.mode === \"from_checkpoint\") {\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"snapshot_restore\",\n data: {\n reason: \"from_checkpoint\",\n checkpointStep: plan.startFromStep,\n restoredState: plan.restoredState ?? {},\n ...(plan.snapshotRef ? { snapshotRef: plan.snapshotRef } : {}),\n simulation: true,\n },\n });\n }\n\n const stepResults: StepReExecutionResult[] = [];\n const originalOutputs = extractLatestStepOutputs(originalEvents);\n\n for (const stepName of plan.stepsToSkip) {\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_step_start\",\n data: { stepName, mode: \"skip\", simulation: true },\n });\n\n const result: StepReExecutionResult = {\n stepName,\n status: \"skipped\",\n matchesOriginal: true,\n };\n\n stepResults.push(result);\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_step_end\",\n data: { stepName, matchesOriginal: true, simulation: true },\n });\n\n if (options.onStepComplete) {\n await options.onStepComplete(stepName, result);\n }\n }\n\n for (const stepName of plan.stepsToRerun) {\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_step_start\",\n data: { stepName, mode: \"rerun\", simulation: true },\n });\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"step_start\",\n data: { stepName, agent: \"reexecution-simulator\" },\n });\n\n const originalOutput = originalOutputs.get(stepName);\n\n if (originalOutput === undefined) {\n const failed: StepReExecutionResult = {\n stepName,\n status: \"failed\",\n matchesOriginal: false,\n diff: \"No original step output found in audit trail.\",\n };\n stepResults.push(failed);\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"step_end\",\n data: { stepName, status: \"failed\", simulation: true },\n });\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_step_end\",\n data: {\n stepName,\n matchesOriginal: false,\n diff: failed.diff,\n simulation: true,\n },\n });\n\n if (options.onStepComplete) {\n await options.onStepComplete(stepName, failed);\n }\n\n continue;\n }\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"cell_end\",\n data: {\n stepName,\n output: originalOutput,\n simulation: {\n type: \"audit_log_replay\",\n liveExecution: false,\n originalExecutionId: options.executionId,\n },\n },\n });\n\n // Simulation mode: replaying original output, matchesOriginal is always true by definition\n const matchesOriginal = true;\n const completed: StepReExecutionResult = {\n stepName,\n status: \"done\",\n output: originalOutput,\n matchesOriginal,\n };\n\n stepResults.push(completed);\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"step_end\",\n data: { stepName, status: \"done\", simulation: true },\n });\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_step_end\",\n data: {\n stepName,\n matchesOriginal,\n simulation: true,\n },\n });\n\n if (options.onStepComplete) {\n await options.onStepComplete(stepName, completed);\n }\n }\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"execution_end\",\n data: {\n status: stepResults.some((result) => result.status === \"failed\") ? \"failed\" : \"done\",\n simulation: true,\n },\n });\n\n const reExecutionEvents = await this.auditTrail.query({ executionId: reExecutionId });\n const diffReport = createDiffReport(plan, originalEvents, reExecutionEvents);\n const success =\n !stepResults.some((result) => result.status === \"failed\") &&\n diffReport.summary.changed === 0 &&\n diffReport.summary.new === 0 &&\n diffReport.summary.removed === 0;\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_diff\",\n data: {\n reExecutionId,\n originalExecutionId: options.executionId,\n diffReport,\n simulation: true,\n },\n });\n\n await this.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: reExecutionId,\n timestamp: now(),\n type: \"reexecution_end\",\n data: {\n reExecutionId,\n success,\n diffSummary: diffReport.summary,\n simulation: true,\n },\n });\n\n return {\n reExecutionId,\n originalExecutionId: options.executionId,\n ...(plan.workflowVersion ? { workflowVersion: plan.workflowVersion } : {}),\n ...(plan.snapshotRef ? { snapshotRef: plan.snapshotRef } : {}),\n plan,\n stepResults,\n diffReport,\n success,\n completedAt: now(),\n };\n }\n}\n","import type { AuditEvent, AuditEventType } from \"./types.js\";\nimport type { StorageAdapter, StructuredAuditEvent } from \"../storage/types.js\";\n\nconst categoryFromType = (type: AuditEventType): StructuredAuditEvent[\"category\"] => {\n if (type.startsWith(\"consensus_\")) return \"consensus\";\n if (type.startsWith(\"policy_\") || type.startsWith(\"gate_\")) return \"policy\";\n if (type.startsWith(\"recovery_\") || type.startsWith(\"snapshot_\") || type === \"reexecution_start\" || type === \"reexecution_step_start\" || type === \"reexecution_step_end\" || type === \"reexecution_end\") {\n return \"recovery\";\n }\n return \"execution\";\n};\n\nconst voteFromData = (data: unknown): StructuredAuditEvent[\"vote\"] | undefined => {\n if (!data || typeof data !== \"object\") return undefined;\n const record = data as Record<string, unknown>;\n const vote = (record.vote ?? record) as Record<string, unknown>;\n\n if (typeof vote.approved === \"boolean\") {\n return {\n decision: vote.approved ? \"approve\" : \"reject\",\n confidence: typeof vote.score === \"number\" ? vote.score : undefined,\n reasoning: typeof vote.reasoning === \"string\" ? vote.reasoning : undefined,\n };\n }\n\n if (typeof vote.decision === \"string\" && [\"approve\", \"reject\", \"abstain\"].includes(vote.decision)) {\n return {\n decision: vote.decision as \"approve\" | \"reject\" | \"abstain\",\n confidence: typeof vote.confidence === \"number\" ? vote.confidence : undefined,\n reasoning: typeof vote.reasoning === \"string\" ? vote.reasoning : undefined,\n };\n }\n\n return undefined;\n};\n\nconst inferActor = (data: unknown): string => {\n if (!data || typeof data !== \"object\") return \"system\";\n const record = data as Record<string, unknown>;\n const candidates = [record.actor, record.agent, record.voterId, (record.vote as Record<string, unknown> | undefined)?.voterId];\n for (const v of candidates) {\n if (typeof v === \"string\" && v.length > 0) return v;\n }\n return \"system\";\n};\n\nconst inferStepName = (data: unknown): string => {\n if (!data || typeof data !== \"object\") return \"runtime\";\n const record = data as Record<string, unknown>;\n return typeof record.stepName === \"string\" && record.stepName.length > 0 ? record.stepName : \"runtime\";\n};\n\nexport function toStructuredAuditEvent(runId: string, event: AuditEvent): StructuredAuditEvent {\n const detail = (event.data && typeof event.data === \"object\") ? (event.data as Record<string, unknown>) : { value: event.data };\n const detailAction = typeof detail.action === \"string\" ? detail.action : undefined;\n return {\n id: event.id,\n runId,\n stepName: inferStepName(event.data),\n timestamp: event.timestamp.toISOString(),\n category: categoryFromType(event.type),\n action: detailAction ?? event.type,\n actor: inferActor(event.data),\n detail,\n vote: voteFromData(event.data),\n };\n}\n\nexport async function persistStructuredAuditEvent(adapter: StorageAdapter | undefined, runId: string, event: AuditEvent): Promise<void> {\n if (!adapter) return;\n const save = (adapter as Partial<StorageAdapter>).saveAuditEvent;\n if (typeof save !== \"function\") return;\n await save.call(adapter, toStructuredAuditEvent(runId, event));\n}\n","/**\n * @module events/event-bus\n * @description Event Bus 구현 - Pub/Sub 패턴, 와일드카드 구독, 이벤트 필터링 지원\n */\n\nimport type { Event, EventType, EventByType, EventCategory } from \"./types\";\nimport type { AgentId } from \"../types\";\n\n/**\n * 이벤트 핸들러 타입\n */\nexport type EventHandler<T extends Event = Event> = (event: T) => void | Promise<void>;\n\n/**\n * 구독 정보 인터페이스\n */\ninterface Subscription<T extends Event = Event> {\n handler: EventHandler<T>;\n eventType: string;\n once: boolean;\n filter?: EventFilter;\n}\n\n/**\n * 구독 해제 함수\n */\nexport type Unsubscribe = () => void;\n\n/**\n * 이벤트 필터 조건\n */\nexport interface EventFilter {\n /** 소스 에이전트 ID */\n source?: AgentId | \"system\";\n /** 상관 ID */\n correlationId?: string;\n /** 커스텀 필터 함수 */\n predicate?: (event: Event) => boolean;\n}\n\n/**\n * Event Bus 설정\n */\nexport interface EventBusOptions {\n /** 최대 리스너 수 (기본: 100) */\n maxListeners?: number;\n /** 비동기 핸들러 에러 시 throw 여부 (기본: false) */\n throwOnAsyncError?: boolean;\n /** 비동기 핸들러 에러 시 에러 이벤트 발행 여부 (기본: true) */\n emitErrorEvent?: boolean;\n /** 이벤트 히스토리 유지 개수 (기본: 0 = 유지 안함) */\n historySize?: number;\n /** 디버그 모드 */\n debug?: boolean;\n}\n\n/**\n * Event Bus 통계\n */\nexport interface EventBusStats {\n /** 총 발행된 이벤트 수 */\n totalEmitted: number;\n /** 타입별 발행 수 */\n emittedByType: Map<string, number>;\n /** 현재 구독자 수 */\n subscriberCount: number;\n /** 타입별 구독자 수 */\n subscribersByType: Map<string, number>;\n}\n\n/**\n * 이벤트 대기용 타임아웃 에러\n */\nexport class EventTimeoutError extends Error {\n constructor(eventType: string, timeout: number) {\n super(`Timeout waiting for event '${eventType}' after ${timeout}ms`);\n this.name = \"EventTimeoutError\";\n }\n}\n\n/**\n * Event Bus\n * @description Blackboard 이벤트를 위한 Pub/Sub 시스템\n * @description EventEmitter 상속하지 않고 자체 구현 (브라우저 호환)\n *\n * @example\n * ```typescript\n * const bus = new EventBus({ historySize: 100 });\n *\n * // 특정 이벤트 구독\n * const unsub = bus.subscribe('task.completed', (event) => {\n * console.log('Task completed:', event.payload.taskId);\n * });\n *\n * // 와일드카드 구독\n * bus.subscribe('task.*', (event) => {\n * console.log('Task event:', event.type);\n * });\n *\n * // 모든 이벤트 구독\n * bus.subscribe('*', (event) => {\n * console.log('Any event:', event.type);\n * });\n *\n * // 필터와 함께 구독\n * bus.subscribeWithFilter('decision.*',\n * { source: createAgentId('ceo') },\n * (event) => console.log('CEO decision event')\n * );\n *\n * // 이벤트 발행\n * bus.emit({\n * id: generateId(),\n * type: 'task.completed',\n * timestamp: new Date(),\n * source: 'system',\n * payload: { taskId: createTaskId('task-1'), result: {}, duration: 5000 }\n * });\n *\n * // 구독 해제\n * unsub();\n * ```\n */\nexport class EventBus {\n private readonly options: Required<EventBusOptions>;\n private history: Event[];\n private stats: EventBusStats;\n private subscriptions: Set<Subscription<Event>>;\n private nextSubscriptionId = 0;\n /** 에러 이벤트 발행 중인지 체크 (재귀 방지) */\n private isEmittingError = false;\n\n constructor(options: EventBusOptions = {}) {\n this.options = {\n maxListeners: options.maxListeners ?? 100,\n throwOnAsyncError: options.throwOnAsyncError ?? false,\n emitErrorEvent: options.emitErrorEvent ?? true,\n historySize: options.historySize ?? 0,\n debug: options.debug ?? false,\n };\n this.history = [];\n this.stats = this.createInitialStats();\n this.subscriptions = new Set();\n }\n\n // === 구독 API ===\n\n /**\n * 이벤트 구독\n * @param eventType - 이벤트 타입 (와일드카드 지원: 'task.*', '*')\n * @param handler - 이벤트 핸들러\n * @returns 구독 해제 함수\n */\n subscribe<T extends EventType>(\n eventType: T | `${EventCategory}.*` | \"*\",\n handler: EventHandler<EventByType<T>>\n ): Unsubscribe {\n this.debugLog(`Subscribing to event type: ${eventType}`);\n\n const subscription: Subscription<Event> = {\n handler: handler as EventHandler<Event>,\n eventType,\n once: false,\n };\n\n this.subscriptions.add(subscription);\n this.updateSubscriberStats();\n\n return () => {\n this.subscriptions.delete(subscription);\n this.updateSubscriberStats();\n this.debugLog(`Unsubscribed from event type: ${eventType}`);\n };\n }\n\n /**\n * 필터와 함께 구독\n * @param eventType - 이벤트 타입\n * @param filter - 필터 조건\n * @param handler - 이벤트 핸들러\n * @returns 구독 해제 함수\n */\n subscribeWithFilter<T extends EventType>(\n eventType: T | `${EventCategory}.*` | \"*\",\n filter: EventFilter,\n handler: EventHandler<EventByType<T>>\n ): Unsubscribe {\n this.debugLog(`Subscribing with filter to event type: ${eventType}`, filter);\n\n const subscription: Subscription<Event> = {\n handler: handler as EventHandler<Event>,\n eventType,\n once: false,\n filter,\n };\n\n this.subscriptions.add(subscription);\n this.updateSubscriberStats();\n\n return () => {\n this.subscriptions.delete(subscription);\n this.updateSubscriberStats();\n this.debugLog(`Unsubscribed (with filter) from event type: ${eventType}`);\n };\n }\n\n /**\n * 일회성 구독\n * @param eventType - 이벤트 타입\n * @param handler - 이벤트 핸들러\n * @returns 구독 해제 함수\n */\n subscribeOnce<T extends EventType>(\n eventType: T,\n handler: EventHandler<EventByType<T>>\n ): Unsubscribe {\n this.debugLog(`Subscribing once to event type: ${eventType}`);\n\n const subscription: Subscription<Event> = {\n handler: handler as EventHandler<Event>,\n eventType,\n once: true,\n };\n\n this.subscriptions.add(subscription);\n this.updateSubscriberStats();\n\n return () => {\n this.subscriptions.delete(subscription);\n this.updateSubscriberStats();\n };\n }\n\n /**\n * 구독 해제\n * @param eventType - 이벤트 타입\n * @param handler - 제거할 핸들러\n */\n unsubscribe<T extends EventType>(\n eventType: T | `${EventCategory}.*` | \"*\",\n handler: EventHandler<EventByType<T>>\n ): void {\n for (const sub of this.subscriptions) {\n if (sub.eventType === eventType && sub.handler === handler) {\n this.subscriptions.delete(sub);\n this.updateSubscriberStats();\n this.debugLog(`Unsubscribed from event type: ${eventType}`);\n return;\n }\n }\n }\n\n /**\n * 모든 구독 해제\n * @param eventType - 특정 이벤트 타입만 해제 (선택)\n */\n unsubscribeAll<T extends EventType>(eventType?: T | `${EventCategory}.*` | \"*\"): void {\n if (eventType) {\n // 특정 타입의 구독만 해제\n const toRemove: Subscription<Event>[] = [];\n for (const sub of this.subscriptions) {\n if (sub.eventType === eventType) {\n toRemove.push(sub);\n }\n }\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n }\n this.debugLog(`Unsubscribed all from event type: ${eventType}`);\n } else {\n // 모든 구독 해제\n this.subscriptions.clear();\n this.debugLog(\"Unsubscribed all subscribers\");\n }\n this.updateSubscriberStats();\n }\n\n /**\n * 이벤트 버스 초기화 (히스토리만 지움, 구독자는 유지)\n */\n clear(): void {\n this.history = [];\n this.stats = this.createInitialStats();\n this.updateSubscriberStats();\n this.debugLog(\"EventBus history cleared\");\n }\n\n // === 발행 API ===\n\n /**\n * 이벤트 발행\n * @param event - 발행할 이벤트\n */\n emit<T extends Event>(event: T): void {\n this.debugLog(`Emitting event: ${event.type}`, event);\n\n // 통계 업데이트\n this.updateStats(event);\n\n // 히스토리에 추가\n this.addToHistory(event);\n\n // 구독자들에게 이벤트 전달\n const toRemove: Subscription<Event>[] = [];\n\n for (const sub of this.subscriptions) {\n // 패턴 매칭 확인\n if (!this.matchesPattern(sub.eventType, event.type)) {\n continue;\n }\n\n // 필터 확인\n if (sub.filter && !this.applyFilter(event, sub.filter)) {\n continue;\n }\n\n // 핸들러 실행\n try {\n const result = sub.handler(event);\n\n // 비동기 핸들러 처리\n if (result instanceof Promise) {\n result.catch((error) => {\n // 에러 이벤트 핸들러 실패 시 별도 경고 로그 (에러 이벤트 재발행 방지)\n if (event.type === \"system.error\") {\n console.warn(\"[EventBus] Error handler failed:\", error);\n // 에러 이벤트의 에러는 재발행하지 않음 (무한 루프 방지)\n } else {\n if (this.options.throwOnAsyncError) {\n throw error;\n }\n console.error(`Error in async event handler:`, error);\n\n // 에러 이벤트 발행\n if (this.options.emitErrorEvent) {\n this.emitError(error, event, sub.eventType);\n }\n }\n });\n }\n } catch (error) {\n console.error(`Error in event handler:`, error);\n\n // 에러 이벤트 발행\n if (this.options.emitErrorEvent) {\n this.emitError(error, event, sub.eventType);\n }\n }\n\n // 일회성 구독인 경우 제거 대기열에 추가\n if (sub.once) {\n toRemove.push(sub);\n }\n }\n\n // 일회성 구독 제거\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n this.updateSubscriberStats();\n }\n }\n\n /**\n * 이벤트 발행 (비동기 핸들러 완료 대기)\n * @param event - 발행할 이벤트\n * @returns 모든 핸들러 완료 시 resolve\n */\n async emitAsync<T extends Event>(event: T): Promise<void> {\n this.debugLog(`Emitting async event: ${event.type}`, event);\n\n // 통계 업데이트\n this.updateStats(event);\n\n // 히스토리에 추가\n this.addToHistory(event);\n\n // 구독자들에게 이벤트 전달 (비동기)\n const promises: Promise<unknown>[] = [];\n const toRemove: Subscription<Event>[] = [];\n\n for (const sub of this.subscriptions) {\n // 패턴 매칭 확인\n if (!this.matchesPattern(sub.eventType, event.type)) {\n continue;\n }\n\n // 필터 확인\n if (sub.filter && !this.applyFilter(event, sub.filter)) {\n continue;\n }\n\n // 핸들러 실행\n try {\n const result = sub.handler(event);\n\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n console.error(`Error in event handler:`, error);\n }\n\n // 일회성 구독인 경우 제거 대기열에 추가\n if (sub.once) {\n toRemove.push(sub);\n }\n }\n\n // 일회성 구독 제거\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n this.updateSubscriberStats();\n }\n\n // 모든 비동기 핸들러 완료 대기\n await Promise.allSettled(promises);\n }\n\n /**\n * 배치 이벤트 발행\n * @param events - 발행할 이벤트 목록\n */\n emitBatch(events: Event[]): void {\n this.debugLog(`Emitting batch of ${events.length} events`);\n\n for (const event of events) {\n this.emit(event);\n }\n }\n\n // === 히스토리 API ===\n\n /**\n * 이벤트 히스토리 조회\n * @param filter - 필터 조건\n * @param limit - 최대 개수\n * @returns 필터링된 이벤트 목록\n */\n getHistory(\n filter?: {\n type?: EventType | `${EventCategory}.*`;\n source?: AgentId | \"system\";\n since?: Date;\n until?: Date;\n limit?: number;\n },\n limitArg?: number\n ): Event[] {\n let events = this.history;\n\n // 타입 필터링\n if (filter?.type) {\n events = events.filter((e) => this.matchesPattern(filter.type!, e.type));\n }\n\n // 소스 필터링\n if (filter?.source) {\n events = events.filter((e) => e.source === filter.source);\n }\n\n // 시간 필터링\n if (filter?.since) {\n events = events.filter((e) => e.timestamp >= filter.since!);\n }\n\n if (filter?.until) {\n events = events.filter((e) => e.timestamp <= filter.until!);\n }\n\n // 제한 (filter.limit 또는 두 번째 인자 사용)\n const limit = filter?.limit ?? limitArg;\n if (limit !== undefined && limit > 0) {\n events = events.slice(-limit);\n }\n\n return events;\n }\n\n /**\n * 히스토리 재생\n * @description 지정된 이벤트들을 다시 발행\n * @param events - 재생할 이벤트 목록\n */\n replay(events: Event[]): void {\n this.debugLog(`Replaying ${events.length} events`);\n\n for (const event of events) {\n this.emit(event);\n }\n }\n\n /**\n * 히스토리 클리어\n */\n clearHistory(): void {\n this.history = [];\n this.debugLog(\"History cleared\");\n }\n\n // === 유틸리티 API ===\n\n /**\n * 통계 조회\n */\n getStats(): Readonly<EventBusStats> & { eventsByType: Record<string, number> } {\n const eventsByType: Record<string, number> = {};\n for (const [type, count] of this.stats.emittedByType.entries()) {\n eventsByType[type] = count;\n }\n\n return {\n totalEmitted: this.stats.totalEmitted,\n emittedByType: new Map(this.stats.emittedByType),\n subscriberCount: this.stats.subscriberCount,\n subscribersByType: new Map(this.stats.subscribersByType),\n eventsByType,\n };\n }\n\n /**\n * 모든 구독 해제\n */\n removeAllSubscribers(): void {\n this.subscriptions.clear();\n this.stats.subscriberCount = 0;\n this.stats.subscribersByType.clear();\n this.debugLog(\"All subscribers removed\");\n }\n\n /**\n * 특정 타입의 모든 구독 해제\n */\n removeSubscribersForType(eventType: EventType | `${EventCategory}.*` | \"*\"): void {\n const toRemove: Subscription<Event>[] = [];\n\n for (const sub of this.subscriptions) {\n if (sub.eventType === eventType) {\n toRemove.push(sub);\n }\n }\n\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n }\n\n this.updateSubscriberStats();\n this.debugLog(`Removed all subscribers for event type: ${eventType}`);\n }\n\n /**\n * 이벤트 대기 (Promise 기반)\n * @param eventType - 대기할 이벤트 타입\n * @param timeout - 타임아웃 (ms)\n * @returns 발생한 이벤트\n */\n waitFor<T extends EventType>(\n eventType: T,\n timeout: number = 30000,\n predicate?: (event: EventByType<T>) => boolean\n ): Promise<EventByType<T>> {\n return new Promise((resolve, reject) => {\n let unsubscribe: Unsubscribe | null = null;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const cleanup = () => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n if (predicate) {\n // 필터가 있는 경우 subscribe 사용 (한 번만 호출)\n unsubscribe = this.subscribe(eventType, (event) => {\n if (predicate(event as EventByType<T>)) {\n cleanup();\n resolve(event as EventByType<T>);\n }\n });\n } else {\n // 필터가 없는 경우 subscribeOnce 사용\n unsubscribe = this.subscribeOnce(eventType, (event) => {\n cleanup();\n resolve(event as EventByType<T>);\n });\n }\n\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new EventTimeoutError(eventType, timeout));\n }, timeout);\n });\n }\n\n /**\n * 이벤트 대기 (조건 충족 시)\n * @param eventType - 대기할 이벤트 타입\n * @param predicate - 조건 함수\n * @param timeout - 타임아웃 (ms)\n */\n waitForCondition<T extends EventType>(\n eventType: T,\n predicate: (event: EventByType<T>) => boolean,\n timeout: number = 30000\n ): Promise<EventByType<T>> {\n return new Promise((resolve, reject) => {\n let unsubscribe: Unsubscribe | null = null;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const cleanup = () => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n unsubscribe = this.subscribe(eventType, (event) => {\n const typedEvent = event as EventByType<T>;\n if (predicate(typedEvent)) {\n cleanup();\n resolve(typedEvent);\n }\n });\n\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new EventTimeoutError(eventType, timeout));\n }, timeout);\n });\n }\n\n // === 내부 메서드 ===\n\n /**\n * 에러 이벤트 발행\n * @description 핸들러 에러 발생 시 시스템 에러 이벤트 발행\n * @private\n */\n private emitError(error: unknown, originalEvent: Event, handlerEventType: string): void {\n // 재귀 방지: 이미 에러 이벤트 발행 중이면 추가 발행을 막음\n if (this.isEmittingError) {\n console.error(\"Suppressing recursive error event:\", error);\n return;\n }\n\n this.isEmittingError = true;\n try {\n // 에러 객체 정제 (민감 데이터 노출 방지)\n const sanitizedError = {\n message: error instanceof Error ? error.message : String(error),\n name: error instanceof Error ? error.name : \"Error\",\n stack: error instanceof Error ? error.stack : undefined,\n };\n\n const errorEvent = {\n id: `evt-error-${crypto.randomUUID()}`,\n type: \"system.error\" as const,\n timestamp: new Date(),\n source: \"system\" as const,\n payload: {\n code: \"EVENT_HANDLER_ERROR\",\n message: sanitizedError.message,\n details: {\n originalEventType: originalEvent.type,\n handlerEventType,\n error: sanitizedError,\n },\n },\n };\n\n // emit()을 통해서만 발행 (emit() 내에서 히스토리/통계 처리)\n this.emit(errorEvent as Event);\n } catch (e) {\n // 에러 이벤트 발행 자체가 실패하면 무시\n console.error(\"Failed to emit error event:\", e);\n } finally {\n this.isEmittingError = false;\n }\n }\n\n /**\n * 와일드카드 패턴 매칭\n * @param pattern - 패턴 (예: 'task.*')\n * @param eventType - 실제 이벤트 타입\n */\n private matchesPattern(pattern: string, eventType: string): boolean {\n if (pattern === \"*\") {\n return true;\n }\n\n if (pattern.endsWith(\"*\")) {\n const prefix = pattern.slice(0, -1); // '*' 제거\n return eventType.startsWith(prefix);\n }\n\n return pattern === eventType;\n }\n\n /**\n * 필터 적용\n * @param event - 이벤트\n * @param filter - 필터 조건\n */\n private applyFilter(event: Event, filter: EventFilter): boolean {\n if (filter.source && event.source !== filter.source) {\n return false;\n }\n\n if (filter.correlationId && event.correlationId !== filter.correlationId) {\n return false;\n }\n\n if (filter.predicate && !filter.predicate(event)) {\n return false;\n }\n\n return true;\n }\n\n /**\n * 히스토리에 이벤트 추가\n */\n private addToHistory(event: Event): void {\n if (this.options.historySize === 0) {\n return;\n }\n\n this.history.push(event);\n\n // 제한 초과 시 오래된 이벤트 제거\n if (this.history.length > this.options.historySize) {\n this.history.shift();\n }\n }\n\n /**\n * 통계 업데이트\n */\n private updateStats(event: Event): void {\n this.stats.totalEmitted++;\n\n const current = this.stats.emittedByType.get(event.type) ?? 0;\n this.stats.emittedByType.set(event.type, current + 1);\n }\n\n /**\n * 구독자 통계 업데이트\n */\n private updateSubscriberStats(): void {\n this.stats.subscriberCount = this.subscriptions.size;\n\n // 타입별 구독자 수 계산\n const countByType = new Map<string, number>();\n for (const sub of this.subscriptions) {\n const current = countByType.get(sub.eventType) ?? 0;\n countByType.set(sub.eventType, current + 1);\n }\n\n this.stats.subscribersByType = countByType;\n }\n\n /**\n * 초기 통계 생성\n */\n private createInitialStats(): EventBusStats {\n return {\n totalEmitted: 0,\n emittedByType: new Map(),\n subscriberCount: 0,\n subscribersByType: new Map(),\n };\n }\n\n /**\n * 디버그 로그\n */\n private debugLog(message: string, data?: unknown): void {\n if (this.options.debug) {\n if (data !== undefined) {\n console.debug(`[EventBus] ${message}`, data);\n } else {\n console.debug(`[EventBus] ${message}`);\n }\n }\n }\n}\n","/**\n * @module events/event-factory\n * @description 이벤트 팩토리 - 타입 안전한 이벤트 생성\n */\n\nimport type { AgentId, TaskId, AgendaId } from \"../types\";\nimport type {\n PhaseChangedEvent,\n ContextUpdatedEvent,\n StateAgentRegisteredEvent,\n StateAgentUpdatedEvent,\n StateTaskCreatedEvent,\n StateTaskAssignedEvent,\n StateTaskCompletedEvent,\n StateTaskFailedEvent,\n AgentRegisteredEvent,\n AgentStatusChangedEvent,\n AgentUpdatedEvent,\n AgentRemovedEvent,\n TaskCreatedEvent,\n TaskAssignedEvent,\n TaskStartedEvent,\n TaskStatusChangedEvent,\n TaskCompletedEvent,\n TaskFailedEvent,\n TaskCancelledEvent,\n DecisionsAgendaCreatedEvent,\n DecisionsAgendaStartedEvent,\n DecisionsOpinionSubmittedEvent,\n DecisionsVotingStartedEvent,\n DecisionsVoteSubmittedEvent,\n DecisionsVotingEndedEvent,\n DecisionsConsensusReachedEvent,\n DecisionsAgendaResolvedEvent,\n AgendaSubmittedEvent,\n AgendaStatusChangedEvent,\n OpinionSubmittedEvent,\n VoteRequestedEvent,\n ConsensusReachedEvent,\n VotingCompletedEvent,\n FactAddedEvent,\n FactUpdatedEvent,\n FactRemovedEvent,\n InferenceAddedEvent,\n KnowledgePatternLearnedEvent,\n PatternAddedEvent,\n SystemSnapshotCreatedEvent,\n SystemSnapshotRestoredEvent,\n SystemErrorEvent,\n VersionConflictEvent,\n StateInitializedEvent,\n SnapshotCreatedEvent,\n SnapshotRestoredEvent,\n BoardPhase,\n AgentStatus,\n TaskStatus,\n AgendaStatus,\n Task,\n Agenda,\n Opinion,\n Resolution,\n Fact,\n Inference,\n Pattern,\n TaskError,\n} from \"./types\";\n\n/**\n * 이벤트 생성 옵션\n */\nexport interface CreateEventOptions {\n /** 상관 ID */\n correlationId?: string;\n /** 소스 (기본: 'system') */\n source?: AgentId | \"system\";\n}\n\n/**\n * 이벤트 팩토리\n * @description 타입 안전한 이벤트 생성\n */\nexport class EventFactory {\n private idGenerator: () => string;\n\n constructor(idGenerator?: () => string) {\n if (idGenerator) {\n this.idGenerator = idGenerator;\n } else {\n let counter = 0;\n this.idGenerator = () => `evt_${++counter}`;\n }\n }\n\n // === State Events ===\n\n createPhaseChanged(\n previousPhase: BoardPhase,\n newPhase: BoardPhase,\n optionsOrSource?: CreateEventOptions | AgentId | \"system\"\n ): PhaseChangedEvent {\n // 세 번째 인자가 string이면 source로 처리\n const options =\n typeof optionsOrSource === \"string\"\n ? { source: optionsOrSource as AgentId | \"system\" }\n : optionsOrSource;\n\n return {\n id: this.idGenerator(),\n type: \"state.phase.changed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { previousPhase, newPhase },\n };\n }\n\n createContextUpdated(\n key: string,\n previousValue: unknown,\n newValue: unknown,\n options?: CreateEventOptions\n ): ContextUpdatedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.context.updated\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { key, previousValue, newValue },\n };\n }\n\n createStateAgentRegistered(\n agent: AgentStatus,\n options?: CreateEventOptions\n ): StateAgentRegisteredEvent {\n return {\n id: this.idGenerator(),\n type: \"state.agent.registered\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agent },\n };\n }\n\n createStateAgentUpdated(\n agentId: AgentId,\n previousStatus: AgentStatus,\n newStatus: AgentStatus,\n options?: CreateEventOptions\n ): StateAgentUpdatedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.agent.updated\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agentId, previousStatus, newStatus },\n };\n }\n\n createStateTaskCreated(task: Task, options?: CreateEventOptions): StateTaskCreatedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.task.created\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { task },\n };\n }\n\n createStateTaskAssigned(\n taskId: TaskId,\n assignedTo: AgentId,\n options?: CreateEventOptions\n ): StateTaskAssignedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.task.assigned\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, assignedTo },\n };\n }\n\n createStateTaskCompleted(\n taskId: TaskId,\n result: unknown,\n duration: number,\n options?: CreateEventOptions\n ): StateTaskCompletedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.task.completed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, result, duration },\n };\n }\n\n createStateTaskFailed(\n taskId: TaskId,\n error: TaskError,\n retryable: boolean,\n options?: CreateEventOptions\n ): StateTaskFailedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.task.failed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, error, retryable },\n };\n }\n\n // === Agent Events ===\n\n createAgentRegistered(agent: AgentStatus, options?: CreateEventOptions): AgentRegisteredEvent {\n return {\n id: this.idGenerator(),\n type: \"state.agent.registered\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agent },\n };\n }\n\n createAgentStatusChanged(\n agentId: AgentId,\n previousStatus: AgentStatus,\n newStatus: AgentStatus,\n options?: CreateEventOptions\n ): AgentStatusChangedEvent {\n return {\n id: this.idGenerator(),\n type: \"agent.status.changed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agentId, previousStatus, newStatus },\n };\n }\n\n createAgentRemoved(\n agentId: AgentId,\n reason: string,\n options?: CreateEventOptions\n ): AgentRemovedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.agent.removed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agentId, reason },\n };\n }\n\n createAgentUpdated(\n agentId: AgentId,\n changes: Partial<AgentStatus>,\n previousValues: Partial<AgentStatus>,\n options?: CreateEventOptions\n ): AgentUpdatedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.agent.updated\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agentId, changes, previousValues },\n };\n }\n\n // === Task Events ===\n\n createTaskCreated(task: Task, options?: CreateEventOptions): TaskCreatedEvent {\n return {\n id: this.idGenerator(),\n type: \"task.created\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { task },\n };\n }\n\n createTaskAssigned(\n taskId: TaskId,\n agentId: AgentId,\n options?: CreateEventOptions\n ): TaskAssignedEvent {\n return {\n id: this.idGenerator(),\n type: \"task.assigned\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, assignedTo: agentId },\n };\n }\n\n createTaskStatusChanged(\n taskId: TaskId,\n previousStatus: TaskStatus,\n newStatus: TaskStatus,\n options?: CreateEventOptions\n ): TaskStatusChangedEvent {\n return {\n id: this.idGenerator(),\n type: \"task.status.changed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, previousStatus, newStatus },\n };\n }\n\n createTaskCompleted(\n taskId: TaskId,\n outputs: unknown,\n duration: number,\n options?: CreateEventOptions\n ): TaskCompletedEvent {\n return {\n id: this.idGenerator(),\n type: \"task.completed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, outputs, duration },\n };\n }\n\n createTaskFailed(\n taskId: TaskId,\n error: TaskError,\n duration: number,\n options?: CreateEventOptions\n ): TaskFailedEvent {\n return {\n id: this.idGenerator(),\n type: \"task.failed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, error, duration },\n };\n }\n\n createTaskStarted(\n taskId: TaskId,\n agentId: AgentId,\n options?: CreateEventOptions\n ): TaskStartedEvent {\n return {\n id: this.idGenerator(),\n type: \"task.started\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, agentId, startedAt: new Date() },\n };\n }\n\n createTaskCancelled(\n taskId: TaskId,\n reason: string,\n options?: CreateEventOptions\n ): TaskCancelledEvent {\n return {\n id: this.idGenerator(),\n type: \"task.cancelled\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { taskId, reason },\n };\n }\n\n // === Decision Events (Spec 호환) ===\n\n createDecisionsAgendaCreated(\n agenda: Agenda,\n options?: CreateEventOptions\n ): DecisionsAgendaCreatedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.agenda.created\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agenda },\n };\n }\n\n createDecisionsAgendaStarted(\n agendaId: AgendaId,\n options?: CreateEventOptions\n ): DecisionsAgendaStartedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.agenda.started\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId },\n };\n }\n\n createDecisionsOpinionSubmitted(\n opinion: Opinion,\n options?: CreateEventOptions\n ): DecisionsOpinionSubmittedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.opinion.submitted\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { opinion },\n };\n }\n\n createDecisionsVotingStarted(\n agendaId: AgendaId,\n deadline: Date,\n options?: CreateEventOptions\n ): DecisionsVotingStartedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.voting.started\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId, deadline },\n };\n }\n\n createDecisionsVoteSubmitted(\n agendaId: AgendaId,\n agentId: AgentId,\n vote: \"approve\" | \"reject\" | \"abstain\",\n options?: CreateEventOptions\n ): DecisionsVoteSubmittedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.vote.submitted\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId, agentId, vote },\n };\n }\n\n createDecisionsVotingEnded(\n agendaId: AgendaId,\n result: Resolution,\n options?: CreateEventOptions\n ): DecisionsVotingEndedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.voting.ended\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId, result },\n };\n }\n\n createDecisionsConsensusReached(\n resolution: Resolution,\n options?: CreateEventOptions\n ): DecisionsConsensusReachedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.consensus.reached\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { resolution },\n };\n }\n\n createDecisionsAgendaResolved(\n agendaId: AgendaId,\n resolution: Resolution,\n options?: CreateEventOptions\n ): DecisionsAgendaResolvedEvent {\n return {\n id: this.idGenerator(),\n type: \"decisions.agenda.resolved\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId, resolution },\n };\n }\n\n // === Decision Events (기존 호환성) ===\n\n createAgendaSubmitted(agenda: Agenda, options?: CreateEventOptions): AgendaSubmittedEvent {\n return {\n id: this.idGenerator(),\n type: \"decision.agenda.submitted\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agenda },\n };\n }\n\n createAgendaStatusChanged(\n agendaId: AgendaId,\n previousStatus: AgendaStatus,\n newStatus: AgendaStatus,\n options?: CreateEventOptions\n ): AgendaStatusChangedEvent {\n return {\n id: this.idGenerator(),\n type: \"decision.agenda.status_changed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId, previousStatus, newStatus },\n };\n }\n\n createOpinionSubmitted(opinion: Opinion, options?: CreateEventOptions): OpinionSubmittedEvent {\n return {\n id: this.idGenerator(),\n type: \"decision.opinion.submitted\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { opinion },\n };\n }\n\n createVoteRequested(\n agendaId: AgendaId,\n deadline: Date,\n requiredVoters: AgentId[],\n options?: CreateEventOptions\n ): VoteRequestedEvent {\n return {\n id: this.idGenerator(),\n type: \"decision.vote.requested\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId, deadline, requiredVoters },\n };\n }\n\n createConsensusReached(\n resolution: Resolution,\n options?: CreateEventOptions\n ): ConsensusReachedEvent {\n return {\n id: this.idGenerator(),\n type: \"decision.consensus.reached\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { resolution },\n };\n }\n\n createVotingCompleted(\n agendaId: AgendaId,\n result: {\n passed: boolean;\n method: string;\n summary: {\n total: number;\n approve: number;\n reject: number;\n abstain: number;\n approvalRate: number;\n quorumReached: boolean;\n };\n },\n options?: CreateEventOptions\n ): VotingCompletedEvent {\n return {\n id: this.idGenerator(),\n type: \"decision.voting.completed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { agendaId, result },\n };\n }\n\n // === Knowledge Events ===\n\n createFactAdded(fact: Fact, options?: CreateEventOptions): FactAddedEvent {\n return {\n id: this.idGenerator(),\n type: \"knowledge.fact.added\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { fact },\n };\n }\n\n createInferenceAdded(inference: Inference, options?: CreateEventOptions): InferenceAddedEvent {\n return {\n id: this.idGenerator(),\n type: \"knowledge.inference.added\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { inference },\n };\n }\n\n createKnowledgePatternLearned(\n pattern: Pattern,\n options?: CreateEventOptions\n ): KnowledgePatternLearnedEvent {\n return {\n id: this.idGenerator(),\n type: \"knowledge.pattern.learned\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { pattern },\n };\n }\n\n createFactUpdated(\n factId: string,\n changes: Partial<Fact>,\n previousValues?: Partial<Fact>,\n options?: CreateEventOptions\n ): FactUpdatedEvent {\n return {\n id: this.idGenerator(),\n type: \"knowledge.fact.updated\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { factId, changes, previousValues },\n };\n }\n\n createFactRemoved(\n factId: string,\n reason: string,\n options?: CreateEventOptions\n ): FactRemovedEvent {\n return {\n id: this.idGenerator(),\n type: \"knowledge.fact.removed\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { factId, reason },\n };\n }\n\n createPatternAdded(pattern: Pattern, options?: CreateEventOptions): PatternAddedEvent {\n return {\n id: this.idGenerator(),\n type: \"knowledge.pattern.added\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { pattern },\n };\n }\n\n // === System Events ===\n\n createSystemSnapshotCreated(\n snapshotId: string,\n timestamp: Date,\n options?: CreateEventOptions\n ): SystemSnapshotCreatedEvent {\n return {\n id: this.idGenerator(),\n type: \"system.snapshot.created\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { snapshotId, timestamp },\n };\n }\n\n createSystemSnapshotRestored(\n snapshotId: string,\n timestamp: Date,\n options?: CreateEventOptions\n ): SystemSnapshotRestoredEvent {\n return {\n id: this.idGenerator(),\n type: \"system.snapshot.restored\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { snapshotId, timestamp },\n };\n }\n\n createSystemError(\n code: string,\n message: string,\n details?: unknown,\n options?: CreateEventOptions\n ): SystemErrorEvent {\n return {\n id: this.idGenerator(),\n type: \"system.error\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { code, message, details },\n };\n }\n\n createVersionConflict(\n path: string,\n expectedVersion: number,\n actualVersion: number,\n options?: CreateEventOptions\n ): VersionConflictEvent {\n return {\n id: this.idGenerator(),\n type: \"system.version.conflict\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { path, expectedVersion, actualVersion },\n };\n }\n\n createStateInitialized(sessionId: string, options?: CreateEventOptions): StateInitializedEvent {\n return {\n id: this.idGenerator(),\n type: \"state.initialized\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { sessionId },\n };\n }\n\n createSnapshotCreated(\n snapshotId: string,\n version: number,\n options?: CreateEventOptions\n ): SnapshotCreatedEvent {\n return {\n id: this.idGenerator(),\n type: \"snapshot.created\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { snapshotId, version },\n };\n }\n\n createSnapshotRestored(\n snapshotId: string,\n previousVersion: number,\n restoredVersion: number,\n options?: CreateEventOptions\n ): SnapshotRestoredEvent {\n return {\n id: this.idGenerator(),\n type: \"snapshot.restored\",\n timestamp: new Date(),\n source: options?.source ?? \"system\",\n correlationId: options?.correlationId,\n payload: { snapshotId, previousVersion, restoredVersion },\n };\n }\n}\n","import type {\n EdgeId,\n GraphQuery,\n IProductionPromotionPort,\n MergeResult,\n NodeId,\n PromotionMeta,\n PromotionResult,\n QueryResult,\n TemporalEdge,\n TemporalNode,\n ValidationResult,\n} from '../../types/tkg';\nimport type { ProductionTKG, StagingTKG } from '../../core/tkg';\n\nclass QueryableTKG {\n protected readonly nodeStore: Map<NodeId, TemporalNode>;\n protected readonly edgeStore: Map<EdgeId, TemporalEdge>;\n\n constructor(nodes: Map<NodeId, TemporalNode> = new Map(), edges: Map<EdgeId, TemporalEdge> = new Map()) {\n this.nodeStore = nodes;\n this.edgeStore = edges;\n }\n\n get nodes(): ReadonlyMap<NodeId, TemporalNode> {\n return this.nodeStore;\n }\n\n get edges(): ReadonlyMap<EdgeId, TemporalEdge> {\n return this.edgeStore;\n }\n\n queryCurrent(query: GraphQuery): QueryResult {\n return this.queryAtTime(query, new Date());\n }\n\n queryAtTime(query: GraphQuery, time = new Date()): QueryResult {\n const nodes = Array.from(this.nodeStore.values()).filter((node) => {\n if (query.nodeTypes && !query.nodeTypes.includes(node.type)) return false;\n if (query.nodeIds && !query.nodeIds.includes(node.id)) return false;\n if (query.tags && (!node.tags || !query.tags.every((tag) => node.tags?.includes(tag)))) return false;\n if (query.minConfidence !== undefined && node.confidence < query.minConfidence) return false;\n return node.valid_from <= time && (!node.valid_to || node.valid_to > time);\n });\n\n const nodeIdSet = new Set(nodes.map((node) => node.id));\n const edges = Array.from(this.edgeStore.values()).filter((edge) => {\n if (query.edgeTypes && !query.edgeTypes.includes(edge.type)) return false;\n if (query.from && edge.from !== query.from) return false;\n if (query.to && edge.to !== query.to) return false;\n if (!nodeIdSet.has(edge.from) || !nodeIdSet.has(edge.to)) return false;\n return edge.valid_from <= time && (!edge.valid_to || edge.valid_to > time);\n });\n\n const confidenceValues = nodes.map((node) => node.confidence);\n const min = confidenceValues.length > 0 ? Math.min(...confidenceValues) : 0;\n const max = confidenceValues.length > 0 ? Math.max(...confidenceValues) : 0;\n\n return {\n nodes,\n edges,\n metadata: {\n queryTime: time,\n resultCount: nodes.length,\n confidenceRange: [min, max] as const,\n },\n };\n }\n\n queryTimeRange(query: GraphQuery, from: Date, to: Date): readonly QueryResult[] {\n return [this.queryAtTime(query, from), this.queryAtTime(query, to)];\n }\n\n queryByConfidence(query: GraphQuery, minConfidence: number): QueryResult {\n return this.queryCurrent({ ...query, minConfidence });\n }\n}\n\nexport class InMemoryStagingTKG extends QueryableTKG implements StagingTKG {\n addNode(node: TemporalNode): NodeId {\n this.nodeStore.set(node.id, node);\n return node.id;\n }\n\n addEdge(edge: TemporalEdge): EdgeId {\n this.edgeStore.set(edge.id, edge);\n return edge.id;\n }\n\n clearNodes(): void {\n this.nodeStore.clear();\n }\n\n restoreNodes(nodes: readonly TemporalNode[]): void {\n this.nodeStore.clear();\n nodes.forEach((node) => this.nodeStore.set(node.id, node));\n }\n\n validateNode(node: TemporalNode): ValidationResult {\n const errors = [];\n if (node.confidence < 0 || node.confidence > 1) {\n errors.push({ field: 'confidence', message: 'confidence must be 0..1', code: 'RANGE' });\n }\n\n return { valid: errors.length === 0, errors, warnings: [] };\n }\n\n validateEdge(edge: TemporalEdge): ValidationResult {\n const errors = [];\n if (edge.confidence < 0 || edge.confidence > 1) {\n errors.push({ field: 'confidence', message: 'confidence must be 0..1', code: 'RANGE' });\n }\n\n return { valid: errors.length === 0, errors, warnings: [] };\n }\n}\n\nexport class InMemoryProductionTKG extends QueryableTKG implements ProductionTKG, IProductionPromotionPort {\n private readonly readonlyNodeView = this.createReadonlyMapView(this.nodeStore);\n private readonly readonlyEdgeView = this.createReadonlyMapView(this.edgeStore);\n\n override get nodes(): ReadonlyMap<NodeId, TemporalNode> {\n return this.readonlyNodeView;\n }\n\n override get edges(): ReadonlyMap<EdgeId, TemporalEdge> {\n return this.readonlyEdgeView;\n }\n\n getValidNodes(at = new Date()): readonly TemporalNode[] {\n return this.queryAtTime({}, at).nodes;\n }\n\n getValidEdges(at = new Date()): readonly TemporalEdge[] {\n return this.queryAtTime({}, at).edges;\n }\n\n private createReadonlyMapView<TKey, TValue>(map: Map<TKey, TValue>): ReadonlyMap<TKey, TValue> {\n return new Proxy(map, {\n get(target, property, receiver) {\n if (property === 'set' || property === 'delete' || property === 'clear') {\n return () => {\n throw new TypeError('ProductionTKG map is read-only');\n };\n }\n\n const value = Reflect.get(target, property, receiver);\n if (typeof value === 'function') {\n return value.bind(target);\n }\n\n return value;\n },\n }) as ReadonlyMap<TKey, TValue>;\n }\n\n promoteNode(node: TemporalNode, _meta?: PromotionMeta): PromotionResult {\n this.nodeStore.set(node.id, node);\n return { nodeId: node.id, success: true, timestamp: new Date() };\n }\n\n promoteEdge(edge: TemporalEdge, _meta?: PromotionMeta): PromotionResult {\n this.edgeStore.set(edge.id, edge);\n return { nodeId: edge.from, success: true, timestamp: new Date() };\n }\n\n promoteBatch(payload: {\n nodes: readonly TemporalNode[];\n edges: readonly TemporalEdge[];\n meta?: PromotionMeta;\n }): MergeResult {\n payload.nodes.forEach((node) => this.nodeStore.set(node.id, node));\n payload.edges.forEach((edge) => this.edgeStore.set(edge.id, edge));\n return {\n mergeId: crypto.randomUUID(),\n timestamp: new Date(),\n nodesPromoted: payload.nodes.length,\n nodesSkipped: 0,\n nodesFailed: 0,\n edgesPromoted: payload.edges.length,\n edgesSkipped: 0,\n conflicts: [],\n duration: 0,\n };\n }\n}\n","import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport type {\n ManualReviewItem,\n ReflectorOperationalMetrics,\n ReflectorOperationalReport,\n ReflectorPersistedState,\n ReflectorStateStore,\n} from './ObserverReflector';\nimport type { TemporalNode } from '../../types/tkg';\n\ninterface SerializedSnapshot {\n readonly mergeId: string;\n readonly nodes: readonly SerializedTemporalNode[];\n}\n\ntype SerializedTemporalNode = Omit<TemporalNode, 'valid_from' | 'valid_to' | 'observed_at' | 'updated_at'> & {\n readonly valid_from: string;\n readonly valid_to?: string;\n readonly observed_at: string;\n readonly updated_at: string;\n};\n\ninterface SerializedReflectorState {\n readonly metrics: ReflectorOperationalMetrics;\n readonly manualReviewQueue: readonly ManualReviewItem[];\n readonly deferredQueue: readonly ManualReviewItem[];\n readonly reportHistory: readonly (Omit<ReflectorOperationalReport, 'generatedAt'> & { readonly generatedAt: string })[];\n readonly rollbackSnapshots: readonly SerializedSnapshot[];\n}\n\nexport class JsonFileReflectorStateStore implements ReflectorStateStore {\n constructor(private readonly filePath: string) {}\n\n load(): ReflectorPersistedState | null {\n if (!existsSync(this.filePath)) {\n return null;\n }\n\n const raw = readFileSync(this.filePath, 'utf8');\n if (!raw.trim()) {\n return null;\n }\n\n try {\n const parsed = JSON.parse(raw) as SerializedReflectorState;\n return {\n metrics: parsed.metrics,\n manualReviewQueue: parsed.manualReviewQueue.map((item) => ({\n ...item,\n queuedAt: new Date(item.queuedAt),\n })),\n deferredQueue: parsed.deferredQueue.map((item) => ({\n ...item,\n queuedAt: new Date(item.queuedAt),\n })),\n reportHistory: parsed.reportHistory.map((report) => ({\n ...report,\n generatedAt: new Date(report.generatedAt),\n })),\n rollbackSnapshots: parsed.rollbackSnapshots.map((snapshot) => ({\n mergeId: snapshot.mergeId,\n nodes: snapshot.nodes.map((node) => this.deserializeNode(node)),\n })),\n };\n } catch {\n return null;\n }\n }\n\n save(state: ReflectorPersistedState): void {\n mkdirSync(dirname(this.filePath), { recursive: true });\n\n const serializable: SerializedReflectorState = {\n metrics: state.metrics,\n manualReviewQueue: state.manualReviewQueue.map((item) => ({\n ...item,\n queuedAt: new Date(item.queuedAt),\n })),\n deferredQueue: state.deferredQueue.map((item) => ({\n ...item,\n queuedAt: new Date(item.queuedAt),\n })),\n reportHistory: state.reportHistory.map((report) => ({\n ...report,\n generatedAt: report.generatedAt.toISOString(),\n })),\n rollbackSnapshots: state.rollbackSnapshots.map((snapshot) => ({\n mergeId: snapshot.mergeId,\n nodes: snapshot.nodes.map((node) => this.serializeNode(node)),\n })),\n };\n\n const tempPath = `${this.filePath}.tmp`;\n writeFileSync(tempPath, JSON.stringify(serializable, null, 2), 'utf8');\n renameSync(tempPath, this.filePath);\n }\n\n private serializeNode(node: TemporalNode): SerializedTemporalNode {\n return {\n ...node,\n valid_from: node.valid_from.toISOString(),\n valid_to: node.valid_to?.toISOString(),\n observed_at: node.observed_at.toISOString(),\n updated_at: node.updated_at.toISOString(),\n };\n }\n\n private deserializeNode(node: SerializedTemporalNode): TemporalNode {\n return {\n ...node,\n valid_from: new Date(node.valid_from),\n valid_to: node.valid_to ? new Date(node.valid_to) : undefined,\n observed_at: new Date(node.observed_at),\n updated_at: new Date(node.updated_at),\n };\n }\n}\n","import type { RetryRecoveryStrategy } from \"./types.js\";\n\nconst DEFAULT_MULTIPLIER = 2;\n\nexport function calculateRetryDelay(strategy: RetryRecoveryStrategy, attempt: number): number {\n const safeAttempt = Math.max(1, attempt);\n\n if (strategy.mode === \"linear\") {\n return Math.min(strategy.maxDelayMs, strategy.initialDelayMs * safeAttempt);\n }\n\n const multiplier = strategy.multiplier ?? DEFAULT_MULTIPLIER;\n const exponential = strategy.initialDelayMs * Math.pow(multiplier, safeAttempt - 1);\n return Math.min(strategy.maxDelayMs, exponential);\n}\n","import { EventEmitter } from \"events\";\n\nimport type { ActorRuntime } from \"../runtime/ActorRuntime\";\nimport type { ActorId, Actor } from \"../types/actor\";\n\nimport {\n SupervisorConfig,\n RestartStrategy,\n RestartDirective,\n BackoffPolicy,\n RestartHistory,\n DeadLetter,\n SupervisorEvents,\n} from \"./types\";\n\n/**\n * 기본 Supervisor 설정\n */\nconst DEFAULT_CONFIG: SupervisorConfig = {\n strategy: RestartStrategy.ONE_FOR_ONE,\n backoff: {\n policy: BackoffPolicy.EXPONENTIAL,\n initialDelay: 1000,\n maxDelay: 30000,\n multiplier: 2,\n },\n maxRestarts: 3,\n restartWindow: 60000, // 1분\n enableDeadLetterQueue: true,\n deadLetterQueueSize: 100,\n debug: false,\n};\n\n/**\n * Supervisor\n *\n * Actor의 실패를 감지하고 재시작 전략에 따라 복구합니다.\n */\nexport class Supervisor extends EventEmitter {\n private readonly config: SupervisorConfig;\n private readonly runtime: ActorRuntime;\n private readonly restartCounts: Map<ActorId, number>;\n private readonly restartTimestamps: Map<ActorId, Date[]>;\n private readonly restartHistory: RestartHistory[];\n private readonly deadLetterQueue: DeadLetter[];\n private readonly watchedActors: Set<ActorId>;\n private isRunning: boolean;\n\n constructor(runtime: ActorRuntime, config?: Partial<SupervisorConfig>) {\n super();\n this.runtime = runtime;\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.restartCounts = new Map();\n this.restartTimestamps = new Map();\n this.restartHistory = [];\n this.deadLetterQueue = [];\n this.watchedActors = new Set();\n this.isRunning = false;\n }\n\n /**\n * Supervisor 시작\n */\n start(): void {\n if (this.isRunning) {\n throw new Error(\"Supervisor is already running\");\n }\n this.isRunning = true;\n this.log(\"Supervisor started\");\n }\n\n /**\n * Supervisor 종료\n */\n stop(): void {\n if (!this.isRunning) {\n return;\n }\n this.isRunning = false;\n this.watchedActors.clear();\n this.log(\"Supervisor stopped\");\n }\n\n /**\n * Actor 감시 시작\n * @param actorId 감시할 Actor ID\n */\n watch(actorId: ActorId): void {\n if (!this.isRunning) {\n throw new Error(\"Supervisor is not running\");\n }\n\n this.watchedActors.add(actorId);\n this.restartCounts.set(actorId, 0);\n this.restartTimestamps.set(actorId, []);\n\n this.log(`Watching actor: ${actorId}`);\n }\n\n /**\n * Actor 감시 종료\n * @param actorId 감시 종료할 Actor ID\n */\n unwatch(actorId: ActorId): void {\n this.watchedActors.delete(actorId);\n this.restartCounts.delete(actorId);\n this.restartTimestamps.delete(actorId);\n\n this.log(`Unwatched actor: ${actorId}`);\n }\n\n /**\n * Actor 실패 처리\n * @param actorId 실패한 Actor ID\n * @param error 실패 원인\n */\n async handleFailure(actorId: ActorId, error: Error): Promise<void> {\n if (!this.isRunning || !this.watchedActors.has(actorId)) {\n return;\n }\n\n this.log(`Actor failed: ${actorId} - ${error.message}`);\n this.emit(\"actor:failed\", actorId, error);\n\n // 재시작 결정\n const directive = this.decideRestart(actorId, error);\n\n switch (directive) {\n case RestartDirective.RESTART:\n await this.performRestart(actorId, error);\n break;\n\n case RestartDirective.STOP:\n await this.performStop(actorId, \"Decider returned STOP\");\n break;\n\n case RestartDirective.ESCALATE:\n this.escalate(actorId, error);\n break;\n }\n }\n\n /**\n * Dead Letter Queue 조회\n */\n getDeadLetters(): DeadLetter[] {\n return [...this.deadLetterQueue];\n }\n\n /**\n * Dead Letter Queue 비우기\n */\n clearDeadLetters(): void {\n this.deadLetterQueue.length = 0;\n }\n\n /**\n * 재시작 이력 조회\n */\n getRestartHistory(actorId?: ActorId): RestartHistory[] {\n if (actorId) {\n return this.restartHistory.filter((h) => h.actorId === actorId);\n }\n return [...this.restartHistory];\n }\n\n /**\n * 감시 중인 Actor 목록\n */\n getWatchedActors(): ActorId[] {\n return Array.from(this.watchedActors);\n }\n\n // ==================== 내부 메서드 ====================\n\n /**\n * 재시작 결정\n */\n private decideRestart(actorId: ActorId, error: Error): RestartDirective {\n // 커스텀 decider가 있으면 사용\n if (this.config.decider) {\n try {\n const actor = this.runtime.getActor(actorId);\n if (actor) {\n return this.config.decider(error, actor);\n }\n } catch {\n // Actor를 찾을 수 없는 경우\n }\n }\n\n // 재시작 윈도우 내 횟수 확인\n const timestamps = this.restartTimestamps.get(actorId) || [];\n const now = Date.now();\n const windowStart = now - this.config.restartWindow;\n\n // 윈도우 내 재시작 횟수 계산\n const recentRestarts = timestamps.filter((t) => t.getTime() > windowStart).length;\n\n if (recentRestarts >= this.config.maxRestarts) {\n this.log(\n `Max restarts exceeded for ${actorId}: ${recentRestarts}/${this.config.maxRestarts}`\n );\n this.emit(\"max-restarts-exceeded\", actorId);\n return RestartDirective.STOP;\n }\n\n return RestartDirective.RESTART;\n }\n\n /**\n * 재시작 수행\n */\n private async performRestart(actorId: ActorId, error: Error): Promise<void> {\n const attempt = (this.restartCounts.get(actorId) || 0) + 1;\n this.restartCounts.set(actorId, attempt);\n\n // 타임스탬프 기록\n const timestamps = this.restartTimestamps.get(actorId) || [];\n timestamps.push(new Date());\n this.restartTimestamps.set(actorId, timestamps);\n\n // 백오프 대기\n const delay = this.calculateBackoff(attempt);\n this.log(`Waiting ${delay}ms before restart (attempt ${attempt})`);\n await this.delay(delay);\n\n try {\n // 전략에 따른 재시작\n switch (this.config.strategy) {\n case RestartStrategy.ONE_FOR_ONE:\n await this.restartOne(actorId);\n break;\n\n case RestartStrategy.ALL_FOR_ONE:\n await this.restartAll();\n break;\n\n case RestartStrategy.REST_FOR_ONE:\n await this.restartRest(actorId);\n break;\n }\n\n // 이력 기록\n this.recordHistory(actorId, error, attempt, true);\n this.emit(\"actor:restarted\", actorId, attempt);\n\n this.log(`Actor restarted: ${actorId} (attempt ${attempt})`);\n } catch (restartError) {\n // 재시작 실패\n this.recordHistory(actorId, error, attempt, false);\n\n // Dead Letter Queue에 추가\n if (this.config.enableDeadLetterQueue) {\n this.addDeadLetter(actorId, restartError as Error, attempt);\n }\n\n // attempt 카운터 기반으로 절대적 재시작 횟수 제한\n const currentAttempt = this.restartCounts.get(actorId) || 0;\n if (currentAttempt >= this.config.maxRestarts) {\n this.emit(\"max-restarts-exceeded\", actorId);\n await this.performStop(actorId, \"Max restarts exceeded after restart failure\");\n } else {\n // handleFailure를 통해 decideRestart 로직을 재평가\n await this.handleFailure(actorId, restartError as Error);\n }\n }\n }\n\n /**\n * OneForOne: 해당 Actor만 재시작\n */\n private async restartOne(actorId: ActorId): Promise<void> {\n await this.runtime.restart(actorId);\n }\n\n /**\n * AllForOne: 모든 감시 중인 Actor 재시작\n */\n private async restartAll(): Promise<void> {\n const restartPromises = Array.from(this.watchedActors).map((id) =>\n this.runtime.restart(id).catch((err) => {\n this.log(`Failed to restart ${id}: ${err.message}`);\n })\n );\n\n await Promise.all(restartPromises);\n }\n\n /**\n * RestForOne: 해당 Actor와 이후 생성된 Actor들 재시작\n */\n private async restartRest(actorId: ActorId): Promise<void> {\n const actorIds = Array.from(this.watchedActors);\n const index = actorIds.indexOf(actorId);\n\n if (index === -1) {\n return;\n }\n\n // 해당 Actor와 이후 Actor들 재시작\n const toRestart = actorIds.slice(index);\n const restartPromises = toRestart.map((id) =>\n this.runtime.restart(id).catch((err) => {\n this.log(`Failed to restart ${id}: ${err.message}`);\n })\n );\n\n await Promise.all(restartPromises);\n }\n\n /**\n * 정지 수행\n */\n private async performStop(actorId: ActorId, reason: string): Promise<void> {\n this.log(`Stopping actor permanently: ${actorId} - ${reason}`);\n\n try {\n await this.runtime.stopById(actorId);\n } catch {\n // 이미 정지됨\n }\n\n this.unwatch(actorId);\n this.emit(\"actor:stopped\", actorId, reason);\n }\n\n /**\n * 에스컬레이션\n */\n private escalate(actorId: ActorId, error: Error): void {\n this.log(`Escalating failure for ${actorId}: ${error.message}`);\n\n // 상위 Supervisor에게 전달 (구현에 따라 다름)\n // 여기서는 이벤트로 처리\n this.emit(\"escalate\", actorId, error);\n }\n\n /**\n * 백오프 계산\n */\n private calculateBackoff(attempt: number): number {\n const {\n policy,\n initialDelay,\n maxDelay,\n multiplier = 2,\n jitterFactor = 0.1,\n } = this.config.backoff;\n\n let delay: number;\n\n switch (policy) {\n case BackoffPolicy.FIXED:\n delay = initialDelay;\n break;\n\n case BackoffPolicy.LINEAR:\n delay = initialDelay * attempt;\n break;\n\n case BackoffPolicy.EXPONENTIAL:\n delay = initialDelay * Math.pow(multiplier, attempt - 1);\n break;\n\n case BackoffPolicy.EXPONENTIAL_JITTER: {\n const base = initialDelay * Math.pow(multiplier, attempt - 1);\n const jitter = base * jitterFactor * (Math.random() * 2 - 1);\n delay = base + jitter;\n break;\n }\n\n default:\n delay = initialDelay;\n }\n\n return Math.min(delay, maxDelay);\n }\n\n /**\n * 이력 기록\n */\n private recordHistory(actorId: ActorId, error: Error, attempt: number, success: boolean): void {\n this.restartHistory.push({\n actorId,\n timestamp: new Date(),\n error,\n attempt,\n success,\n });\n\n // 최근 100개만 유지\n if (this.restartHistory.length > 100) {\n this.restartHistory.shift();\n }\n }\n\n /**\n * Dead Letter 추가\n */\n private addDeadLetter(actorId: ActorId, error: Error, retryCount: number): void {\n const letter: DeadLetter = {\n payload: null, // 실제 구현에서는 실패한 메시지 포함\n actorId,\n error,\n timestamp: new Date(),\n retryCount,\n };\n\n this.deadLetterQueue.push(letter);\n\n // 최대 크기 유지\n const maxSize = this.config.deadLetterQueueSize || 100;\n while (this.deadLetterQueue.length > maxSize) {\n this.deadLetterQueue.shift();\n }\n\n this.emit(\"dead-letter\", letter);\n this.log(`Dead letter added for ${actorId}`);\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n private log(message: string): void {\n if (!this.config.debug) return;\n console.log(`[Supervisor] ${message}`);\n }\n}\n","import type { ActorId, Actor } from \"../types/actor\";\n\n/**\n * 재시작 전략 유형\n */\nexport enum RestartStrategy {\n /**\n * OneForOne: 실패한 Actor만 재시작\n * - 다른 Actor에 영향 없음\n * - 독립적인 Actor에 적합\n */\n ONE_FOR_ONE = \"one-for-one\",\n\n /**\n * AllForOne: 하나가 실패하면 모든 Actor 재시작\n * - 강한 의존성이 있는 Actor 그룹에 적합\n * - 일관된 상태 복원 필요 시 사용\n */\n ALL_FOR_ONE = \"all-for-one\",\n\n /**\n * RestForOne: 실패한 Actor와 이후 생성된 Actor들 재시작\n * - 순서 의존성이 있는 Actor에 적합\n */\n REST_FOR_ONE = \"rest-for-one\",\n}\n\n/**\n * 재시작 지시\n */\nexport enum RestartDirective {\n /** 재시작 */\n RESTART = \"restart\",\n\n /** 재시작하지 않음 (정상 종료 처리) */\n STOP = \"stop\",\n\n /** 상위 Supervisor로 에스컬레이션 */\n ESCALATE = \"escalate\",\n}\n\n/**\n * 백오프 정책 유형\n */\nexport enum BackoffPolicy {\n /** 고정 대기 시간 */\n FIXED = \"fixed\",\n\n /** 지수 백오프 */\n EXPONENTIAL = \"exponential\",\n\n /** 선형 백오프 */\n LINEAR = \"linear\",\n\n /** 지터가 포함된 지수 백오프 */\n EXPONENTIAL_JITTER = \"exponential-jitter\",\n}\n\n/**\n * 백오프 설정\n */\nexport interface BackoffConfig {\n /** 백오프 정책 */\n policy: BackoffPolicy;\n\n /** 초기 대기 시간 (ms) */\n initialDelay: number;\n\n /** 최대 대기 시간 (ms) */\n maxDelay: number;\n\n /** 지수/선형 배율 */\n multiplier?: number;\n\n /** 지터 범위 (0-1) */\n jitterFactor?: number;\n}\n\n/**\n * Supervisor 설정\n */\nexport interface SupervisorConfig {\n /** 재시작 전략 */\n strategy: RestartStrategy;\n\n /** 백오프 설정 */\n backoff: BackoffConfig;\n\n /** 최대 재시작 횟수 (기간 내) */\n maxRestarts: number;\n\n /** 재시작 횟수 리셋 기간 (ms) */\n restartWindow: number;\n\n /** 재시작 결정 함수 (커스텀 로직) */\n decider?: (error: Error, actor: Actor) => RestartDirective;\n\n /** Dead Letter Queue 활성화 */\n enableDeadLetterQueue?: boolean;\n\n /** Dead Letter Queue 최대 크기 */\n deadLetterQueueSize?: number;\n\n /** 디버그 모드 */\n debug?: boolean;\n}\n\n/**\n * 재시작 이력\n */\nexport interface RestartHistory {\n /** Actor ID */\n actorId: ActorId;\n\n /** 재시작 시간 */\n timestamp: Date;\n\n /** 재시작 원인 에러 */\n error: Error;\n\n /** 재시작 시도 횟수 */\n attempt: number;\n\n /** 재시작 성공 여부 */\n success: boolean;\n}\n\n/**\n * Dead Letter\n */\nexport interface DeadLetter {\n /** 원본 메시지/작업 */\n payload: unknown;\n\n /** 실패한 Actor ID */\n actorId: ActorId;\n\n /** 실패 에러 */\n error: Error;\n\n /** 실패 시간 */\n timestamp: Date;\n\n /** 재시도 횟수 */\n retryCount: number;\n}\n\n/**\n * Supervisor 이벤트\n */\nexport interface SupervisorEvents {\n /** Actor 실패 시 */\n \"actor:failed\": (actorId: ActorId, error: Error) => void;\n\n /** Actor 재시작 시 */\n \"actor:restarted\": (actorId: ActorId, attempt: number) => void;\n\n /** Actor 영구 정지 시 */\n \"actor:stopped\": (actorId: ActorId, reason: string) => void;\n\n /** Dead Letter 발생 시 */\n \"dead-letter\": (letter: DeadLetter) => void;\n\n /** 최대 재시작 초과 시 */\n \"max-restarts-exceeded\": (actorId: ActorId) => void;\n\n /** 에스컬레이션 */\n escalate: (actorId: ActorId, error: Error) => void;\n}\n","import type {\n AlternativeRecoveryStrategy,\n CellFailure,\n EscalateRecoveryStrategy,\n RecoveryContext,\n RecoveryEngine as RecoveryEngineContract,\n RecoveryResult,\n RecoveryHandleOptions,\n RecoveryStrategy,\n RecoveryStrategyPlugin,\n RollbackRecoveryStrategy,\n RetryRecoveryStrategy,\n} from \"./types.js\";\nimport { calculateRetryDelay } from \"./RetryStrategy.js\";\n\nconst defaultWait = async (ms: number): Promise<void> => {\n await new Promise((resolve) => setTimeout(resolve, ms));\n};\n\nconst fail = (strategy: RecoveryStrategy[\"type\"], error: Error): RecoveryResult => ({\n status: \"failed\",\n strategy,\n error,\n});\n\nclass RetryStrategyPluginImpl implements RecoveryStrategyPlugin {\n readonly type = \"retry\" as const;\n\n async execute(\n failure: CellFailure,\n strategy: RetryRecoveryStrategy,\n context: Required<RecoveryContext>\n ): Promise<RecoveryResult> {\n const { retryExecutor, wait } = context;\n\n if (!retryExecutor) {\n return fail(this.type, new Error(\"retryExecutor is required for retry strategy\"));\n }\n\n if (failure.attempt >= strategy.maxAttempts) {\n return {\n status: \"failed\",\n strategy: this.type,\n attempts: failure.attempt,\n error: new Error(`max retry attempts reached: ${failure.attempt}/${strategy.maxAttempts}`),\n };\n }\n\n const nextAttempt = failure.attempt + 1;\n const delay = calculateRetryDelay(strategy, nextAttempt);\n await wait(delay);\n\n try {\n await retryExecutor.executeRetry({ ...failure, attempt: nextAttempt });\n return {\n status: \"recovered\",\n strategy: this.type,\n attempts: nextAttempt,\n details: { delayMs: delay, mode: strategy.mode },\n };\n } catch (error) {\n return {\n status: \"failed\",\n strategy: this.type,\n attempts: nextAttempt,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n }\n}\n\nclass RollbackStrategyPluginImpl implements RecoveryStrategyPlugin {\n readonly type = \"rollback\" as const;\n\n async execute(\n _failure: CellFailure,\n strategy: RollbackRecoveryStrategy,\n context: Required<RecoveryContext>\n ): Promise<RecoveryResult> {\n if (!context.snapshotStore) {\n return fail(this.type, new Error(\"snapshotStore is required for rollback strategy\"));\n }\n\n try {\n await context.snapshotStore.restore(strategy.snapshotId);\n return {\n status: \"recovered\",\n strategy: this.type,\n details: { snapshotId: strategy.snapshotId },\n };\n } catch (error) {\n return fail(this.type, error instanceof Error ? error : new Error(String(error)));\n }\n }\n}\n\nclass EscalateStrategyPluginImpl implements RecoveryStrategyPlugin {\n readonly type = \"escalate\" as const;\n\n async execute(\n failure: CellFailure,\n strategy: EscalateRecoveryStrategy,\n context: Required<RecoveryContext>\n ): Promise<RecoveryResult> {\n if (!context.escalationNotifier) {\n return fail(this.type, new Error(\"escalationNotifier is required for escalate strategy\"));\n }\n\n try {\n await context.escalationNotifier.notify({\n failure,\n severity: strategy.severity,\n channel: strategy.channel,\n summary: strategy.summary,\n });\n\n return {\n status: \"escalated\",\n strategy: this.type,\n details: { channel: strategy.channel, severity: strategy.severity },\n };\n } catch (error) {\n return fail(this.type, error instanceof Error ? error : new Error(String(error)));\n }\n }\n}\n\nclass AlternativeStrategyPluginImpl implements RecoveryStrategyPlugin {\n readonly type = \"alternative\" as const;\n\n async execute(\n failure: CellFailure,\n strategy: AlternativeRecoveryStrategy,\n context: Required<RecoveryContext>\n ): Promise<RecoveryResult> {\n if (!context.alternativeExecutor) {\n return fail(this.type, new Error(\"alternativeExecutor is required for alternative strategy\"));\n }\n\n try {\n const result = await context.alternativeExecutor.executeAlternative({\n failure,\n stepName: strategy.stepName,\n payload: strategy.payload,\n });\n\n return {\n status: \"recovered\",\n strategy: this.type,\n details: { stepName: strategy.stepName, result },\n };\n } catch (error) {\n return fail(this.type, error instanceof Error ? error : new Error(String(error)));\n }\n }\n}\n\nexport class RecoveryEngine implements RecoveryEngineContract {\n private readonly context: Required<RecoveryContext>;\n private readonly plugins = new Map<RecoveryStrategy[\"type\"], RecoveryStrategyPlugin>();\n\n constructor(context: RecoveryContext = {}) {\n this.context = {\n retryExecutor: context.retryExecutor,\n snapshotStore: context.snapshotStore,\n escalationNotifier: context.escalationNotifier,\n alternativeExecutor: context.alternativeExecutor,\n consensusGate: context.consensusGate,\n auditTrail: context.auditTrail,\n wait: context.wait ?? defaultWait,\n };\n\n this.register(new RetryStrategyPluginImpl());\n this.register(new RollbackStrategyPluginImpl());\n this.register(new EscalateStrategyPluginImpl());\n this.register(new AlternativeStrategyPluginImpl());\n }\n\n register(plugin: RecoveryStrategyPlugin): void {\n this.plugins.set(plugin.type, plugin);\n }\n\n async handle(\n failure: CellFailure,\n strategy: RecoveryStrategy,\n options: RecoveryHandleOptions = {}\n ): Promise<RecoveryResult> {\n await this.recordAudit(\"recovery_start\", failure, {\n strategy: strategy.type,\n options,\n });\n\n if (options.consensusSessionId && this.context.consensusGate) {\n const consensus = this.context.consensusGate.evaluate(options.consensusSessionId);\n if (consensus.status !== \"pass\") {\n const blockedResult: RecoveryResult = {\n status: \"failed\",\n strategy: strategy.type,\n error: new Error(\n `recovery blocked by consensus status: ${consensus.status} (session: ${options.consensusSessionId})`\n ),\n details: {\n consensusSessionId: options.consensusSessionId,\n consensusStatus: consensus.status,\n },\n };\n\n await this.recordAudit(\"recovery_end\", failure, {\n strategy: strategy.type,\n result: blockedResult,\n });\n\n return blockedResult;\n }\n }\n\n const plugin = this.plugins.get(strategy.type);\n const result = !plugin\n ? fail(strategy.type, new Error(`unsupported recovery strategy: ${strategy.type}`))\n : await plugin.execute(failure, strategy, this.context);\n\n await this.recordAudit(\"recovery_end\", failure, {\n strategy: strategy.type,\n result,\n });\n\n return result;\n }\n\n private async recordAudit(\n type: \"recovery_start\" | \"recovery_end\",\n failure: CellFailure,\n data: unknown\n ): Promise<void> {\n if (!this.context.auditTrail) {\n return;\n }\n\n await this.context.auditTrail.record({\n id: crypto.randomUUID(),\n executionId: failure.executionId,\n cellId: failure.cellId,\n timestamp: new Date(),\n type,\n data,\n });\n }\n}\n\n// Legacy export for compatibility during M1 migration.\nexport { Supervisor as LegacyRecoveryEngine } from \"../_legacy/actor/supervision/Supervisor.js\";\nexport { RecoveryEngine as DefaultRecoveryEngine };\n","import type { ActorRuntime } from \"../runtime/ActorRuntime\";\nimport type { ActorId } from \"../types/actor\";\n\nimport { Supervisor } from \"./Supervisor\";\nimport type { SupervisorConfig } from \"./types\";\n\n/**\n * Supervisor 트리 노드\n */\ninterface SupervisorNode {\n id: string;\n supervisor: Supervisor;\n parent: string | null;\n children: Set<string>;\n}\n\n/**\n * Supervisor Tree\n *\n * 계층적인 Supervisor 구조를 관리합니다.\n * 상위 Supervisor가 하위 Supervisor와 Actor들을 감독합니다.\n */\nexport class SupervisorTree {\n private readonly nodes: Map<string, SupervisorNode>;\n private readonly runtime: ActorRuntime;\n private rootId: string | null;\n\n constructor(runtime: ActorRuntime) {\n this.runtime = runtime;\n this.nodes = new Map();\n this.rootId = null;\n }\n\n /**\n * 루트 Supervisor 생성\n * @param config Supervisor 설정\n * @returns 루트 Supervisor ID\n */\n createRoot(config?: Partial<SupervisorConfig>): string {\n if (this.rootId) {\n throw new Error(\"Root supervisor already exists\");\n }\n\n const id = this.generateId(\"root\");\n const supervisor = new Supervisor(this.runtime, config);\n\n this.nodes.set(id, {\n id,\n supervisor,\n parent: null,\n children: new Set(),\n });\n\n this.rootId = id;\n supervisor.start();\n\n // 에스컬레이션 처리 (루트는 에스컬레이션 불가)\n supervisor.on(\"escalate\", (actorId: ActorId, error: Error) => {\n console.error(`[SupervisorTree] Escalation at root for ${actorId}:`, error);\n });\n\n return id;\n }\n\n /**\n * 자식 Supervisor 생성\n * @param parentId 부모 Supervisor ID\n * @param config Supervisor 설정\n * @returns 자식 Supervisor ID\n */\n createChild(parentId: string, config?: Partial<SupervisorConfig>): string {\n const parent = this.nodes.get(parentId);\n if (!parent) {\n throw new Error(`Parent supervisor not found: ${parentId}`);\n }\n\n const id = this.generateId(\"child\");\n const supervisor = new Supervisor(this.runtime, config);\n\n this.nodes.set(id, {\n id,\n supervisor,\n parent: parentId,\n children: new Set(),\n });\n\n parent.children.add(id);\n supervisor.start();\n\n // 에스컬레이션 처리\n supervisor.on(\"escalate\", (actorId: ActorId, error: Error) => {\n this.handleEscalation(id, actorId, error);\n });\n\n return id;\n }\n\n /**\n * Supervisor 조회\n * @param id Supervisor ID\n * @returns Supervisor 인스턴스\n */\n getSupervisor(id: string): Supervisor {\n const node = this.nodes.get(id);\n if (!node) {\n throw new Error(`Supervisor not found: ${id}`);\n }\n return node.supervisor;\n }\n\n /**\n * 루트 Supervisor 조회\n */\n getRoot(): Supervisor | null {\n if (!this.rootId) {\n return null;\n }\n return this.nodes.get(this.rootId)?.supervisor || null;\n }\n\n /**\n * Supervisor 제거\n * @param id Supervisor ID\n */\n remove(id: string): void {\n const node = this.nodes.get(id);\n if (!node) {\n return;\n }\n\n // 자식들 먼저 제거\n for (const childId of node.children) {\n this.remove(childId);\n }\n\n // Supervisor 정지\n node.supervisor.stop();\n\n // 부모에서 제거\n if (node.parent) {\n const parent = this.nodes.get(node.parent);\n parent?.children.delete(id);\n }\n\n // 맵에서 제거\n this.nodes.delete(id);\n\n // 루트인 경우\n if (id === this.rootId) {\n this.rootId = null;\n }\n }\n\n /**\n * 전체 트리 정지\n */\n shutdown(): void {\n if (this.rootId) {\n this.remove(this.rootId);\n }\n }\n\n /**\n * 트리 구조 출력 (디버그용)\n */\n printTree(): string {\n if (!this.rootId) {\n return \"(empty tree)\";\n }\n\n const lines: string[] = [];\n this.printNode(this.rootId, 0, lines);\n return lines.join(\"\\n\");\n }\n\n // ==================== 내부 메서드 ====================\n\n private handleEscalation(supervisorId: string, actorId: ActorId, error: Error): void {\n const node = this.nodes.get(supervisorId);\n if (!node || !node.parent) {\n // 루트 도달 - 처리 불가\n console.error(`[SupervisorTree] Unhandled escalation for ${actorId}:`, error);\n return;\n }\n\n // 부모 Supervisor에게 전달\n const parent = this.nodes.get(node.parent);\n if (parent) {\n parent.supervisor.handleFailure(actorId, error);\n }\n }\n\n private printNode(id: string, depth: number, lines: string[]): void {\n const node = this.nodes.get(id);\n if (!node) return;\n\n const indent = \" \".repeat(depth);\n const watched = node.supervisor.getWatchedActors();\n lines.push(`${indent}[${id}] watching: ${watched.join(\", \") || \"(none)\"}`);\n\n for (const childId of node.children) {\n this.printNode(childId, depth + 1, lines);\n }\n }\n\n private generateId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { buildGraph, generateExecutionPlan, getNextSteps, parseWorkflow, type Step, type Workflow } from \"../_legacy/workflow/index.js\";\nimport type { CellManager } from \"../cell/CellManager.js\";\nimport type { Task } from \"../cell/types.js\";\nimport type { AuditTrail } from \"../audit/AuditTrail.js\";\nimport type { AuditEventType } from \"../audit/types.js\";\nimport { persistStructuredAuditEvent } from \"../audit/AuditReplay.js\";\nimport type { ConsensusGate } from \"../consensus/ConsensusGate.js\";\nimport type { PolicyEngine } from \"../policy/PolicyEngine.js\";\nimport type { PolicyDecision } from \"../policy/types.js\";\nimport type { RecoveryEngine, RecoveryStrategy } from \"../recovery/types.js\";\nimport type { StateBinder, StateBinding } from \"../state/StateBinder.js\";\nimport type { StorageAdapter, RunRecord, StepRecord, ResumeOptions } from \"../storage/types.js\";\nimport type { ArtifactStore } from \"../artifacts/types.js\";\nimport { CheckpointManager, PolicyDriftError } from \"../checkpoint/CheckpointManager.js\";\nimport type { PolicyHashInput } from \"../checkpoint/policy-hash.js\";\nimport { parseDuration } from \"./utils.js\";\nimport type {\n Execution,\n ExecutionFilter,\n ExecutionStepStatus,\n GateWaitState,\n GateWaitStateStore,\n ResumeResult,\n RuntimeOrchestrator as RuntimeOrchestratorContract,\n RuntimeOrchestratorOptions,\n} from \"./types.js\";\n\nexport interface RuntimeOrchestratorDependencies {\n cellManager: CellManager;\n policyEngine: PolicyEngine;\n stateBinder?: StateBinder;\n auditTrail?: AuditTrail;\n consensusGate?: ConsensusGate;\n recoveryEngine?: RecoveryEngine;\n gateWaitStateStore?: GateWaitStateStore;\n storageAdapter?: StorageAdapter;\n artifactStore?: ArtifactStore;\n}\n\ninterface WaitingContext {\n workflow: Workflow;\n step: Step;\n completed: Set<string>;\n scheduled: Set<string>;\n input: unknown;\n}\n\ninterface StepGateDecision {\n gateType: GateWaitState[\"gateType\"];\n config?: { timeout?: string; fallback?: \"fail\" | \"escalate\" | \"auto-approve\" };\n}\n\ninterface RuntimeGateDecision extends Extract<PolicyDecision, { type: \"gate\" }> {\n gateType: GateWaitState[\"gateType\"];\n config?: { timeout?: string; fallback?: \"fail\" | \"escalate\" | \"auto-approve\" };\n}\n\ninterface BackEdgeState {\n source: string;\n target: string;\n iterationCount: number;\n costUsd: number;\n}\n\ninterface BackEdgeTriggerResult {\n step: Step;\n status: \"back_edge\";\n targetStep: string;\n}\n\nconst LOOP_KEY_PREFIX = \"__obora.loop.\";\nconst STARVATION_TIMEOUT_MS_DEFAULT = 60000;\nconst defaultWait = async (ms: number): Promise<void> => {\n if (ms <= 0) {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, ms));\n};\n\nconst inMemoryGateStateStore = (): GateWaitStateStore => {\n const states = new Map<string, GateWaitState>();\n return {\n save: async (state) => {\n states.set(state.executionId, structuredClone(state));\n },\n get: async (executionId) => {\n const value = states.get(executionId);\n return value ? structuredClone(value) : undefined;\n },\n delete: async (executionId) => {\n states.delete(executionId);\n },\n };\n};\n\nexport class DefaultRuntimeOrchestrator implements RuntimeOrchestratorContract {\n private readonly workflows = new Map<string, Workflow>();\n private readonly executions = new Map<string, Execution>();\n private readonly waitingContexts = new Map<string, WaitingContext>();\n private readonly approvedGateSteps = new Set<string>();\n private readonly createExecutionId: () => string;\n private readonly now: () => Date;\n private readonly wait: (ms: number) => Promise<void>;\n private readonly starvationTimeoutMs: number;\n private readonly gateWaitStateStore: GateWaitStateStore;\n\n private policyConfig: PolicyHashInput = {};\n private checkpointManager?: CheckpointManager;\n\n constructor(\n private readonly dependencies: RuntimeOrchestratorDependencies,\n private readonly options: RuntimeOrchestratorOptions = {}\n ) {\n this.createExecutionId = options.createExecutionId ?? (() => randomUUID());\n this.now = options.now ?? (() => new Date());\n this.wait = options.wait ?? defaultWait;\n this.starvationTimeoutMs = options.starvationTimeoutMs ?? STARVATION_TIMEOUT_MS_DEFAULT;\n this.gateWaitStateStore = dependencies.gateWaitStateStore ?? inMemoryGateStateStore();\n if (dependencies.storageAdapter) {\n this.checkpointManager = new CheckpointManager(dependencies.storageAdapter);\n }\n }\n\n /** Set the policy config used for checkpoint drift detection */\n setPolicyConfig(config: PolicyHashInput): void {\n this.policyConfig = config;\n }\n\n define(name: string, workflow: Workflow | string): void {\n const parsed = typeof workflow === \"string\" ? parseWorkflow(workflow) : workflow;\n this.validateBackEdgeIntegrity(parsed);\n this.workflows.set(name, structuredClone(parsed));\n }\n\n async run(name: string, input: unknown): Promise<Execution> {\n const workflow = this.workflows.get(name);\n if (!workflow) {\n throw new Error(`Workflow is not defined: ${name}`);\n }\n\n const plan = generateExecutionPlan(workflow);\n if (!plan.isValid) {\n throw new Error(`Invalid workflow DAG: ${(plan.cyclicPath ?? []).join(\" -> \")}`);\n }\n\n const execution = this.createExecution(name, workflow, input, plan.executionOrder);\n this.executions.set(execution.id, execution);\n await this.persistRun(execution);\n\n await this.recordAudit(execution.id, \"execution_start\", {\n workflowName: name,\n stepOrder: execution.stepOrder,\n input,\n });\n\n const completed = new Set<string>();\n const scheduled = new Set<string>();\n return this.executeLoop(execution, workflow, input, completed, scheduled);\n }\n\n async resume(runId: string, options: ResumeOptions = {}): Promise<ResumeResult> {\n const adapter = this.dependencies.storageAdapter;\n if (!adapter || !this.checkpointManager) {\n throw new Error(\"StorageAdapter is required for resume\");\n }\n\n // 1. Load run and checkpoint\n const runRecord = await adapter.getRun(runId);\n if (!runRecord) {\n throw new Error(`Run not found: ${runId}`);\n }\n\n const checkpoint = await this.checkpointManager.getLatestCheckpoint(runId);\n if (!checkpoint) {\n throw new Error(`No checkpoint found for run: ${runId}`);\n }\n\n // 2. Detect policy drift\n const drift = this.checkpointManager.detectDrift(checkpoint, this.policyConfig);\n const driftPolicy = options.driftPolicy ?? \"warn\";\n\n if (drift.drifted) {\n await this.recordAudit(runId, \"recovery_start\", {\n type: \"policy_drift_detected\",\n category: \"recovery\",\n action: \"policy_drift_detected\",\n runId,\n oldHash: drift.oldHash,\n newHash: drift.newHash,\n driftPolicy,\n timestamp: this.now().toISOString(),\n });\n\n if (driftPolicy === \"reject\") {\n throw new PolicyDriftError(drift.oldHash, drift.newHash);\n }\n }\n\n // 3. Load steps and determine restoration policy\n const steps = await adapter.getSteps(runId);\n const workflow = this.workflows.get(runRecord.workflowName);\n if (!workflow) {\n throw new Error(`Workflow is not defined: ${runRecord.workflowName}`);\n }\n\n const allStepNames = workflow.steps.map((s) => s.name);\n const stepPolicies = this.checkpointManager.resolveStepPolicies(\n steps,\n checkpoint.completedSteps,\n allStepNames,\n options,\n );\n\n // 4. Create new execution with restored state\n const execution = this.createExecution(\n runRecord.workflowName,\n workflow,\n runRecord.input,\n allStepNames,\n );\n // Override execution id with original runId so all persistence (runs, steps, checkpoints)\n // stays under the same run identity\n execution.id = runId;\n this.executions.set(execution.id, execution);\n\n // Update run record to link resumed execution\n await adapter.saveRun({\n ...runRecord,\n status: \"running\",\n completedAt: undefined,\n });\n\n await this.recordAudit(execution.id, \"snapshot_restore\", {\n originalRunId: runId,\n checkpointId: checkpoint.id,\n restoredSteps: stepPolicies.filter((p) => p.action === \"restore\").map((p) => p.stepName),\n rerunSteps: stepPolicies.filter((p) => p.action === \"rerun\").map((p) => p.stepName),\n });\n\n // 4b. Restore StateBinder state from checkpoint snapshot\n if (this.dependencies.stateBinder && checkpoint.stateSnapshot) {\n const snapshot = checkpoint.stateSnapshot as Record<string, unknown>;\n // Re-bind outputs from checkpoint as state\n // StateBinder operates through bind(), so we restore by writing snapshot entries\n // as completed step outputs to maintain state consistency\n for (const [key, value] of Object.entries(snapshot)) {\n // Skip non-serializable values (functions, symbols); restore all JSON-safe values including primitives\n if (typeof value === \"function\" || typeof value === \"symbol\") continue;\n await this.dependencies.stateBinder.bind(\n { success: true, output: value, toolCalls: [], metrics: { durationMs: 0, tokenUsage: { input: 0, output: 0 }, retries: 0 } },\n [{ source: \"output\", target: key }],\n );\n }\n }\n\n if (checkpoint.stateSnapshot && typeof checkpoint.stateSnapshot === \"object\") {\n const snapshot = checkpoint.stateSnapshot as Record<string, unknown>;\n for (const [key, value] of Object.entries(snapshot)) {\n if (key.startsWith(LOOP_KEY_PREFIX)) {\n execution.outputs[key] = value;\n }\n }\n }\n\n // 5. Restore completed steps and execute remaining\n const completed = new Set<string>();\n const scheduled = new Set<string>();\n const restoredSteps: string[] = [];\n const rerunSteps: string[] = [];\n\n for (const policy of stepPolicies) {\n if (policy.action === \"restore\") {\n completed.add(policy.stepName);\n execution.completedSteps = [...completed];\n execution.outputs[policy.stepName] = policy.output ?? {};\n const record = execution.stepRecords[policy.stepName];\n if (record) {\n record.status = \"completed\";\n record.startedAt = this.now();\n record.endedAt = this.now();\n }\n restoredSteps.push(policy.stepName);\n } else if (policy.action === \"skip\") {\n completed.add(policy.stepName);\n const record = execution.stepRecords[policy.stepName];\n if (record) {\n record.status = \"skipped\";\n }\n } else {\n rerunSteps.push(policy.stepName);\n }\n }\n\n // Sync completedSteps so skip-only resumes report accurate state\n execution.completedSteps = [...completed];\n\n await this.persistRun(execution);\n\n // Execute remaining steps — execution.id is already set to runId above,\n // so executeLoop's checkpoint saves naturally use the correct run identity.\n // No need to wrap checkpointManager (which would be unsafe under concurrent resumes).\n const result = await this.executeLoop(execution, workflow, runRecord.input, completed, scheduled);\n\n // Save final checkpoint under original runId\n if (this.checkpointManager) {\n const lastStep = allStepNames[allStepNames.length - 1];\n await this.checkpointManager.saveCheckpoint(\n runId,\n lastStep,\n [...completed],\n execution.outputs,\n this.policyConfig,\n );\n }\n\n return {\n execution: result,\n restoredSteps,\n rerunSteps,\n driftDetected: drift.drifted,\n };\n }\n\n async approve(executionId: string): Promise<Execution> {\n const execution = this.requireExecution(executionId);\n const waitingContext = this.waitingContexts.get(executionId);\n if (!waitingContext || !execution.waitingGate) {\n throw new Error(`Execution is not waiting on gate: ${executionId}`);\n }\n\n execution.waitingGate.status = \"approved\";\n await this.gateWaitStateStore.save(execution.waitingGate);\n await this.gateWaitStateStore.delete(executionId);\n await this.recordAudit(execution.id, \"gate_resolve\", {\n stepName: waitingContext.step.name,\n gateType: execution.waitingGate.gateType,\n status: \"approved\",\n });\n\n const record = execution.stepRecords[waitingContext.step.name]!;\n record.status = \"pending\";\n record.error = undefined;\n record.endedAt = undefined;\n\n execution.waitingGate = undefined;\n execution.status = \"running\";\n execution.error = undefined;\n waitingContext.scheduled.delete(waitingContext.step.name);\n this.approvedGateSteps.add(`${execution.id}:${waitingContext.step.name}`);\n this.waitingContexts.delete(executionId);\n\n return this.executeLoop(\n execution,\n waitingContext.workflow,\n waitingContext.input,\n waitingContext.completed,\n waitingContext.scheduled\n );\n }\n\n async reject(executionId: string, reason = \"Gate rejected\"): Promise<Execution> {\n const execution = this.requireExecution(executionId);\n if (!execution.waitingGate) {\n throw new Error(`Execution is not waiting on gate: ${executionId}`);\n }\n\n execution.waitingGate.status = \"rejected\";\n await this.gateWaitStateStore.save(execution.waitingGate);\n await this.gateWaitStateStore.delete(executionId);\n await this.recordAudit(execution.id, \"gate_resolve\", {\n stepName: execution.waitingGate.stepName,\n gateType: execution.waitingGate.gateType,\n status: \"rejected\",\n reason,\n });\n\n const record = execution.stepRecords[execution.waitingGate.stepName]!;\n record.status = \"failed\";\n record.error = reason;\n record.endedAt = this.now();\n\n execution.status = \"failed\";\n execution.error = reason;\n execution.endedAt = this.now();\n execution.waitingGate = undefined;\n this.waitingContexts.delete(executionId);\n await this.recordExecutionEnd(execution);\n\n return this.cloneExecution(execution);\n }\n\n async onGateTimeout(executionId: string): Promise<Execution> {\n const execution = this.requireExecution(executionId);\n const gate = execution.waitingGate;\n if (!gate) {\n throw new Error(`Execution is not waiting on gate: ${executionId}`);\n }\n\n const waitingContext = this.waitingContexts.get(executionId);\n\n if (gate.fallback === \"auto-approve\") {\n if (!waitingContext) {\n throw new Error(`Execution waiting context is missing: ${executionId}`);\n }\n\n gate.status = \"approved\";\n await this.gateWaitStateStore.save(gate);\n await this.gateWaitStateStore.delete(executionId);\n await this.recordAudit(execution.id, \"gate_resolve\", {\n stepName: gate.stepName,\n gateType: gate.gateType,\n status: \"approved\",\n fallback: \"auto-approve\",\n });\n\n const record = execution.stepRecords[gate.stepName]!;\n record.status = \"pending\";\n record.error = undefined;\n record.endedAt = undefined;\n\n execution.waitingGate = undefined;\n execution.status = \"running\";\n execution.error = undefined;\n waitingContext.scheduled.delete(gate.stepName);\n this.approvedGateSteps.add(`${execution.id}:${gate.stepName}`);\n this.waitingContexts.delete(executionId);\n\n return this.executeLoop(\n execution,\n waitingContext.workflow,\n waitingContext.input,\n waitingContext.completed,\n waitingContext.scheduled\n );\n }\n\n gate.status = \"timeout\";\n await this.gateWaitStateStore.save(gate);\n await this.gateWaitStateStore.delete(executionId);\n await this.recordAudit(execution.id, \"gate_resolve\", {\n stepName: gate.stepName,\n gateType: gate.gateType,\n status: \"timeout\",\n });\n\n const record = execution.stepRecords[gate.stepName]!;\n record.status = \"failed\";\n record.error = `Gate timeout: ${gate.gateType}`;\n record.endedAt = this.now();\n\n if (gate.fallback === \"escalate\" && this.dependencies.recoveryEngine) {\n const recovery = await this.dependencies.recoveryEngine.handle(\n {\n executionId: execution.id,\n cellId: `gate:${gate.stepName}`,\n stepName: gate.stepName,\n attempt: 1,\n error: new Error(record.error),\n },\n { type: \"escalate\", severity: \"high\", channel: \"human-approval\", summary: record.error }\n );\n record.recovery = recovery;\n }\n\n execution.status = \"failed\";\n execution.error = record.error;\n execution.endedAt = this.now();\n execution.waitingGate = undefined;\n this.waitingContexts.delete(executionId);\n await this.recordExecutionEnd(execution);\n return this.cloneExecution(execution);\n }\n\n getExecution(id: string): Execution {\n const execution = this.executions.get(id);\n if (!execution) {\n throw new Error(`Execution not found: ${id}`);\n }\n return this.cloneExecution(execution);\n }\n\n listExecutions(filter?: ExecutionFilter): Execution[] {\n const items = [...this.executions.values()].filter((execution) => {\n if (filter?.status && execution.status !== filter.status) {\n return false;\n }\n if (filter?.workflowName && execution.workflowName !== filter.workflowName) {\n return false;\n }\n return true;\n });\n\n return items.map((execution) => this.cloneExecution(execution));\n }\n\n private requireExecution(executionId: string): Execution {\n const execution = this.executions.get(executionId);\n if (!execution) {\n throw new Error(`Execution not found: ${executionId}`);\n }\n return execution;\n }\n\n private async executeLoop(\n execution: Execution,\n workflow: Workflow,\n input: unknown,\n completed: Set<string>,\n scheduled: Set<string>\n ): Promise<Execution> {\n while (true) {\n const starvationTimedOut = new Set(\n Object.entries(execution.stepRecords)\n .filter(([, rec]) => rec.status === \"failed\" && rec.error === \"starvation_timeout\")\n .map(([name]) => name),\n );\n const schedulableCompleted = new Set<string>([...completed, ...starvationTimedOut]);\n if (schedulableCompleted.size >= workflow.steps.length) {\n break;\n }\n\n const candidates = getNextSteps(workflow, schedulableCompleted)\n .filter((step) => !scheduled.has(step.name))\n .sort((a, b) => execution.stepOrder.indexOf(a.name) - execution.stepOrder.indexOf(b.name));\n\n if (candidates.length === 0) {\n execution.status = \"failed\";\n execution.error = \"No executable step found while execution is incomplete\";\n execution.endedAt = this.now();\n await this.recordAudit(execution.id, \"error\", { message: execution.error });\n await this.recordExecutionEnd(execution);\n return this.cloneExecution(execution);\n }\n\n const maxParallel = workflow.config?.max_parallel && workflow.config.max_parallel > 0\n ? workflow.config.max_parallel\n : 1;\n const runnable = candidates.slice(0, maxParallel);\n runnable.forEach((step) => scheduled.add(step.name));\n\n const batchResults = await Promise.all(runnable.map((step) => this.runStep(execution, workflow, step, input, completed)));\n\n for (const result of batchResults) {\n if (result.status === \"completed\") {\n completed.add(result.step.name);\n execution.completedSteps = [...completed];\n\n // Save checkpoint after each step completion\n if (this.checkpointManager) {\n await this.checkpointManager.saveCheckpoint(\n execution.id,\n result.step.name,\n [...completed],\n execution.outputs,\n this.policyConfig,\n );\n }\n\n continue;\n }\n\n if (result.status === \"back_edge\") {\n this.pruneForBackEdge(execution, workflow, completed, scheduled, result.targetStep);\n execution.completedSteps = [...completed];\n if (this.checkpointManager) {\n await this.checkpointManager.saveCheckpoint(\n execution.id,\n result.step.name,\n [...completed],\n execution.outputs,\n this.policyConfig,\n );\n }\n continue;\n }\n\n if (result.status === \"waiting\") {\n execution.status = \"waiting\";\n execution.error = `Execution is waiting at step: ${result.step.name}`;\n this.waitingContexts.set(execution.id, {\n workflow,\n step: result.step,\n completed,\n scheduled,\n input,\n });\n return this.cloneExecution(execution);\n }\n\n // Save checkpoint on failure so resume can pick up from here\n if (this.checkpointManager) {\n await this.checkpointManager.saveCheckpoint(\n execution.id,\n result.step.name,\n [...completed],\n execution.outputs,\n this.policyConfig,\n );\n }\n\n execution.status = \"failed\";\n execution.error = result.error ?? `Step failed: ${result.step.name}`;\n execution.endedAt = this.now();\n await this.recordExecutionEnd(execution);\n return this.cloneExecution(execution);\n }\n }\n\n execution.status = \"completed\";\n execution.endedAt = this.now();\n await this.recordExecutionEnd(execution);\n return this.cloneExecution(execution);\n }\n\n private createExecution(name: string, workflow: Workflow, input: unknown, stepOrder: string[]): Execution {\n const startedAt = this.now();\n return {\n id: this.createExecutionId(),\n workflowName: name,\n status: \"running\",\n input,\n startedAt,\n stepOrder,\n completedSteps: [],\n stepRecords: Object.fromEntries(\n workflow.steps.map((step) => [\n step.name,\n {\n stepName: step.name,\n status: \"pending\" as ExecutionStepStatus,\n },\n ])\n ),\n outputs: {},\n };\n }\n\n private async runStep(\n execution: Execution,\n workflow: Workflow,\n step: Step,\n workflowInput: unknown,\n completed: Set<string>,\n ): Promise<{\n step: Step;\n status: \"completed\" | \"failed\" | \"waiting\" | \"back_edge\";\n targetStep?: string;\n error?: string;\n }> {\n const record = execution.stepRecords[step.name]!;\n record.status = \"running\";\n record.startedAt = this.now();\n await this.persistStep(execution, step.name);\n\n await this.recordAudit(execution.id, \"step_start\", {\n stepName: step.name,\n agent: step.agent,\n });\n\n const decision = this.dependencies.policyEngine.enforce(\n { type: \"step_start\", name: step.name, params: { agent: step.agent } },\n { stepName: step.name }\n );\n\n record.policyDecision = decision;\n await this.recordAudit(execution.id, \"policy_check\", {\n stepName: step.name,\n decision,\n });\n\n if (decision.type === \"deny\") {\n record.status = \"failed\";\n record.error = decision.reason;\n record.endedAt = this.now();\n await this.persistStep(execution, step.name);\n await this.recordAudit(execution.id, \"policy_deny\", {\n stepName: step.name,\n reason: decision.reason,\n });\n await this.recordAudit(execution.id, \"step_end\", {\n stepName: step.name,\n status: record.status,\n error: record.error,\n });\n return { step, status: \"failed\", error: decision.reason };\n }\n\n const gateDecision = this.mergeGateDecision(\n decision.type === \"gate\" ? decision : undefined,\n this.extractGateConfig(step)\n );\n\n if (gateDecision) {\n const approvedKey = `${execution.id}:${step.name}`;\n if (this.approvedGateSteps.has(approvedKey)) {\n this.approvedGateSteps.delete(approvedKey);\n } else {\n const gateWait = this.createGateWaitState(execution.id, step, gateDecision);\n await this.recordAudit(execution.id, \"gate_wait\", {\n stepName: step.name,\n gateType: gateDecision.gateType,\n timeout: gateWait.timeout,\n });\n if (this.options.onGate) {\n const gateResult = await this.options.onGate(execution, step, gateDecision);\n if (gateResult === \"rejected\") {\n record.status = \"failed\";\n record.error = `Gate rejected: ${gateDecision.gateType}`;\n record.endedAt = this.now();\n await this.persistStep(execution, step.name);\n await this.recordAudit(execution.id, \"gate_resolve\", {\n stepName: step.name,\n gateType: gateDecision.gateType,\n status: \"rejected\",\n });\n await this.recordAudit(execution.id, \"step_end\", {\n stepName: step.name,\n status: record.status,\n error: record.error,\n });\n return { step, status: \"failed\", error: record.error };\n }\n await this.recordAudit(execution.id, \"gate_resolve\", {\n stepName: step.name,\n gateType: gateDecision.gateType,\n status: \"approved\",\n });\n } else {\n record.status = \"waiting\";\n record.error = `Gate required: ${gateDecision.gateType}`;\n record.endedAt = this.now();\n execution.waitingGate = gateWait;\n await this.persistStep(execution, step.name);\n await this.gateWaitStateStore.save(gateWait);\n return { step, status: \"waiting\", error: record.error };\n }\n }\n }\n\n const cellId = this.dependencies.cellManager.createCell({\n config: this.buildCellConfig(step),\n runTask: async (task) => this.buildStepOutput(step, task, workflowInput, execution.outputs),\n });\n\n await this.recordAudit(execution.id, \"cell_start\", {\n stepName: step.name,\n cellId,\n }, { cellId });\n\n try {\n const result = await this.dependencies.cellManager.execute(cellId, this.stepToTask(step, workflowInput));\n record.result = result;\n record.endedAt = this.now();\n this.trackLoopCost(execution, workflow, step.name, result.metrics.costUsd, completed);\n\n await this.recordAudit(execution.id, \"cell_end\", {\n stepName: step.name,\n success: result.success,\n metrics: result.metrics,\n }, { cellId });\n\n for (const toolCall of result.toolCalls) {\n await this.recordAudit(execution.id, \"tool_call\", {\n stepName: step.name,\n toolName: toolCall.toolName,\n params: toolCall.params,\n }, { cellId, durationMs: toolCall.durationMs });\n await this.recordAudit(execution.id, \"tool_result\", {\n stepName: step.name,\n toolName: toolCall.toolName,\n status: toolCall.status,\n result: toolCall.result,\n error: toolCall.error,\n }, { cellId, durationMs: toolCall.durationMs });\n }\n\n if (!result.success) {\n const failure = await this.handleStepFailure(execution, workflow, step, cellId, result.output, result.metrics.costUsd, completed);\n await this.recordAudit(execution.id, \"step_end\", {\n stepName: step.name,\n status: failure.status === \"back_edge\" ? \"back_edge\" : \"failed\",\n error: failure.error,\n }, { cellId });\n return failure;\n }\n\n await this.bindStepState(execution, step, result);\n\n const consensusResult = await this.evaluateConsensusIfNeeded(step, execution);\n if (consensusResult) {\n record.consensus = consensusResult;\n await this.recordAudit(execution.id, \"consensus_result\", {\n stepName: step.name,\n result: consensusResult,\n });\n if (consensusResult.status !== \"pass\") {\n const reason = consensusResult.status === \"fail\" ? consensusResult.reason : `consensus ${consensusResult.status}`;\n const failure = await this.handleStepFailure(execution, workflow, step, cellId, { error: reason }, result.metrics.costUsd, completed);\n await this.recordAudit(execution.id, \"step_end\", {\n stepName: step.name,\n status: \"failed\",\n error: failure.error,\n }, { cellId });\n return failure;\n }\n }\n\n record.status = \"completed\";\n record.endedAt = this.now();\n execution.outputs[step.name] = result.output;\n try {\n await this.captureArtifacts(execution.id, step.name, result.output, result.toolCalls);\n } catch (artifactError) {\n await this.recordAudit(execution.id, \"warning\", {\n stepName: step.name,\n message: \"Artifact capture failed\",\n error: artifactError instanceof Error ? artifactError.message : String(artifactError),\n }, { cellId });\n }\n await this.persistStep(execution, step.name);\n await this.recordAudit(execution.id, \"step_end\", {\n stepName: step.name,\n status: \"completed\",\n }, { cellId });\n return { step, status: \"completed\" };\n } finally {\n await this.dependencies.cellManager.stopCell(cellId, \"Step execution finished\");\n }\n }\n\n private async evaluateConsensusIfNeeded(step: Step, execution: Execution) {\n const consensusGate = this.dependencies.consensusGate;\n const consensusConfig = this.extractConsensusConfig(step);\n if (!consensusGate || !consensusConfig) {\n return undefined;\n }\n\n const session = consensusGate.setup(consensusConfig);\n const votes = await this.options.consensusVoteProvider?.(step, this.cloneExecution(execution), consensusConfig) ?? [];\n for (const vote of votes) {\n consensusGate.registerVote(session.id, vote);\n await this.recordAudit(execution.id, \"consensus_vote\", {\n stepName: step.name,\n sessionId: session.id,\n vote,\n });\n }\n return consensusGate.evaluate(session.id);\n }\n\n private async handleStepFailure(\n execution: Execution,\n workflow: Workflow,\n step: Step,\n cellId: string,\n output: unknown,\n cellCostUsd: number | undefined,\n completed: Set<string>,\n ): Promise<{ step: Step; status: \"failed\" | \"completed\" | \"back_edge\"; targetStep?: string; error?: string }> {\n const record = execution.stepRecords[step.name]!;\n const error = this.extractError(output);\n\n const backEdgeResult = await this.tryHandleBackEdge(execution, workflow, step, error, cellId, cellCostUsd, completed);\n if (backEdgeResult) {\n return backEdgeResult;\n }\n\n const strategy = this.extractRecoveryStrategy(step, execution) ?? this.options.defaultRecoveryStrategy;\n if (strategy && this.dependencies.recoveryEngine) {\n await this.recordAudit(execution.id, \"recovery_start\", {\n stepName: step.name,\n strategy,\n error,\n }, { cellId });\n const recovery = await this.dependencies.recoveryEngine.handle(\n {\n executionId: execution.id,\n cellId,\n stepName: step.name,\n attempt: 1,\n error: new Error(error),\n },\n strategy\n );\n await this.recordAudit(execution.id, \"recovery_end\", {\n stepName: step.name,\n strategy,\n recovery,\n }, { cellId });\n record.recovery = recovery;\n if (recovery.status === \"recovered\") {\n record.status = \"completed\";\n record.endedAt = this.now();\n execution.outputs[step.name] = { recovered: true, strategy: strategy.type };\n await this.persistStep(execution, step.name);\n return { step, status: \"completed\" };\n }\n }\n\n record.status = \"failed\";\n record.error = error;\n record.endedAt ??= this.now();\n await this.persistStep(execution, step.name);\n return { step, status: \"failed\", error };\n }\n\n private async tryHandleBackEdge(\n execution: Execution,\n workflow: Workflow,\n step: Step,\n error: string,\n cellId: string,\n _unusedCellCost: number | undefined,\n completed: Set<string>,\n ): Promise<BackEdgeTriggerResult | undefined> {\n const onFail = step.on_fail;\n if (!onFail?.goto) {\n return undefined;\n }\n\n const state = this.getBackEdgeState(execution, step.name, onFail.goto);\n const maxCostEscalation = onFail.max_cost_escalation ?? onFail.escalate_on_exhaust;\n const exhausted = state.iterationCount >= onFail.max_iterations;\n const costExceeded = onFail.max_cost !== null && state.costUsd > onFail.max_cost;\n\n if (costExceeded || exhausted) {\n const escalation = costExceeded ? maxCostEscalation : onFail.escalate_on_exhaust;\n const escalationStrategy = this.toBackEdgeEscalationStrategy(escalation, step.name, onFail.goto, error);\n const recovery = await this.runRecovery(execution, step, cellId, error, escalationStrategy);\n execution.stepRecords[step.name]!.recovery = recovery;\n execution.stepRecords[step.name]!.status = \"failed\";\n execution.stepRecords[step.name]!.error = error;\n execution.stepRecords[step.name]!.endedAt = this.now();\n await this.persistStep(execution, step.name);\n\n if (costExceeded) {\n await this.recordAudit(execution.id, \"workflow.back_edge_cost_exceeded\", {\n source_step: step.name,\n target_step: onFail.goto,\n iteration: state.iterationCount,\n max_cost_usd: onFail.max_cost,\n actual_cost_usd: state.costUsd,\n escalation_action: escalation,\n timestamp: this.now().toISOString(),\n }, { cellId });\n } else {\n await this.recordAudit(execution.id, \"workflow.back_edge_exhausted\", {\n source_step: step.name,\n target_step: onFail.goto,\n total_iterations: state.iterationCount,\n escalation_action: escalation,\n total_cost_usd: state.costUsd,\n timestamp: this.now().toISOString(),\n }, { cellId });\n }\n\n return { step, status: \"failed\", error };\n }\n\n const nextState: BackEdgeState = {\n ...state,\n iterationCount: state.iterationCount + 1,\n };\n this.setBackEdgeState(execution, nextState);\n\n if (onFail.reset_state) {\n // reset_state clears only the target step output key in the execution output map.\n delete execution.outputs[onFail.goto];\n }\n\n await this.recordAudit(execution.id, \"workflow.back_edge_triggered\", {\n source_step: step.name,\n target_step: onFail.goto,\n iteration: nextState.iterationCount,\n reason: \"FAIL\",\n cost_so_far_usd: nextState.costUsd,\n timestamp: this.now().toISOString(),\n }, { cellId });\n\n await this.handleStarvation(execution, workflow, step.name, onFail.goto, completed);\n await this.wait(onFail.cooldown_ms);\n\n const record = execution.stepRecords[step.name]!;\n record.status = \"failed\";\n record.error = error;\n record.endedAt = this.now();\n await this.persistStep(execution, step.name);\n return { step, status: \"back_edge\", targetStep: onFail.goto };\n }\n\n private loopStateKey(stepId: string, field: \"iteration_count\" | \"cost_usd\" | \"target\"): string {\n return `${LOOP_KEY_PREFIX}${stepId}.${field}`;\n }\n\n private validateBackEdgeIntegrity(workflow: Workflow): void {\n const steps = workflow.steps ?? [];\n const stepNames = new Set(steps.map((s) => s.name));\n const deps = new Map<string, string[]>();\n for (const step of steps) {\n deps.set(step.name, step.depends_on ?? []);\n }\n\n const canReachDependency = (source: string, target: string): boolean => {\n const visited = new Set<string>();\n const stack = [...(deps.get(source) ?? [])];\n while (stack.length > 0) {\n const current = stack.pop()!;\n if (current === target) return true;\n if (visited.has(current)) continue;\n visited.add(current);\n for (const parent of deps.get(current) ?? []) stack.push(parent);\n }\n return false;\n };\n\n for (const step of steps) {\n const goto = step.on_fail?.goto;\n if (!goto) continue;\n if (!stepNames.has(goto)) {\n throw new Error(`Step '${step.name}' on_fail.goto references non-existent step '${goto}'`);\n }\n if (goto === step.name) {\n throw new Error(`Step '${step.name}': self-loop is not allowed for on_fail.goto`);\n }\n if (!canReachDependency(step.name, goto)) {\n throw new Error(`Step '${step.name}': back-edge target '${goto}' must precede source '${step.name}' in dependency graph`);\n }\n }\n }\n\n private getBackEdgeState(execution: Execution, source: string, target: string): BackEdgeState {\n const iterationRaw = execution.outputs[this.loopStateKey(source, \"iteration_count\")];\n const costRaw = execution.outputs[this.loopStateKey(source, \"cost_usd\")];\n const targetRaw = execution.outputs[this.loopStateKey(source, \"target\")];\n\n const iterationCount = typeof iterationRaw === \"number\" && Number.isFinite(iterationRaw) ? iterationRaw : 1;\n const costUsd = typeof costRaw === \"number\" && Number.isFinite(costRaw) ? costRaw : 0;\n const currentTarget = typeof targetRaw === \"string\" ? targetRaw : target;\n\n return { source, target: currentTarget, iterationCount, costUsd };\n }\n\n private setBackEdgeState(execution: Execution, state: BackEdgeState): void {\n execution.outputs[this.loopStateKey(state.source, \"iteration_count\")] = state.iterationCount;\n execution.outputs[this.loopStateKey(state.source, \"cost_usd\")] = state.costUsd;\n execution.outputs[this.loopStateKey(state.source, \"target\")] = state.target;\n }\n\n private getCachedGraph(execution: Execution, workflow: Workflow) {\n const metadata = (execution.metadata ??= {});\n const cached = metadata.__oboraWorkflowGraph as { key?: string; graph?: ReturnType<typeof buildGraph> } | undefined;\n const graphKey = workflow.steps.map((step) => {\n const deps = step.depends_on?.join(\",\") ?? \"\";\n const backEdge = step.on_fail?.goto ?? \"\";\n return `${step.name}:${deps}:${backEdge}`;\n }).join(\"|\");\n\n if (cached?.graph && cached.key === graphKey) {\n return cached.graph;\n }\n\n const graph = buildGraph(workflow.steps);\n metadata.__oboraWorkflowGraph = { key: graphKey, graph };\n return graph;\n }\n\n private trackLoopCost(execution: Execution, workflow: Workflow, stepName: string, costUsd: number | undefined): void {\n if (typeof costUsd !== \"number\" || !Number.isFinite(costUsd) || costUsd <= 0) {\n return;\n }\n\n const graph = this.getCachedGraph(execution, workflow);\n for (const sourceStep of workflow.steps) {\n const target = sourceStep.on_fail?.goto;\n if (!target) {\n continue;\n }\n if (!this.isStepInBackEdgeChain(graph.edges, target, sourceStep.name, stepName)) {\n continue;\n }\n\n const state = this.getBackEdgeState(execution, sourceStep.name, target);\n state.costUsd += costUsd;\n this.setBackEdgeState(execution, state);\n }\n }\n\n private isStepInBackEdgeChain(\n edges: Map<string, Set<string>>,\n chainTarget: string,\n chainSource: string,\n stepName: string,\n ): boolean {\n const reachable = (from: string, to: string): boolean => {\n if (from === to) {\n return true;\n }\n const visited = new Set<string>();\n const queue = [from];\n while (queue.length > 0) {\n const node = queue.shift()!;\n const deps = edges.get(node) ?? new Set<string>();\n for (const dep of deps) {\n if (dep === to) {\n return true;\n }\n if (!visited.has(dep)) {\n visited.add(dep);\n queue.push(dep);\n }\n }\n }\n return false;\n };\n\n return reachable(chainTarget, stepName) && reachable(stepName, chainSource);\n }\n\n private pruneForBackEdge(\n execution: Execution,\n workflow: Workflow,\n completed: Set<string>,\n scheduled: Set<string>,\n targetStep: string,\n ): void {\n const graph = this.getCachedGraph(execution, workflow);\n const queue = [targetStep];\n const visited = new Set<string>();\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n completed.delete(current);\n scheduled.delete(current);\n\n const dependents = graph.edges.get(current) ?? new Set<string>();\n for (const dependent of dependents) {\n queue.push(dependent);\n }\n }\n }\n\n private async runRecovery(\n execution: Execution,\n step: Step,\n cellId: string,\n error: string,\n strategy: RecoveryStrategy | undefined,\n ) {\n if (!strategy || !this.dependencies.recoveryEngine) {\n return undefined;\n }\n\n await this.recordAudit(execution.id, \"recovery_start\", {\n stepName: step.name,\n strategy,\n error,\n }, { cellId });\n const recovery = await this.dependencies.recoveryEngine.handle(\n {\n executionId: execution.id,\n cellId,\n stepName: step.name,\n attempt: 1,\n error: new Error(error),\n },\n strategy,\n );\n await this.recordAudit(execution.id, \"recovery_end\", {\n stepName: step.name,\n strategy,\n recovery,\n }, { cellId });\n return recovery;\n }\n\n private toBackEdgeEscalationStrategy(\n escalation: \"human\" | \"dlq\" | \"fail\",\n source: string,\n target: string,\n error: string,\n ): RecoveryStrategy | undefined {\n if (escalation === \"fail\") {\n return undefined;\n }\n const channel = escalation === \"human\" ? \"human\" : \"dlq\";\n return {\n type: \"escalate\",\n severity: \"high\",\n channel,\n summary: `back-edge exhausted for ${source} -> ${target}: ${error}`,\n };\n }\n\n private async handleStarvation(\n execution: Execution,\n workflow: Workflow,\n sourceStep: string,\n targetStep: string,\n completed: Set<string>,\n ): Promise<void> {\n const maxParallel = workflow.config?.max_parallel && workflow.config.max_parallel > 0\n ? workflow.config.max_parallel\n : 1;\n const ready = getNextSteps(workflow, new Set(execution.completedSteps)).filter((step) => step.name !== targetStep);\n if (ready.length === 0 || maxParallel <= 1) {\n return;\n }\n\n const starvationRoot = (execution.metadata ??= {});\n const starvationMap = ((starvationRoot.__oboraStarvation as Record<string, string> | undefined) ??= {});\n const nowIso = this.now().toISOString();\n\n for (const blocked of ready) {\n const startedAt = starvationMap[blocked.name] ?? nowIso;\n starvationMap[blocked.name] = startedAt;\n const waitDurationMs = this.now().getTime() - new Date(startedAt).getTime();\n const timedOut = waitDurationMs > this.starvationTimeoutMs;\n\n await this.recordAudit(execution.id, \"workflow.step_starvation_warning\", {\n blocked_step: blocked.name,\n blocking_loop: { source: sourceStep, target: targetStep },\n wait_duration_ms: waitDurationMs,\n action: timedOut ? \"timeout\" : \"continue\",\n timestamp: this.now().toISOString(),\n });\n\n if (!timedOut) {\n continue;\n }\n\n const blockedRecord = execution.stepRecords[blocked.name];\n if (blockedRecord) {\n blockedRecord.status = \"failed\";\n blockedRecord.error = \"starvation_timeout\";\n blockedRecord.endedAt = this.now();\n }\n const recoveryStrategy = this.extractRecoveryStrategy(blocked, execution) ?? this.options.defaultRecoveryStrategy;\n const recovery = await this.runRecovery(\n execution,\n blocked,\n `starvation:${blocked.name}`,\n \"starvation_timeout\",\n recoveryStrategy,\n );\n if (blockedRecord) {\n blockedRecord.recovery = recovery;\n }\n await this.persistStep(execution, blocked.name);\n }\n }\n\n private extractGateConfig(step: Step): StepGateDecision | undefined {\n const rawStep = step as Step & { gate?: unknown; gate_config?: unknown; config?: Record<string, unknown> };\n const gate = rawStep.gate;\n const gateConfig = rawStep.gate_config ?? (rawStep.config as Record<string, unknown> | undefined)?.gate_config;\n\n const validGateTypes: GateWaitState[\"gateType\"][] = [\"human-approval\", \"consensus\", \"external\"];\n\n const parseConfig = (value: unknown): StepGateDecision[\"config\"] => {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const config = value as Record<string, unknown>;\n return {\n timeout: typeof config.timeout === \"string\" ? config.timeout : undefined,\n fallback:\n config.fallback === \"fail\" ||\n config.fallback === \"escalate\" ||\n config.fallback === \"auto-approve\"\n ? config.fallback\n : undefined,\n };\n };\n\n if (gate === undefined || gate === false) {\n return undefined;\n }\n\n if (gate === true) {\n const parsedConfig = parseConfig(gateConfig);\n const gateType = parsedConfig && gateConfig && typeof gateConfig === \"object\"\n && validGateTypes.includes((gateConfig as Record<string, unknown>).type as GateWaitState[\"gateType\"])\n ? (gateConfig as Record<string, unknown>).type as GateWaitState[\"gateType\"]\n : \"human-approval\";\n return { gateType, config: parsedConfig };\n }\n\n if (typeof gate === \"string\" && validGateTypes.includes(gate as GateWaitState[\"gateType\"])) {\n return { gateType: gate as GateWaitState[\"gateType\"], config: parseConfig(gateConfig) };\n }\n\n if (typeof gate === \"object\" && gate !== null) {\n const gateObj = gate as Record<string, unknown>;\n const gateType = typeof gateObj.type === \"string\" && validGateTypes.includes(gateObj.type as GateWaitState[\"gateType\"])\n ? gateObj.type as GateWaitState[\"gateType\"]\n : \"human-approval\";\n const mergedConfig = { ...parseConfig(gateObj), ...parseConfig(gateConfig) };\n return { gateType, config: mergedConfig };\n }\n\n return undefined;\n }\n\n private mergeGateDecision(\n policyDecision?: Extract<PolicyDecision, { type: \"gate\" }>,\n stepGate?: StepGateDecision\n ): RuntimeGateDecision | undefined {\n if (!policyDecision && !stepGate) {\n return undefined;\n }\n\n const policyConfig = policyDecision?.config && typeof policyDecision.config === \"object\"\n ? policyDecision.config as { timeout?: unknown; fallback?: unknown }\n : undefined;\n\n const mergedConfig = {\n timeout: typeof policyConfig?.timeout === \"string\" ? policyConfig.timeout : undefined,\n fallback:\n policyConfig?.fallback === \"fail\" ||\n policyConfig?.fallback === \"escalate\" ||\n policyConfig?.fallback === \"auto-approve\"\n ? policyConfig.fallback\n : undefined,\n ...stepGate?.config,\n };\n\n return {\n type: \"gate\",\n gateType: stepGate?.gateType ?? (policyDecision?.gateType as GateWaitState[\"gateType\"] ?? \"human-approval\"),\n config: mergedConfig,\n };\n }\n\n /**\n * Consensus schema compatibility:\n * - Canonical (SCHEMAS.md): `step.consensus.rule`, `step.consensus.best_effort`\n * - Legacy compatibility: `step.consensus.type`, `step.consensus.bestEffort`\n * - Transitional fallback: `step.config.consensus` (older workflow fixtures)\n */\n private extractConsensusConfig(step: Step) {\n const directConsensus = (step as Step & { consensus?: Record<string, unknown> }).consensus;\n const fallbackConsensus = (step.config as Record<string, unknown> | undefined)?.consensus as\n | Record<string, unknown>\n | undefined;\n const raw = directConsensus ?? fallbackConsensus;\n\n if (!raw) {\n return undefined;\n }\n\n // SCHEMAS.md uses `consensus.min`; runtime consensus gate consumes `minRequired` internally.\n // Keep backward compatibility with legacy `minRequired` while prioritizing `min`.\n const minRequired = typeof raw.min === \"number\"\n ? raw.min\n : typeof raw.minRequired === \"number\"\n ? raw.minRequired\n : 1;\n\n const bestEffort = Array.isArray(raw.best_effort)\n ? raw.best_effort\n : Array.isArray(raw.bestEffort)\n ? raw.bestEffort\n : undefined;\n\n return {\n type:\n (raw.rule as \"majority\" | \"unanimous\" | \"weighted\" | \"score-threshold\" | \"custom\") ??\n (raw.type as \"majority\" | \"unanimous\" | \"weighted\" | \"score-threshold\" | \"custom\") ??\n \"majority\",\n voters: Array.isArray(raw.voters) ? raw.voters as Array<{ id: string; weight?: number }> : [],\n minRequired,\n threshold: typeof raw.threshold === \"number\" ? raw.threshold : undefined,\n timeout: typeof raw.timeout === \"string\" ? raw.timeout : undefined,\n bestEffort: Array.isArray(bestEffort) ? bestEffort.filter((value): value is string => typeof value === \"string\") : undefined,\n };\n }\n\n private extractRecoveryStrategy(step: Step, execution: Execution) {\n const workflow = this.workflows.get(execution.workflowName);\n const workflowRecovery = workflow?.recovery?.[step.name] as Record<string, unknown> | undefined;\n const legacyRecovery = (step.config as Record<string, unknown> | undefined)?.recovery as Record<string, unknown> | undefined;\n\n const modern = this.toRecoveryStrategyFromWorkflow(workflowRecovery);\n if (modern) {\n return modern;\n }\n\n return this.toRecoveryStrategyFromLegacy(legacyRecovery);\n }\n\n private toRecoveryStrategyFromWorkflow(raw?: Record<string, unknown>) {\n if (!raw || typeof raw.on_fail !== \"string\") {\n return undefined;\n }\n\n if (raw.on_fail === \"retry\") {\n return {\n type: \"retry\" as const,\n mode: (raw.backoff as \"linear\" | \"exponential\") ?? \"linear\",\n maxAttempts: typeof raw.max_retries === \"number\" ? raw.max_retries : 1,\n initialDelayMs: typeof raw.backoff_base === \"string\" ? parseDuration(raw.backoff_base) : 0,\n maxDelayMs: 0,\n };\n }\n\n if (raw.on_fail === \"rollback\") {\n return { type: \"rollback\" as const, snapshotId: String(raw.snapshot_id ?? raw.snapshotId ?? \"\") };\n }\n\n if (raw.on_fail === \"escalate\") {\n return {\n type: \"escalate\" as const,\n severity: \"high\" as const,\n channel: String(raw.to ?? \"human\"),\n summary: typeof raw.summary === \"string\" ? raw.summary : undefined,\n };\n }\n\n if (raw.on_fail === \"alternative\") {\n const fallback = raw.fallback as { name?: unknown } | undefined;\n return {\n type: \"alternative\" as const,\n stepName: typeof fallback?.name === \"string\" ? fallback.name : String(raw.to ?? \"\"),\n payload: fallback,\n };\n }\n\n if (raw.on_fail === \"custom\" && typeof raw.custom === \"string\") {\n return { type: \"custom\" as const, handlerPath: raw.custom };\n }\n\n return undefined;\n }\n\n private toRecoveryStrategyFromLegacy(raw?: Record<string, unknown>) {\n if (!raw || typeof raw.type !== \"string\") {\n return undefined;\n }\n\n if (raw.type === \"retry\") {\n return {\n type: \"retry\" as const,\n mode: (raw.mode as \"linear\" | \"exponential\") ?? \"linear\",\n maxAttempts: typeof raw.maxAttempts === \"number\" ? raw.maxAttempts : 1,\n initialDelayMs: typeof raw.initialDelayMs === \"number\" ? raw.initialDelayMs : 0,\n maxDelayMs: typeof raw.maxDelayMs === \"number\" ? raw.maxDelayMs : 0,\n multiplier: typeof raw.multiplier === \"number\" ? raw.multiplier : undefined,\n };\n }\n\n if (raw.type === \"rollback\") {\n return { type: \"rollback\" as const, snapshotId: String(raw.snapshotId ?? \"\") };\n }\n\n if (raw.type === \"escalate\") {\n return {\n type: \"escalate\" as const,\n severity: (raw.severity as \"low\" | \"medium\" | \"high\" | \"critical\") ?? \"high\",\n channel: String(raw.channel ?? \"human\"),\n summary: typeof raw.summary === \"string\" ? raw.summary : undefined,\n };\n }\n\n if (raw.type === \"alternative\") {\n return {\n type: \"alternative\" as const,\n stepName: String(raw.stepName ?? \"\"),\n payload: raw.payload,\n };\n }\n\n return undefined;\n }\n\n private createGateWaitState(\n executionId: string,\n step: Step,\n decision: RuntimeGateDecision\n ): GateWaitState {\n const config = (decision.config ?? {}) as {\n timeout?: string;\n fallback?: \"fail\" | \"escalate\" | \"auto-approve\";\n };\n return {\n executionId,\n stepName: step.name,\n gateType: decision.gateType as GateWaitState[\"gateType\"],\n status: \"waiting\",\n createdAt: this.now(),\n timeout: config.timeout,\n fallback: config.fallback,\n persisted: true,\n };\n }\n\n private stepToTask(step: Step, input: unknown): Task {\n return {\n id: `${step.name}:${this.now().getTime()}`,\n type: `workflow-step:${step.name}`,\n description: step.description ?? `Execute workflow step ${step.name}`,\n input: {\n workflowInput: input,\n step,\n },\n priority: 0,\n metadata: {\n stepName: step.name,\n agent: step.agent,\n },\n };\n }\n\n private buildCellConfig(step: Step): { timeout?: number; metadata: Record<string, unknown> } {\n return {\n timeout: step.timeout ? parseDuration(step.timeout) : undefined,\n metadata: {\n stepName: step.name,\n agent: step.agent,\n },\n };\n }\n\n private buildStepOutput(\n step: Step,\n task: Task,\n workflowInput: unknown,\n outputs: Record<string, unknown>\n ): Record<string, unknown> {\n return {\n stepName: step.name,\n agent: step.agent,\n task,\n workflowInput,\n previousOutputs: { ...outputs },\n };\n }\n\n private async bindStepState(execution: Execution, step: Step, result: { success: boolean; output: unknown }): Promise<void> {\n const bindings = this.extractStateBindings(step);\n if (!this.dependencies.stateBinder || bindings.length === 0) {\n return;\n }\n\n await this.dependencies.stateBinder.bind(result, bindings);\n }\n\n private extractStateBindings(step: Step): StateBinding[] {\n const directBindings = (step as Step & { bindings?: unknown }).bindings;\n if (Array.isArray(directBindings)) {\n return directBindings.filter(this.isStateBinding);\n }\n\n const config = step.config as Record<string, unknown> | undefined;\n const configBindings = config?.bindings;\n if (Array.isArray(configBindings)) {\n return configBindings.filter(this.isStateBinding);\n }\n\n return [];\n }\n\n private readonly isStateBinding = (value: unknown): value is StateBinding => {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Record<string, unknown>;\n return typeof candidate.source === \"string\" && typeof candidate.target === \"string\";\n };\n\n private async recordExecutionEnd(execution: Execution): Promise<void> {\n await this.recordAudit(execution.id, \"execution_end\", {\n status: execution.status,\n completedSteps: execution.completedSteps,\n error: execution.error,\n endedAt: execution.endedAt,\n });\n await this.persistRun(execution);\n }\n\n // ── Persistence hooks (opt-in) ──\n\n private static mapExecutionStatusToRunStatus(status: Execution[\"status\"]): RunRecord[\"status\"] {\n switch (status) {\n case \"running\": return \"running\";\n case \"completed\": return \"completed\";\n case \"failed\": return \"failed\";\n case \"waiting\":\n case \"suspended\": return \"suspended\";\n default: return \"running\";\n }\n }\n\n private async persistRun(execution: Execution): Promise<void> {\n const adapter = this.dependencies.storageAdapter;\n if (!adapter) return;\n const input = (typeof execution.input === \"object\" && execution.input !== null && !Array.isArray(execution.input))\n ? execution.input as Record<string, unknown>\n : { value: execution.input };\n await adapter.saveRun({\n id: execution.id,\n workflowName: execution.workflowName,\n status: DefaultRuntimeOrchestrator.mapExecutionStatusToRunStatus(execution.status),\n input,\n startedAt: execution.startedAt.toISOString(),\n completedAt: execution.endedAt?.toISOString(),\n metadata: execution.metadata,\n });\n }\n\n private async persistStep(execution: Execution, stepName: string): Promise<void> {\n const adapter = this.dependencies.storageAdapter;\n if (!adapter) return;\n const rec = execution.stepRecords[stepName];\n if (!rec) return;\n await adapter.saveStep({\n id: `${execution.id}:${stepName}`,\n runId: execution.id,\n stepName,\n status: rec.status === \"pending\" || rec.status === \"waiting\" ? \"running\" : rec.status as StepRecord[\"status\"],\n input: undefined,\n output: rec.result ? (rec.result as unknown as Record<string, unknown>) : undefined,\n error: rec.error ? this.toStepError(rec) : undefined,\n startedAt: rec.startedAt?.toISOString() ?? new Date().toISOString(),\n completedAt: rec.endedAt?.toISOString(),\n durationMs: rec.startedAt && rec.endedAt\n ? rec.endedAt.getTime() - rec.startedAt.getTime()\n : undefined,\n });\n }\n\n private toStepError(rec: { error?: string; recovery?: { error?: unknown } }): StepRecord[\"error\"] {\n // Try to extract structured error info from recovery context\n const raw = rec.recovery?.error;\n if (raw && typeof raw === \"object\" && raw !== null && \"code\" in raw && \"message\" in raw) {\n const err = raw as { code: string; message: string; stack?: string };\n return { code: err.code, message: err.message, stack: err.stack };\n }\n // For OboraError-like objects with code property\n if (raw instanceof Error) {\n const code = \"code\" in raw && typeof (raw as Record<string, unknown>).code === \"string\"\n ? (raw as Record<string, unknown>).code as string\n : \"STEP_ERROR\";\n return { code, message: raw.message, stack: raw.stack };\n }\n return { code: \"STEP_ERROR\", message: rec.error ?? \"Unknown error\" };\n }\n\n private async captureArtifacts(\n runId: string,\n stepName: string,\n output: unknown,\n toolCalls: Array<{ toolName?: string; params?: unknown; status?: string }>,\n ): Promise<void> {\n const store = this.dependencies.artifactStore;\n const adapter = this.dependencies.storageAdapter;\n if (!store || !adapter) return;\n\n const candidates: Array<{ name: string; mime: string; data: Buffer }> = [];\n\n // Rule 1) explicit artifacts tag in step output\n if (output && typeof output === \"object\" && \"artifacts\" in (output as Record<string, unknown>)) {\n const tagged = (output as Record<string, unknown>).artifacts;\n const list = Array.isArray(tagged) ? tagged : [tagged];\n for (const item of list) {\n if (!item || typeof item !== \"object\") continue;\n const rec = item as Record<string, unknown>;\n const name = typeof rec.name === \"string\" ? rec.name : undefined;\n const mime = typeof rec.mime === \"string\" ? rec.mime : \"application/octet-stream\";\n const data = rec.data;\n if (!name || data === undefined || data === null) continue;\n const buf = Buffer.isBuffer(data) ? data : Buffer.from(typeof data === \"string\" ? data : JSON.stringify(data), \"utf-8\");\n candidates.push({ name, mime, data: buf });\n }\n }\n\n // Rule 2) file_write tool calls\n for (const tool of toolCalls) {\n if (tool.toolName !== \"file_write\" || tool.status !== \"success\") continue;\n const params = tool.params as Record<string, unknown> | undefined;\n if (!params) continue;\n const path = typeof params.path === \"string\" ? params.path : undefined;\n const content = typeof params.content === \"string\" ? params.content : undefined;\n if (!path || content === undefined) continue;\n const parts = path.split(/[\\\\/]/);\n const name = parts[parts.length - 1] ?? `${stepName}.txt`;\n candidates.push({ name, mime: \"text/plain\", data: Buffer.from(content, \"utf-8\") });\n }\n\n // Rule 3) structured JSON output fallback (only when no explicit artifacts were detected)\n if (candidates.length === 0 && output && typeof output === \"object\" && !Array.isArray(output)) {\n candidates.push({\n name: `${stepName}.json`,\n mime: \"application/json\",\n data: Buffer.from(JSON.stringify(output, null, 2), \"utf-8\"),\n });\n }\n\n const seen = new Set<string>();\n for (const c of candidates) {\n if (seen.has(c.name)) continue;\n seen.add(c.name);\n const saved = await store.save(runId, stepName, c.name, c.data, c.mime);\n await adapter.saveArtifact({\n id: saved.id,\n runId: saved.runId,\n stepName: saved.stepName,\n name: saved.name,\n mimeType: saved.mime,\n sizeBytes: saved.size,\n storageRef: saved.path,\n createdAt: saved.createdAt,\n });\n }\n }\n\n private async recordAudit(\n executionId: string,\n type: AuditEventType,\n data: unknown,\n options: { cellId?: string; durationMs?: number } = {}\n ): Promise<void> {\n const event = {\n id: randomUUID(),\n executionId,\n cellId: options.cellId,\n timestamp: this.now(),\n type,\n data,\n metadata: options.durationMs !== undefined ? { durationMs: options.durationMs } : undefined,\n };\n\n if (this.dependencies.auditTrail) {\n await this.dependencies.auditTrail.record(event);\n }\n\n await persistStructuredAuditEvent(this.dependencies.storageAdapter, executionId, event);\n }\n\n private extractError(output: unknown): string {\n if (output && typeof output === \"object\" && \"error\" in (output as Record<string, unknown>)) {\n const value = (output as Record<string, unknown>).error;\n if (typeof value === \"string\") {\n return value;\n }\n }\n return \"Step execution failed\";\n }\n\n private cloneExecution(execution: Execution): Execution {\n return structuredClone(execution);\n }\n}\n","export function greet(name: string): string {\n return `Hello, ${name}!`;\n}\n\nexport function log(message: string): void {\n console.log(`[Obora] ${message}`);\n}\n","/**\n * Error codes and classes for obora-kit\n * @module @obora/core/errors\n */\n\n/**\n * Error codes mapping\n * Reference: docs/spec/10-error-codes.md\n */\nexport const ErrorCodes = {\n // General errors (E1xxx)\n E1001: \"Unknown error\",\n E1002: \"Configuration not found\",\n E1003: \"Permission denied\",\n\n // YAML/Parse errors (E2xxx)\n E2001: \"Invalid YAML syntax\",\n E2002: \"Missing required field\",\n E2003: \"Invalid field type\",\n E2004: \"Unknown field\",\n E2005: \"Invalid duration format\",\n E2006: \"Duplicate step name\",\n\n // Dependency errors (E3xxx)\n E3001: \"Circular dependency detected\",\n E3002: \"Missing dependency\",\n E3003: \"Self dependency\",\n E3004: \"Unresolved input file\",\n\n // Runtime errors (E4xxx)\n E4001: \"Step execution failed\",\n E4002: \"Timeout exceeded\",\n E4003: \"Agent not found\",\n E4004: \"Lock acquisition failed\",\n E4005: \"Step failed after retries exhausted\",\n E4006: \"Spec validation failed\",\n E4007: \"Context assembly failed\",\n\n // Agent errors (E6xxx)\n E6003: \"OpenClaw connection failed\",\n} as const;\n\nexport type ErrorCode = keyof typeof ErrorCodes;\n\n/**\n * Base error class for obora-kit\n */\nexport class OboraError extends Error {\n public readonly code: ErrorCode;\n public readonly details?: Record<string, unknown>;\n\n constructor(code: ErrorCode, message?: string, details?: Record<string, unknown>) {\n const baseMessage = ErrorCodes[code];\n const fullMessage = message\n ? `${code}: ${baseMessage} - ${message}`\n : `${code}: ${baseMessage}`;\n super(fullMessage);\n this.name = \"OboraError\";\n this.code = code;\n this.details = details;\n }\n}\n\n/**\n * YAML parsing error\n */\nexport class ParseError extends OboraError {\n constructor(code: ErrorCode, message?: string, details?: Record<string, unknown>) {\n super(code, message, details);\n this.name = \"ParseError\";\n }\n}\n\n/**\n * Dependency resolution error\n */\nexport class DependencyError extends OboraError {\n constructor(code: ErrorCode, message?: string, details?: Record<string, unknown>) {\n super(code, message, details);\n this.name = \"DependencyError\";\n }\n}\n","/**\n * Actionable diagnosis templates for high-frequency errors\n * Each template follows: Hypothesis → Evidence → Command → Rollback\n * @module @obora/core/errors/diagnosis\n */\n\nexport interface DiagnosisTemplate {\n /** Error code */\n code: string;\n /** One-line summary */\n title: string;\n /** Probable cause hypothesis */\n hypothesis: string;\n /** How to confirm the hypothesis */\n evidence: string;\n /** Command(s) to fix */\n commands: string[];\n /** How to undo if the fix makes things worse */\n rollback: string;\n}\n\nconst templates: Record<string, DiagnosisTemplate> = {\n E4001: {\n code: \"E4001\",\n title: \"Agent execution failed\",\n hypothesis:\n \"BaseAgent.execute() returned { success: false }. The agent encountered a business-logic failure (bad prompt, invalid input, etc.).\",\n evidence: \"Review step output and agent logs for the failure reason.\",\n commands: [\n \"obora run --from-step <failed-step> -f <feature> # Re-run from failed step\",\n \"# Check agent configuration and step inputs\",\n ],\n rollback: \"No side effects — agent failure is contained within the step.\",\n },\n E4002: {\n code: \"E4002\",\n title: \"Step execution timeout\",\n hypothesis:\n \"The step exceeded its configured timeout. The agent.execute() call was aborted via AbortSignal.\",\n evidence: \"Check step timeout configuration and agent response time.\",\n commands: [\n \"# Increase timeout in workflow YAML: timeout: '5m'\",\n \"obora run --from-step <failed-step> -f <feature> # Re-run\",\n ],\n rollback: \"No side effects — timeout aborts cleanly via AbortController.\",\n },\n E4003: {\n code: \"E4003\",\n title: \"Agent resolution failed\",\n hypothesis:\n \"AgentResolver.resolve() could not find or instantiate the agent specified in the step. The agent name may be misspelled or unregistered.\",\n evidence: \"Check step.agent value against registered agent names.\",\n commands: [\n \"obora validate # Verify workflow agent references\",\n ],\n rollback: \"No side effects — resolution failure occurs before execution.\",\n },\n E4004: {\n code: \"E4004\",\n title: \"Lock acquisition failed\",\n hypothesis:\n \"A previous obora process crashed without releasing the lock, or another instance is running.\",\n evidence: \"Check for stale lock files: ls -la .obora/locks/\",\n commands: [\n \"obora lock clean # Remove stale locks\",\n \"# Or wait and retry after the other process finishes\",\n ],\n rollback: \"No rollback needed — lock clean only removes stale locks.\",\n },\n E4005: {\n code: \"E4005\",\n title: \"Step failed after retries exhausted\",\n hypothesis:\n \"The agent failed repeatedly. Common causes: invalid prompt, missing input file, or agent misconfiguration.\",\n evidence:\n \"Review step logs: cat .obora/features/<feature>/.obora/outputs/<step>.md\",\n commands: [\n \"obora run --from-step <failed-step> -f <feature> # Re-run from failed step\",\n \"obora validate # Check workflow definition\",\n ],\n rollback:\n \"Outputs from failed steps are not committed. Safe to re-run.\",\n },\n E4006: {\n code: \"E4006\",\n title: \"Spec validation failed\",\n hypothesis:\n \"Required spec files (proposal.md, design.md, etc.) are missing or malformed.\",\n evidence:\n \"Check feature directory: ls .obora/features/<feature>/\",\n commands: [\n \"obora validate -f <feature> # See detailed validation errors\",\n \"# Then create/fix the missing spec files\",\n ],\n rollback: \"No destructive action — just add the missing files.\",\n },\n E4007: {\n code: \"E4007\",\n title: \"Context assembly failed\",\n hypothesis:\n \"ContextBuilder failed to assemble AgentContext (Blackboard init, sessionId, etc.). This is an infrastructure error.\",\n evidence: \"Check Blackboard availability and context configuration.\",\n commands: [\n \"# Verify blackboard package is installed and configured\",\n \"obora validate # Check project integrity\",\n ],\n rollback: \"No side effects — context assembly failure occurs before execution.\",\n },\n E6003: {\n code: \"E6003\",\n title: \"OpenClaw connection failed\",\n hypothesis:\n \"The OpenClaw gateway is not running, or the connection endpoint is misconfigured.\",\n evidence:\n \"Check gateway status: openclaw gateway status\",\n commands: [\n \"openclaw gateway start # Start the gateway\",\n \"openclaw gateway restart # Or restart if already running\",\n ],\n rollback:\n \"openclaw gateway stop # Stop if the restart caused issues\",\n },\n};\n\n/**\n * Get diagnosis template for a given error code.\n * Returns undefined if no template exists.\n */\nexport function getDiagnosis(code: string): DiagnosisTemplate | undefined {\n return templates[code];\n}\n\n/**\n * Format a diagnosis template as a human-readable CLI string.\n */\nexport function formatDiagnosis(diag: DiagnosisTemplate): string {\n const lines: string[] = [\n \"\",\n `💊 Diagnosis for ${diag.code}: ${diag.title}`,\n \"\",\n ` Hypothesis : ${diag.hypothesis}`,\n ` Evidence : ${diag.evidence}`,\n ` Fix :`,\n ...diag.commands.map((c) => ` $ ${c}`),\n ` Rollback : ${diag.rollback}`,\n \"\",\n ];\n return lines.join(\"\\n\");\n}\n\n/**\n * Get all registered diagnosis templates.\n */\nexport function getAllDiagnoses(): DiagnosisTemplate[] {\n return Object.values(templates);\n}\n","/**\n * Workflow YAML parser\n * @module @obora/core/parser/workflow-parser\n */\n\nimport { parse as parseYaml, YAMLParseError } from \"yaml\";\n\nimport { DependencyError, ParseError } from \"../errors/index.js\";\nimport { buildGraph, topologicalSort } from \"../graph/index.js\";\nimport type {\n BackEdgeEscalation,\n ConsensusConfig,\n DependencyMap,\n GateConfig,\n GateType,\n ParserOptions,\n PolicyOverride,\n RecoveryStrategyConfig,\n StateBinding,\n Step,\n StepOnFailConfig,\n Workflow,\n WorkflowConfig,\n WorkflowMode,\n AuditConfig,\n} from \"../types/workflow.js\";\n\n// Known fields for strict mode validation\nconst KNOWN_WORKFLOW_FIELDS = [\"name\", \"version\", \"description\", \"mode\", \"config\", \"policy\", \"steps\", \"recovery\", \"audit\"];\n\nconst KNOWN_STEP_FIELDS = [\n \"name\",\n \"agent\",\n \"description\",\n \"provider\",\n \"model\",\n \"depends_on\",\n \"inputs\",\n \"outputs\",\n \"timeout\",\n \"skills\",\n \"tools\",\n \"bindings\",\n \"consensus\",\n \"gate\",\n \"gate_config\",\n \"pattern\",\n \"participants\",\n \"policy\",\n \"on_fail\",\n \"config\",\n];\n\nconst KNOWN_CONFIG_FIELDS = [\"retry\", \"retry_delay\", \"continue_on_error\", \"max_parallel\"];\n\n// Valid duration pattern: positive integer followed by s/m/h/d\nconst DURATION_PATTERN = /^[1-9]\\d*[smhd]$/;\n\n// Spec files that don't need to be produced by a step\nconst SPEC_FILES = [\"proposal.md\", \"design.md\", \"tasks.md\", \"status.yaml\"];\n\n/**\n * Validate duration format\n */\nfunction validateDuration(value: string, field: string): void {\n if (!DURATION_PATTERN.test(value)) {\n throw new ParseError(\n \"E2005\",\n `'${field}' has invalid duration format: '${value}'. Use format like '5s', '1m', '2h', '1d'`\n );\n }\n}\n\n/**\n * Check for unknown fields\n */\nfunction checkUnknownFields(\n obj: Record<string, unknown>,\n knownFields: string[],\n context: string,\n options: ParserOptions\n): void {\n const unknownFields = Object.keys(obj).filter((k) => !knownFields.includes(k));\n\n if (unknownFields.length > 0) {\n const message = `Unknown field(s) in ${context}: ${unknownFields.join(\", \")}`;\n if (options.strict) {\n throw new ParseError(\"E2004\", message);\n } else if (options.onWarning) {\n options.onWarning(`E2004: ${message}`);\n }\n }\n}\n\n/**\n * Parse a raw YAML object into a Step\n */\nfunction parseStateBindings(raw: unknown, stepName: string): StateBinding[] | undefined {\n if (raw === undefined) {\n return undefined;\n }\n if (!Array.isArray(raw)) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'bindings' must be an array`);\n }\n\n return raw.map((item, index) => {\n if (typeof item !== \"object\" || item === null) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'bindings[${index}]' must be an object`);\n }\n const binding = item as Record<string, unknown>;\n if (typeof binding.source !== \"string\" || typeof binding.target !== \"string\") {\n throw new ParseError(\"E2003\", `Step '${stepName}': binding requires string 'source' and 'target'`);\n }\n\n return {\n source: binding.source,\n target: binding.target,\n transform: typeof binding.transform === \"string\" ? binding.transform : undefined,\n condition: typeof binding.condition === \"string\" ? binding.condition : undefined,\n };\n });\n}\n\nfunction parseConsensus(raw: unknown, stepName: string): ConsensusConfig | undefined {\n if (raw === undefined) {\n return undefined;\n }\n\n if (typeof raw !== \"object\" || raw === null) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'consensus' must be an object`);\n }\n\n const obj = raw as Record<string, unknown>;\n const validTypes = [\"majority\", \"unanimous\", \"weighted\", \"score-threshold\", \"custom\"] as const;\n const type = obj.type;\n if (typeof type !== \"string\" || !validTypes.includes(type as (typeof validTypes)[number])) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'consensus.type' is invalid`);\n }\n\n return {\n type: type as ConsensusConfig[\"type\"],\n voters: Array.isArray(obj.voters) ? obj.voters as ConsensusConfig[\"voters\"] : undefined,\n min: typeof obj.min === \"number\" ? obj.min : undefined,\n of: typeof obj.of === \"number\" ? obj.of : undefined,\n threshold: typeof obj.threshold === \"number\" ? obj.threshold : undefined,\n timeout: typeof obj.timeout === \"string\" ? obj.timeout : undefined,\n best_effort: Array.isArray(obj.best_effort) ? obj.best_effort.filter((x): x is string => typeof x === \"string\") : undefined,\n custom: typeof obj.custom === \"string\" ? obj.custom : undefined,\n };\n}\n\nfunction parseGateConfig(raw: unknown, stepName: string): GateConfig | undefined {\n if (raw === undefined) {\n return undefined;\n }\n if (typeof raw !== \"object\" || raw === null) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'gate_config' must be an object`);\n }\n\n const config = raw as Record<string, unknown>;\n return {\n timeout: typeof config.timeout === \"string\" ? config.timeout : undefined,\n fallback:\n config.fallback === \"fail\" || config.fallback === \"escalate\" || config.fallback === \"auto-approve\"\n ? config.fallback\n : undefined,\n escalation_to: typeof config.escalation_to === \"string\" ? config.escalation_to : undefined,\n };\n}\n\nfunction parsePolicyOverride(raw: unknown, stepName: string): PolicyOverride | undefined {\n if (raw === undefined) {\n return undefined;\n }\n if (typeof raw !== \"object\" || raw === null) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'policy' must be an object`);\n }\n\n const policy = raw as Record<string, unknown>;\n return {\n sandbox: typeof policy.sandbox === \"string\" ? policy.sandbox : undefined,\n tools_override: Array.isArray(policy.tools_override)\n ? policy.tools_override.filter((item): item is { name: string; effect: \"allow\" | \"deny\" | \"transform\" | \"gate\" } => {\n if (typeof item !== \"object\" || item === null) {\n return false;\n }\n const candidate = item as Record<string, unknown>;\n return typeof candidate.name === \"string\"\n && (candidate.effect === \"allow\" || candidate.effect === \"deny\" || candidate.effect === \"transform\" || candidate.effect === \"gate\");\n })\n : undefined,\n };\n}\n\nfunction parseOnFail(raw: unknown, stepName: string): StepOnFailConfig | undefined {\n if (raw === undefined) {\n return undefined;\n }\n\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'on_fail' must be an object`);\n }\n\n const config = raw as Record<string, unknown>;\n if (typeof config.goto !== \"string\" || config.goto.length === 0) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'on_fail.goto' must be a non-empty string`);\n }\n\n if (config.max_iterations === undefined || typeof config.max_iterations !== \"number\" || !Number.isInteger(config.max_iterations)) {\n throw new ParseError(\"E2003\", `Step '${stepName}': 'max_iterations' is required and must be an integer`);\n }\n if (config.max_iterations < 1) {\n throw new ParseError(\"E2003\", `max_iterations must be \\u2265 1, got ${config.max_iterations}`);\n }\n\n const escalation = config.escalate_on_exhaust ?? \"fail\";\n if (escalation !== \"human\" && escalation !== \"dlq\" && escalation !== \"fail\") {\n throw new ParseError(\"E2003\", `unknown escalation: ${String(escalation)}`);\n }\n\n const cooldownMs = config.cooldown_ms ?? 0;\n if (typeof cooldownMs !== \"number\" || !Number.isInteger(cooldownMs) || cooldownMs < 0 || cooldownMs > 300000) {\n throw new ParseError(\"E2003\", `cooldown_ms must be 0~300000ms, got ${String(cooldownMs)}`);\n }\n\n if (config.max_cost !== undefined && config.max_cost !== null) {\n if (typeof config.max_cost !== \"number\" || config.max_cost <= 0) {\n throw new ParseError(\"E2003\", `max_cost must be positive, got ${String(config.max_cost)}`);\n }\n }\n\n // Spec: omitted max_cost_escalation = null at parser level. Inheritance from escalate_on_exhaust happens at runtime.\n const maxCostEscalationRaw = config.max_cost_escalation ?? null;\n if (maxCostEscalationRaw !== null && maxCostEscalationRaw !== \"human\" && maxCostEscalationRaw !== \"dlq\" && maxCostEscalationRaw !== \"fail\") {\n throw new ParseError(\"E2003\", `unknown escalation: ${String(maxCostEscalationRaw)}`);\n }\n\n return {\n goto: config.goto,\n max_iterations: config.max_iterations,\n escalate_on_exhaust: escalation as BackEdgeEscalation,\n cooldown_ms: cooldownMs,\n reset_state: Boolean(config.reset_state ?? false),\n max_cost: config.max_cost === undefined ? null : config.max_cost as number | null,\n max_cost_escalation: maxCostEscalationRaw as BackEdgeEscalation | null,\n };\n}\n\nfunction parseStep(raw: unknown, index: number, options: ParserOptions): Step {\n if (typeof raw !== \"object\" || raw === null) {\n throw new ParseError(\"E2003\", `Step at index ${index} must be an object`);\n }\n\n const obj = raw as Record<string, unknown>;\n\n // Check required fields\n if (!obj.name) {\n throw new ParseError(\"E2002\", `Step at index ${index} is missing required field 'name'`);\n }\n if (typeof obj.name !== \"string\") {\n throw new ParseError(\"E2003\", `Step at index ${index}: 'name' must be a string`);\n }\n\n if (!obj.agent) {\n throw new ParseError(\"E2002\", `Step '${obj.name}' is missing required field 'agent'`);\n }\n if (typeof obj.agent !== \"string\") {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'agent' must be a string`);\n }\n\n // Check unknown fields\n checkUnknownFields(obj, KNOWN_STEP_FIELDS, `step '${obj.name}'`, options);\n\n if (obj.provider !== undefined && typeof obj.provider !== \"string\") {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'provider' must be a string`);\n }\n\n if (obj.model !== undefined && typeof obj.model !== \"string\") {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'model' must be a string`);\n }\n\n // Validate optional fields\n if (obj.timeout !== undefined) {\n if (typeof obj.timeout !== \"string\") {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'timeout' must be a string`);\n }\n validateDuration(obj.timeout, `step '${obj.name}'.timeout`);\n }\n\n if (obj.depends_on !== undefined) {\n if (!Array.isArray(obj.depends_on)) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'depends_on' must be an array`);\n }\n if (!obj.depends_on.every((d) => typeof d === \"string\")) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'depends_on' must be an array of strings`);\n }\n }\n\n if (obj.inputs !== undefined) {\n if (!Array.isArray(obj.inputs)) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'inputs' must be an array`);\n }\n if (!obj.inputs.every((i) => typeof i === \"string\")) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'inputs' must be an array of strings`);\n }\n }\n\n if (obj.outputs !== undefined) {\n if (!Array.isArray(obj.outputs)) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'outputs' must be an array`);\n }\n if (!obj.outputs.every((o) => typeof o === \"string\")) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'outputs' must be an array of strings`);\n }\n }\n\n // Validate description type\n if (obj.description !== undefined && typeof obj.description !== \"string\") {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'description' must be a string`);\n }\n\n if (obj.skills !== undefined) {\n if (!Array.isArray(obj.skills)) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'skills' must be an array`);\n }\n if (!obj.skills.every((skill) => typeof skill === \"string\")) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'skills' must be an array of strings`);\n }\n }\n\n if (obj.tools !== undefined) {\n if (!Array.isArray(obj.tools) || !obj.tools.every((tool) => typeof tool === \"string\")) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'tools' must be an array of strings`);\n }\n }\n\n if (obj.gate !== undefined) {\n const validGates: GateType[] = [\"human-approval\", \"consensus\", \"external\"];\n if (!validGates.includes(obj.gate as GateType)) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'gate' must be one of ${validGates.join(\", \")}`);\n }\n }\n\n if (obj.pattern !== undefined && typeof obj.pattern !== \"string\") {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'pattern' must be a string`);\n }\n\n if (obj.participants !== undefined && (typeof obj.participants !== \"object\" || obj.participants === null || Array.isArray(obj.participants))) {\n throw new ParseError(\"E2003\", `Step '${obj.name}': 'participants' must be an object`);\n }\n\n return {\n name: obj.name,\n agent: obj.agent,\n description: obj.description as string | undefined,\n provider: obj.provider as string | undefined,\n model: obj.model as string | undefined,\n depends_on: obj.depends_on as string[] | undefined,\n inputs: obj.inputs as string[] | undefined,\n outputs: obj.outputs as string[] | undefined,\n timeout: obj.timeout as string | undefined,\n skills: obj.skills as string[] | undefined,\n tools: obj.tools as string[] | undefined,\n bindings: parseStateBindings(obj.bindings, obj.name),\n consensus: parseConsensus(obj.consensus, obj.name),\n gate: obj.gate as GateType | undefined,\n gate_config: parseGateConfig(obj.gate_config, obj.name),\n pattern: obj.pattern as string | undefined,\n participants: obj.participants as Record<string, string> | undefined,\n policy: parsePolicyOverride(obj.policy, obj.name),\n on_fail: parseOnFail(obj.on_fail, obj.name),\n config: obj.config as Record<string, unknown> | undefined,\n };\n}\n\n/**\n * Parse workflow config\n */\nfunction parseConfig(raw: unknown, options: ParserOptions): WorkflowConfig | undefined {\n if (raw === undefined) return undefined;\n\n if (typeof raw !== \"object\" || raw === null) {\n throw new ParseError(\"E2003\", \"'config' must be an object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n checkUnknownFields(obj, KNOWN_CONFIG_FIELDS, \"config\", options);\n\n // Validate config field types\n if (obj.retry !== undefined && typeof obj.retry !== \"number\") {\n throw new ParseError(\"E2003\", \"'config.retry' must be a number\");\n }\n\n if (obj.retry_delay !== undefined) {\n if (typeof obj.retry_delay !== \"string\") {\n throw new ParseError(\"E2003\", \"'config.retry_delay' must be a string\");\n }\n validateDuration(obj.retry_delay, \"config.retry_delay\");\n }\n\n if (obj.continue_on_error !== undefined && typeof obj.continue_on_error !== \"boolean\") {\n throw new ParseError(\"E2003\", \"'config.continue_on_error' must be a boolean\");\n }\n\n if (obj.max_parallel !== undefined && typeof obj.max_parallel !== \"number\") {\n throw new ParseError(\"E2003\", \"'config.max_parallel' must be a number\");\n }\n\n return {\n retry: obj.retry as number | undefined,\n retry_delay: obj.retry_delay as string | undefined,\n continue_on_error: obj.continue_on_error as boolean | undefined,\n max_parallel: obj.max_parallel as number | undefined,\n };\n}\n\nfunction parseAudit(raw: unknown): AuditConfig | undefined {\n if (raw === undefined) {\n return undefined;\n }\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new ParseError(\"E2003\", \"'audit' must be an object\");\n }\n\n const audit = raw as Record<string, unknown>;\n const store = audit.store;\n if (store !== \"duckdb\" && store !== \"sqlite\" && store !== \"custom\") {\n throw new ParseError(\"E2003\", \"'audit.store' must be one of: duckdb, sqlite, custom\");\n }\n\n return {\n store,\n path: typeof audit.path === \"string\" ? audit.path : undefined,\n retention: typeof audit.retention === \"string\" ? audit.retention : undefined,\n custom: typeof audit.custom === \"string\" ? audit.custom : undefined,\n };\n}\n\nfunction parseRecovery(raw: unknown): Record<string, RecoveryStrategyConfig> | undefined {\n if (raw === undefined) {\n return undefined;\n }\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new ParseError(\"E2003\", \"'recovery' must be an object\");\n }\n\n const recovery = raw as Record<string, unknown>;\n const parsed: Record<string, RecoveryStrategyConfig> = {};\n\n for (const [stepName, config] of Object.entries(recovery)) {\n if (typeof config !== \"object\" || config === null) {\n throw new ParseError(\"E2003\", `'recovery.${stepName}' must be an object`);\n }\n\n const item = config as Record<string, unknown>;\n const valid = [\"retry\", \"rollback\", \"escalate\", \"alternative\", \"custom\"];\n if (!valid.includes(String(item.on_fail))) {\n throw new ParseError(\"E2003\", `'recovery.${stepName}.on_fail' is invalid`);\n }\n\n parsed[stepName] = {\n on_fail: item.on_fail as RecoveryStrategyConfig[\"on_fail\"],\n max_retries: typeof item.max_retries === \"number\" ? item.max_retries : undefined,\n backoff: item.backoff === \"linear\" || item.backoff === \"exponential\" ? item.backoff : undefined,\n backoff_base: typeof item.backoff_base === \"string\" ? item.backoff_base : undefined,\n to: typeof item.to === \"string\" ? item.to : undefined,\n fallback: item.fallback as RecoveryStrategyConfig[\"fallback\"],\n custom: typeof item.custom === \"string\" ? item.custom : undefined,\n };\n }\n\n return parsed;\n}\n\n/**\n * Check for duplicate step names\n */\nfunction checkDuplicateSteps(steps: Step[]): void {\n const names = new Set<string>();\n for (const step of steps) {\n if (names.has(step.name)) {\n throw new ParseError(\"E2006\", `Duplicate step name: '${step.name}'`);\n }\n names.add(step.name);\n }\n}\n\n/**\n * Check for self-dependencies\n */\nfunction checkSelfDependencies(steps: Step[]): void {\n for (const step of steps) {\n if (step.depends_on?.includes(step.name)) {\n throw new DependencyError(\"E3003\", `Step '${step.name}' depends on itself`);\n }\n }\n}\n\n/**\n * Check for missing dependencies\n */\nfunction checkMissingDependencies(steps: Step[]): void {\n const stepNames = new Set(steps.map((s) => s.name));\n\n for (const step of steps) {\n if (step.depends_on) {\n for (const dep of step.depends_on) {\n if (!stepNames.has(dep)) {\n throw new DependencyError(\n \"E3002\",\n `Step '${step.name}' depends on non-existent step '${dep}'`\n );\n }\n }\n }\n }\n}\n\n/**\n * Check for circular dependencies using DFS\n */\nfunction checkCircularDependencies(steps: Step[]): void {\n const graph = new Map<string, string[]>();\n for (const step of steps) {\n graph.set(step.name, step.depends_on || []);\n }\n\n const visited = new Set<string>();\n const recStack = new Set<string>();\n\n function hasCycle(node: string, path: string[]): boolean {\n visited.add(node);\n recStack.add(node);\n\n const deps = graph.get(node) || [];\n for (const dep of deps) {\n if (!visited.has(dep)) {\n if (hasCycle(dep, [...path, dep])) {\n return true;\n }\n } else if (recStack.has(dep)) {\n throw new DependencyError(\n \"E3001\",\n `Circular dependency detected: ${[...path, node, dep].join(\" -> \")}`\n );\n }\n }\n\n recStack.delete(node);\n return false;\n }\n\n for (const step of steps) {\n if (!visited.has(step.name)) {\n hasCycle(step.name, [step.name]);\n }\n }\n}\n\nfunction checkOnFailMutualExclusion(\n steps: Step[],\n recovery: Record<string, RecoveryStrategyConfig> | undefined,\n): void {\n for (const step of steps) {\n if (!step.on_fail?.goto) {\n continue;\n }\n\n const workflowRecovery = recovery?.[step.name];\n const legacyRecovery = (step.config as Record<string, unknown> | undefined)?.recovery as Record<string, unknown> | undefined;\n const hasLegacyOnFail = typeof legacyRecovery?.on_fail === \"string\";\n const hasWorkflowOnFail = typeof workflowRecovery?.on_fail === \"string\";\n\n if (hasLegacyOnFail || hasWorkflowOnFail) {\n throw new ParseError(\n \"E2003\",\n `Step '${step.name}': 'on_fail.goto' and 'recovery.on_fail' are mutually exclusive`,\n );\n }\n }\n}\n\nfunction checkOnFailBackEdges(steps: Step[]): void {\n const stepNames = new Set(steps.map((s) => s.name));\n const byTarget = new Map<string, string[]>();\n const graph = buildGraph(steps);\n const topo = topologicalSort(graph);\n\n if (!topo.success) {\n return;\n }\n\n const canReachDependency = (from: string, target: string): boolean => {\n const visited = new Set<string>();\n const queue = [from];\n while (queue.length > 0) {\n const current = queue.shift()!;\n const deps = graph.reverseEdges.get(current) ?? new Set<string>();\n for (const dep of deps) {\n if (dep === target) {\n return true;\n }\n if (!visited.has(dep)) {\n visited.add(dep);\n queue.push(dep);\n }\n }\n }\n return false;\n };\n\n for (const step of steps) {\n const backEdge = step.on_fail;\n if (!backEdge) {\n continue;\n }\n\n if (backEdge.goto === step.name) {\n throw new ParseError(\"E2003\", `Step '${step.name}': self-loop is not allowed for on_fail.goto`);\n }\n\n if (!stepNames.has(backEdge.goto)) {\n throw new DependencyError(\"E3002\", `Step '${step.name}' on_fail.goto references non-existent step '${backEdge.goto}'`);\n }\n\n if (!canReachDependency(step.name, backEdge.goto)) {\n throw new ParseError(\n \"E2003\",\n `back-edge target '${backEdge.goto}' must precede source '${step.name}' in dependency graph`,\n );\n }\n\n const sources = byTarget.get(backEdge.goto) ?? [];\n sources.push(step.name);\n byTarget.set(backEdge.goto, sources);\n }\n\n for (const [target, sources] of byTarget) {\n if (sources.length >= 3) {\n throw new ParseError(\"E2003\", `Too many back-edges point to '${target}': ${sources.length} (maximum: 2)`);\n }\n }\n}\n\n/**\n * Check for unresolved input files\n */\nfunction checkUnresolvedInputs(steps: Step[], options: ParserOptions): void {\n // Collect all outputs\n const availableOutputs = new Set<string>();\n for (const step of steps) {\n if (step.outputs) {\n for (const output of step.outputs) {\n availableOutputs.add(output);\n }\n }\n }\n\n // Check inputs\n for (const step of steps) {\n if (step.inputs) {\n for (const input of step.inputs) {\n // Skip spec files\n const filename = input.split(\"/\").pop() || input;\n if (SPEC_FILES.includes(filename)) {\n continue;\n }\n\n if (!availableOutputs.has(input)) {\n if (options.strict) {\n throw new DependencyError(\n \"E3004\",\n `Step '${step.name}' requires input '${input}' but no step produces it`\n );\n } else if (options.onWarning) {\n options.onWarning(\n `E3004: Step '${step.name}' requires input '${input}' but no step produces it`\n );\n }\n }\n }\n }\n }\n}\n\n/**\n * Parse workflow YAML string into typed Workflow object\n */\nexport function parseWorkflow(yamlContent: string, options: ParserOptions = {}): Workflow {\n let raw: unknown;\n\n // Parse YAML\n try {\n raw = parseYaml(yamlContent);\n } catch (error) {\n if (error instanceof YAMLParseError) {\n throw new ParseError(\"E2001\", error.message);\n }\n throw error;\n }\n\n if (typeof raw !== \"object\" || raw === null) {\n throw new ParseError(\"E2001\", \"Workflow must be a YAML object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n // Check unknown fields\n checkUnknownFields(obj, KNOWN_WORKFLOW_FIELDS, \"workflow\", options);\n\n // Check required fields\n if (!obj.name) {\n throw new ParseError(\"E2002\", \"Missing required field 'name'\");\n }\n if (typeof obj.name !== \"string\") {\n throw new ParseError(\"E2003\", \"'name' must be a string\");\n }\n\n if (!obj.steps) {\n throw new ParseError(\"E2002\", \"Missing required field 'steps'\");\n }\n if (!Array.isArray(obj.steps)) {\n throw new ParseError(\"E2003\", \"'steps' must be an array\");\n }\n\n // Validate optional workflow field types\n if (obj.version !== undefined && typeof obj.version !== \"string\") {\n throw new ParseError(\"E2003\", \"'version' must be a string\");\n }\n\n if (obj.description !== undefined && typeof obj.description !== \"string\") {\n throw new ParseError(\"E2003\", \"'description' must be a string\");\n }\n\n if (obj.policy !== undefined && typeof obj.policy !== \"string\") {\n throw new ParseError(\"E2003\", \"'policy' must be a string\");\n }\n\n // Validate mode if present\n if (obj.mode !== undefined) {\n const validModes: WorkflowMode[] = [\"auto\", \"supervised\", \"gated\", \"manual\"];\n if (!validModes.includes(obj.mode as WorkflowMode)) {\n throw new ParseError(\"E2003\", `'mode' must be one of: ${validModes.join(\", \")}`);\n }\n }\n\n // Parse steps\n const steps = obj.steps.map((s, i) => parseStep(s, i, options));\n const recovery = parseRecovery(obj.recovery);\n\n // Validate steps\n checkDuplicateSteps(steps);\n checkSelfDependencies(steps);\n checkMissingDependencies(steps);\n checkCircularDependencies(steps);\n checkOnFailMutualExclusion(steps, recovery);\n checkOnFailBackEdges(steps);\n checkUnresolvedInputs(steps, options);\n\n return {\n name: obj.name,\n version: obj.version as string | undefined,\n description: obj.description as string | undefined,\n mode: obj.mode as WorkflowMode | undefined,\n config: parseConfig(obj.config, options),\n policy: obj.policy as string | undefined,\n steps,\n recovery,\n audit: parseAudit(obj.audit),\n };\n}\n\n/**\n * Resolve dependencies including implicit ones from inputs/outputs\n */\nexport function resolveDependencies(workflow: Workflow): DependencyMap {\n const deps = new Map<string, string[]>();\n\n // Build output map: file -> step name\n const outputMap = new Map<string, string>();\n for (const step of workflow.steps) {\n if (step.outputs) {\n for (const output of step.outputs) {\n outputMap.set(output, step.name);\n }\n }\n }\n\n // Resolve dependencies for each step\n for (const step of workflow.steps) {\n const stepDeps = new Set<string>(step.depends_on || []);\n\n // Add implicit dependencies from inputs\n if (step.inputs) {\n for (const input of step.inputs) {\n const producer = outputMap.get(input);\n if (producer && producer !== step.name) {\n stepDeps.add(producer);\n }\n }\n }\n\n deps.set(step.name, Array.from(stepDeps));\n }\n\n return deps;\n}\n","/**\n * Graph utilities for dependency resolution\n * @module @obora/core/graph\n */\n\nimport type { Step } from \"../types/workflow.js\";\n\n/**\n * Graph representation using adjacency list\n */\nexport interface Graph {\n /** Set of all node names */\n nodes: Set<string>;\n /** Edge map: node -> set of dependent nodes (forward direction) */\n edges: Map<string, Set<string>>;\n /** Reverse edge map: node -> set of nodes this node depends on */\n reverseEdges: Map<string, Set<string>>;\n}\n\n/**\n * Result of cycle detection\n */\nexport interface CycleResult {\n /** Whether a cycle exists */\n hasCycle: boolean;\n /** The path that forms the cycle (if any) */\n cyclePath?: string[];\n}\n\n/**\n * Result of topological sort\n */\nexport interface TopologicalResult {\n /** Whether sort was successful (no cycles) */\n success: boolean;\n /** Sorted node names in execution order */\n order: string[];\n /** Cycle path if cycle detected */\n cyclePath?: string[];\n}\n\n/**\n * Build a graph from steps\n */\nexport function buildGraph(steps: Step[]): Graph {\n const nodes = new Set<string>();\n const edges = new Map<string, Set<string>>();\n const reverseEdges = new Map<string, Set<string>>();\n\n // Initialize nodes\n for (const step of steps) {\n nodes.add(step.name);\n edges.set(step.name, new Set());\n reverseEdges.set(step.name, new Set());\n }\n\n // Add explicit dependencies\n for (const step of steps) {\n if (step.depends_on) {\n for (const dep of step.depends_on) {\n if (nodes.has(dep)) {\n edges.get(dep)!.add(step.name);\n reverseEdges.get(step.name)!.add(dep);\n }\n }\n }\n }\n\n // Add implicit dependencies from inputs/outputs\n const outputMap = new Map<string, string>();\n for (const step of steps) {\n if (step.outputs) {\n for (const output of step.outputs) {\n outputMap.set(output, step.name);\n }\n }\n }\n\n for (const step of steps) {\n if (step.inputs) {\n for (const input of step.inputs) {\n const producer = outputMap.get(input);\n if (producer && producer !== step.name) {\n edges.get(producer)!.add(step.name);\n reverseEdges.get(step.name)!.add(producer);\n }\n }\n }\n }\n\n return { nodes, edges, reverseEdges };\n}\n\n/**\n * Detect cycles using DFS\n */\nexport function detectCycles(graph: Graph): CycleResult {\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const parent = new Map<string, string>();\n\n function dfs(node: string, path: string[]): string[] | null {\n visited.add(node);\n recStack.add(node);\n\n const deps = graph.reverseEdges.get(node) || [];\n for (const dep of deps) {\n if (!visited.has(dep)) {\n parent.set(dep, node);\n const cycle = dfs(dep, [...path, dep]);\n if (cycle) return cycle;\n } else if (recStack.has(dep)) {\n // Found cycle - reconstruct path\n const cycleStart = path.indexOf(dep);\n const cyclePath = [...path.slice(cycleStart), node, dep];\n return cyclePath;\n }\n }\n\n recStack.delete(node);\n return null;\n }\n\n for (const node of graph.nodes) {\n if (!visited.has(node)) {\n const cycle = dfs(node, [node]);\n if (cycle) {\n return { hasCycle: true, cyclePath: cycle };\n }\n }\n }\n\n return { hasCycle: false };\n}\n\n/**\n * Topological sort using Kahn's Algorithm\n */\nexport function topologicalSort(graph: Graph): TopologicalResult {\n // First check for cycles\n const cycleCheck = detectCycles(graph);\n if (cycleCheck.hasCycle) {\n return {\n success: false,\n order: [],\n cyclePath: cycleCheck.cyclePath,\n };\n }\n\n // Kahn's Algorithm\n const indegree = new Map<string, number>();\n const order: string[] = [];\n\n // Initialize indegrees\n for (const node of graph.nodes) {\n indegree.set(node, 0);\n }\n\n // Calculate indegrees\n for (const node of graph.nodes) {\n const dependents = graph.edges.get(node) || [];\n for (const dependent of dependents) {\n indegree.set(dependent, (indegree.get(dependent) || 0) + 1);\n }\n }\n\n // Find nodes with indegree 0\n const queue: string[] = [];\n for (const [node, degree] of indegree) {\n if (degree === 0) {\n queue.push(node);\n }\n }\n\n // Process queue\n while (queue.length > 0) {\n // Sort queue for deterministic ordering\n queue.sort();\n const current = queue.shift()!;\n order.push(current);\n\n const dependents = graph.edges.get(current) || [];\n for (const dependent of dependents) {\n const newDegree = (indegree.get(dependent) || 1) - 1;\n indegree.set(dependent, newDegree);\n if (newDegree === 0) {\n queue.push(dependent);\n }\n }\n }\n\n return { success: true, order };\n}\n\n/**\n * Compute execution levels for each node\n * Level 0 = no dependencies, Level N = depends on nodes up to level N-1\n */\nexport function computeLevels(graph: Graph): Map<string, number> {\n const levels = new Map<string, number>();\n\n // Initialize all levels to 0\n for (const node of graph.nodes) {\n levels.set(node, 0);\n }\n\n // BFS to compute levels\n const sorted = topologicalSort(graph);\n if (!sorted.success) {\n return levels;\n }\n\n for (const node of sorted.order) {\n const deps = graph.reverseEdges.get(node) || [];\n let maxDepLevel = -1;\n\n for (const dep of deps) {\n const depLevel = levels.get(dep) || 0;\n if (depLevel > maxDepLevel) {\n maxDepLevel = depLevel;\n }\n }\n\n levels.set(node, maxDepLevel + 1);\n }\n\n return levels;\n}\n\n/**\n * Group nodes by execution level\n */\nexport function groupByLevel(steps: Step[]): Map<number, Step[]> {\n const graph = buildGraph(steps);\n const levels = computeLevels(graph);\n const groups = new Map<number, Step[]>();\n\n for (const step of steps) {\n const level = levels.get(step.name) || 0;\n if (!groups.has(level)) {\n groups.set(level, []);\n }\n groups.get(level)!.push(step);\n }\n\n return groups;\n}\n","/**\n * Workflow validator using JSON Schema and graph analysis\n * @module @obora/core/validator/workflow-validator\n */\n\nimport Ajv, { type ErrorObject } from \"ajv\";\nimport addFormats from \"ajv-formats\";\n\nimport { DependencyError, ParseError } from \"../errors/index.js\";\nimport { detectCycles } from \"../graph/index.js\";\nimport { parseWorkflow } from \"../parser/workflow-parser.js\";\nimport type { Step, Workflow } from \"../types/workflow.js\";\n\n/**\n * Error code enum for validation errors\n */\nexport enum ValidationErrorCode {\n INVALID_SCHEMA = \"INVALID_SCHEMA\",\n CIRCULAR_DEPENDENCY = \"CIRCULAR_DEPENDENCY\",\n MISSING_REFERENCE = \"MISSING_REFERENCE\",\n SELF_REFERENCE = \"SELF_REFERENCE\",\n INVALID_EXECUTION_LEVEL = \"INVALID_EXECUTION_LEVEL\",\n}\n\n/**\n * Validation error details\n */\nexport interface ValidationError {\n /** Error code */\n code: string;\n /** Human-readable error message */\n message: string;\n /** JSON path to the error location */\n path: string;\n /** Line number (if available) */\n line?: number;\n /** Column number (if available) */\n column?: number;\n /** Suggested fix */\n suggestion?: string;\n}\n\n/**\n * Validation result\n */\nexport interface ValidationResult {\n /** Whether validation passed */\n isValid: boolean;\n /** List of errors */\n errors: ValidationError[];\n /** List of warnings */\n warnings: ValidationError[];\n}\n\n/**\n * JSON Schema for workflow validation\n */\nconst workflowSchema = {\n type: \"object\",\n required: [\"name\", \"steps\"],\n properties: {\n name: { type: \"string\" },\n version: { type: \"string\" },\n description: { type: \"string\" },\n mode: { type: \"string\", enum: [\"auto\", \"supervised\", \"gated\", \"manual\"] },\n config: {\n type: \"object\",\n properties: {\n retry: { type: \"integer\", minimum: 0 },\n retry_delay: { type: \"string\", pattern: \"^[1-9]\\\\d*[smhd]$\" },\n continue_on_error: { type: \"boolean\" },\n max_parallel: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n steps: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"name\", \"agent\"],\n properties: {\n name: { type: \"string\" },\n agent: { type: \"string\" },\n description: { type: \"string\" },\n provider: { type: \"string\" },\n model: { type: \"string\" },\n depends_on: { type: \"array\", items: { type: \"string\" } },\n inputs: { type: \"array\", items: { type: \"string\" } },\n outputs: { type: \"array\", items: { type: \"string\" } },\n timeout: { type: \"string\", pattern: \"^[1-9]\\\\d*[smhd]$\" },\n skills: { type: \"array\", items: { type: \"string\" } },\n on_fail: {\n type: \"object\",\n required: [\"goto\", \"max_iterations\"],\n properties: {\n goto: { type: \"string\" },\n max_iterations: { type: \"integer\", minimum: 1 },\n escalate_on_exhaust: { type: \"string\", enum: [\"human\", \"dlq\", \"fail\"] },\n cooldown_ms: { type: \"integer\", minimum: 0, maximum: 300000 },\n reset_state: { type: \"boolean\" },\n max_cost: { anyOf: [{ type: \"number\", exclusiveMinimum: 0 }, { type: \"null\" }] },\n max_cost_escalation: { anyOf: [{ type: \"string\", enum: [\"human\", \"dlq\", \"fail\"] }, { type: \"null\" }] },\n },\n additionalProperties: false,\n },\n config: { type: \"object\" },\n },\n additionalProperties: false,\n },\n },\n },\n additionalProperties: false,\n} as const;\n\n// Initialize AJV validator\nconst ajv = new Ajv({ allErrors: true });\naddFormats(ajv);\nconst workflowValidate = ajv.compile(workflowSchema);\n\n/**\n * Convert JSON path to dot notation\n */\nfunction jsonPathToDotPath(path: string): string {\n return path.replace(/^\\//, \"\").replace(/\\//g, \".\").replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\n/**\n * Get line number from JSON path (simplified - requires source tracking for precise location)\n */\nfunction getLineNumberFromPath(_path: string): number | undefined {\n // For precise line numbers, we would need to track source positions during parsing\n // This is a placeholder for future enhancement\n return undefined;\n}\n\n/**\n * Validate workflow using JSON Schema\n */\nexport function validateSchema(workflow: unknown): ValidationError[] {\n const errors: ValidationError[] = [];\n\n const valid = workflowValidate(workflow);\n if (!valid && workflowValidate.errors) {\n for (const err of workflowValidate.errors) {\n errors.push({\n code: ValidationErrorCode.INVALID_SCHEMA,\n message: err.message || \"Invalid schema\",\n path: jsonPathToDotPath(err.instancePath || \"\"),\n line: getLineNumberFromPath(err.instancePath || \"\"),\n suggestion: getSuggestion(err),\n });\n }\n }\n\n return errors;\n}\n\n/**\n * Get suggestion for a validation error\n */\nfunction getSuggestion(err: ErrorObject): string | undefined {\n switch (err.keyword) {\n case \"required\":\n return `Add missing property: ${err.params.missingProperty}`;\n case \"type\":\n return `Expected type: ${err.params.type}`;\n case \"enum\":\n return `Must be one of: ${(err.params.allowedValues as string[]).join(\", \")}`;\n case \"pattern\":\n return \"Format must match the required pattern\";\n case \"additionalProperties\":\n return \"Remove unknown property or check spelling\";\n default:\n return undefined;\n }\n}\n\n/**\n * Check for circular dependencies using graph module\n */\nexport function validateCircularDependencies(steps: Step[]): ValidationError[] {\n const errors: ValidationError[] = [];\n\n // Build simple graph for cycle detection\n const graph = new Map<string, string[]>();\n for (const step of steps) {\n graph.set(step.name, step.depends_on || []);\n }\n\n // Use detectCycles from graph module\n const { hasCycle, cyclePath } = detectCycles({\n nodes: new Set(steps.map((s) => s.name)),\n edges: new Map(),\n reverseEdges: new Map(Array.from(graph.entries()).map(([node, deps]) => [node, new Set(deps)])),\n });\n\n if (hasCycle && cyclePath) {\n errors.push({\n code: ValidationErrorCode.CIRCULAR_DEPENDENCY,\n message: \"Circular dependency detected in workflow\",\n path: cyclePath.join(\" -> \"),\n suggestion: `Remove one of the dependencies in the cycle: ${cyclePath.join(\" → \")}`,\n });\n }\n\n return errors;\n}\n\n/**\n * Check for self-references\n */\nexport function validateSelfReferences(steps: Step[]): ValidationError[] {\n const errors: ValidationError[] = [];\n\n for (const step of steps) {\n if (step.depends_on?.includes(step.name)) {\n errors.push({\n code: ValidationErrorCode.SELF_REFERENCE,\n message: `Step '${step.name}' depends on itself`,\n path: `steps.${step.name}.depends_on`,\n suggestion: `Remove '${step.name}' from its own dependencies`,\n });\n }\n }\n\n return errors;\n}\n\n/**\n * Check for missing references\n */\nexport function validateMissingReferences(steps: Step[]): ValidationError[] {\n const errors: ValidationError[] = [];\n const stepNames = new Set(steps.map((s) => s.name));\n\n for (const step of steps) {\n if (step.depends_on) {\n for (const dep of step.depends_on) {\n if (!stepNames.has(dep)) {\n errors.push({\n code: ValidationErrorCode.MISSING_REFERENCE,\n message: `Step '${step.name}' depends on non-existent step '${dep}'`,\n path: `steps.${step.name}.depends_on`,\n suggestion: `Create step '${dep}' or remove the dependency`,\n });\n }\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Check for unresolved inputs\n */\nexport function validateInputs(steps: Step[]): ValidationError[] {\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n\n // Collect all outputs\n const availableOutputs = new Set<string>();\n for (const step of steps) {\n if (step.outputs) {\n for (const output of step.outputs) {\n availableOutputs.add(output);\n }\n }\n }\n\n // Spec files that don't need to be produced by a step\n const specFiles = [\"proposal.md\", \"design.md\", \"tasks.md\", \"status.yaml\"];\n\n // Check inputs\n for (const step of steps) {\n if (step.inputs) {\n for (const input of step.inputs) {\n const filename = input.split(\"/\").pop() || input;\n if (specFiles.includes(filename)) {\n continue;\n }\n\n if (!availableOutputs.has(input)) {\n warnings.push({\n code: \"UNRESOLVED_INPUT\",\n message: `Step '${step.name}' requires input '${input}' but no step produces it`,\n path: `steps.${step.name}.inputs`,\n suggestion: `Add a step that produces '${input}' or remove it from inputs`,\n });\n }\n }\n }\n }\n\n return [...errors, ...warnings];\n}\n\n/**\n * Full workflow validation\n */\nexport function validateWorkflow(workflow: Workflow): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n\n // Schema validation\n const schemaErrors = validateSchema(workflow);\n errors.push(...schemaErrors);\n\n // Skip further validation if schema is invalid\n if (schemaErrors.length > 0) {\n return { isValid: false, errors, warnings };\n }\n\n // Dependency validations\n errors.push(...validateSelfReferences(workflow.steps));\n errors.push(...validateMissingReferences(workflow.steps));\n errors.push(...validateCircularDependencies(workflow.steps));\n\n // Input validation (produces warnings)\n const inputValidation = validateInputs(workflow.steps);\n inputValidation.forEach((v) => {\n if (v.code === \"UNRESOLVED_INPUT\") {\n warnings.push(v);\n } else {\n errors.push(v);\n }\n });\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Parse and validate workflow from YAML string\n */\nexport function parseAndValidate(yamlContent: string): ValidationResult {\n try {\n const workflow = parseWorkflow(yamlContent);\n return validateWorkflow(workflow);\n } catch (error) {\n if (error instanceof ParseError || error instanceof DependencyError) {\n return {\n isValid: false,\n errors: [\n {\n code: error.code,\n message: error.message,\n path: \"\",\n suggestion: getParseErrorSuggestion(error.code),\n },\n ],\n warnings: [],\n };\n }\n throw error;\n }\n}\n\n/**\n * Get suggestion for parse errors\n */\nfunction getParseErrorSuggestion(code: string): string | undefined {\n switch (code) {\n case \"E2001\":\n return \"Check YAML syntax and structure\";\n case \"E2002\":\n return \"Add the missing required field\";\n case \"E2003\":\n return \"Check field type and format\";\n case \"E3001\":\n return \"Remove or restructure circular dependencies\";\n case \"E3002\":\n return \"Create the referenced step or remove the dependency\";\n case \"E3003\":\n return \"Remove self-reference from depends_on\";\n default:\n return undefined;\n }\n}\n","/**\n * Dependency resolver using Kahn's Algorithm\n * @module @obora/core/resolver/dependency-resolver\n */\n\nimport {\n type CycleResult,\n buildGraph,\n detectCycles,\n computeLevels,\n groupByLevel,\n topologicalSort as graphTopologicalSort,\n} from \"../graph/index.js\";\nimport type { Step, Workflow } from \"../types/workflow.js\";\n\n/**\n * Step group at a specific execution level\n */\nexport interface StepGroup {\n /** Execution level (0 = no dependencies, 1+ = depends on earlier levels) */\n level: number;\n /** Steps that can be executed in parallel at this level */\n steps: Step[];\n /** Whether steps in this group can be executed in parallel */\n parallelizable: boolean;\n}\n\n/**\n * Execution plan for a workflow\n */\nexport interface ExecutionPlan {\n /** Whether the plan is valid (no cycles) */\n isValid: boolean;\n /** Execution order of step names */\n executionOrder: string[];\n /** Cyclic dependency path (if any) */\n cyclicPath?: string[];\n /** Steps grouped by execution level */\n stepGroups: StepGroup[];\n /** Conditional back-edges (source -> target) */\n backEdges: Array<{ source: string; target: string }>;\n /** Non-fatal planning warnings */\n warnings: string[];\n}\n\n/**\n * Dependency graph representation\n */\nexport interface DependencyGraph {\n /** Map of step name to Step object */\n nodes: Map<string, Step>;\n /** Map of step name to list of dependency step names */\n edges: Map<string, string[]>;\n /** Conditional back-edges (source -> target) */\n backEdges: Map<string, string>;\n}\n\n/**\n * Build dependency graph from steps\n */\nexport function buildDependencyGraph(steps: Step[]): DependencyGraph {\n const graph = buildGraph(steps);\n const stepMap = new Map<string, Step>();\n\n for (const step of steps) {\n stepMap.set(step.name, step);\n }\n\n // Extract edges from graph\n const edges = new Map<string, string[]>();\n for (const [node, deps] of graph.reverseEdges) {\n edges.set(node, Array.from(deps));\n }\n\n const backEdges = new Map<string, string>();\n for (const step of steps) {\n if (step.on_fail?.goto) {\n backEdges.set(step.name, step.on_fail.goto);\n }\n }\n\n return {\n nodes: stepMap,\n edges,\n backEdges,\n };\n}\n\nfunction analyzeBackEdges(steps: Step[]): { backEdges: Array<{ source: string; target: string }>; warnings: string[] } {\n const backEdges = steps\n .filter((step) => typeof step.on_fail?.goto === \"string\")\n .map((step) => ({ source: step.name, target: step.on_fail!.goto }));\n\n const warnings: string[] = [];\n const byTarget = new Map<string, string[]>();\n for (const edge of backEdges) {\n const sources = byTarget.get(edge.target) ?? [];\n sources.push(edge.source);\n byTarget.set(edge.target, sources);\n }\n\n for (const [target, sources] of byTarget) {\n if (sources.length >= 2) {\n warnings.push(`Multiple back-edges point to '${target}': ${sources.join(\", \")}`);\n }\n }\n\n return { backEdges, warnings };\n}\n\n/**\n * Resolve execution order using topological sort (Kahn's Algorithm)\n */\nexport function resolveTopologicalOrder(steps: Step[]): string[] | null {\n const graph = buildGraph(steps);\n const result = graphTopologicalSort(graph);\n\n if (!result.success) {\n return null;\n }\n\n return result.order;\n}\n\n/**\n * Check for cycles using DFS\n */\nexport function detectCyclesDFS(steps: Step[]): CycleResult {\n const graph = buildGraph(steps);\n return detectCycles(graph);\n}\n\n/**\n * Calculate execution levels using BFS\n */\nexport function calculateExecutionLevels(steps: Step[]): Map<string, number> {\n const graph = buildGraph(steps);\n return computeLevels(graph);\n}\n\n/**\n * Group steps by execution level\n */\nexport function groupStepsByLevel(steps: Step[]): StepGroup[] {\n const groups = groupByLevel(steps);\n const result: StepGroup[] = [];\n\n const sortedLevels = Array.from(groups.keys()).sort((a, b) => a - b);\n\n for (const level of sortedLevels) {\n const stepsAtLevel = groups.get(level)!;\n result.push({\n level,\n steps: stepsAtLevel,\n parallelizable: stepsAtLevel.length > 1,\n });\n }\n\n return result;\n}\n\n/**\n * Generate full execution plan\n */\nexport function generateExecutionPlan(workflow: Workflow): ExecutionPlan {\n const backEdgeAnalysis = analyzeBackEdges(workflow.steps);\n\n // Check for cycles\n const cycleCheck = detectCyclesDFS(workflow.steps);\n\n if (cycleCheck.hasCycle) {\n return {\n isValid: false,\n executionOrder: [],\n cyclicPath: cycleCheck.cyclePath,\n stepGroups: [],\n backEdges: backEdgeAnalysis.backEdges,\n warnings: backEdgeAnalysis.warnings,\n };\n }\n\n // Get execution order\n const executionOrder = resolveTopologicalOrder(workflow.steps) || [];\n\n // Get step groups\n const stepGroups = groupStepsByLevel(workflow.steps);\n\n return {\n isValid: true,\n executionOrder,\n stepGroups,\n backEdges: backEdgeAnalysis.backEdges,\n warnings: backEdgeAnalysis.warnings,\n };\n}\n\n/**\n * Get next executable steps from current execution state\n */\nexport function getNextSteps(workflow: Workflow, completedSteps: Set<string>): Step[] {\n const graph = buildGraph(workflow.steps);\n const nextSteps: Step[] = [];\n\n for (const step of workflow.steps) {\n // Skip already completed steps\n if (completedSteps.has(step.name)) {\n continue;\n }\n\n // Get all dependencies\n const deps = graph.reverseEdges.get(step.name) || new Set();\n\n // Check if all dependencies are completed\n const allDepsCompleted = Array.from(deps).every((dep) => completedSteps.has(dep));\n\n if (allDepsCompleted) {\n nextSteps.push(step);\n }\n }\n\n return nextSteps;\n}\n\n/**\n * Validate execution order\n */\nexport function validateExecutionOrder(\n workflow: Workflow,\n order: string[]\n): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n const stepNames = new Set(workflow.steps.map((s) => s.name));\n\n // Check all steps are present\n for (const step of workflow.steps) {\n if (!order.includes(step.name)) {\n errors.push(`Step '${step.name}' is missing from execution order`);\n }\n }\n\n // Check order contains only valid steps\n for (const name of order) {\n if (!stepNames.has(name)) {\n errors.push(`Execution order contains unknown step '${name}'`);\n }\n }\n\n // Check dependencies come before dependents\n const completed = new Set<string>();\n const graph = buildGraph(workflow.steps);\n\n for (const name of order) {\n const deps = graph.reverseEdges.get(name) || new Set();\n for (const dep of deps) {\n if (!completed.has(dep)) {\n errors.push(`Step '${name}' comes before its dependency '${dep}'`);\n }\n }\n completed.add(name);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","/**\n * M6-02: CheckpointManager — Creates and restores checkpoints for run resume.\n *\n * Responsibilities:\n * - Save checkpoint after each step completion\n * - Load latest checkpoint for a run\n * - Detect policy drift\n * - Determine step restoration policy\n */\n\nimport { randomUUID } from \"node:crypto\";\n\nimport type { StorageAdapter, CheckpointRecord, StepRecord, ResumeOptions } from \"../storage/types.js\";\nimport { computePolicyHash, type PolicyHashInput } from \"./policy-hash.js\";\n\nexport interface CheckpointStepPolicy {\n stepName: string;\n action: \"restore\" | \"rerun\" | \"skip\";\n output?: Record<string, unknown>;\n}\n\nexport interface PolicyDriftResult {\n drifted: boolean;\n oldHash: string;\n newHash: string;\n}\n\nexport class PolicyDriftError extends Error {\n constructor(\n public readonly oldHash: string,\n public readonly newHash: string,\n ) {\n super(`Policy drift detected: checkpoint hash ${oldHash} != current hash ${newHash}`);\n this.name = \"PolicyDriftError\";\n }\n}\n\nexport class CheckpointManager {\n constructor(private readonly storage: StorageAdapter) {}\n\n async saveCheckpoint(\n runId: string,\n stepName: string,\n completedSteps: string[],\n stateSnapshot: unknown,\n policyConfig: PolicyHashInput,\n ): Promise<CheckpointRecord> {\n const record: CheckpointRecord = {\n id: randomUUID(),\n runId,\n stepName,\n stateSnapshot,\n completedSteps: [...completedSteps],\n policyHash: computePolicyHash(policyConfig),\n createdAt: new Date().toISOString(),\n };\n await this.storage.saveCheckpoint(record);\n return record;\n }\n\n async getLatestCheckpoint(runId: string): Promise<CheckpointRecord | null> {\n return this.storage.getLatestCheckpoint(runId);\n }\n\n detectDrift(checkpoint: CheckpointRecord, currentPolicyConfig: PolicyHashInput): PolicyDriftResult {\n const newHash = computePolicyHash(currentPolicyConfig);\n return {\n drifted: checkpoint.policyHash !== newHash,\n oldHash: checkpoint.policyHash,\n newHash,\n };\n }\n\n /**\n * Determine step restoration policy per the design spec:\n * - completed → restore (use cached output)\n * - failed → rerun\n * - running → rerun\n * - skipped → skip\n */\n resolveStepPolicies(\n steps: StepRecord[],\n completedSteps: string[],\n allStepNames: string[],\n options: ResumeOptions = {},\n ): CheckpointStepPolicy[] {\n const stepMap = new Map(steps.map((s) => [s.stepName, s]));\n const completedSet = new Set(completedSteps);\n\n // Validate fromStep if specified\n if (options.fromStep && !allStepNames.includes(options.fromStep)) {\n throw new Error(\n `Invalid fromStep: '${options.fromStep}' is not a valid step name. Available steps: ${allStepNames.join(\", \")}`,\n );\n }\n\n // If fromStep is specified, everything before it that was completed is restored\n const fromStepIdx = options.fromStep\n ? allStepNames.indexOf(options.fromStep)\n : -1;\n\n return allStepNames.map((stepName, idx) => {\n const step = stepMap.get(stepName);\n\n // If fromStep specified and this step is before it\n if (fromStepIdx >= 0 && idx < fromStepIdx && completedSet.has(stepName)) {\n return {\n stepName,\n action: \"restore\" as const,\n output: step?.output ?? undefined,\n };\n }\n\n // If fromStep specified and this step is at or after fromStep\n if (fromStepIdx >= 0 && idx >= fromStepIdx) {\n return { stepName, action: \"rerun\" as const };\n }\n\n // No fromStep: use step status-based policy\n if (!step) {\n return { stepName, action: \"rerun\" as const };\n }\n\n switch (step.status) {\n case \"completed\":\n return {\n stepName,\n action: \"restore\" as const,\n output: step.output ?? undefined,\n };\n case \"skipped\":\n return { stepName, action: \"skip\" as const };\n case \"failed\":\n case \"running\":\n default:\n return { stepName, action: \"rerun\" as const };\n }\n });\n }\n}\n","/**\n * M6-02: Policy hash computation for drift detection.\n *\n * Includes resources + policies config; excludes persistence/artifacts settings.\n * Uses deterministic JSON serialization (sorted keys) + SHA-256.\n */\n\nimport { createHash } from \"node:crypto\";\n\nexport interface PolicyHashInput {\n resources?: Record<string, unknown>;\n policies?: Record<string, unknown>;\n}\n\nfunction sortedStringify(value: unknown): string {\n if (value === null || value === undefined) return JSON.stringify(value);\n if (Array.isArray(value)) {\n return \"[\" + value.map(sortedStringify).join(\",\") + \"]\";\n }\n if (typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return \"{\" + keys.map((k) => JSON.stringify(k) + \":\" + sortedStringify(obj[k])).join(\",\") + \"}\";\n }\n return JSON.stringify(value);\n}\n\nexport function computePolicyHash(input: PolicyHashInput): string {\n const data = sortedStringify({\n resources: input.resources ?? {},\n policies: input.policies ?? {},\n });\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n","/**\n * StepExecutor — bridges workflow Step to BaseAgent.execute()\n */\n\nimport type { Step } from \"../../../_legacy/workflow/index.js\";\nimport {\n type AgentConfig,\n SkillLoader,\n SkillRegistry,\n} from \"@obora/adapters\";\nimport { OboraError, type ErrorCode } from \"../../../_legacy/workflow/index.js\";\nimport type {\n BaseAgent,\n Task,\n TaskResult,\n AgentContext,\n} from \"../../agents/roles/index.js\";\nimport type { StepErrorMetadata } from \"./types.js\";\nimport { parseDuration } from \"./utils.js\";\nimport { calculateDelay, waitWithAbort } from \"./retry-policy.js\";\n\nexport interface StepResult {\n success: boolean;\n output?: string;\n error?: string;\n diagnosisCode?: ErrorCode;\n errorMeta?: StepErrorMetadata;\n}\n\nexport interface AgentResolver {\n resolve(agentName: string): BaseAgent | Promise<BaseAgent>;\n resolve(query: { agent?: string; type?: string; config?: AgentConfig }): BaseAgent | Promise<BaseAgent>;\n}\n\nexport { parseDuration } from \"./utils.js\";\n\nexport function stepToTask(step: Step): Task {\n return {\n id: step.name,\n type: step.agent,\n description: step.description ?? step.name,\n input: step.config ?? {},\n priority: 1,\n metadata: {\n inputs: step.inputs,\n outputs: step.outputs,\n },\n };\n}\n\nfunction isRetryExhaustedError(error: unknown): error is { attempts?: number; originalError?: unknown; lastError?: unknown; getLastErrorCode?: () => string | undefined; getRootCause?: () => unknown } {\n return !!error && typeof error === \"object\" && ((error as { name?: string }).name === \"RetryExhaustedError\" || \"attempts\" in (error as object));\n}\n\nfunction formatOutput(result: TaskResult): string {\n if (typeof result.output === \"string\") return result.output;\n if (result.output == null) return \"\";\n return JSON.stringify(result.output, null, 2);\n}\n\nfunction buildStepErrorMetadata(error: Error, diagnosisCode: ErrorCode): StepErrorMetadata {\n const errorWithMeta = error as Error & {\n provider?: string;\n statusCode?: number;\n attempts?: number;\n };\n\n const retryLastError = (() => {\n if (!isRetryExhaustedError(error)) return undefined;\n\n const retryError = error as {\n getLastErrorCode?: () => string | undefined;\n getRootCause?: () => unknown;\n lastError?: { lastErrorCode?: string };\n };\n\n const lastErrorCode =\n retryError.getLastErrorCode?.() ?? retryError.lastError?.lastErrorCode;\n if (lastErrorCode?.startsWith(\"E4\")) {\n return lastErrorCode as ErrorCode;\n }\n\n const rootCause = retryError.getRootCause?.() ?? retryError.originalError ?? retryError.lastError;\n return mapErrorToDiagnosis(rootCause);\n })();\n\n return {\n code: diagnosisCode as StepErrorMetadata[\"code\"],\n message: error.message,\n provider: errorWithMeta.provider,\n statusCode: errorWithMeta.statusCode,\n attempts: isRetryExhaustedError(error) ? error.attempts : errorWithMeta.attempts,\n lastError: retryLastError,\n failedAt: new Date().toISOString(),\n };\n}\n\nfunction mapErrorToDiagnosis(error: unknown): ErrorCode {\n if (isRetryExhaustedError(error)) return \"E4005\";\n if (error instanceof DOMException && error.name === \"AbortError\") return \"E4002\";\n\n // Preserve agent-layer error codes (E4010, E4012, E4013)\n if (error instanceof OboraError && error.code) {\n return error.code;\n }\n\n // Aggregate provider-internal rate-limit code to retry-exhausted diagnosis\n if (error instanceof Error && \"code\" in error) {\n const code = (error as Error & { code?: unknown }).code;\n if (code === \"E4011\") {\n return \"E4005\";\n }\n }\n\n // Preserve typed E4xxx codes on generic Error objects\n if (error instanceof Error && \"code\" in error) {\n const code = (error as Error & { code?: unknown }).code;\n if (typeof code === \"string\" && code.startsWith(\"E4\")) {\n return code as ErrorCode;\n }\n }\n\n // Preserve typed E4xxx codes on plain objects (e.g. RetryErrorMetadata)\n if (error && typeof error === \"object\" && \"code\" in error) {\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"string\" && code.startsWith(\"E4\")) {\n return code as ErrorCode;\n }\n }\n\n return \"E4001\";\n}\n\nconst DEFAULT_TIMEOUT_MS = 600_000;\n\nexport interface ExecuteStepOptions {\n timeoutMs?: number;\n signal?: AbortSignal;\n retryAttempts?: number;\n resolvedAgentConfig?: AgentConfig;\n onEvent?: (event: unknown) => void;\n}\n\nasync function executeOnce(\n step: Step,\n agent: BaseAgent,\n context: AgentContext,\n timeoutMs: number,\n externalSignal?: AbortSignal,\n onEvent?: (event: unknown) => void,\n): Promise<StepResult> {\n const timeoutCtrl = new AbortController();\n\n if (externalSignal?.aborted) {\n return {\n success: false,\n error: \"Execution cancelled before start\",\n diagnosisCode: \"E4006\",\n };\n }\n\n const timeoutId = setTimeout(() => timeoutCtrl.abort(\"timeout\"), timeoutMs);\n const signal = externalSignal\n ? AbortSignal.any([externalSignal, timeoutCtrl.signal])\n : timeoutCtrl.signal;\n\n if (signal.aborted) {\n return {\n success: false,\n error: \"Execution cancelled before start\",\n diagnosisCode: \"E4006\",\n };\n }\n\n let abortHandler: (() => void) | undefined;\n\n let unsubscribe: (() => void) | undefined;\n\n try {\n const subscribable = agent as BaseAgent & { subscribe?: (listener: (event: unknown) => void) => () => void };\n if (typeof subscribable.subscribe === \"function\") {\n unsubscribe = subscribable.subscribe((event) => {\n onEvent?.(event);\n });\n }\n\n const result = await Promise.race([\n agent.execute(taskToRun(step), {\n ...context,\n signal,\n } as AgentContext),\n new Promise<never>((_resolve, reject) => {\n abortHandler = () => reject(new DOMException(\"Aborted\", \"AbortError\"));\n signal.addEventListener(\"abort\", abortHandler, { once: true });\n }),\n ]);\n\n if (!result.success) {\n let diagnosisCode: ErrorCode;\n if (externalSignal?.aborted) {\n diagnosisCode = \"E4006\";\n } else if (timeoutCtrl.signal.aborted) {\n diagnosisCode = \"E4002\";\n } else {\n diagnosisCode = result.error ? mapErrorToDiagnosis(result.error) : \"E4001\";\n }\n\n return {\n success: false,\n output: formatOutput(result),\n error: result.error?.message,\n diagnosisCode,\n ...(result.error\n ? { errorMeta: buildStepErrorMetadata(result.error, diagnosisCode) }\n : {}),\n };\n }\n\n return { success: true, output: formatOutput(result) };\n } catch (e: unknown) {\n if (e instanceof DOMException && e.name === \"AbortError\") {\n if (timeoutCtrl.signal.aborted) {\n return {\n success: false,\n error: \"Timeout exceeded\",\n diagnosisCode: \"E4002\",\n };\n }\n return {\n success: false,\n error: \"Execution cancelled\",\n diagnosisCode: \"E4006\",\n };\n }\n\n const diagnosisCode = mapErrorToDiagnosis(e);\n return {\n success: false,\n error: e instanceof Error ? e.message : String(e),\n diagnosisCode,\n ...(e instanceof Error ? { errorMeta: buildStepErrorMetadata(e, diagnosisCode) } : {}),\n };\n } finally {\n if (abortHandler) {\n signal.removeEventListener(\"abort\", abortHandler);\n }\n unsubscribe?.();\n clearTimeout(timeoutId);\n }\n}\n\nfunction taskToRun(step: Step): Task {\n return stepToTask(step);\n}\n\nexport async function executeStep(\n step: Step,\n resolver: AgentResolver,\n context: AgentContext,\n options?: ExecuteStepOptions,\n): Promise<StepResult> {\n let agent: BaseAgent;\n try {\n agent = await resolver.resolve({\n agent: step.agent,\n type: step.agent,\n config: options?.resolvedAgentConfig,\n });\n } catch {\n return {\n success: false,\n error: `Agent resolution failed for '${step.agent}'`,\n diagnosisCode: \"E4003\",\n };\n }\n\n let loadedSkills: Awaited<ReturnType<SkillLoader[\"loadSkills\"]>> | undefined;\n const skillLoader = new SkillLoader(new SkillRegistry({ cwd: process.cwd() }));\n\n if (step.skills && step.skills.length > 0) {\n loadedSkills = await skillLoader.loadSkills(step.skills, {\n cwd: process.cwd(),\n agentId: agent.id,\n stepName: step.name,\n });\n\n const configurable = agent as BaseAgent & {\n configureRuntimeExtensions?: (input: { tools?: unknown[]; systemPromptAppend?: string }) => void;\n };\n\n configurable.configureRuntimeExtensions?.({\n tools: loadedSkills.tools,\n systemPromptAppend: loadedSkills.systemPrompt,\n });\n }\n\n let timeoutMs: number;\n if (options?.timeoutMs != null) {\n timeoutMs = options.timeoutMs;\n } else if (step.timeout) {\n try {\n timeoutMs = parseDuration(step.timeout);\n } catch {\n timeoutMs = DEFAULT_TIMEOUT_MS;\n }\n } else {\n timeoutMs = DEFAULT_TIMEOUT_MS;\n }\n\n try {\n const maxAttempts = Math.max(1, (options?.retryAttempts ?? 0) + 1);\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const result = await executeOnce(step, agent, context, timeoutMs, options?.signal, options?.onEvent);\n if (result.success) return result;\n\n const retryable = result.diagnosisCode === \"E4001\";\n if (!retryable || attempt >= maxAttempts) {\n return result;\n }\n\n const continuable = agent as BaseAgent & { continue?: () => Promise<void> };\n if (typeof continuable.continue === \"function\") {\n try {\n await continuable.continue();\n } catch {\n // continue() best-effort, fallback to delay retry\n }\n }\n\n const delay = calculateDelay(attempt - 1, {\n baseDelayMs: 1000,\n maxDelayMs: 30_000,\n });\n\n try {\n await waitWithAbort(delay, options?.signal);\n } catch (e) {\n if (e instanceof DOMException && e.name === \"AbortError\") {\n return {\n success: false,\n error: \"Execution cancelled\",\n diagnosisCode: \"E4006\",\n };\n }\n throw e;\n }\n }\n\n return {\n success: false,\n error: \"Unknown execution failure\",\n diagnosisCode: \"E4001\",\n };\n } finally {\n if (loadedSkills) {\n await skillLoader.teardown(loadedSkills.loaded);\n }\n const configurable = agent as BaseAgent & { clearRuntimeExtensions?: () => void };\n configurable.clearRuntimeExtensions?.();\n }\n}\n","export interface RetryPolicy {\n baseDelayMs: number;\n maxDelayMs: number;\n backoffMultiplier?: number;\n jitterRatio?: number;\n}\n\nconst DEFAULT_BACKOFF_MULTIPLIER = 2;\nconst DEFAULT_JITTER_RATIO = 0.2;\n\nexport function calculateDelay(attempt: number, policy: RetryPolicy): number {\n const multiplier = policy.backoffMultiplier ?? DEFAULT_BACKOFF_MULTIPLIER;\n const jitterRatio = policy.jitterRatio ?? DEFAULT_JITTER_RATIO;\n\n const exponential = policy.baseDelayMs * Math.pow(multiplier, Math.max(0, attempt));\n const capped = Math.min(exponential, policy.maxDelayMs);\n const jitter = capped * jitterRatio * (Math.random() * 2 - 1);\n\n return Math.max(0, Math.min(policy.maxDelayMs, Math.round(capped + jitter)));\n}\n\nexport async function waitWithAbort(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n signal?.removeEventListener(\"abort\", onAbort);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n\n const timeoutId = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n","/**\n * ContextBuilder — assembles AgentContext with a shared Blackboard\n * for workflow execution.\n *\n * Responsibilities:\n * - Create one Blackboard per workflow run (single session scope)\n * - Build AgentContext for each step with board, task, history\n * - Record step results/errors on the board for inter-step state sharing\n * - Maintain single-writer: only this module writes step results to board\n *\n * @module @obora/cli/runtime/context-builder\n */\n\nimport type { ChatMessage } from \"@obora/adapters\";\nimport type { AgentContext, Task } from \"../../agents/roles/index.js\";\nimport { Blackboard } from \"./blackboard.js\";\nimport type { Step, Workflow } from \"../../../_legacy/workflow/index.js\";\nimport type { StepResult } from \"./step-executor.js\";\nimport { stepToTask } from \"./step-executor.js\";\nimport type { StepErrorMetadata } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Metadata stored in blackboard state.context.workflow for replay/trace */\nexport interface WorkflowMeta {\n workflowName: string;\n workflowVersion: string;\n featureName: string;\n startedAt: string;\n sessionId: string;\n}\n\n/** Result record stored on blackboard for each step */\nexport interface StepResultRecord {\n success: boolean;\n output: string | null;\n error: string | null;\n errorMeta?: StepErrorMetadata | null;\n diagnosisCode: string | null;\n completedAt: string | null;\n failedAt: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Clock abstraction (injectable for testing)\n// ---------------------------------------------------------------------------\n\n/** Returns an ISO-8601 timestamp string. Injectable for deterministic tests. */\nexport type Clock = () => string;\n\nconst defaultClock: Clock = () => new Date().toISOString();\n\n/** Module-level clock; override via `setClock()` for testing. */\nlet activeClock: Clock = defaultClock;\nlet warnedDeprecatedDirectWrite = false;\n\n/** Override the clock used by record* functions. Pass `null` to reset. */\nexport function setClock(clock: Clock | null): void {\n activeClock = clock ?? defaultClock;\n}\n\n// ---------------------------------------------------------------------------\n// Blackboard factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a Blackboard instance scoped to a single workflow run.\n *\n * Initialises `state.context.workflow` with replay-friendly metadata and\n * `state.steps` as an empty container for per-step results.\n */\nexport function createWorkflowBlackboard(\n sessionId: string,\n workflow: Workflow,\n featureName: string,\n): Blackboard {\n const meta: WorkflowMeta = {\n workflowName: workflow.name,\n workflowVersion: workflow.version ?? \"1.0\",\n featureName,\n startedAt: activeClock(),\n sessionId,\n };\n\n const board = new Blackboard({\n state: {\n context: {\n workflow: meta as unknown as Record<string, unknown>,\n steps: {},\n },\n },\n });\n\n // Compatibility shim for agents expecting board.write().\n // Deprecated no-op to avoid crashing legacy agents while preserving\n // runtime single-writer policy via recordStepResult/recordStepError.\n Object.defineProperty(board as unknown as { write?: (path: string, value: unknown) => void }, \"write\", {\n value: (path: string, _value: unknown) => {\n if (!warnedDeprecatedDirectWrite && process.env.NODE_ENV !== \"test\") {\n warnedDeprecatedDirectWrite = true;\n console.warn(\n `[Blackboard] Deprecated: direct write(\"${path}\") is a no-op. Use recordStepResult/recordStepError.`,\n );\n }\n // no-op: single-writer policy — mutation only via recordStepResult/recordStepError\n },\n configurable: false,\n enumerable: false,\n writable: false,\n });\n\n return board;\n}\n\n// ---------------------------------------------------------------------------\n// Context assembly\n// ---------------------------------------------------------------------------\n\n/**\n * Build an AgentContext for a single step execution.\n *\n * @param sessionId - Workflow run session ID\n * @param board - Shared Blackboard instance (workflow-scoped)\n * @param step - Current workflow step\n * @param history - Accumulated LLM chat history from prior steps\n */\nexport function buildAgentContext(\n sessionId: string,\n board: Blackboard | AgentContext[\"board\"],\n step: Step,\n history: ChatMessage[] = [],\n): AgentContext {\n const task = stepToTask(step);\n\n return {\n sessionId,\n board: board as unknown as AgentContext[\"board\"],\n currentTask: task,\n history,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Step result recording (single-writer on board)\n// ---------------------------------------------------------------------------\n\n/**\n * Record a successful step result on the blackboard.\n * Path: `state.context.steps.<stepName>`\n */\nexport function recordStepResult(\n board: Blackboard | AgentContext[\"board\"],\n stepName: string,\n result: StepResult,\n): void {\n const record: StepResultRecord = {\n success: result.success,\n output: result.output ?? null,\n error: null,\n errorMeta: null,\n diagnosisCode: null,\n completedAt: activeClock(),\n failedAt: null,\n };\n (board as Blackboard).recordStepResult(stepName, record);\n}\n\n/**\n * Record a failed step result on the blackboard.\n * Path: `state.context.steps.<stepName>`\n */\nexport function recordStepError(\n board: Blackboard | AgentContext[\"board\"],\n stepName: string,\n result: StepResult,\n): void {\n const record: StepResultRecord = {\n success: false,\n output: null,\n error: result.error ?? \"Unknown error\",\n errorMeta: result.errorMeta ?? null,\n diagnosisCode: result.diagnosisCode ?? null,\n completedAt: null,\n failedAt: activeClock(),\n };\n (board as Blackboard).recordStepError(stepName, {\n message: record.error ?? \"Unknown error\",\n code: record.diagnosisCode as StepErrorMetadata[\"code\"] | undefined,\n failedAt: record.failedAt ?? undefined,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Inter-step state query\n// ---------------------------------------------------------------------------\n\n/**\n * Read a previous step's result from the blackboard.\n * Returns null if the step has not been recorded yet.\n *\n * Uses a single `board.read({ strict: false })` call for atomicity\n * and efficiency (one traversal instead of exists + read).\n */\nexport function readStepResult(\n board: Blackboard | AgentContext[\"board\"],\n stepName: string,\n): StepResultRecord | null {\n const value = board.read<StepResultRecord | undefined>(\n `state.context.steps.${stepName}`,\n { strict: false },\n );\n return value ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// History management\n// ---------------------------------------------------------------------------\n\n/**\n * Maximum number of chat messages retained in the rolling history window.\n * Prevents unbounded memory growth in long workflows while keeping enough\n * context for downstream steps.\n */\nexport const MAX_HISTORY_LENGTH = 200;\n\n/**\n * Append a message to the chat history, trimming the oldest entries when\n * the history exceeds `MAX_HISTORY_LENGTH`.\n *\n * **Note:** Mutates the input array in-place for performance. Callers\n * sharing the array reference should be aware of this contract.\n */\nexport function appendHistory(\n history: ChatMessage[],\n message: ChatMessage,\n): void {\n history.push(message);\n if (history.length > MAX_HISTORY_LENGTH) {\n // Remove oldest entries to stay within budget\n const excess = history.length - MAX_HISTORY_LENGTH;\n history.splice(0, excess);\n }\n}\n","import { OboraErrorCode } from \"../errors/OboraErrorCode.js\";\n\nexport { OboraErrorCode };\n\n/**\n * Core domain patterns. \"composite\" is a meta-pattern registered separately\n * because it orchestrates other patterns rather than implementing domain logic.\n */\nexport const BUILTIN_PATTERN_KINDS = [\n \"pipeline\",\n \"discussion\",\n \"consensus\",\n \"brainstorming\",\n \"peer-review\",\n \"red-blue\",\n \"fan-out-fan-in\",\n \"supervisor\",\n] as const;\n\nexport type BuiltinPatternKind = (typeof BUILTIN_PATTERN_KINDS)[number];\n\nexport type PatternFailureCategory = \"failure\" | \"timeout\" | \"escalation\";\n\nexport interface PatternRuntimeHooks {\n onStart?(context: PatternRuntimeContext): Promise<void> | void;\n onEvent?(event: PatternRuntimeEvent, context: PatternRuntimeContext): Promise<void> | void;\n onComplete?(result: PatternRuntimeResult, context: PatternRuntimeContext): Promise<void> | void;\n onError?(error: unknown, context: PatternRuntimeContext): Promise<void> | void;\n}\n\nexport type PatternExecutionFn = (context: PatternRuntimeContext) => Promise<PatternRuntimeResult>;\n\n/**\n * External runtime contract used by orchestrator/executors.\n * `run` is the stable entrypoint for runtime integration.\n */\nexport interface PatternRuntimeContract {\n readonly name: string;\n readonly kind: BuiltinPatternKind | (string & {});\n readonly version?: string;\n\n validateConfig?(config: PatternConfig): void;\n run: PatternExecutionFn;\n}\n\nexport interface PatternRuntimeEvent {\n type: string;\n payload?: unknown;\n timestamp?: string;\n}\n\nexport interface PatternPayloadContext {\n steps?: Array<(input: unknown) => unknown | Promise<unknown>>;\n input?: unknown;\n [key: string]: unknown;\n}\n\nexport interface PatternRuntimeContext extends PatternPayloadContext {\n executionId?: string;\n stepName?: string;\n pattern: string;\n participants?: Record<string, string>;\n config?: PatternConfig;\n emit?: (event: PatternRuntimeEvent) => Promise<void> | void;\n hooks?: PatternRuntimeHooks;\n}\n\nexport interface PatternPayloadResult {\n success: boolean;\n output: unknown;\n metadata?: Record<string, unknown>;\n}\n\nexport interface PatternRuntimeResult extends PatternPayloadResult {\n pattern: string;\n}\n\n/**\n * SCHEMAS SSOT naming uses PatternContext/PatternResult.\n * Keep these aliases bound to runtime I/O types.\n */\nexport type PatternContext = PatternRuntimeContext;\nexport type PatternResult = PatternRuntimeResult;\n\nexport type CustomConvergenceFn = (context: {\n round: number;\n opinions: Record<string, string>;\n participants: string[];\n}) => boolean;\n\nexport type VoterRole = \"ai\" | \"human\" | \"service\";\n\nexport interface VoterRoleConfig {\n /** Role of this voter. Default: \"ai\". */\n role: VoterRole;\n /** Voter ids assigned this role. */\n voters: string[];\n}\n\nexport type EscalationTrigger = \"timeout\" | \"quorum_not_met\";\n\nexport interface EscalationConfig {\n /** Which failure conditions trigger escalation instead of plain failure/throw. */\n triggers: EscalationTrigger[];\n /** Opaque target identifier for the escalation handler. */\n target?: string;\n}\n\nexport type CustomEvaluator = (context: {\n votes: Array<{ voterId: string; approved: boolean; score?: number; reason?: string; role?: VoterRole }>;\n participants: string[];\n requiredParticipants: string[];\n config: ConsensusPatternConfig;\n}) =>\n | boolean\n | {\n approved: boolean;\n reason?: string;\n score?: number;\n };\n\nexport interface DiscussionPatternConfig {\n max_rounds?: number;\n convergence?: \"no_disagreements\" | \"majority\" | \"unanimous\" | \"custom\";\n on_deadlock?: \"escalate\" | \"retry\" | \"fail\";\n /** Number of extra retry rounds when on_deadlock='retry'. Default 1. Must be >= 1. */\n retry_budget?: number;\n custom_convergence?: CustomConvergenceFn;\n}\n\nexport interface ConsensusPatternConfig {\n rule?: \"majority\" | \"unanimous\" | \"weighted\" | \"score-threshold\" | \"custom\";\n weights?: Record<string, number>;\n threshold?: number;\n timeout?: string;\n best_effort?: string[];\n custom_evaluate?: CustomEvaluator;\n /** Voter role assignments. Voters not listed default to \"ai\". */\n voter_roles?: VoterRoleConfig[];\n /** Escalation integration point for timeout/quorum failures. */\n escalation?: EscalationConfig;\n}\n\nexport interface BrainstormingPatternConfig {\n phase_1?: \"generate\";\n phase_2?: \"evaluate\";\n top_n?: number;\n dedup?: \"semantic\" | \"exact\";\n}\n\nexport interface PeerReviewPatternConfig {\n min_score?: number;\n p0_allowed?: number;\n max_rounds?: number;\n best_effort?: string[];\n}\n\nexport type RedBlueEscalationTrigger = \"max_rounds_exhausted\";\n\nexport interface RedBlueEscalationConfig {\n /** Which failure conditions trigger escalation instead of plain failure. */\n triggers: RedBlueEscalationTrigger[];\n /** Opaque target identifier for the escalation handler. */\n target?: string;\n}\n\nexport interface RedBluePatternConfig {\n red_team?: string[];\n blue_team?: string[];\n max_rounds?: number;\n convergence?: \"red_finds_nothing\" | \"max_rounds\" | \"custom\";\n /** Required when convergence='custom'. */\n custom_convergence?: (payload: {\n round: number;\n rounds: Array<{ round: number; red_findings: Record<string, unknown>; blue_responses: Record<string, unknown> }>;\n current_round: { round: number; red_findings: Record<string, unknown>; blue_responses: Record<string, unknown> };\n subject: unknown;\n red_team: string[];\n blue_team: string[];\n }) => boolean;\n /** Escalation integration point for failure paths. */\n escalation?: RedBlueEscalationConfig;\n}\n\nexport interface PipelinePatternConfig {\n stages?: string[];\n}\n\n/**\n * failure_policy controls how partial participant failures are handled:\n * - \"best_effort\" (default): succeed if at least 1 participant succeeds.\n * - \"required\": succeed only if >= min_success participants succeed.\n * When min_success is omitted under \"required\", ALL participants must succeed.\n *\n * min_success: minimum number of successful participants for \"required\" mode.\n * Must be >= 1 and <= participant count. Ignored under \"best_effort\".\n */\nexport interface FanOutFanInPatternConfig {\n merge?: \"concatenate\" | \"rank\" | \"vote\" | \"custom\";\n failure_policy?: \"best_effort\" | \"required\";\n /** Minimum successful participants for \"required\" mode. Defaults to total participant count. */\n min_success?: number;\n}\nexport interface SupervisorPatternConfig {\n strategy?: \"one_for_one\" | \"one_for_all\";\n max_restarts?: number;\n backoff?: \"linear\" | \"exponential\";\n}\n\nexport interface CompositeStage {\n name: string;\n pattern: string;\n config?: Record<string, unknown>;\n participants?: Record<string, string>;\n input_from?: \"previous\" | \"root\" | string;\n}\n\nexport interface CompositePatternConfig {\n stages: CompositeStage[];\n on_stage_failure?: \"fail\" | \"skip\" | \"escalate\";\n}\n\nexport interface CustomPatternDefinition {\n name: string;\n version?: string;\n kind?: string;\n description?: string;\n execute: (context: PatternRuntimeContext) => Promise<PatternPayloadResult>;\n validateConfig?: (config: PatternConfig) => void;\n}\n\nexport interface CustomPatternConfig {\n [key: string]: unknown;\n}\n\nexport type PatternConfig =\n | DiscussionPatternConfig\n | ConsensusPatternConfig\n | BrainstormingPatternConfig\n | PeerReviewPatternConfig\n | RedBluePatternConfig\n | PipelinePatternConfig\n | FanOutFanInPatternConfig\n | SupervisorPatternConfig\n | CompositePatternConfig\n | CustomPatternConfig;\n\nexport type PatternConfigByKind = {\n discussion: DiscussionPatternConfig;\n consensus: ConsensusPatternConfig;\n brainstorming: BrainstormingPatternConfig;\n \"peer-review\": PeerReviewPatternConfig;\n \"red-blue\": RedBluePatternConfig;\n pipeline: PipelinePatternConfig;\n \"fan-out-fan-in\": FanOutFanInPatternConfig;\n supervisor: SupervisorPatternConfig;\n composite: CompositePatternConfig;\n};\n\nexport type PatternYamlStep<K extends keyof PatternConfigByKind = keyof PatternConfigByKind> = {\n pattern: K;\n config?: PatternConfigByKind[K];\n};\n\nexport type BlackboardDomain =\n | \"agenda\"\n | \"meeting-state-machine\"\n | \"message-bus\"\n | \"consensus-rule-engine\"\n | \"voting-session-store\"\n | \"knowledge\"\n | \"decision\"\n | \"state\"\n | \"actor-pool\"\n | \"supervisor\"\n | \"supervisor-tree\";\n\nexport type PatternBlackboardDomainMapping = Record<keyof PatternConfigByKind, readonly BlackboardDomain[]>;\n\nexport const PATTERN_BLACKBOARD_DOMAIN_MAP: PatternBlackboardDomainMapping = {\n discussion: [\"agenda\", \"meeting-state-machine\", \"message-bus\"],\n consensus: [\"consensus-rule-engine\", \"voting-session-store\"],\n brainstorming: [\"knowledge\"],\n \"peer-review\": [\"decision\", \"consensus-rule-engine\"],\n \"red-blue\": [\"meeting-state-machine\", \"knowledge\"],\n pipeline: [\"state\"],\n \"fan-out-fan-in\": [\"actor-pool\", \"knowledge\"],\n supervisor: [\"supervisor\", \"supervisor-tree\"],\n composite: [\"state\", \"knowledge\"],\n};\n\nexport const PATTERN_ERROR_CODE_MAP: Record<keyof PatternConfigByKind, Record<PatternFailureCategory, OboraErrorCode>> = {\n discussion: {\n failure: OboraErrorCode.CONSENSUS_FAIL,\n timeout: OboraErrorCode.CONSENSUS_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n consensus: {\n failure: OboraErrorCode.CONSENSUS_FAIL,\n timeout: OboraErrorCode.CONSENSUS_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n brainstorming: {\n failure: OboraErrorCode.ORCH_DEPENDENCY_FAILED,\n timeout: OboraErrorCode.ORCH_EXECUTION_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n \"peer-review\": {\n failure: OboraErrorCode.CONSENSUS_FAIL,\n timeout: OboraErrorCode.CONSENSUS_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n \"red-blue\": {\n failure: OboraErrorCode.ORCH_DEPENDENCY_FAILED,\n timeout: OboraErrorCode.ORCH_EXECUTION_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n pipeline: {\n failure: OboraErrorCode.ORCH_DEPENDENCY_FAILED,\n timeout: OboraErrorCode.ORCH_EXECUTION_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n \"fan-out-fan-in\": {\n failure: OboraErrorCode.ORCH_DEPENDENCY_FAILED,\n timeout: OboraErrorCode.ORCH_EXECUTION_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n supervisor: {\n failure: OboraErrorCode.RECOVERY_RETRY_EXHAUSTED,\n timeout: OboraErrorCode.CELL_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n composite: {\n failure: OboraErrorCode.ORCH_DEPENDENCY_FAILED,\n timeout: OboraErrorCode.ORCH_EXECUTION_TIMEOUT,\n escalation: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n },\n};\n\nexport function isBuiltinPatternKind(value: string): value is BuiltinPatternKind {\n return (BUILTIN_PATTERN_KINDS as readonly string[]).includes(value);\n}\n\n/**\n * Internal pattern implementation contract.\n * - `run`: external runtime entrypoint (called by orchestrator/executors)\n * - `execute`: internal compatibility entrypoint (delegates to `run`)\n * External callers should always use `run`.\n */\nexport interface CollaborationPattern extends PatternRuntimeContract {\n execute: PatternExecutionFn;\n}\n\nexport abstract class CollaborationPatternBase implements CollaborationPattern {\n abstract readonly name: string;\n abstract readonly kind: BuiltinPatternKind | (string & {});\n readonly version = \"1.0.0\";\n\n validateConfig(_config: PatternConfig): void {\n // optional override\n }\n\n /**\n * Internal compatibility entrypoint; delegates to `run`.\n */\n async execute(context: PatternRuntimeContext): Promise<PatternRuntimeResult> {\n return this.run(context);\n }\n\n /**\n * External runtime entrypoint used by orchestrator.\n * Error channel contract:\n * - throw: unrecoverable external constraint violations (timeout/policy/etc), handled by upper recovery.\n * - return { success: false }: expected business-level failure (e.g., quorum not met / rejected).\n */\n async run(context: PatternRuntimeContext): Promise<PatternRuntimeResult> {\n await context.hooks?.onStart?.(context);\n\n try {\n this.validateConfig(context.config ?? {});\n const result = await this.onExecute(context);\n const normalized: PatternRuntimeResult = {\n ...result,\n pattern: context.pattern,\n };\n await context.hooks?.onComplete?.(normalized, context);\n return normalized;\n } catch (error) {\n await context.hooks?.onError?.(error, context);\n throw error;\n }\n }\n\n protected abstract onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult>;\n}\n","import type { PluginRegistry } from \"../plugins/PluginRegistry.js\";\nimport type { PatternPlugin } from \"../plugins/types.js\";\nimport type { CollaborationPattern } from \"./types.js\";\n\n/**\n * PatternRegistry is a convenience facade over the pattern bucket in PluginRegistry.\n *\n * - Runtime implementations may register plain CollaborationPattern instances here.\n * - If a PluginRegistry facade is provided, lookup/list operations are type-linked to\n * `type = \"pattern\"` plugin entries.\n */\nexport class PatternRegistry {\n private readonly patterns = new Map<string, CollaborationPattern>();\n\n constructor(\n private readonly pluginFacade?: Pick<PluginRegistry, \"get\" | \"has\" | \"list\">\n ) {}\n\n register(pattern: CollaborationPattern): void {\n if (!pattern.name || pattern.name.trim().length === 0) {\n throw new Error(\"Pattern name is required\");\n }\n\n this.patterns.set(pattern.name, pattern);\n }\n\n unregister(name: string): void {\n this.patterns.delete(name);\n }\n\n get(name: string): CollaborationPattern {\n if (this.patterns.has(name)) {\n return this.patterns.get(name)!;\n }\n\n if (this.pluginFacade?.has(\"pattern\", name)) {\n return this.pluginFacade.get<PatternPlugin>(\"pattern\", name);\n }\n\n throw new Error(`Pattern '${name}' was not found`);\n }\n\n has(name: string): boolean {\n return this.patterns.has(name) || (this.pluginFacade?.has(\"pattern\", name) ?? false);\n }\n\n list(): CollaborationPattern[] {\n if (!this.pluginFacade) {\n return [...this.patterns.values()];\n }\n\n const pluginPatterns = this.pluginFacade.list(\"pattern\") as PatternPlugin[];\n const merged = new Map<string, CollaborationPattern>(pluginPatterns.map((pattern) => [pattern.name, pattern]));\n\n for (const [name, pattern] of this.patterns.entries()) {\n merged.set(name, pattern);\n }\n\n return [...merged.values()];\n }\n}\n","import type { PatternRegistry } from \"./PatternRegistry.js\";\nimport {\n CollaborationPatternBase,\n type CollaborationPattern,\n type CustomPatternDefinition,\n type PatternConfig,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n} from \"./types.js\";\n\nexport type { CustomPatternDefinition } from \"./types.js\";\n\nexport interface RegisterCustomPatternOptions {\n replace?: boolean;\n logger?: Pick<Console, \"warn\">;\n}\n\nclass ConfigBackedCustomPattern extends CollaborationPatternBase {\n readonly name: string;\n readonly kind: string;\n readonly version: string;\n readonly description?: string;\n\n constructor(private readonly definition: CustomPatternDefinition) {\n super();\n this.name = definition.name;\n this.kind = definition.kind ?? definition.name;\n this.version = definition.version ?? \"1.0.0\";\n this.description = definition.description;\n }\n\n validateConfig(config: PatternConfig): void {\n this.definition.validateConfig?.(config);\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n return this.definition.execute(context);\n }\n}\n\nexport function registerCustomPattern(\n registry: PatternRegistry,\n pattern: CollaborationPattern,\n options: RegisterCustomPatternOptions = {}\n): void {\n validatePatternContract(pattern);\n\n const existing = registry.has(pattern.name) ? registry.get(pattern.name) : undefined;\n\n if (existing && !options.replace) {\n throw new Error(`Custom pattern '${pattern.name}' is already registered`);\n }\n\n if (existing && options.replace) {\n if ((existing.version ?? \"1.0.0\") === (pattern.version ?? \"1.0.0\")) {\n (options.logger ?? console).warn(\n `Custom pattern '${pattern.name}' is being replaced with the same version '${pattern.version ?? \"1.0.0\"}'`\n );\n }\n registry.unregister(pattern.name);\n }\n\n registry.register(pattern);\n}\n\nexport function registerCustomPatternFromConfig(\n registry: PatternRegistry,\n config: CustomPatternDefinition,\n options: RegisterCustomPatternOptions = {}\n): void {\n validateCustomPatternDefinition(config);\n registerCustomPattern(registry, new ConfigBackedCustomPattern(config), options);\n}\n\nexport function validatePatternContract(pattern: CollaborationPattern): void {\n if (!pattern || typeof pattern !== \"object\") {\n throw new Error(\"Custom pattern must be an object\");\n }\n\n if (typeof pattern.name !== \"string\" || pattern.name.trim().length === 0) {\n throw new Error(\"Custom pattern name is required\");\n }\n\n if (typeof pattern.kind !== \"string\" || pattern.kind.trim().length === 0) {\n throw new Error(\"Custom pattern kind is required\");\n }\n\n if (typeof pattern.run !== \"function\") {\n throw new Error(\"Custom pattern must implement run(context)\");\n }\n\n if (typeof pattern.execute !== \"function\") {\n throw new Error(\"Custom pattern must implement execute(context)\");\n }\n}\n\nfunction validateCustomPatternDefinition(config: CustomPatternDefinition): void {\n if (!config || typeof config !== \"object\") {\n throw new Error(\"Custom pattern definition must be an object\");\n }\n\n if (typeof config.name !== \"string\" || config.name.trim().length === 0) {\n throw new Error(\"Custom pattern definition name is required\");\n }\n\n if (typeof config.execute !== \"function\") {\n throw new Error(\"Custom pattern definition execute(context) is required\");\n }\n\n if (config.validateConfig !== undefined && typeof config.validateConfig !== \"function\") {\n throw new Error(\"Custom pattern definition validateConfig must be a function\");\n }\n}\n","import * as nodePath from \"node:path\";\nimport { readFileSync } from \"node:fs\";\nimport { parse as parseYaml } from \"yaml\";\nimport { OboraErrorCode } from \"../errors/OboraErrorCode.js\";\nimport { validatePatternContract } from \"./CustomPatternAPI.js\";\nimport type { PatternRegistry } from \"./PatternRegistry.js\";\nimport type { CollaborationPattern } from \"./types.js\";\n\nexport interface ResolveCustomPatternOptions {\n cwd?: string;\n loadFromFile?: (filePath: string, options?: { cwd?: string }) => CollaborationPattern | Promise<CollaborationPattern>;\n}\n\n/**\n * Normalize and resolve a file path, handling relative paths via cwd.\n * Uses node:path for cross-platform correctness.\n */\nfunction resolveFilePath(filePath: string, cwd?: string): string {\n const normalized = nodePath.normalize(filePath);\n if (nodePath.isAbsolute(normalized)) {\n return normalized;\n }\n const base = cwd ?? process.cwd();\n return nodePath.resolve(base, normalized);\n}\n\n/**\n * Check if a file path looks like a YAML file reference.\n */\nfunction isYamlPath(filePath: string): boolean {\n const ext = nodePath.extname(filePath).toLowerCase();\n return ext === \".yaml\" || ext === \".yml\";\n}\n\nexport function resolveCustomPattern(\n registry: PatternRegistry,\n patternRef: string,\n options: ResolveCustomPatternOptions = {}\n): CollaborationPattern {\n if (typeof patternRef !== \"string\" || patternRef.trim().length === 0) {\n throw createStepNotFoundError(patternRef, \"Pattern name is required\");\n }\n\n if (registry.has(patternRef)) {\n return registry.get(patternRef);\n }\n\n if (looksLikeFilePath(patternRef)) {\n const resolvedPath = resolveFilePath(patternRef, options.cwd);\n\n // YAML file refs use built-in YAML loader by default\n if (isYamlPath(resolvedPath) && !options.loadFromFile) {\n const pattern = loadPatternFromYamlFile(resolvedPath);\n validateResolvedPattern(pattern, patternRef);\n return pattern;\n }\n\n const loader = options.loadFromFile ?? loadCustomPatternFromFile;\n const result = loader(resolvedPath, { cwd: options.cwd });\n if (result && typeof (result as Promise<CollaborationPattern>).then === \"function\") {\n throw new Error(\n `Custom pattern file loader returned a Promise. Use resolveCustomPatternAsync() for async loading, or provide a synchronous loader.`\n );\n }\n validateResolvedPattern(result as CollaborationPattern, patternRef);\n return result as CollaborationPattern;\n }\n\n throw createStepNotFoundError(\n patternRef,\n `Custom pattern '${patternRef}' is not registered. Register it via registerCustomPattern() before workflow execution.`\n );\n}\n\nexport async function resolveCustomPatternAsync(\n registry: PatternRegistry,\n patternRef: string,\n options: ResolveCustomPatternOptions = {}\n): Promise<CollaborationPattern> {\n if (typeof patternRef !== \"string\" || patternRef.trim().length === 0) {\n throw createStepNotFoundError(patternRef, \"Pattern name is required\");\n }\n\n if (registry.has(patternRef)) {\n return registry.get(patternRef);\n }\n\n if (looksLikeFilePath(patternRef)) {\n const resolvedPath = resolveFilePath(patternRef, options.cwd);\n\n // YAML file refs use built-in YAML loader by default\n if (isYamlPath(resolvedPath) && !options.loadFromFile) {\n const pattern = loadPatternFromYamlFile(resolvedPath);\n validateResolvedPattern(pattern, patternRef);\n return pattern;\n }\n\n const loader = options.loadFromFile ?? loadCustomPatternFromFile;\n const result = await loader(resolvedPath, { cwd: options.cwd });\n validateResolvedPattern(result, patternRef);\n return result;\n }\n\n throw createStepNotFoundError(\n patternRef,\n `Custom pattern '${patternRef}' is not registered. Register it via registerCustomPattern() before workflow execution.`\n );\n}\n\n/**\n * Load a CollaborationPattern from a YAML file.\n * Reads the file synchronously, parses YAML, and returns the parsed object.\n */\nexport function loadPatternFromYamlFile(resolvedPath: string): CollaborationPattern {\n try {\n const content = readFileSync(resolvedPath, \"utf-8\");\n const parsed = parseYaml(content);\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(`YAML file did not produce a valid object`);\n }\n return parsed as CollaborationPattern;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `Failed to load custom pattern from YAML '${resolvedPath}': ${message}`\n );\n }\n}\n\n/**\n * Validate that a resolved pattern meets the contract requirements.\n * Reuses the same validation logic as registerCustomPattern.\n */\nfunction validateResolvedPattern(pattern: CollaborationPattern, patternRef: string): void {\n try {\n validatePatternContract(pattern);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw createStepNotFoundError(\n patternRef,\n `Pattern loaded from '${patternRef}' failed contract validation: ${message}`\n );\n }\n}\n\n/**\n * Default file-path based pattern loading for JS/TS modules.\n * Path is already resolved by the caller.\n */\nexport function loadCustomPatternFromFile(filePath: string, options?: { cwd?: string }): CollaborationPattern {\n const resolvedPath = filePath;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const mod = require(resolvedPath);\n return extractPatternFromModule(mod, resolvedPath);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"ERR_REQUIRE_ESM\") || message.includes(\"Must use import\")) {\n throw new Error(\n `Cannot synchronously load ESM pattern file '${resolvedPath}'. ` +\n `Use resolveCustomPatternAsync() or provide a synchronous loadFromFile option.`\n );\n }\n throw new Error(\n `Failed to load custom pattern from '${resolvedPath}': ${message}`\n );\n }\n}\n\nfunction extractPatternFromModule(mod: Record<string, unknown>, filePath: string): CollaborationPattern {\n const candidate = mod.default ?? mod.pattern;\n if (!candidate) {\n throw new Error(\n `Pattern file '${filePath}' must export a default or named 'pattern' export implementing CollaborationPattern.`\n );\n }\n return candidate as CollaborationPattern;\n}\n\nfunction looksLikeFilePath(value: string): boolean {\n return (\n value.includes(\"/\") ||\n value.includes(\"\\\\\") ||\n value.endsWith(\".js\") ||\n value.endsWith(\".ts\") ||\n value.endsWith(\".mjs\") ||\n value.endsWith(\".yaml\") ||\n value.endsWith(\".yml\")\n );\n}\n\nfunction createStepNotFoundError(patternRef: string, detail: string): Error & { code: OboraErrorCode } {\n const error = new Error(`[${OboraErrorCode.ORCH_STEP_NOT_FOUND}] ${detail} (pattern: '${patternRef}')`) as Error & {\n code: OboraErrorCode;\n };\n error.code = OboraErrorCode.ORCH_STEP_NOT_FOUND;\n return error;\n}\n","import { CollaborationPatternBase, type BuiltinPatternKind, type PatternPayloadResult, type PatternRuntimeContext } from \"../types.js\";\n\nexport class PipelinePattern extends CollaborationPatternBase {\n readonly name = \"pipeline\";\n readonly kind: BuiltinPatternKind = \"pipeline\";\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const steps = context.steps ?? [];\n let current = context.input;\n\n for (const step of steps) {\n current = await step(current);\n }\n\n return {\n success: true,\n output: current,\n metadata: { steps: steps.length },\n };\n }\n}\n","import type { AgendaId } from '../../types';\n\nexport type AgendaStatus = 'draft' | 'pending' | 'active' | 'completed' | 'cancelled';\n\nexport interface Agenda {\n readonly id: AgendaId;\n readonly title: string;\n readonly description?: string;\n readonly priority: number;\n readonly dueAt?: Date;\n readonly status: AgendaStatus;\n readonly createdAt: Date;\n readonly updatedAt: Date;\n}\n\nexport interface CreateAgendaInput {\n id: AgendaId;\n title: string;\n description?: string;\n priority?: number;\n dueAt?: Date;\n}\n\nexport interface UpdateAgendaInput {\n title?: string;\n description?: string | null;\n priority?: number;\n dueAt?: Date | null;\n}\n\nexport const AGENDA_STATUS_TRANSITIONS: Record<AgendaStatus, AgendaStatus[]> = {\n draft: ['pending', 'cancelled'],\n pending: ['active', 'cancelled'],\n active: ['completed', 'cancelled'],\n completed: [],\n cancelled: [],\n};\n","import type { AgentId } from '../../types';\nimport type {\n AgendaCreatedDomainEvent,\n AgendaUpdatedDomainEvent,\n AgendaStatusChangedDomainEvent,\n AgendaDeletedDomainEvent,\n} from '../../events/types';\n\nexport type AgendaCreatedEvent = AgendaCreatedDomainEvent;\nexport type AgendaUpdatedEvent = AgendaUpdatedDomainEvent;\nexport type AgendaStatusChangedEvent = AgendaStatusChangedDomainEvent;\nexport type AgendaDeletedEvent = AgendaDeletedDomainEvent;\n\nexport type AgendaDomainEvent =\n | AgendaCreatedEvent\n | AgendaUpdatedEvent\n | AgendaStatusChangedEvent\n | AgendaDeletedEvent;\n\nconst createImmutableEventDate = (date = new Date()): Date => {\n // Capture epoch once; all reads derive from this frozen value.\n const epoch = Date.prototype.getTime.call(date);\n const source = new Date(epoch);\n\n const mutators = new Set<PropertyKey>([\n 'setTime',\n 'setMilliseconds',\n 'setUTCMilliseconds',\n 'setSeconds',\n 'setUTCSeconds',\n 'setMinutes',\n 'setUTCMinutes',\n 'setHours',\n 'setUTCHours',\n 'setDate',\n 'setUTCDate',\n 'setMonth',\n 'setUTCMonth',\n 'setFullYear',\n 'setUTCFullYear',\n 'setYear',\n ]);\n\n // Use a plain-object target so Date.prototype.set*.call(proxy, ...)\n // throws TypeError (\"called on incompatible receiver\") even if the\n // caller bypasses the Proxy get-trap via .call/.apply on the prototype.\n const shell: Record<PropertyKey, unknown> = {};\n\n const immutableDate = new Proxy(shell, {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n get(_target, prop, _receiver) {\n if (mutators.has(prop)) {\n return () => {\n throw new TypeError('Agenda event date is immutable');\n };\n }\n if (prop === Symbol.toPrimitive) {\n return (hint: string) => (hint === 'number' ? epoch : source.toString());\n }\n const value = (source as unknown as Record<PropertyKey, unknown>)[prop];\n if (typeof value === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n return (value as Function).bind(source);\n }\n return value;\n },\n getPrototypeOf() {\n return Date.prototype;\n },\n set() {\n throw new TypeError('Agenda event date is immutable');\n },\n defineProperty() {\n throw new TypeError('Agenda event date is immutable');\n },\n deleteProperty() {\n throw new TypeError('Agenda event date is immutable');\n },\n setPrototypeOf() {\n throw new TypeError('Agenda event date is immutable');\n },\n });\n\n return Object.freeze(immutableDate) as unknown as Date;\n};\n\nexport const createAgendaEventMeta = (source: AgentId | 'system' = 'system') => ({\n id: `evt-agenda-${crypto.randomUUID()}`,\n timestamp: createImmutableEventDate(),\n source,\n});\n","import type { EventBus } from '../../events';\nimport type { AgentId, AgendaId } from '../../types';\nimport {\n AGENDA_STATUS_TRANSITIONS,\n type Agenda,\n type AgendaStatus,\n type CreateAgendaInput,\n type UpdateAgendaInput,\n} from './types';\nimport { createAgendaEventMeta, type AgendaDomainEvent } from './events';\n\nexport class AgendaValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'AgendaValidationError';\n }\n}\n\nexport class AgendaNotFoundError extends Error {\n constructor(id: AgendaId) {\n super(`Agenda not found: ${id}`);\n this.name = 'AgendaNotFoundError';\n }\n}\n\nexport class AgendaTransitionError extends Error {\n constructor(from: AgendaStatus, to: AgendaStatus) {\n super(`Invalid agenda status transition: ${from} -> ${to}`);\n this.name = 'AgendaTransitionError';\n }\n}\n\nexport interface AgendaStoreOptions {\n eventBus?: EventBus;\n}\n\nexport class AgendaStore {\n private readonly agendas = new Map<AgendaId, Agenda>();\n\n constructor(private readonly options: AgendaStoreOptions = {}) {}\n\n private cloneAgenda(agenda: Agenda): Agenda {\n return {\n ...agenda,\n dueAt: agenda.dueAt ? new Date(agenda.dueAt.getTime()) : undefined,\n createdAt: new Date(agenda.createdAt.getTime()),\n updatedAt: new Date(agenda.updatedAt.getTime()),\n };\n }\n\n private toImmutableEventDate(date: Date): Date {\n const immutable = new Date(date.getTime());\n const mutators = [\n 'setTime',\n 'setMilliseconds',\n 'setUTCMilliseconds',\n 'setSeconds',\n 'setUTCSeconds',\n 'setMinutes',\n 'setUTCMinutes',\n 'setHours',\n 'setUTCHours',\n 'setDate',\n 'setUTCDate',\n 'setMonth',\n 'setUTCMonth',\n 'setFullYear',\n 'setUTCFullYear',\n 'setYear',\n ] as const;\n\n for (const method of mutators) {\n Object.defineProperty(immutable, method, {\n value: () => {\n throw new TypeError('Agenda event date is immutable');\n },\n writable: false,\n configurable: false,\n });\n }\n\n return Object.freeze(immutable);\n }\n\n private cloneAgendaForEvent(agenda: Agenda): Agenda {\n return {\n ...agenda,\n dueAt: agenda.dueAt ? this.toImmutableEventDate(agenda.dueAt) : undefined,\n createdAt: this.toImmutableEventDate(agenda.createdAt),\n updatedAt: this.toImmutableEventDate(agenda.updatedAt),\n };\n }\n\n private getExisting(id: AgendaId): Agenda {\n const agenda = this.agendas.get(id);\n if (!agenda) {\n throw new AgendaNotFoundError(id);\n }\n return agenda;\n }\n\n private deepFreeze<T>(value: T): T {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n const target = value as Record<string, unknown>;\n for (const nested of Object.values(target)) {\n this.deepFreeze(nested);\n }\n\n return Object.freeze(value);\n }\n\n create(input: CreateAgendaInput, source: AgentId | 'system' = 'system'): Agenda {\n this.validateCreateInput(input);\n if (this.agendas.has(input.id)) {\n throw new AgendaValidationError(`Agenda already exists: ${input.id}`);\n }\n\n const now = new Date();\n const agenda: Agenda = {\n id: input.id,\n title: input.title.trim(),\n description: input.description?.trim(),\n priority: input.priority ?? 3,\n dueAt: input.dueAt ? new Date(input.dueAt.getTime()) : undefined,\n status: 'draft',\n createdAt: now,\n updatedAt: now,\n };\n\n this.agendas.set(agenda.id, this.cloneAgenda(agenda));\n this.emit({\n ...createAgendaEventMeta(source),\n type: 'agenda.created',\n payload: { agenda: this.cloneAgendaForEvent(agenda) },\n });\n return this.cloneAgenda(agenda);\n }\n\n getById(id: AgendaId): Agenda {\n return this.cloneAgenda(this.getExisting(id));\n }\n\n list(): Agenda[] {\n return [...this.agendas.values()]\n .map((agenda) => this.cloneAgenda(agenda))\n .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());\n }\n\n update(id: AgendaId, patch: UpdateAgendaInput, source: AgentId | 'system' = 'system'): Agenda {\n const previous = this.getExisting(id);\n this.validatePatchInput(patch);\n\n const nextDescription =\n patch.description === undefined\n ? previous.description\n : patch.description === null\n ? undefined\n : patch.description.trim();\n\n const nextDueAt =\n patch.dueAt === undefined\n ? previous.dueAt\n : patch.dueAt === null\n ? undefined\n : new Date(patch.dueAt.getTime());\n\n const current: Agenda = {\n ...previous,\n title: patch.title?.trim() ?? previous.title,\n description: nextDescription,\n priority: patch.priority ?? previous.priority,\n dueAt: nextDueAt,\n updatedAt: new Date(),\n };\n\n this.agendas.set(id, this.cloneAgenda(current));\n this.emit({\n ...createAgendaEventMeta(source),\n type: 'agenda.updated',\n payload: {\n agendaId: previous.id,\n previous: this.cloneAgendaForEvent(previous),\n current: this.cloneAgendaForEvent(current),\n },\n });\n\n return this.cloneAgenda(current);\n }\n\n transition(id: AgendaId, nextStatus: AgendaStatus, source: AgentId | 'system' = 'system'): Agenda {\n const agenda = this.getExisting(id);\n const allowed = AGENDA_STATUS_TRANSITIONS[agenda.status];\n if (!allowed.includes(nextStatus)) {\n throw new AgendaTransitionError(agenda.status, nextStatus);\n }\n\n const updated: Agenda = {\n ...agenda,\n status: nextStatus,\n updatedAt: new Date(),\n };\n\n this.agendas.set(id, this.cloneAgenda(updated));\n this.emit({\n ...createAgendaEventMeta(source),\n type: 'agenda.status.changed',\n payload: {\n agendaId: id,\n previousStatus: agenda.status,\n newStatus: nextStatus,\n },\n });\n\n return this.cloneAgenda(updated);\n }\n\n delete(id: AgendaId, source: AgentId | 'system' = 'system'): Agenda {\n const existing = this.getExisting(id);\n this.agendas.delete(id);\n this.emit({\n ...createAgendaEventMeta(source),\n type: 'agenda.deleted',\n payload: {\n agendaId: id,\n deleted: this.cloneAgendaForEvent(existing),\n },\n });\n\n return this.cloneAgenda(existing);\n }\n\n private emit(event: AgendaDomainEvent): void {\n this.options.eventBus?.emit(this.deepFreeze(event));\n }\n\n private validateCreateInput(input: CreateAgendaInput): void {\n if (!input.id) {\n throw new AgendaValidationError('Agenda id is required');\n }\n if (!input.title?.trim()) {\n throw new AgendaValidationError('Agenda title is required');\n }\n if (input.description !== undefined && !input.description.trim()) {\n throw new AgendaValidationError('Agenda description cannot be empty string');\n }\n if (input.priority !== undefined && (input.priority < 1 || input.priority > 5)) {\n throw new AgendaValidationError('Agenda priority must be between 1 and 5');\n }\n if (input.dueAt && Number.isNaN(input.dueAt.getTime())) {\n throw new AgendaValidationError('Agenda dueAt must be a valid Date');\n }\n }\n\n private validatePatchInput(patch: UpdateAgendaInput): void {\n if (patch.title !== undefined && !patch.title.trim()) {\n throw new AgendaValidationError('Agenda title cannot be empty');\n }\n if (patch.priority !== undefined && (patch.priority < 1 || patch.priority > 5)) {\n throw new AgendaValidationError('Agenda priority must be between 1 and 5');\n }\n if (patch.description !== undefined && patch.description !== null && !patch.description.trim()) {\n throw new AgendaValidationError('Agenda description cannot be empty string');\n }\n if (patch.dueAt && Number.isNaN(patch.dueAt.getTime())) {\n throw new AgendaValidationError('Agenda dueAt must be a valid Date');\n }\n }\n}\n","import type { ConsensusResult } from '../../domains/consensus';\nimport type { Event } from '../../events';\nimport { EventBus } from '../../events';\nimport type {\n MeetingEvent,\n MeetingState,\n MeetingStateMachineOptions,\n MeetingStateSnapshot,\n TransitionLog,\n} from './types';\n\nconst DEFAULT_DISCUSSION_TIMEOUT_MS = 10 * 60 * 1000;\nconst DEFAULT_VOTING_TIMEOUT_MS = 5 * 60 * 1000;\n\nexport class MeetingStateMachine {\n private state: MeetingState = 'idle';\n private enteredAt = new Date();\n private lastEventAt = new Date();\n private logs: TransitionLog[] = [];\n private readonly discussionTimeoutMs: number;\n private readonly votingTimeoutMs: number;\n\n constructor(\n private readonly eventBus = new EventBus(),\n options: MeetingStateMachineOptions = {},\n ) {\n this.discussionTimeoutMs = options.discussionTimeoutMs ?? DEFAULT_DISCUSSION_TIMEOUT_MS;\n this.votingTimeoutMs = options.votingTimeoutMs ?? DEFAULT_VOTING_TIMEOUT_MS;\n }\n\n getState(): MeetingState {\n return this.state;\n }\n\n getLogs(): readonly TransitionLog[] {\n return this.logs;\n }\n\n apply(event: MeetingEvent): MeetingState {\n const next = this.resolveNextState(this.state, event);\n const ts = event.timestamp ?? new Date();\n\n this.lastEventAt = ts;\n\n if (next !== this.state) {\n const previous = this.state;\n this.state = next;\n this.enteredAt = ts;\n this.logs.push({\n from: previous,\n to: next,\n eventType: event.type,\n timestamp: ts,\n reason: event.payload?.reason,\n });\n\n this.emitTransitionEvent(previous, next, event);\n }\n\n return this.state;\n }\n\n tick(now = new Date()): MeetingState {\n const elapsed = now.getTime() - this.enteredAt.getTime();\n\n if (this.state === 'discussion' && elapsed >= this.discussionTimeoutMs) {\n return this.apply({\n type: 'workflow.timeout',\n timestamp: now,\n payload: { reason: 'discussion timeout' },\n });\n }\n\n if (this.state === 'voting' && elapsed >= this.votingTimeoutMs) {\n return this.apply({\n type: 'workflow.timeout',\n timestamp: now,\n payload: { reason: 'voting timeout' },\n });\n }\n\n return this.state;\n }\n\n toSnapshot(): MeetingStateSnapshot {\n return {\n state: this.state,\n enteredAt: this.enteredAt,\n lastEventAt: this.lastEventAt,\n logs: [...this.logs],\n };\n }\n\n static fromSnapshot(snapshot: MeetingStateSnapshot, eventBus = new EventBus()): MeetingStateMachine {\n const machine = new MeetingStateMachine(eventBus);\n machine.state = snapshot.state;\n machine.enteredAt = snapshot.enteredAt;\n machine.lastEventAt = snapshot.lastEventAt;\n machine.logs = [...snapshot.logs];\n return machine;\n }\n\n private resolveNextState(current: MeetingState, event: MeetingEvent): MeetingState {\n if (event.type === 'workflow.cancelled') {\n return 'resolved';\n }\n\n if (event.type === 'workflow.timeout') {\n if (current === 'discussion' || current === 'voting' || current === 'debate') {\n return 'resolving';\n }\n return current;\n }\n\n if (event.type === 'workflow.quorum.lost') {\n return current === 'voting' ? 'debate' : current;\n }\n\n switch (current) {\n case 'idle':\n return event.type === 'agenda.created' ? 'agenda_setting' : current;\n case 'agenda_setting':\n return event.type === 'agenda.status.changed' && event.payload?.status === 'IN_PROGRESS'\n ? 'discussion'\n : current;\n case 'discussion':\n return event.type === 'decisions.voting.started' ? 'voting' : current;\n case 'debate':\n return event.type === 'decisions.voting.started' ? 'voting' : current;\n case 'voting':\n return event.type === 'decisions.voting.ended' ? 'resolving' : current;\n case 'resolving':\n return event.type === 'workflow.consensus.computed' ? 'resolved' : current;\n case 'resolved':\n default:\n return current;\n }\n }\n\n private emitTransitionEvent(from: MeetingState, to: MeetingState, event: MeetingEvent): void {\n this.eventBus.emit({\n id: `evt-workflow-${crypto.randomUUID()}`,\n type: 'state.phase.changed',\n source: 'system',\n timestamp: event.timestamp ?? new Date(),\n payload: {\n previousPhase: from,\n newPhase: to,\n eventType: event.type,\n },\n } as unknown as Event);\n }\n\n static consensusEvent(consensus: ConsensusResult, timestamp = new Date()): MeetingEvent {\n return {\n type: 'workflow.consensus.computed',\n timestamp,\n payload: {\n consensus,\n reason: consensus.status,\n },\n };\n }\n}\n","import type { ConsensusResult } from '../../domains/consensus';\n\nexport const MEETING_STATES = [\n 'idle',\n 'agenda_setting',\n 'discussion',\n 'debate',\n 'voting',\n 'resolving',\n 'resolved',\n] as const;\n\nexport type MeetingState = (typeof MEETING_STATES)[number];\n\nexport type MeetingEventType =\n | 'agenda.created'\n | 'agenda.status.changed'\n | 'decisions.voting.started'\n | 'decisions.voting.ended'\n | 'workflow.consensus.computed'\n | 'workflow.timeout'\n | 'workflow.quorum.lost'\n | 'workflow.cancelled';\n\nexport interface MeetingEvent {\n readonly type: MeetingEventType;\n readonly timestamp?: Date;\n readonly payload?: {\n readonly status?: string;\n readonly consensus?: ConsensusResult;\n readonly reason?: string;\n };\n}\n\nexport interface TransitionLog {\n readonly from: MeetingState;\n readonly to: MeetingState;\n readonly eventType: MeetingEventType;\n readonly timestamp: Date;\n readonly reason?: string;\n}\n\nexport interface MeetingStateSnapshot {\n readonly state: MeetingState;\n readonly enteredAt: Date;\n readonly lastEventAt: Date;\n readonly logs: readonly TransitionLog[];\n}\n\nexport interface MeetingStateMachineOptions {\n readonly discussionTimeoutMs?: number;\n readonly votingTimeoutMs?: number;\n}\n","import { AgendaStore } from \"../../consensus/agenda/index.js\";\nimport { EventBus } from \"../../_legacy/blackboard/events/index.js\";\nimport { MeetingStateMachine } from \"./discussion/index.js\";\nimport {\n CollaborationPatternBase,\n type BuiltinPatternKind,\n type DiscussionPatternConfig,\n PATTERN_BLACKBOARD_DOMAIN_MAP,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n} from \"../types.js\";\n\ntype DiscussionOpinion = string;\n\ntype RoundOpinions = Record<string, DiscussionOpinion>;\n\ninterface DiscussionInputShape {\n topic?: string;\n opinions?: Record<string, unknown>;\n rounds?: Array<Record<string, unknown>>;\n}\n\ninterface ConvergenceEvaluation {\n converged: boolean;\n decision?: DiscussionOpinion;\n disagreements: number;\n}\n\ninterface CustomConvergenceContext {\n round: number;\n opinions: RoundOpinions;\n participants: string[];\n}\n\ntype CustomConvergenceFn = (context: CustomConvergenceContext) => boolean;\n\nconst DEFAULT_MAX_ROUNDS = 3;\nconst DEFAULT_CONVERGENCE: Required<DiscussionPatternConfig>[\"convergence\"] = \"no_disagreements\";\nconst DEFAULT_DEADLOCK: Required<DiscussionPatternConfig>[\"on_deadlock\"] = \"fail\";\n\nexport class DiscussionPattern extends CollaborationPatternBase {\n readonly name = \"discussion\";\n readonly kind: BuiltinPatternKind = \"discussion\";\n\n validateConfig(config: DiscussionPatternConfig): void {\n if (config.max_rounds !== undefined) {\n if (!Number.isInteger(config.max_rounds) || config.max_rounds < 1) {\n throw new Error(\"discussion.max_rounds must be an integer >= 1\");\n }\n }\n\n if (config.convergence !== undefined) {\n const allowed = new Set([\"no_disagreements\", \"majority\", \"unanimous\", \"custom\"]);\n if (!allowed.has(config.convergence)) {\n throw new Error(\"discussion.convergence must be one of: no_disagreements, majority, unanimous, custom\");\n }\n }\n\n if (config.on_deadlock !== undefined) {\n const allowed = new Set([\"escalate\", \"retry\", \"fail\"]);\n if (!allowed.has(config.on_deadlock)) {\n throw new Error(\"discussion.on_deadlock must be one of: escalate, retry, fail\");\n }\n }\n\n if (config.retry_budget !== undefined) {\n if (!Number.isInteger(config.retry_budget) || config.retry_budget < 1) {\n throw new Error(\"discussion.retry_budget must be an integer >= 1\");\n }\n if (config.on_deadlock !== \"retry\") {\n throw new Error(\"discussion.retry_budget is only valid when on_deadlock=\\\"retry\\\"\");\n }\n }\n\n if (config.convergence === \"custom\") {\n if (config.custom_convergence === undefined) {\n throw new Error(\"discussion.convergence='custom' requires custom_convergence function\");\n }\n if (typeof config.custom_convergence !== \"function\") {\n throw new Error(\"discussion.custom_convergence must be a function\");\n }\n }\n }\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const participants = Object.keys(context.participants ?? {});\n if (participants.length === 0) {\n throw new Error(\"discussion pattern requires at least one participant\");\n }\n\n const config = (context.config ?? {}) as DiscussionPatternConfig;\n const maxRounds = config.max_rounds ?? DEFAULT_MAX_ROUNDS;\n const convergence = config.convergence ?? DEFAULT_CONVERGENCE;\n const onDeadlock = config.on_deadlock ?? DEFAULT_DEADLOCK;\n\n const messageBus = new EventBus({ historySize: 200 });\n const agendaStore = new AgendaStore({ eventBus: messageBus });\n const meetingStateMachine = new MeetingStateMachine(messageBus);\n\n const agendaId = `discussion-${context.executionId ?? context.stepName ?? \"agenda\"}`;\n const topic = this.getDiscussionInput(context).topic ?? context.stepName ?? \"Discussion\";\n\n agendaStore.create({ id: agendaId, title: topic }, \"system\");\n agendaStore.transition(agendaId, \"pending\", \"system\");\n agendaStore.transition(agendaId, \"active\", \"system\");\n\n meetingStateMachine.apply({ type: \"agenda.created\" });\n meetingStateMachine.apply({ type: \"agenda.status.changed\", payload: { status: \"IN_PROGRESS\" } });\n\n const rounds: Array<{ round: number; opinions: RoundOpinions; converged: boolean; decision?: string }> = [];\n let decision: string | undefined;\n let converged = false;\n\n const retryBudget = config.retry_budget ?? 1;\n const roundLimit = onDeadlock === \"retry\" ? maxRounds + retryBudget : maxRounds;\n\n for (let round = 1; round <= roundLimit; round++) {\n await context.emit?.({\n type: \"discussion_round_start\",\n payload: { round, participants },\n });\n\n const opinions = this.collectRoundOpinions(context, participants, round);\n const evaluation = this.evaluateConvergence({\n convergence,\n opinions,\n participants,\n round,\n context,\n });\n\n rounds.push({\n round,\n opinions,\n converged: evaluation.converged,\n decision: evaluation.decision,\n });\n\n await context.emit?.({\n type: \"discussion_round_end\",\n payload: {\n round,\n opinions,\n converged: evaluation.converged,\n decision: evaluation.decision,\n disagreements: evaluation.disagreements,\n },\n });\n\n if (evaluation.converged) {\n converged = true;\n decision = evaluation.decision;\n break;\n }\n }\n\n meetingStateMachine.apply({ type: \"decisions.voting.started\" });\n meetingStateMachine.apply({ type: \"decisions.voting.ended\" });\n\n if (converged) {\n meetingStateMachine.apply({\n type: \"workflow.consensus.computed\",\n payload: { reason: \"converged\" },\n });\n agendaStore.transition(agendaId, \"completed\", \"system\");\n\n return {\n success: true,\n output: {\n topic,\n status: \"consensus-reached\",\n decision,\n rounds,\n },\n metadata: {\n rounds: rounds.length,\n converged: true,\n convergence,\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"discussion\"],\n meeting_state: meetingStateMachine.getState(),\n },\n };\n }\n\n const deadlockResult = this.handleDeadlock(onDeadlock, rounds.length);\n\n if (deadlockResult.status === \"escalated\") {\n agendaStore.transition(agendaId, \"cancelled\", \"system\");\n meetingStateMachine.apply({\n type: \"workflow.timeout\",\n payload: { reason: \"deadlock escalation\" },\n });\n } else {\n agendaStore.transition(agendaId, \"cancelled\", \"system\");\n meetingStateMachine.apply({\n type: \"workflow.timeout\",\n payload: { reason: \"deadlock\" },\n });\n }\n\n return {\n success: false,\n output: {\n topic,\n status: deadlockResult.status,\n reason: \"max_rounds_reached\",\n rounds,\n },\n metadata: {\n rounds: rounds.length,\n converged: false,\n convergence,\n on_deadlock: onDeadlock,\n ...(onDeadlock === \"retry\" && { retry_budget: config.retry_budget ?? 1, retry_rounds_used: rounds.length - maxRounds }),\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"discussion\"],\n meeting_state: meetingStateMachine.getState(),\n },\n };\n }\n\n private getDiscussionInput(context: PatternRuntimeContext): DiscussionInputShape {\n const input = context.input;\n if (!input || typeof input !== \"object\") {\n return {};\n }\n\n return input as DiscussionInputShape;\n }\n\n private collectRoundOpinions(\n context: PatternRuntimeContext,\n participants: string[],\n round: number\n ): RoundOpinions {\n const input = this.getDiscussionInput(context);\n const roundInput = input.rounds?.[round - 1];\n\n const opinions: RoundOpinions = {};\n for (const participant of participants) {\n const raw = roundInput?.[participant] ?? input.opinions?.[participant] ?? participant;\n opinions[participant] = String(raw);\n }\n\n return opinions;\n }\n\n private evaluateConvergence(args: {\n convergence: NonNullable<DiscussionPatternConfig[\"convergence\"]>;\n opinions: RoundOpinions;\n participants: string[];\n round: number;\n context: PatternRuntimeContext;\n }): ConvergenceEvaluation {\n const values = Object.values(args.opinions);\n const counts = this.countOpinions(values);\n const sorted = [...counts.entries()].sort((a, b) => b[1] - a[1]);\n const [topOpinion, topCount] = sorted[0] ?? [undefined, 0];\n const disagreements = values.length - topCount;\n\n if (args.convergence === \"no_disagreements\" || args.convergence === \"unanimous\") {\n return {\n converged: sorted.length <= 1,\n decision: sorted.length <= 1 ? topOpinion : undefined,\n disagreements,\n };\n }\n\n if (args.convergence === \"majority\") {\n const required = Math.floor(args.participants.length / 2) + 1;\n const converged = topCount >= required;\n return {\n converged,\n decision: converged ? topOpinion : undefined,\n disagreements,\n };\n }\n\n const customFn = this.resolveCustomConvergence(args.context);\n const customConverged = customFn({\n round: args.round,\n opinions: args.opinions,\n participants: args.participants,\n });\n\n return {\n converged: customConverged,\n decision: customConverged ? topOpinion : undefined,\n disagreements,\n };\n }\n\n private resolveCustomConvergence(context: PatternRuntimeContext): CustomConvergenceFn {\n const configFn = (context.config as { custom_convergence?: unknown } | undefined)?.custom_convergence;\n if (typeof configFn === \"function\") {\n return configFn as CustomConvergenceFn;\n }\n\n const contextFn = (context as PatternRuntimeContext & { customConvergence?: unknown }).customConvergence;\n if (typeof contextFn === \"function\") {\n return contextFn as CustomConvergenceFn;\n }\n\n throw new Error(\"discussion.convergence='custom' requires custom_convergence function\");\n }\n\n private countOpinions(opinions: DiscussionOpinion[]): Map<string, number> {\n const counts = new Map<string, number>();\n for (const opinion of opinions) {\n counts.set(opinion, (counts.get(opinion) ?? 0) + 1);\n }\n return counts;\n }\n\n private handleDeadlock(\n action: NonNullable<DiscussionPatternConfig[\"on_deadlock\"]>,\n rounds: number\n ): { status: \"failed\" | \"escalated\"; rounds: number } {\n if (action === \"escalate\") {\n return { status: \"escalated\", rounds };\n }\n\n if (action === \"retry\") {\n return { status: \"failed\", rounds };\n }\n\n return { status: \"failed\", rounds };\n }\n}\n","import { OboraErrorCode } from \"../../errors/OboraErrorCode.js\";\nimport { VotingSessionStore } from \"../../consensus/voting/VotingSessionStore.js\";\nimport {\n CollaborationPatternBase,\n type BuiltinPatternKind,\n type ConsensusPatternConfig,\n type EscalationTrigger,\n type VoterRole,\n PATTERN_BLACKBOARD_DOMAIN_MAP,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n} from \"../types.js\";\n\ntype VoteValue = boolean | number | { approved?: unknown; score?: unknown; reason?: unknown };\n\ninterface ConsensusInputShape {\n topic?: string;\n startedAt?: string | Date;\n votes?: Record<string, VoteValue>;\n}\n\ninterface NormalizedVote {\n voterId: string;\n approved: boolean;\n score?: number;\n reason?: string;\n role?: VoterRole;\n}\n\ninterface CustomEvaluationContext {\n votes: NormalizedVote[];\n participants: string[];\n requiredParticipants: string[];\n config: ConsensusPatternConfig;\n}\n\ntype CustomEvaluatorResult =\n | boolean\n | {\n approved: boolean;\n reason?: string;\n score?: number;\n };\n\ntype CustomEvaluator = (context: CustomEvaluationContext) => CustomEvaluatorResult;\n\nconst DEFAULT_RULE: NonNullable<ConsensusPatternConfig[\"rule\"]> = \"majority\";\nconst DEFAULT_THRESHOLD_BY_RULE: Record<\"weighted\" | \"score-threshold\", number> = {\n weighted: 0.5,\n \"score-threshold\": 0.5,\n};\n\nexport class ConsensusPattern extends CollaborationPatternBase {\n readonly name = \"consensus\";\n readonly kind: BuiltinPatternKind = \"consensus\";\n\n validateConfig(config: ConsensusPatternConfig): void {\n if (config.rule !== undefined) {\n const allowed = new Set([\"majority\", \"unanimous\", \"weighted\", \"score-threshold\", \"custom\"]);\n if (!allowed.has(config.rule)) {\n throw new Error(\"consensus.rule must be one of: majority, unanimous, weighted, score-threshold, custom\");\n }\n }\n\n if (config.threshold !== undefined && (!Number.isFinite(config.threshold) || config.threshold < 0 || config.threshold > 1)) {\n throw new Error(\"consensus.threshold must be a finite number in [0, 1]\");\n }\n\n if (config.best_effort !== undefined && !Array.isArray(config.best_effort)) {\n throw new Error(\"consensus.best_effort must be a string[]\");\n }\n\n if (config.best_effort && config.best_effort.some((voterId) => typeof voterId !== \"string\" || voterId.trim().length === 0)) {\n throw new Error(\"consensus.best_effort must contain non-empty voter ids\");\n }\n\n if (config.weights !== undefined) {\n for (const [voterId, weight] of Object.entries(config.weights)) {\n if (voterId.trim().length === 0 || !Number.isFinite(weight) || weight < 0) {\n throw new Error(\"consensus.weights must map non-empty voter ids to finite numbers >= 0\");\n }\n }\n }\n\n if (config.timeout !== undefined && parseTimeoutToMs(config.timeout) === undefined) {\n throw new Error(\"consensus.timeout must match /^(\\\\d+)(ms|s|m|h)$/\");\n }\n\n if (config.rule === \"custom\") {\n const candidate = (config as ConsensusPatternConfig & { custom_evaluate?: unknown }).custom_evaluate;\n if (candidate !== undefined && typeof candidate !== \"function\") {\n throw new Error(\"consensus.custom_evaluate must be a function when provided\");\n }\n }\n\n if (config.voter_roles !== undefined) {\n if (!Array.isArray(config.voter_roles)) {\n throw new Error(\"consensus.voter_roles must be an array of VoterRoleConfig\");\n }\n const validRoles = new Set([\"ai\", \"human\", \"service\"]);\n for (const rc of config.voter_roles) {\n if (!validRoles.has(rc.role)) {\n throw new Error(`consensus.voter_roles[].role must be one of: ai, human, service (got \"${rc.role}\")`);\n }\n if (!Array.isArray(rc.voters) || rc.voters.length === 0) {\n throw new Error(\"consensus.voter_roles[].voters must be a non-empty string[]\");\n }\n }\n }\n\n if (config.escalation !== undefined) {\n const validTriggers = new Set([\"timeout\", \"quorum_not_met\"]);\n if (!Array.isArray(config.escalation.triggers) || config.escalation.triggers.length === 0) {\n throw new Error(\"consensus.escalation.triggers must be a non-empty array\");\n }\n for (const t of config.escalation.triggers) {\n if (!validTriggers.has(t)) {\n throw new Error(`consensus.escalation.triggers must be one of: timeout, quorum_not_met (got \"${t}\")`);\n }\n }\n }\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const participants = Object.keys(context.participants ?? {});\n if (participants.length === 0) {\n throw new Error(\"consensus pattern requires at least one participant\");\n }\n\n const config = (context.config ?? {}) as ConsensusPatternConfig;\n const rule = config.rule ?? DEFAULT_RULE;\n const bestEffort = new Set(config.best_effort ?? []);\n const requiredParticipants = participants.filter((participant) => !bestEffort.has(participant));\n\n // Build voter role map from config\n const voterRoleMap = this.buildVoterRoleMap(config, participants);\n\n const input = this.getConsensusInput(context);\n const votes = this.collectVotes(participants, input.votes, voterRoleMap);\n\n await context.emit?.({\n type: \"consensus_vote_start\",\n payload: {\n rule,\n participants,\n required: requiredParticipants,\n best_effort: [...bestEffort],\n voter_roles: Object.fromEntries(voterRoleMap),\n },\n });\n\n // VotingSessionStore integration: create, record, close, and use tally for cross-validation\n const votingSessionStore = new VotingSessionStore();\n const votingSession = votingSessionStore.create({\n agendaId: `consensus:${context.executionId ?? context.stepName ?? \"session\"}`,\n policy: rule === \"score-threshold\" || rule === \"custom\" ? \"majority\" : rule,\n quorum: requiredParticipants.length,\n createdBy: \"runtime:consensus-pattern\",\n });\n votingSessionStore.open(votingSession.id);\n\n for (const vote of votes) {\n votingSessionStore.addVote({\n sessionId: votingSession.id,\n voterId: vote.voterId,\n option: vote.approved ? \"approve\" : \"reject\",\n weight: config.weights?.[vote.voterId],\n });\n\n await context.emit?.({\n type: \"consensus_vote_cast\",\n payload: {\n voterId: vote.voterId,\n approved: vote.approved,\n score: vote.score,\n reason: vote.reason,\n role: vote.role,\n },\n });\n }\n\n const requiredVoteCount = votes.filter((vote) => requiredParticipants.includes(vote.voterId)).length;\n if (requiredVoteCount < requiredParticipants.length) {\n const timeoutMs = parseTimeoutToMs(config.timeout);\n if (timeoutMs !== undefined && this.hasTimedOut(timeoutMs, input.startedAt, context)) {\n // Close store session before escalation/throw\n votingSessionStore.close(votingSession.id);\n\n if (this.shouldEscalate(\"timeout\", config)) {\n return this.buildEscalationResult(\n \"timeout\",\n config,\n participants,\n votes,\n rule,\n requiredParticipants,\n bestEffort,\n votingSessionStore.getTally(votingSession.id),\n context,\n );\n }\n\n const timeoutError = Object.assign(new Error(\"consensus voting timed out\"), {\n code: OboraErrorCode.CONSENSUS_TIMEOUT,\n });\n\n await context.emit?.({\n type: \"consensus_result\",\n payload: {\n status: \"timeout\",\n reason: \"required voters timeout\",\n received_required: requiredVoteCount,\n required_total: requiredParticipants.length,\n },\n });\n\n throw timeoutError;\n }\n\n // Close store session before quorum failure\n votingSessionStore.close(votingSession.id);\n\n if (this.shouldEscalate(\"quorum_not_met\", config)) {\n return this.buildEscalationResult(\n \"quorum_not_met\",\n config,\n participants,\n votes,\n rule,\n requiredParticipants,\n bestEffort,\n votingSessionStore.getTally(votingSession.id),\n context,\n );\n }\n\n await context.emit?.({\n type: \"consensus_result\",\n payload: {\n status: \"fail\",\n reason: \"quorum_not_met\",\n received_required: requiredVoteCount,\n required_total: requiredParticipants.length,\n },\n });\n\n return {\n success: false,\n output: {\n status: \"quorum-not-met\",\n reason: OboraErrorCode.CONSENSUS_QUORUM_NOT_MET,\n participants,\n votes,\n },\n metadata: {\n rule,\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"consensus\"],\n required_participants: requiredParticipants,\n best_effort: [...bestEffort],\n },\n };\n }\n\n // Close store session and get tally for cross-validation\n votingSessionStore.close(votingSession.id);\n const tally = votingSessionStore.getTally(votingSession.id);\n\n const verdict = this.evaluateRule(rule, votes, participants, requiredParticipants, config, context);\n\n await context.emit?.({\n type: \"consensus_result\",\n payload: {\n status: verdict.approved ? \"pass\" : \"fail\",\n reason: verdict.reason,\n score: verdict.score,\n },\n });\n\n return {\n success: verdict.approved,\n output: {\n status: verdict.approved ? \"consensus-reached\" : \"consensus-rejected\",\n rule,\n reason: verdict.reason,\n score: verdict.score,\n votes,\n },\n metadata: {\n rule,\n threshold: config.threshold,\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"consensus\"],\n required_participants: requiredParticipants,\n best_effort: [...bestEffort],\n store_tally: tally ?? undefined,\n },\n };\n }\n\n private buildVoterRoleMap(config: ConsensusPatternConfig, participants: string[]): Map<string, VoterRole> {\n const map = new Map<string, VoterRole>();\n // Default all to \"ai\"\n for (const p of participants) {\n map.set(p, \"ai\");\n }\n // Override from config\n if (config.voter_roles) {\n for (const rc of config.voter_roles) {\n for (const v of rc.voters) {\n map.set(v, rc.role);\n }\n }\n }\n return map;\n }\n\n private shouldEscalate(trigger: EscalationTrigger, config: ConsensusPatternConfig): boolean {\n return config.escalation?.triggers?.includes(trigger) === true;\n }\n\n private async buildEscalationResult(\n trigger: EscalationTrigger,\n config: ConsensusPatternConfig,\n participants: string[],\n votes: NormalizedVote[],\n rule: string,\n requiredParticipants: string[],\n bestEffort: Set<string>,\n tally: unknown,\n context: PatternRuntimeContext,\n ): Promise<PatternPayloadResult> {\n await context.emit?.({\n type: \"consensus_escalation\",\n payload: {\n trigger,\n escalation_target: config.escalation?.target,\n participants,\n votes,\n rule,\n },\n });\n\n return {\n success: false,\n output: {\n status: \"escalated\",\n trigger,\n escalation_target: config.escalation?.target,\n reason: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n participants,\n votes,\n },\n metadata: {\n rule,\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"consensus\"],\n required_participants: requiredParticipants,\n best_effort: [...bestEffort],\n store_tally: tally ?? undefined,\n },\n };\n }\n\n private getConsensusInput(context: PatternRuntimeContext): ConsensusInputShape {\n const input = context.input;\n if (!input || typeof input !== \"object\") {\n return {};\n }\n\n return input as ConsensusInputShape;\n }\n\n private collectVotes(participants: string[], rawVotes: Record<string, VoteValue> | undefined, roleMap: Map<string, VoterRole>): NormalizedVote[] {\n if (!rawVotes) {\n return [];\n }\n\n const votes: NormalizedVote[] = [];\n for (const participant of participants) {\n if (!(participant in rawVotes)) {\n continue;\n }\n\n const vote = this.normalizeVote(participant, rawVotes[participant]);\n vote.role = roleMap.get(participant) ?? \"ai\";\n votes.push(vote);\n }\n\n return votes;\n }\n\n private normalizeVote(voterId: string, vote: VoteValue): NormalizedVote {\n if (typeof vote === \"boolean\") {\n return { voterId, approved: vote };\n }\n\n if (typeof vote === \"number\") {\n return { voterId, approved: vote > 0, score: clampScore(vote) };\n }\n\n if (vote && typeof vote === \"object\") {\n const approved = typeof vote.approved === \"boolean\" ? vote.approved : Boolean(vote.score && Number(vote.score) > 0);\n const score = typeof vote.score === \"number\" ? clampScore(vote.score) : undefined;\n const reason = typeof vote.reason === \"string\" ? vote.reason : undefined;\n return { voterId, approved, score, reason };\n }\n\n return { voterId, approved: false };\n }\n\n private hasTimedOut(timeoutMs: number, startedAt: Date | string | undefined, context: PatternRuntimeContext): boolean {\n const now = this.resolveNow(context);\n const start = resolveStartTime(startedAt, now);\n return now.getTime() - start.getTime() >= timeoutMs;\n }\n\n private resolveNow(context: PatternRuntimeContext): Date {\n const nowFn = (context as PatternRuntimeContext & { now?: unknown }).now;\n if (typeof nowFn === \"function\") {\n const now = nowFn();\n if (now instanceof Date) {\n return now;\n }\n }\n return new Date();\n }\n\n private evaluateRule(\n rule: NonNullable<ConsensusPatternConfig[\"rule\"]>,\n votes: NormalizedVote[],\n participants: string[],\n requiredParticipants: string[],\n config: ConsensusPatternConfig,\n context: PatternRuntimeContext\n ): { approved: boolean; reason: string; score?: number } {\n if (rule === \"unanimous\") {\n const rejected = votes.some((vote) => requiredParticipants.includes(vote.voterId) && !vote.approved);\n return {\n approved: !rejected,\n reason: rejected ? \"unanimous consensus rejected\" : \"unanimous consensus reached\",\n };\n }\n\n if (rule === \"weighted\") {\n const threshold = config.threshold ?? DEFAULT_THRESHOLD_BY_RULE.weighted;\n // M2-03A: only required participants influence weighted verdict\n const requiredVotes = votes.filter((vote) => requiredParticipants.includes(vote.voterId));\n const totalWeight = requiredVotes.reduce((sum, vote) => sum + (config.weights?.[vote.voterId] ?? 1), 0);\n const approvedWeight = requiredVotes\n .filter((vote) => vote.approved)\n .reduce((sum, vote) => sum + (config.weights?.[vote.voterId] ?? 1), 0);\n const ratio = totalWeight <= 0 ? 0 : approvedWeight / totalWeight;\n return {\n approved: ratio >= threshold,\n reason: ratio >= threshold ? \"weighted threshold met\" : \"weighted threshold not met\",\n score: ratio,\n };\n }\n\n if (rule === \"score-threshold\") {\n const threshold = config.threshold ?? DEFAULT_THRESHOLD_BY_RULE[\"score-threshold\"];\n // M2-03A: only required participants influence score-threshold verdict\n const requiredVotes = votes.filter((vote) => requiredParticipants.includes(vote.voterId));\n const scoredVotes = requiredVotes.filter((vote) => typeof vote.score === \"number\");\n const average = scoredVotes.length === 0 ? 0 : scoredVotes.reduce((sum, vote) => sum + (vote.score ?? 0), 0) / scoredVotes.length;\n return {\n approved: average >= threshold,\n reason: average >= threshold ? \"score threshold met\" : \"score threshold not met\",\n score: average,\n };\n }\n\n if (rule === \"custom\") {\n const evaluator = this.resolveCustomEvaluator(config, context);\n const custom = evaluator({ votes, participants, requiredParticipants, config });\n if (typeof custom === \"boolean\") {\n return {\n approved: custom,\n reason: custom ? \"custom rule approved\" : \"custom rule rejected\",\n };\n }\n\n return {\n approved: custom.approved,\n reason: custom.reason ?? (custom.approved ? \"custom rule approved\" : \"custom rule rejected\"),\n score: custom.score,\n };\n }\n\n // majority: only required participants influence decision/score.\n // best_effort voters contribute telemetry but must not overturn required-majority verdict.\n const requiredApprovedCount = votes.filter(\n (vote) => requiredParticipants.includes(vote.voterId) && vote.approved\n ).length;\n const required = Math.floor(requiredParticipants.length / 2) + 1;\n const approved = requiredApprovedCount >= required;\n return {\n approved,\n reason: approved ? \"majority reached\" : \"majority not reached\",\n score: requiredParticipants.length === 0 ? 0 : requiredApprovedCount / requiredParticipants.length,\n };\n }\n\n private resolveCustomEvaluator(config: ConsensusPatternConfig, context: PatternRuntimeContext): CustomEvaluator {\n const configFn = (config as ConsensusPatternConfig & { custom_evaluate?: unknown }).custom_evaluate;\n if (typeof configFn === \"function\") {\n return configFn as CustomEvaluator;\n }\n\n const contextFn = (context as PatternRuntimeContext & { customConsensusEvaluate?: unknown }).customConsensusEvaluate;\n if (typeof contextFn === \"function\") {\n return contextFn as CustomEvaluator;\n }\n\n throw new Error(\"consensus.rule='custom' requires custom_evaluate function\");\n }\n}\n\nfunction parseTimeoutToMs(timeout?: string): number | undefined {\n if (!timeout) {\n return undefined;\n }\n\n const match = timeout.trim().match(/^(\\d+)(ms|s|m|h)$/);\n if (!match) {\n return undefined;\n }\n\n const value = Number(match[1]);\n const unit = match[2];\n if (unit === \"ms\") return value;\n if (unit === \"s\") return value * 1_000;\n if (unit === \"m\") return value * 60_000;\n return value * 3_600_000;\n}\n\nfunction resolveStartTime(startedAt: Date | string | undefined, fallback: Date): Date {\n if (startedAt instanceof Date) {\n return startedAt;\n }\n\n if (typeof startedAt === \"string\") {\n const parsed = new Date(startedAt);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n\n return fallback;\n}\n\n/** Clamp a score value to [0, 1]. Undefined input returns undefined. */\nfunction clampScore(score: number): number;\nfunction clampScore(score: number | undefined): number | undefined;\nfunction clampScore(score: number | undefined): number | undefined {\n return score === undefined ? undefined : Math.max(0, Math.min(1, score));\n}\n","import {\n CollaborationPatternBase,\n type BrainstormingPatternConfig,\n type BuiltinPatternKind,\n PATTERN_BLACKBOARD_DOMAIN_MAP,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n} from \"../types.js\";\n\ntype ParticipantId = string;\n\ninterface BrainstormInputShape {\n topic?: string;\n ideas?: Record<string, unknown>;\n evaluations?: Record<string, Record<string, unknown>>;\n}\n\ninterface IdeaRecord {\n id: string;\n text: string;\n generated_by: ParticipantId;\n}\n\ninterface RankedIdea extends IdeaRecord {\n score: number;\n rank: number;\n scores_by_participant: Record<string, number>;\n}\n\ntype SemanticDedupFn = (ideas: IdeaRecord[], context: PatternRuntimeContext) => Promise<IdeaRecord[]> | IdeaRecord[];\ntype RankFn = (\n ideas: IdeaRecord[],\n participants: string[],\n input: BrainstormInputShape,\n context: PatternRuntimeContext\n) => Promise<Array<Omit<RankedIdea, \"rank\">>> | Array<Omit<RankedIdea, \"rank\">>;\ntype GenerateFn = (\n participant: string,\n input: BrainstormInputShape,\n context: PatternRuntimeContext\n) => Promise<string[]> | string[];\n\nconst DEFAULT_PHASE_1: NonNullable<BrainstormingPatternConfig[\"phase_1\"]> = \"generate\";\nconst DEFAULT_PHASE_2: NonNullable<BrainstormingPatternConfig[\"phase_2\"]> = \"evaluate\";\nconst DEFAULT_DEDUP: NonNullable<BrainstormingPatternConfig[\"dedup\"]> = \"exact\";\n\nexport class BrainstormPattern extends CollaborationPatternBase {\n readonly name = \"brainstorming\";\n readonly kind: BuiltinPatternKind = \"brainstorming\";\n\n validateConfig(config: BrainstormingPatternConfig): void {\n if (config.phase_1 !== undefined && config.phase_1 !== \"generate\") {\n throw new Error(\"brainstorming.phase_1 must be 'generate'\");\n }\n\n if (config.phase_2 !== undefined && config.phase_2 !== \"evaluate\") {\n throw new Error(\"brainstorming.phase_2 must be 'evaluate'\");\n }\n\n if (config.top_n !== undefined && (!Number.isInteger(config.top_n) || config.top_n < 1)) {\n throw new Error(\"brainstorming.top_n must be an integer >= 1\");\n }\n\n if (config.dedup !== undefined && config.dedup !== \"exact\" && config.dedup !== \"semantic\") {\n throw new Error(\"brainstorming.dedup must be one of: exact, semantic\");\n }\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const participants = Object.keys(context.participants ?? {});\n if (participants.length === 0) {\n throw new Error(\"brainstorming pattern requires at least one participant\");\n }\n\n const config = (context.config ?? {}) as BrainstormingPatternConfig;\n const input = this.getInput(context);\n\n const phase1 = config.phase_1 ?? DEFAULT_PHASE_1;\n const phase2 = config.phase_2 ?? DEFAULT_PHASE_2;\n const dedup = config.dedup ?? DEFAULT_DEDUP;\n\n await context.emit?.({\n type: \"brainstorm_generate_start\",\n payload: { phase: phase1, participants },\n });\n\n const generatedIdeas = await this.generateIdeas(participants, input, context);\n\n await context.emit?.({\n type: \"brainstorm_generate_end\",\n payload: {\n phase: phase1,\n generated_count: generatedIdeas.length,\n },\n });\n\n const dedupedIdeas = await this.deduplicate(generatedIdeas, dedup, context);\n\n await context.emit?.({\n type: \"brainstorm_evaluate_start\",\n payload: {\n phase: phase2,\n candidates: dedupedIdeas.length,\n },\n });\n\n const ranked = await this.rankIdeas(dedupedIdeas, participants, input, context);\n const topN = config.top_n ?? ranked.length;\n const selected = ranked.slice(0, topN);\n\n await context.emit?.({\n type: \"brainstorm_evaluate_end\",\n payload: {\n phase: phase2,\n evaluated_count: ranked.length,\n selected_count: selected.length,\n },\n });\n\n return {\n success: true,\n output: {\n domain: \"knowledge\",\n brainstorming: {\n topic: input.topic ?? context.stepName ?? \"Brainstorm\",\n phase_1: phase1,\n phase_2: phase2,\n dedup,\n top_n: config.top_n,\n participants,\n generated: generatedIdeas,\n deduped: dedupedIdeas,\n ranked,\n selected,\n },\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"brainstorming\"],\n generated_count: generatedIdeas.length,\n deduped_count: dedupedIdeas.length,\n ranked_count: ranked.length,\n selected_count: selected.length,\n },\n };\n }\n\n private getInput(context: PatternRuntimeContext): BrainstormInputShape {\n if (!context.input || typeof context.input !== \"object\") {\n return {};\n }\n\n return context.input as BrainstormInputShape;\n }\n\n private async generateIdeas(\n participants: string[],\n input: BrainstormInputShape,\n context: PatternRuntimeContext\n ): Promise<IdeaRecord[]> {\n const generator = (context as PatternRuntimeContext & { brainstormGenerateIdeas?: GenerateFn }).brainstormGenerateIdeas;\n\n const results = await Promise.all(\n participants.map(async (participant) => {\n const values = generator\n ? await generator(participant, input, context)\n : this.readParticipantIdeasFromInput(participant, input);\n\n return values.map((text, index) => ({\n id: `${participant}-${index + 1}`,\n text,\n generated_by: participant,\n }));\n })\n );\n\n return results.flat();\n }\n\n private readParticipantIdeasFromInput(participant: string, input: BrainstormInputShape): string[] {\n const raw = input.ideas?.[participant];\n if (Array.isArray(raw)) {\n return raw.map((item) => String(item));\n }\n\n if (raw === undefined) {\n return [];\n }\n\n return [String(raw)];\n }\n\n private async deduplicate(\n ideas: IdeaRecord[],\n mode: NonNullable<BrainstormingPatternConfig[\"dedup\"]>,\n context: PatternRuntimeContext\n ): Promise<IdeaRecord[]> {\n if (mode === \"semantic\") {\n const semanticDedup = (context as PatternRuntimeContext & { brainstormSemanticDedup?: SemanticDedupFn })\n .brainstormSemanticDedup;\n if (typeof semanticDedup === \"function\") {\n return semanticDedup(ideas, context);\n }\n }\n\n return this.exactDedup(ideas);\n }\n\n private exactDedup(ideas: IdeaRecord[]): IdeaRecord[] {\n const seen = new Set<string>();\n const result: IdeaRecord[] = [];\n\n for (const idea of ideas) {\n if (seen.has(idea.text)) {\n continue;\n }\n seen.add(idea.text);\n result.push(idea);\n }\n\n return result;\n }\n\n private async rankIdeas(\n ideas: IdeaRecord[],\n participants: string[],\n input: BrainstormInputShape,\n context: PatternRuntimeContext\n ): Promise<RankedIdea[]> {\n const customRank = (context as PatternRuntimeContext & { brainstormRankIdeas?: RankFn }).brainstormRankIdeas;\n\n if (typeof customRank === \"function\") {\n const ranked = await customRank(ideas, participants, input, context);\n return [...ranked]\n .sort((a, b) => b.score - a.score)\n .map((idea, index) => ({ ...idea, rank: index + 1 }));\n }\n\n const ranked = ideas\n .map((idea) => {\n const scoresByParticipant: Record<string, number> = {};\n let sum = 0;\n\n for (const participant of participants) {\n const rawScore = input.evaluations?.[participant]?.[idea.text];\n const numericScore = typeof rawScore === \"number\" ? rawScore : Number(rawScore ?? 0);\n const safeScore = Number.isFinite(numericScore) ? numericScore : 0;\n scoresByParticipant[participant] = safeScore;\n sum += safeScore;\n }\n\n const divisor = participants.length === 0 ? 1 : participants.length;\n return {\n ...idea,\n score: sum / divisor,\n scores_by_participant: scoresByParticipant,\n };\n })\n .sort((a, b) => b.score - a.score || a.id.localeCompare(b.id))\n .map((idea, index) => ({ ...idea, rank: index + 1 }));\n\n return ranked;\n }\n}\n","import { OboraErrorCode } from \"../../errors/OboraErrorCode.js\";\nimport {\n CollaborationPatternBase,\n type BuiltinPatternKind,\n PATTERN_BLACKBOARD_DOMAIN_MAP,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n type PeerReviewPatternConfig,\n} from \"../types.js\";\n\ntype IssueSeverity = \"P0\" | \"P1\" | \"P2\";\ntype PeerReviewFailureReason = \"score_below_threshold\" | \"p0_exceeded\" | \"quorum_not_met\";\n\ninterface ReviewIssue {\n severity?: unknown;\n description?: unknown;\n}\n\ninterface RawReview {\n score?: unknown;\n issues?: unknown;\n}\n\ninterface RoundInput {\n reviews?: Record<string, RawReview>;\n}\n\ninterface PeerReviewInputShape {\n subject?: unknown;\n startedAt?: string | Date;\n reviews?: Record<string, RawReview>;\n rounds?: RoundInput[];\n}\n\ninterface NormalizedIssue {\n severity: IssueSeverity;\n description: string;\n}\n\ninterface NormalizedReview {\n reviewer: string;\n score: number;\n issues: NormalizedIssue[];\n}\n\ninterface RoundSummary {\n round: number;\n reviewed_by: string[];\n missing_reviewers: string[];\n report: {\n issue_counts: Record<IssueSeverity, number>;\n scores_by_reviewer: Record<string, number[]>;\n average_score: number;\n };\n}\n\nconst DEFAULT_MIN_SCORE = 0;\nconst DEFAULT_P0_ALLOWED = 0;\nconst DEFAULT_MAX_ROUNDS = 1;\n\n/**\n * Peer review pattern contract.\n *\n * Quorum\n * - required reviewers = participants - best_effort\n * - quorum = all required reviewers responded in the same round\n * - best_effort reviewers do not block quorum when missing\n * - if quorum is not met, continue to next round until max_rounds\n * - when max_rounds is exhausted without quorum, return success:false with reason \"quorum_not_met\"\n *\n * Termination channel\n * - Return `success:false` (business failure) for:\n * - average score < min_score => reason \"score_below_threshold\"\n * - P0 count > p0_allowed => reason \"p0_exceeded\"\n * - quorum not met after max_rounds => reason \"quorum_not_met\"\n * - all business failures include `OboraErrorCode.CONSENSUS_FAIL` in output.error_codes\n * - Throw for external constraint violations:\n * - timeout exceeded (`startedAt` + `config.timeout`) => throws with `OboraErrorCode.CONSENSUS_TIMEOUT`\n *\n * best_effort semantics\n * - `best_effort` is a list of participant IDs\n * - missing best_effort reviewers are ignored for quorum\n * - responded best_effort reviews are included in average score, issue aggregation, and P0 checks\n */\nexport class PeerReviewPattern extends CollaborationPatternBase {\n readonly name = \"peer-review\";\n readonly kind: BuiltinPatternKind = \"peer-review\";\n\n validateConfig(config: PeerReviewPatternConfig & { timeout?: string }): void {\n if (config.min_score !== undefined && (!Number.isFinite(config.min_score) || config.min_score < 0)) {\n throw new Error(\"peer-review.min_score must be a finite number >= 0\");\n }\n\n if (config.p0_allowed !== undefined && (!Number.isInteger(config.p0_allowed) || config.p0_allowed < 0)) {\n throw new Error(\"peer-review.p0_allowed must be an integer >= 0\");\n }\n\n if (config.max_rounds !== undefined && (!Number.isInteger(config.max_rounds) || config.max_rounds < 1)) {\n throw new Error(\"peer-review.max_rounds must be an integer >= 1\");\n }\n\n if (config.best_effort !== undefined && !Array.isArray(config.best_effort)) {\n throw new Error(\"peer-review.best_effort must be a string[]\");\n }\n\n if (config.best_effort && config.best_effort.some((reviewer) => typeof reviewer !== \"string\" || reviewer.trim().length === 0)) {\n throw new Error(\"peer-review.best_effort must contain non-empty reviewer ids\");\n }\n\n if (config.timeout !== undefined && parseTimeoutToMs(config.timeout) === undefined) {\n throw new Error(\"peer-review.timeout must match /^(\\\\d+)(ms|s|m|h)$/\");\n }\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const reviewers = Object.keys(context.participants ?? {});\n if (reviewers.length === 0) {\n throw new Error(\"peer-review pattern requires at least one participant\");\n }\n\n const config = (context.config ?? {}) as PeerReviewPatternConfig & { timeout?: string };\n const minScore = config.min_score ?? DEFAULT_MIN_SCORE;\n const p0Allowed = config.p0_allowed ?? DEFAULT_P0_ALLOWED;\n const maxRounds = config.max_rounds ?? DEFAULT_MAX_ROUNDS;\n const bestEffort = new Set(config.best_effort ?? []);\n\n const requiredReviewers = reviewers.filter((reviewer) => !bestEffort.has(reviewer));\n const input = this.getInput(context);\n const timeoutMs = parseTimeoutToMs(config.timeout);\n\n const rounds = this.resolveRounds(input, maxRounds);\n const roundSummaries: RoundSummary[] = [];\n let finalReviews: NormalizedReview[] = [];\n\n for (let index = 0; index < maxRounds; index += 1) {\n if (this.hasTimedOut(timeoutMs, input.startedAt, context)) {\n await context.emit?.({\n type: \"peer_review_result\",\n payload: {\n status: \"timeout\",\n reason: \"timeout_exceeded\",\n },\n });\n\n throw Object.assign(new Error(\"peer-review timed out\"), {\n code: OboraErrorCode.CONSENSUS_TIMEOUT,\n errorCode: OboraErrorCode.CONSENSUS_TIMEOUT,\n runState: \"timeout\" as const,\n finalPass: false,\n });\n }\n\n const roundNumber = index + 1;\n const round = rounds[index] ?? {};\n\n await context.emit?.({\n type: \"peer_review_round_start\",\n payload: {\n round: roundNumber,\n max_rounds: maxRounds,\n required_reviewers: requiredReviewers,\n best_effort_reviewers: [...bestEffort],\n },\n });\n\n const reviews = this.collectReviews(reviewers, round.reviews);\n const reviewedBy = reviews.map((review) => review.reviewer);\n const missingReviewers = reviewers.filter((reviewer) => !reviewedBy.includes(reviewer));\n const missingRequired = missingReviewers.filter((reviewer) => requiredReviewers.includes(reviewer));\n\n const report = this.buildReport(reviews);\n roundSummaries.push({\n round: roundNumber,\n reviewed_by: reviewedBy,\n missing_reviewers: missingReviewers,\n report,\n });\n\n await context.emit?.({\n type: \"peer_review_round_end\",\n payload: {\n round: roundNumber,\n reviewed_by: reviewedBy,\n missing_reviewers: missingReviewers,\n average_score: report.average_score,\n issue_counts: report.issue_counts,\n },\n });\n\n if (missingRequired.length > 0) {\n const isLastRound = roundNumber >= maxRounds;\n if (!isLastRound) {\n continue;\n }\n\n return this.buildBusinessFailureResult({\n context,\n input,\n reason: \"quorum_not_met\",\n minScore,\n p0Allowed,\n maxRounds,\n bestEffort,\n roundSummaries,\n finalReport: report,\n });\n }\n\n finalReviews = reviews;\n break;\n }\n\n if (finalReviews.length === 0) {\n const lastRound = rounds[Math.max(0, roundSummaries.length - 1)]?.reviews;\n finalReviews = this.collectReviews(reviewers, lastRound);\n if (roundSummaries.length === 0) {\n throw new Error(\"peer-review failed to collect review rounds\");\n }\n }\n\n const finalReport = this.buildReport(finalReviews);\n const passByScore = finalReport.average_score >= minScore;\n const passByP0 = finalReport.issue_counts.P0 <= p0Allowed;\n const passed = passByScore && passByP0;\n\n if (!passed) {\n const reason: PeerReviewFailureReason = !passByScore ? \"score_below_threshold\" : \"p0_exceeded\";\n return this.buildBusinessFailureResult({\n context,\n input,\n reason,\n minScore,\n p0Allowed,\n maxRounds,\n bestEffort,\n roundSummaries,\n finalReport,\n });\n }\n\n await context.emit?.({\n type: \"peer_review_result\",\n payload: {\n status: \"pass\",\n reason: \"criteria_satisfied\",\n average_score: finalReport.average_score,\n min_score: minScore,\n p0_count: finalReport.issue_counts.P0,\n p0_allowed: p0Allowed,\n },\n });\n\n return {\n success: true,\n output: {\n status: \"pass\",\n // Canonical contract fields (M2-05)\n runState: \"done\" as const,\n finalPass: true,\n decisionReason: \"criteria_satisfied\",\n subject: input.subject,\n review: {\n rounds: roundSummaries,\n final_round: roundSummaries.at(-1)?.round ?? 0,\n criteria: {\n min_score: minScore,\n p0_allowed: p0Allowed,\n },\n report: finalReport,\n },\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"peer-review\"],\n decision: \"PASS\",\n max_rounds: maxRounds,\n best_effort_reviewers: [...bestEffort],\n },\n };\n }\n\n private async buildBusinessFailureResult(params: {\n context: PatternRuntimeContext;\n input: PeerReviewInputShape;\n reason: PeerReviewFailureReason;\n minScore: number;\n p0Allowed: number;\n maxRounds: number;\n bestEffort: Set<string>;\n roundSummaries: RoundSummary[];\n finalReport: {\n issue_counts: Record<IssueSeverity, number>;\n scores_by_reviewer: Record<string, number[]>;\n average_score: number;\n };\n }): Promise<PatternPayloadResult> {\n const { context, input, reason, minScore, p0Allowed, maxRounds, bestEffort, roundSummaries, finalReport } = params;\n\n await context.emit?.({\n type: \"peer_review_result\",\n payload: {\n status: \"fail\",\n reason,\n average_score: finalReport.average_score,\n min_score: minScore,\n p0_count: finalReport.issue_counts.P0,\n p0_allowed: p0Allowed,\n },\n });\n\n return {\n success: false,\n output: {\n status: \"fail\",\n reason,\n error_codes: [OboraErrorCode.CONSENSUS_FAIL],\n // Canonical contract fields (M2-05)\n runState: \"failed\" as const,\n finalPass: false,\n decisionReason: reason,\n errorCode: OboraErrorCode.CONSENSUS_FAIL,\n subject: input.subject,\n review: {\n rounds: roundSummaries,\n final_round: roundSummaries.at(-1)?.round ?? 0,\n criteria: {\n min_score: minScore,\n p0_allowed: p0Allowed,\n },\n report: finalReport,\n },\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"peer-review\"],\n decision: \"FAIL\",\n max_rounds: maxRounds,\n best_effort_reviewers: [...bestEffort],\n },\n };\n }\n\n private getInput(context: PatternRuntimeContext): PeerReviewInputShape {\n if (!context.input || typeof context.input !== \"object\") {\n return {};\n }\n\n return context.input as PeerReviewInputShape;\n }\n\n private resolveRounds(input: PeerReviewInputShape, maxRounds: number): RoundInput[] {\n if (Array.isArray(input.rounds) && input.rounds.length > 0) {\n return input.rounds.slice(0, maxRounds);\n }\n\n return [{ reviews: input.reviews }];\n }\n\n private collectReviews(reviewers: string[], rawReviews: Record<string, RawReview> | undefined): NormalizedReview[] {\n if (!rawReviews) {\n return [];\n }\n\n const reviews: NormalizedReview[] = [];\n\n for (const reviewer of reviewers) {\n if (!(reviewer in rawReviews)) {\n continue;\n }\n\n const raw = rawReviews[reviewer] ?? {};\n const scoreValue = typeof raw.score === \"number\" ? raw.score : Number(raw.score ?? 0);\n const score = Number.isFinite(scoreValue) ? scoreValue : 0;\n\n const issuesArray = Array.isArray(raw.issues) ? raw.issues : [];\n const issues = issuesArray\n .filter((issue): issue is ReviewIssue => !!issue && typeof issue === \"object\")\n .map((issue) => ({\n severity: normalizeSeverity(issue.severity),\n description: typeof issue.description === \"string\" ? issue.description : \"\",\n }));\n\n reviews.push({\n reviewer,\n score,\n issues,\n });\n }\n\n return reviews;\n }\n\n private buildReport(reviews: NormalizedReview[]): {\n issue_counts: Record<IssueSeverity, number>;\n scores_by_reviewer: Record<string, number[]>;\n average_score: number;\n } {\n const issueCounts: Record<IssueSeverity, number> = {\n P0: 0,\n P1: 0,\n P2: 0,\n };\n\n const scoresByReviewer: Record<string, number[]> = {};\n let scoreTotal = 0;\n\n for (const review of reviews) {\n scoreTotal += review.score;\n scoresByReviewer[review.reviewer] = [...(scoresByReviewer[review.reviewer] ?? []), review.score];\n\n for (const issue of review.issues) {\n issueCounts[issue.severity] += 1;\n }\n }\n\n const average = reviews.length === 0 ? 0 : scoreTotal / reviews.length;\n\n return {\n issue_counts: issueCounts,\n scores_by_reviewer: scoresByReviewer,\n average_score: average,\n };\n }\n\n private hasTimedOut(timeoutMs: number | undefined, startedAt: Date | string | undefined, context: PatternRuntimeContext): boolean {\n if (timeoutMs === undefined) {\n return false;\n }\n\n const now = this.resolveNow(context);\n const start = resolveStartTime(startedAt, now);\n return now.getTime() - start.getTime() >= timeoutMs;\n }\n\n private resolveNow(context: PatternRuntimeContext): Date {\n const nowFn = (context as PatternRuntimeContext & { now?: unknown }).now;\n if (typeof nowFn === \"function\") {\n const now = nowFn();\n if (now instanceof Date) {\n return now;\n }\n }\n return new Date();\n }\n}\n\nfunction normalizeSeverity(value: unknown): IssueSeverity {\n if (typeof value !== \"string\") {\n return \"P2\";\n }\n\n const upper = value.toUpperCase();\n if (upper === \"P0\" || upper === \"P1\" || upper === \"P2\") {\n return upper;\n }\n\n return \"P2\";\n}\n\nfunction parseTimeoutToMs(timeout?: string): number | undefined {\n if (!timeout) {\n return undefined;\n }\n\n const match = timeout.trim().match(/^(\\d+)(ms|s|m|h)$/);\n if (!match) {\n return undefined;\n }\n\n const value = Number(match[1]);\n const unit = match[2];\n if (unit === \"ms\") return value;\n if (unit === \"s\") return value * 1_000;\n if (unit === \"m\") return value * 60_000;\n return value * 3_600_000;\n}\n\nfunction resolveStartTime(startedAt: Date | string | undefined, fallback: Date): Date {\n if (startedAt instanceof Date) {\n return startedAt;\n }\n\n if (typeof startedAt === \"string\") {\n const parsed = new Date(startedAt);\n if (!Number.isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n\n return fallback;\n}\n","import { OboraErrorCode } from \"../../errors/OboraErrorCode.js\";\nimport {\n CollaborationPatternBase,\n type BuiltinPatternKind,\n PATTERN_BLACKBOARD_DOMAIN_MAP,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n type SupervisorPatternConfig,\n} from \"../types.js\";\n\ntype SupervisorStrategy = \"one_for_one\" | \"one_for_all\";\ntype BackoffType = \"linear\" | \"exponential\";\n\ntype WorkerStatus = \"completed\" | \"failed\" | \"restarting\";\n\ninterface WorkerResultInput {\n success?: unknown;\n output?: unknown;\n error?: unknown;\n}\n\ninterface SupervisorInput {\n tasks?: Record<string, unknown>;\n results?: Record<string, WorkerResultInput>;\n}\n\ninterface NormalizedWorkerResult {\n success: boolean;\n output?: unknown;\n error?: string;\n}\n\ninterface WorkerState {\n status: WorkerStatus;\n restarts: number;\n output?: unknown;\n}\n\nconst DEFAULT_STRATEGY: SupervisorStrategy = \"one_for_one\";\nconst DEFAULT_MAX_RESTARTS = 3;\nconst DEFAULT_BACKOFF: BackoffType = \"linear\";\n\n/**\n * Internal safety guard to prevent infinite loops in the restart cycle.\n * This is NOT a user-facing config — it caps the total number of loop iterations\n * to protect against bugs in attempt-queue logic. In normal operation the loop\n * terminates via maxRestarts well before this limit.\n *\n * Rationale: maxRestarts × workers should always be << GUARD_LOOP_LIMIT.\n * If you hit this, it indicates a logic bug, not a config problem.\n */\nconst GUARD_LOOP_LIMIT = 10_000;\n\nexport class SupervisorPattern extends CollaborationPatternBase {\n readonly name = \"supervisor\";\n readonly kind: BuiltinPatternKind = \"supervisor\";\n\n validateConfig(config: SupervisorPatternConfig): void {\n if (config.strategy !== undefined && config.strategy !== \"one_for_one\" && config.strategy !== \"one_for_all\") {\n throw new Error(\"supervisor.strategy must be one of: one_for_one | one_for_all\");\n }\n\n if (\n config.max_restarts !== undefined &&\n (!Number.isInteger(config.max_restarts) || config.max_restarts < 0)\n ) {\n throw new Error(\"supervisor.max_restarts must be an integer >= 0\");\n }\n\n if (config.backoff !== undefined && config.backoff !== \"linear\" && config.backoff !== \"exponential\") {\n throw new Error(\"supervisor.backoff must be one of: linear | exponential\");\n }\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const workers = Object.keys(context.participants ?? {});\n if (workers.length === 0) {\n throw new Error(\"supervisor pattern requires at least one participant\");\n }\n\n const config = (context.config ?? {}) as SupervisorPatternConfig;\n const strategy = (config.strategy ?? DEFAULT_STRATEGY) as SupervisorStrategy;\n const maxRestarts = config.max_restarts ?? DEFAULT_MAX_RESTARTS;\n const backoff = (config.backoff ?? DEFAULT_BACKOFF) as BackoffType;\n\n const input = this.getInput(context);\n const attemptQueues = this.buildAttemptQueues(workers, input.tasks);\n\n const currentResults: Record<string, NormalizedWorkerResult> = {};\n const workerStates: Record<string, WorkerState> = {};\n const backoffByWorker: Record<string, number[]> = {};\n\n for (const worker of workers) {\n currentResults[worker] =\n this.normalizeResult(input.results?.[worker]) ??\n this.shiftAttempt(worker, attemptQueues) ??\n { success: true };\n\n workerStates[worker] = {\n status: currentResults[worker].success ? \"completed\" : \"failed\",\n restarts: 0,\n output: currentResults[worker].output,\n };\n\n backoffByWorker[worker] = [];\n }\n\n let totalRestarts = 0;\n\n await context.emit?.({\n type: \"supervisor_start\",\n payload: {\n strategy,\n workers,\n max_restarts: maxRestarts,\n backoff,\n },\n });\n\n let guard = 0;\n while (guard < GUARD_LOOP_LIMIT) {\n guard += 1;\n\n for (const worker of workers) {\n const result = currentResults[worker];\n await context.emit?.({\n type: \"worker_result\",\n payload: {\n worker,\n success: result.success,\n output: result.output,\n error: result.error,\n restarts: workerStates[worker].restarts,\n },\n });\n }\n\n const failedWorkers = workers.filter((worker) => currentResults[worker].success === false);\n if (failedWorkers.length === 0) {\n return {\n success: true,\n output: {\n workers: workerStates,\n strategy,\n total_restarts: totalRestarts,\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP.supervisor,\n decision: \"PASS\",\n backoff,\n backoff_schedule: backoffByWorker,\n /** Audit integration: events are emit-only; no external audit sink is wired by default. */\n audit_emit_only: true,\n },\n };\n }\n\n if (strategy === \"one_for_one\") {\n for (const failedWorker of failedWorkers) {\n if (workerStates[failedWorker].restarts >= maxRestarts) {\n await context.emit?.({\n type: \"supervisor_max_restarts\",\n payload: {\n worker: failedWorker,\n strategy,\n max_restarts: maxRestarts,\n total_restarts: totalRestarts,\n },\n });\n\n workerStates[failedWorker].status = \"failed\";\n\n return {\n success: false,\n output: {\n reason: \"max_restarts_exceeded\",\n error_codes: [OboraErrorCode.RECOVERY_RETRY_EXHAUSTED],\n workers: workerStates,\n strategy,\n total_restarts: totalRestarts,\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP.supervisor,\n decision: \"FAIL\",\n backoff,\n backoff_schedule: backoffByWorker,\n /** Audit integration: events are emit-only; no external audit sink is wired by default. */\n audit_emit_only: true,\n },\n };\n }\n\n workerStates[failedWorker].restarts += 1;\n workerStates[failedWorker].status = \"restarting\";\n totalRestarts += 1;\n\n const waitStep = this.computeBackoff(workerStates[failedWorker].restarts, backoff);\n backoffByWorker[failedWorker].push(waitStep);\n\n await context.emit?.({\n type: \"worker_restart\",\n payload: {\n worker: failedWorker,\n strategy,\n restart_count: workerStates[failedWorker].restarts,\n total_restarts: totalRestarts,\n backoff,\n wait_step: waitStep,\n },\n });\n\n currentResults[failedWorker] =\n this.shiftAttempt(failedWorker, attemptQueues) ??\n currentResults[failedWorker];\n\n workerStates[failedWorker].status = currentResults[failedWorker].success ? \"completed\" : \"failed\";\n workerStates[failedWorker].output = currentResults[failedWorker].output;\n }\n\n continue;\n }\n\n if (totalRestarts >= maxRestarts) {\n await context.emit?.({\n type: \"supervisor_max_restarts\",\n payload: {\n worker: \"*\",\n strategy,\n max_restarts: maxRestarts,\n total_restarts: totalRestarts,\n },\n });\n\n for (const worker of workers) {\n if (!currentResults[worker].success) {\n workerStates[worker].status = \"failed\";\n }\n }\n\n return {\n success: false,\n output: {\n reason: \"max_restarts_exceeded\",\n error_codes: [OboraErrorCode.RECOVERY_RETRY_EXHAUSTED],\n workers: workerStates,\n strategy,\n total_restarts: totalRestarts,\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP.supervisor,\n decision: \"FAIL\",\n backoff,\n backoff_schedule: backoffByWorker,\n /** Audit integration: events are emit-only; no external audit sink is wired by default. */\n audit_emit_only: true,\n },\n };\n }\n\n totalRestarts += 1;\n\n for (const worker of workers) {\n workerStates[worker].restarts += 1;\n workerStates[worker].status = \"restarting\";\n\n const waitStep = this.computeBackoff(workerStates[worker].restarts, backoff);\n backoffByWorker[worker].push(waitStep);\n }\n\n await context.emit?.({\n type: \"worker_restart\",\n payload: {\n worker: failedWorkers[0],\n strategy,\n restart_all: true,\n affected_workers: workers,\n restart_count: totalRestarts,\n total_restarts: totalRestarts,\n backoff,\n },\n });\n\n for (const worker of workers) {\n currentResults[worker] = this.shiftAttempt(worker, attemptQueues) ?? currentResults[worker];\n workerStates[worker].status = currentResults[worker].success ? \"completed\" : \"failed\";\n workerStates[worker].output = currentResults[worker].output;\n }\n }\n\n throw new Error(\"supervisor pattern exceeded internal guard limit\");\n }\n\n private getInput(context: PatternRuntimeContext): SupervisorInput {\n if (!context.input || typeof context.input !== \"object\") {\n return {};\n }\n\n return context.input as SupervisorInput;\n }\n\n private normalizeResult(result: WorkerResultInput | undefined): NormalizedWorkerResult | undefined {\n if (!result || typeof result !== \"object\") {\n return undefined;\n }\n\n return {\n success: result.success === true,\n output: result.output,\n error: typeof result.error === \"string\" ? result.error : undefined,\n };\n }\n\n private buildAttemptQueues(\n workers: string[],\n tasks: Record<string, unknown> | undefined\n ): Record<string, NormalizedWorkerResult[]> {\n const queues: Record<string, NormalizedWorkerResult[]> = {};\n\n for (const worker of workers) {\n const task = tasks?.[worker];\n const attempts = this.extractAttempts(task).map((attempt) => this.normalizeResult(attempt)).filter((item): item is NormalizedWorkerResult => !!item);\n queues[worker] = attempts;\n }\n\n return queues;\n }\n\n private extractAttempts(task: unknown): WorkerResultInput[] {\n if (!task || typeof task !== \"object\") {\n return [];\n }\n\n const attemptsValue = (task as { attempts?: unknown }).attempts;\n if (!Array.isArray(attemptsValue)) {\n return [];\n }\n\n return attemptsValue.filter((attempt): attempt is WorkerResultInput => !!attempt && typeof attempt === \"object\");\n }\n\n private shiftAttempt(\n worker: string,\n queues: Record<string, NormalizedWorkerResult[]>\n ): NormalizedWorkerResult | undefined {\n const queue = queues[worker];\n if (!queue || queue.length === 0) {\n return undefined;\n }\n\n return queue.shift();\n }\n\n private computeBackoff(restartCount: number, backoff: BackoffType): number {\n if (backoff === \"exponential\") {\n return 2 ** (restartCount - 1);\n }\n\n return restartCount;\n }\n}\n","import { OboraErrorCode } from \"../../errors/OboraErrorCode.js\";\nimport {\n CollaborationPatternBase,\n type BuiltinPatternKind,\n type FanOutFanInPatternConfig,\n PATTERN_BLACKBOARD_DOMAIN_MAP,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n} from \"../types.js\";\n\ninterface FanOutFanInInput {\n task?: unknown;\n items?: unknown[];\n responses?: Record<string, unknown>;\n}\n\ninterface ParticipantResult {\n success: boolean;\n output?: unknown;\n}\n\ntype FanOutProcessFn = (\n participant: string,\n payload: { task?: unknown; items?: unknown[] },\n context: PatternRuntimeContext\n) => Promise<unknown> | unknown;\n\ntype FanOutMergeFn = (\n outputs: unknown[],\n participantResults: Record<string, ParticipantResult>,\n context: PatternRuntimeContext\n) => Promise<unknown> | unknown;\n\nconst VALID_MERGE = new Set<NonNullable<FanOutFanInPatternConfig[\"merge\"]>>([\"concatenate\", \"rank\", \"vote\", \"custom\"]);\nconst VALID_FAILURE_POLICY = new Set<NonNullable<FanOutFanInPatternConfig[\"failure_policy\"]>>([\"best_effort\", \"required\"]);\n\nexport class FanOutFanInPattern extends CollaborationPatternBase {\n readonly name = \"fan-out-fan-in\";\n readonly kind: BuiltinPatternKind = \"fan-out-fan-in\";\n\n validateConfig(config: FanOutFanInPatternConfig): void {\n if (config.merge !== undefined && !VALID_MERGE.has(config.merge)) {\n throw new Error(\"fan-out-fan-in.merge must be one of: concatenate, rank, vote, custom\");\n }\n if (config.failure_policy !== undefined && !VALID_FAILURE_POLICY.has(config.failure_policy)) {\n throw new Error(\"fan-out-fan-in.failure_policy must be one of: best_effort, required\");\n }\n if (config.min_success !== undefined) {\n if (!Number.isInteger(config.min_success) || config.min_success < 1) {\n throw new Error(\"fan-out-fan-in.min_success must be an integer >= 1\");\n }\n }\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const participants = Object.keys(context.participants ?? {});\n if (participants.length === 0) {\n throw new Error(\"fan-out-fan-in pattern requires at least one participant\");\n }\n\n const config = (context.config ?? {}) as FanOutFanInPatternConfig;\n const input = this.getInput(context);\n const mergeStrategy = config.merge ?? \"concatenate\";\n const failurePolicy = config.failure_policy ?? \"best_effort\";\n const minSuccess = failurePolicy === \"required\" ? (config.min_success ?? participants.length) : 1;\n\n // Validate min_success against actual participant count\n if (failurePolicy === \"required\" && config.min_success !== undefined && config.min_success > participants.length) {\n throw new Error(\n `fan-out-fan-in.min_success (${config.min_success}) exceeds participant count (${participants.length})`\n );\n }\n\n await context.emit?.({\n type: \"fanout_start\",\n payload: {\n participants,\n merge: mergeStrategy,\n failure_policy: failurePolicy,\n min_success: minSuccess,\n has_task: input.task !== undefined,\n items_count: Array.isArray(input.items) ? input.items.length : 0,\n },\n });\n\n const participantResults: Record<string, ParticipantResult> = {};\n\n const results = await Promise.all(\n participants.map(async (participant, index) => {\n const payload = this.buildParticipantPayload(input, participants.length, index);\n const result = await this.processParticipant(participant, payload, input, context);\n participantResults[participant] = result;\n\n await context.emit?.({\n type: \"fanout_participant_result\",\n payload: {\n participant,\n success: result.success,\n has_output: Object.prototype.hasOwnProperty.call(result, \"output\"),\n },\n });\n\n return { participant, ...result };\n })\n );\n\n const successful = results.filter((result) => result.success);\n\n // Check failure threshold based on policy\n if (successful.length === 0) {\n return {\n success: false,\n output: {\n reason: \"all_participants_failed\",\n error_codes: [OboraErrorCode.ORCH_DEPENDENCY_FAILED],\n merged: [],\n participant_results: participantResults,\n merge_strategy: mergeStrategy,\n failure_policy: failurePolicy,\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"fan-out-fan-in\"],\n responded_participants: 0,\n missing_participants: participants.length,\n },\n };\n }\n\n if (failurePolicy === \"required\" && successful.length < minSuccess) {\n return {\n success: false,\n output: {\n reason: \"min_success_not_met\",\n error_codes: [OboraErrorCode.ORCH_DEPENDENCY_FAILED],\n merged: [],\n participant_results: participantResults,\n merge_strategy: mergeStrategy,\n failure_policy: failurePolicy,\n min_success: minSuccess,\n actual_success: successful.length,\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"fan-out-fan-in\"],\n responded_participants: successful.length,\n missing_participants: participants.length - successful.length,\n },\n };\n }\n\n const outputs = successful.map((result) => result.output);\n const merged = await this.mergeOutputs(mergeStrategy, outputs, participantResults, context);\n\n await context.emit?.({\n type: \"fanin_merge\",\n payload: {\n merge_strategy: mergeStrategy,\n failure_policy: failurePolicy,\n responded_participants: successful.length,\n missing_participants: participants.length - successful.length,\n },\n });\n\n return {\n success: true,\n output: {\n merged,\n participant_results: participantResults,\n merge_strategy: mergeStrategy,\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"fan-out-fan-in\"],\n responded_participants: successful.length,\n missing_participants: participants.length - successful.length,\n },\n };\n }\n\n private getInput(context: PatternRuntimeContext): FanOutFanInInput {\n if (!context.input || typeof context.input !== \"object\") {\n return {};\n }\n\n return context.input as FanOutFanInInput;\n }\n\n private buildParticipantPayload(input: FanOutFanInInput, participantCount: number, participantIndex: number): { task?: unknown; items?: unknown[] } {\n if (!Array.isArray(input.items) || input.items.length === 0) {\n return { task: input.task };\n }\n\n const assignedItems = input.items.filter((_, index) => index % participantCount === participantIndex);\n return {\n task: input.task,\n items: assignedItems,\n };\n }\n\n private async processParticipant(\n participant: string,\n payload: { task?: unknown; items?: unknown[] },\n input: FanOutFanInInput,\n context: PatternRuntimeContext\n ): Promise<ParticipantResult> {\n const processFn = (context as PatternRuntimeContext & { fanOutFanInProcessFn?: FanOutProcessFn }).fanOutFanInProcessFn;\n\n try {\n if (typeof processFn === \"function\") {\n const output = await processFn(participant, payload, context);\n return { success: true, output };\n }\n\n if (input.responses && Object.prototype.hasOwnProperty.call(input.responses, participant)) {\n return {\n success: true,\n output: input.responses[participant],\n };\n }\n\n return { success: false };\n } catch {\n return { success: false };\n }\n }\n\n private async mergeOutputs(\n mergeStrategy: NonNullable<FanOutFanInPatternConfig[\"merge\"]>,\n outputs: unknown[],\n participantResults: Record<string, ParticipantResult>,\n context: PatternRuntimeContext\n ): Promise<unknown> {\n switch (mergeStrategy) {\n case \"concatenate\":\n return outputs;\n case \"rank\":\n return this.rankMerge(outputs);\n case \"vote\":\n return this.voteMerge(outputs);\n case \"custom\": {\n const customMerge = (context as PatternRuntimeContext & { fanOutFanInMergeFn?: FanOutMergeFn }).fanOutFanInMergeFn;\n if (typeof customMerge === \"function\") {\n return customMerge(outputs, participantResults, context);\n }\n // Fallback: when merge=\"custom\" but no fanOutFanInMergeFn is provided,\n // fall back to concatenate. This is intentional for forward-compatibility\n // (e.g., declarative configs where the merge fn is resolved later).\n // The fanin_merge event's merge_strategy still reports \"custom\".\n return outputs;\n }\n default:\n return outputs;\n }\n }\n\n private rankMerge(outputs: unknown[]): unknown[] {\n const normalized = outputs.map((output, index) => ({\n output,\n index,\n score: this.extractScore(output),\n }));\n\n normalized.sort((a, b) => b.score - a.score || a.index - b.index);\n return normalized.map((item) => item.output);\n }\n\n /**\n * Vote merge: tallies outputs by serialized key, returns the value with the highest count.\n * Tie-breaker rule: when two or more values have the same vote count,\n * the value that appeared first (lowest participant index) wins.\n * This is deterministic and stable across runs with the same input order.\n */\n private voteMerge(outputs: unknown[]): unknown {\n const tally = new Map<string, { count: number; value: unknown; firstIndex: number }>();\n\n outputs.forEach((output, index) => {\n const key = this.serializeVoteKey(output);\n const existing = tally.get(key);\n if (existing) {\n existing.count += 1;\n return;\n }\n\n tally.set(key, {\n count: 1,\n value: output,\n firstIndex: index,\n });\n });\n\n // Sort: highest count wins; on tie, lowest firstIndex wins (first-seen)\n const winner = [...tally.values()].sort((a, b) => b.count - a.count || a.firstIndex - b.firstIndex)[0];\n return winner?.value;\n }\n\n private extractScore(output: unknown): number {\n if (!output || typeof output !== \"object\") {\n return Number.NEGATIVE_INFINITY;\n }\n\n const score = (output as { score?: unknown }).score;\n if (typeof score === \"number\" && Number.isFinite(score)) {\n return score;\n }\n\n const numeric = Number(score);\n return Number.isFinite(numeric) ? numeric : Number.NEGATIVE_INFINITY;\n }\n\n private serializeVoteKey(output: unknown): string {\n if (typeof output === \"string\") {\n return `str:${output}`;\n }\n\n if (typeof output === \"number\" || typeof output === \"boolean\" || output === null || output === undefined) {\n return String(output);\n }\n\n try {\n return JSON.stringify(output);\n } catch {\n return String(output);\n }\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { OboraErrorCode } from \"../../errors/OboraErrorCode.js\";\nimport {\n CollaborationPatternBase,\n type BuiltinPatternKind,\n PATTERN_BLACKBOARD_DOMAIN_MAP,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n type RedBluePatternConfig,\n} from \"../types.js\";\n\ninterface RedBlueRoundInput {\n red_findings?: Record<string, unknown>;\n blue_responses?: Record<string, unknown>;\n}\n\ninterface RedBlueInputShape {\n subject?: unknown;\n rounds?: RedBlueRoundInput[];\n}\n\ninterface RoundSummary {\n /** Stable artifact identifier for this round output. */\n round_id: string;\n round: number;\n red_team: string[];\n blue_team: string[];\n red_findings: Record<string, unknown>;\n blue_responses: Record<string, unknown>;\n}\n\nconst DEFAULT_MAX_ROUNDS = 1;\nconst DEFAULT_CONVERGENCE: NonNullable<RedBluePatternConfig[\"convergence\"]> = \"max_rounds\";\n\nexport class RedBluePattern extends CollaborationPatternBase {\n readonly name = \"red-blue\";\n readonly kind: BuiltinPatternKind = \"red-blue\";\n\n validateConfig(config: RedBluePatternConfig): void {\n if (config.max_rounds !== undefined && (!Number.isInteger(config.max_rounds) || config.max_rounds < 1)) {\n throw new Error(\"red-blue.max_rounds must be an integer >= 1\");\n }\n\n if (\n config.convergence !== undefined &&\n config.convergence !== \"red_finds_nothing\" &&\n config.convergence !== \"max_rounds\" &&\n config.convergence !== \"custom\"\n ) {\n throw new Error(\"red-blue.convergence must be one of: red_finds_nothing, max_rounds, custom\");\n }\n\n if (config.convergence === \"custom\" && typeof config.custom_convergence !== \"function\") {\n throw new Error(\"red-blue: convergence='custom' requires a custom_convergence function\");\n }\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const participants = Object.keys(context.participants ?? {});\n if (participants.length === 0) {\n throw new Error(\"red-blue pattern requires at least one participant\");\n }\n\n const config = (context.config ?? {}) as RedBluePatternConfig;\n const maxRounds = config.max_rounds ?? DEFAULT_MAX_ROUNDS;\n const convergence = config.convergence ?? DEFAULT_CONVERGENCE;\n const { redTeam, blueTeam } = this.resolveTeams(participants, config);\n const input = this.getInput(context);\n const roundsInput = this.resolveRounds(input, maxRounds);\n\n const rounds: RoundSummary[] = [];\n let converged = false;\n let convergenceRound: number | undefined;\n\n for (let index = 0; index < maxRounds; index += 1) {\n const roundNumber = index + 1;\n const roundInput = roundsInput[index] ?? {};\n const redFindings = this.normalizeRecord(roundInput.red_findings);\n const blueResponses = this.normalizeRecord(roundInput.blue_responses);\n\n await context.emit?.({\n type: \"red_blue_round_start\",\n payload: {\n round: roundNumber,\n max_rounds: maxRounds,\n red_team: redTeam,\n blue_team: blueTeam,\n },\n });\n\n const summary: RoundSummary = {\n round_id: randomUUID(),\n round: roundNumber,\n red_team: redTeam,\n blue_team: blueTeam,\n red_findings: redFindings,\n blue_responses: blueResponses,\n };\n rounds.push(summary);\n\n await context.emit?.({\n type: \"red_blue_round_end\",\n payload: {\n round: roundNumber,\n red_findings_count: Object.keys(redFindings).length,\n blue_responses_count: Object.keys(blueResponses).length,\n },\n });\n\n const shouldConverge = this.checkConvergence({\n mode: convergence,\n context,\n roundNumber,\n rounds,\n currentRound: summary,\n input,\n redTeam,\n blueTeam,\n });\n\n if (shouldConverge) {\n converged = true;\n convergenceRound = roundNumber;\n break;\n }\n }\n\n if (!converged && convergence === \"red_finds_nothing\") {\n const escalation = config.escalation;\n const shouldEscalate = escalation?.triggers?.includes(\"max_rounds_exhausted\");\n\n if (shouldEscalate) {\n await context.emit?.({\n type: \"red_blue_escalation\",\n payload: {\n trigger: \"max_rounds_exhausted\",\n target: escalation?.target,\n rounds_completed: rounds.length,\n max_rounds: maxRounds,\n round_ids: rounds.map((r) => r.round_id),\n },\n });\n }\n\n return {\n success: false,\n output: {\n reason: \"convergence_not_reached\",\n error_codes: [OboraErrorCode.ORCH_DEPENDENCY_FAILED],\n rounds,\n converged: false,\n ...(shouldEscalate ? { escalated: true, escalation_target: escalation?.target } : {}),\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"red-blue\"],\n decision: \"FAIL\",\n max_rounds: maxRounds,\n convergence,\n red_team: redTeam,\n blue_team: blueTeam,\n round_ids: rounds.map((r) => r.round_id),\n ...(shouldEscalate ? { escalated: true, escalation_target: escalation?.target } : {}),\n },\n };\n }\n\n if (!converged && (convergence === \"max_rounds\" || convergence === \"custom\")) {\n converged = true;\n convergenceRound = rounds.length;\n }\n\n return {\n success: true,\n output: {\n rounds,\n converged,\n convergence_round: convergenceRound,\n },\n metadata: {\n blackboard_domains: PATTERN_BLACKBOARD_DOMAIN_MAP[\"red-blue\"],\n decision: \"PASS\",\n max_rounds: maxRounds,\n convergence,\n red_team: redTeam,\n blue_team: blueTeam,\n round_ids: rounds.map((r) => r.round_id),\n },\n };\n }\n\n private getInput(context: PatternRuntimeContext): RedBlueInputShape {\n if (!context.input || typeof context.input !== \"object\") {\n return {};\n }\n\n return context.input as RedBlueInputShape;\n }\n\n private resolveRounds(input: RedBlueInputShape, maxRounds: number): RedBlueRoundInput[] {\n if (!Array.isArray(input.rounds) || input.rounds.length === 0) {\n return Array.from({ length: maxRounds }, () => ({}));\n }\n\n return input.rounds.slice(0, maxRounds);\n }\n\n private resolveTeams(participants: string[], config: RedBluePatternConfig): { redTeam: string[]; blueTeam: string[] } {\n if (config.red_team || config.blue_team) {\n const redTeam = this.normalizeTeam(config.red_team, \"red_team\", participants);\n const blueTeam = this.normalizeTeam(config.blue_team, \"blue_team\", participants);\n\n if (redTeam.length === 0 || blueTeam.length === 0) {\n throw new Error(\"red-blue.red_team and red-blue.blue_team must each contain at least one participant\");\n }\n\n const overlap = redTeam.filter((member) => blueTeam.includes(member));\n if (overlap.length > 0) {\n throw new Error(`red-blue: participants cannot be on both teams: ${overlap.join(\", \")}`);\n }\n\n return { redTeam, blueTeam };\n }\n\n const splitIndex = Math.ceil(participants.length / 2);\n const redTeam = participants.slice(0, splitIndex);\n const blueTeam = participants.slice(splitIndex);\n\n if (blueTeam.length === 0) {\n throw new Error(\"red-blue pattern requires at least two participants for automatic team split\");\n }\n\n return { redTeam, blueTeam };\n }\n\n private normalizeTeam(team: string[] | undefined, fieldName: \"red_team\" | \"blue_team\", participants: string[]): string[] {\n if (!Array.isArray(team)) {\n return [];\n }\n\n const normalized = team.map((member) => (typeof member === \"string\" ? member.trim() : \"\")).filter((member) => member.length > 0);\n\n const invalid = normalized.filter((member) => !participants.includes(member));\n if (invalid.length > 0) {\n throw new Error(`red-blue.${fieldName} contains unknown participant ids: ${invalid.join(\", \")}`);\n }\n\n return [...new Set(normalized)];\n }\n\n private normalizeRecord(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return {};\n }\n\n return { ...(value as Record<string, unknown>) };\n }\n\n private checkConvergence(params: {\n mode: NonNullable<RedBluePatternConfig[\"convergence\"]>;\n context: PatternRuntimeContext;\n roundNumber: number;\n rounds: RoundSummary[];\n currentRound: RoundSummary;\n input: RedBlueInputShape;\n redTeam: string[];\n blueTeam: string[];\n }): boolean {\n const { mode, context, roundNumber, rounds, currentRound, input, redTeam, blueTeam } = params;\n\n if (mode === \"red_finds_nothing\") {\n return Object.keys(currentRound.red_findings).length === 0;\n }\n\n if (mode === \"custom\") {\n const config = (context.config ?? {}) as RedBluePatternConfig;\n // Also support legacy context-level fn for backward compat\n const customConvergence = config.custom_convergence ?? (context as PatternRuntimeContext & {\n redBlueConvergenceFn?: typeof config.custom_convergence;\n }).redBlueConvergenceFn;\n\n if (typeof customConvergence !== \"function\") {\n // Should not reach here due to validateConfig, but guard anyway\n throw new Error(\"red-blue: convergence='custom' requires a custom_convergence function\");\n }\n\n return customConvergence({\n round: roundNumber,\n rounds,\n current_round: currentRound,\n subject: input.subject,\n red_team: redTeam,\n blue_team: blueTeam,\n });\n }\n\n return false;\n }\n}\n","import type { PatternRegistry } from \"../PatternRegistry.js\";\nimport {\n CollaborationPatternBase,\n OboraErrorCode,\n type PatternPayloadResult,\n type PatternRuntimeContext,\n type CompositePatternConfig,\n type CompositeStage,\n} from \"../types.js\";\n\ntype StageFailureMode = \"fail\" | \"skip\" | \"escalate\";\n\ninterface CompositeStageResult {\n name: string;\n pattern: string;\n success: boolean;\n output: unknown;\n}\n\nexport class CompositePattern extends CollaborationPatternBase {\n readonly name = \"composite\";\n readonly kind = \"composite\" as const;\n\n constructor(private readonly registry: PatternRegistry) {\n super();\n }\n\n validateConfig(config: CompositePatternConfig): void {\n if (!Array.isArray(config.stages)) {\n throw new Error(\"composite.stages must be an array\");\n }\n\n const seen = new Set<string>();\n for (const [index, stage] of config.stages.entries()) {\n if (!stage || typeof stage !== \"object\") {\n throw new Error(`composite.stages[${index}] must be an object`);\n }\n\n if (typeof stage.name !== \"string\" || stage.name.trim().length === 0) {\n throw new Error(`composite.stages[${index}].name must be a non-empty string`);\n }\n\n if (seen.has(stage.name)) {\n throw new Error(`composite.stages contains duplicate stage name '${stage.name}'`);\n }\n seen.add(stage.name);\n\n if (typeof stage.pattern !== \"string\" || stage.pattern.trim().length === 0) {\n throw new Error(`composite.stages[${index}].pattern must be a non-empty string`);\n }\n\n if (\n stage.input_from !== undefined &&\n typeof stage.input_from !== \"string\"\n ) {\n throw new Error(`composite.stages[${index}].input_from must be a string when provided`);\n }\n }\n\n if (\n config.on_stage_failure !== undefined &&\n config.on_stage_failure !== \"fail\" &&\n config.on_stage_failure !== \"skip\" &&\n config.on_stage_failure !== \"escalate\"\n ) {\n throw new Error(\"composite.on_stage_failure must be one of: fail, skip, escalate\");\n }\n }\n\n protected async onExecute(context: PatternRuntimeContext): Promise<PatternPayloadResult> {\n const config = (context.config ?? {}) as CompositePatternConfig;\n const stages = config.stages ?? [];\n const onStageFailure: StageFailureMode = config.on_stage_failure ?? \"fail\";\n\n const rootInput = context.input;\n const results: CompositeStageResult[] = [];\n const outputsByStageName = new Map<string, unknown>();\n\n await context.emit?.({\n type: \"composite_start\",\n payload: {\n stages: stages.map((stage) => ({ name: stage.name, pattern: stage.pattern })),\n on_stage_failure: onStageFailure,\n },\n });\n\n for (let index = 0; index < stages.length; index += 1) {\n const stage = stages[index]!;\n const stageInput = this.resolveStageInput({\n stage,\n index,\n rootInput,\n results,\n outputsByStageName,\n });\n\n await context.emit?.({\n type: \"composite_stage_start\",\n payload: {\n index,\n name: stage.name,\n pattern: stage.pattern,\n input_from: index === 0 ? \"root\" : (stage.input_from ?? \"previous\"),\n },\n });\n\n const pattern = this.registry.get(stage.pattern);\n\n try {\n const stageResult = await pattern.run({\n ...context,\n pattern: stage.pattern,\n config: (stage.config ?? {}) as never,\n participants: stage.participants ?? context.participants,\n input: stageInput,\n });\n\n const normalized: CompositeStageResult = {\n name: stage.name,\n pattern: stage.pattern,\n success: stageResult.success,\n output: stageResult.output,\n };\n\n results.push(normalized);\n outputsByStageName.set(stage.name, stageResult.output);\n\n await context.emit?.({\n type: \"composite_stage_end\",\n payload: {\n index,\n name: stage.name,\n pattern: stage.pattern,\n success: stageResult.success,\n output: stageResult.output,\n },\n });\n\n if (!stageResult.success) {\n if (onStageFailure === \"skip\") {\n // When on_stage_failure is \"skip\", the failed stage's output ({ reason: \"failed\" })\n // becomes available to subsequent stages via input_from. This is intentional:\n // downstream stages can inspect the failure and react accordingly.\n continue;\n }\n\n if (onStageFailure === \"escalate\") {\n throw Object.assign(\n new Error(`composite stage \"${stage.name}\" (pattern: ${stage.pattern}) failed and escalation requested`),\n { code: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT, stageResult }\n );\n }\n\n await context.emit?.({\n type: \"composite_end\",\n payload: {\n success: false,\n completed_stages: results.length,\n stages: results,\n },\n });\n\n return {\n success: false,\n output: {\n stages: results,\n completed_stages: results.length,\n },\n };\n }\n } catch (error) {\n await context.emit?.({\n type: \"composite_stage_end\",\n payload: {\n index,\n name: stage.name,\n pattern: stage.pattern,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n },\n });\n\n if (onStageFailure === \"skip\") {\n const fallbackOutput = {\n error: error instanceof Error ? error.message : String(error),\n };\n results.push({\n name: stage.name,\n pattern: stage.pattern,\n success: false,\n output: fallbackOutput,\n });\n outputsByStageName.set(stage.name, fallbackOutput);\n continue;\n }\n\n if (onStageFailure === \"escalate\") {\n // If already normalized (from non-throw escalate path caught by this catch), re-throw as-is\n const existingCode =\n error && typeof error === \"object\" && \"code\" in error\n ? Reflect.get(error, \"code\")\n : undefined;\n if (existingCode === OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT) {\n throw error;\n }\n throw Object.assign(\n new Error(`composite stage \"${stage.name}\" (pattern: ${stage.pattern}) failed and escalation requested`),\n {\n code: OboraErrorCode.RECOVERY_ESCALATION_TIMEOUT,\n stageResult: {\n success: false,\n output: { error: error instanceof Error ? error.message : String(error) },\n },\n }\n );\n }\n\n await context.emit?.({\n type: \"composite_end\",\n payload: {\n success: false,\n completed_stages: results.length,\n stages: results,\n },\n });\n\n return {\n success: false,\n output: {\n stages: results,\n completed_stages: results.length,\n },\n };\n }\n }\n\n await context.emit?.({\n type: \"composite_end\",\n payload: {\n success: true,\n completed_stages: results.length,\n stages: results,\n },\n });\n\n return {\n success: true,\n output: {\n stages: results,\n completed_stages: results.length,\n },\n };\n }\n\n private resolveStageInput(args: {\n stage: CompositeStage;\n index: number;\n rootInput: unknown;\n results: CompositeStageResult[];\n outputsByStageName: Map<string, unknown>;\n }): unknown {\n if (args.index === 0) {\n return args.rootInput;\n }\n\n const source = args.stage.input_from ?? \"previous\";\n if (source === \"previous\") {\n return args.results.at(-1)?.output;\n }\n\n if (source === \"root\") {\n return args.rootInput;\n }\n\n if (!args.outputsByStageName.has(source)) {\n throw new Error(`composite stage '${args.stage.name}' references unknown input_from stage '${source}'`);\n }\n\n return args.outputsByStageName.get(source);\n }\n}\n\n","import type { AnyPlugin, PluginType, PluginValidationResult } from \"./types.js\";\n\nconst REQUIRED_METHODS_BY_TYPE: Record<PluginType, string[]> = {\n agent: [\"createAgent\"],\n tool: [\"schema\", \"execute\"],\n pattern: [\"execute\"],\n \"policy-rule\": [\"evaluate\"],\n \"recovery-strategy\": [\"handle\"],\n \"consensus-rule\": [\"evaluate\"],\n \"audit-store\": [\"record\", \"query\"],\n \"state-transform\": [\"transform\"],\n};\n\nconst VALID_TYPES = new Set<PluginType>(Object.keys(REQUIRED_METHODS_BY_TYPE) as PluginType[]);\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction hasOwnKey(target: unknown, key: string): boolean {\n return !!target && typeof target === \"object\" && key in target;\n}\n\nexport function validatePlugin(plugin: unknown): PluginValidationResult {\n const errors: string[] = [];\n\n if (!plugin || typeof plugin !== \"object\") {\n return { valid: false, errors: [\"plugin must be an object\"] };\n }\n\n const candidate = plugin as Record<string, unknown>;\n\n if (!isNonEmptyString(candidate.name)) {\n errors.push(\"plugin.name is required\");\n }\n\n if (!isNonEmptyString(candidate.version)) {\n errors.push(\"plugin.version is required\");\n }\n\n if (!isNonEmptyString(candidate.type) || !VALID_TYPES.has(candidate.type as PluginType)) {\n errors.push(\"plugin.type is invalid\");\n }\n\n if (errors.length > 0) {\n return { valid: false, errors };\n }\n\n const requiredMethods = REQUIRED_METHODS_BY_TYPE[candidate.type as PluginType];\n for (const field of requiredMethods) {\n if (!hasOwnKey(candidate, field)) {\n errors.push(`plugin.${field} is required for type '${candidate.type}'`);\n continue;\n }\n\n if (field === \"schema\") {\n const schema = candidate.schema;\n if (!schema || typeof schema !== \"object\") {\n errors.push(\"plugin.schema must be an object\");\n }\n continue;\n }\n\n if (typeof candidate[field] !== \"function\") {\n errors.push(`plugin.${field} must be a function`);\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\nexport function assertValidPlugin(plugin: unknown): asserts plugin is AnyPlugin {\n const result = validatePlugin(plugin);\n if (!result.valid) {\n throw new Error(`Invalid plugin: ${result.errors.join(\", \")}`);\n }\n}\n","import type { AnyPlugin, OboraPlugin, PluginType } from \"./types.js\";\nimport { assertValidPlugin } from \"./validator.js\";\n\nexport interface RegisterOptions {\n replace?: boolean;\n}\n\nexport class PluginRegistry {\n private readonly byName = new Map<string, AnyPlugin>();\n private readonly byType = new Map<PluginType, Map<string, AnyPlugin>>();\n\n async register(plugin: AnyPlugin, options: RegisterOptions = {}): Promise<void> {\n assertValidPlugin(plugin);\n\n const existing = this.byName.get(plugin.name);\n if (existing && !options.replace) {\n throw new Error(`Plugin '${plugin.name}' is already registered`);\n }\n\n if (existing) {\n await this.unregister(existing.name);\n }\n\n let bucket = this.byType.get(plugin.type);\n if (!bucket) {\n bucket = new Map<string, AnyPlugin>();\n this.byType.set(plugin.type, bucket);\n }\n\n bucket.set(plugin.name, plugin);\n this.byName.set(plugin.name, plugin);\n await plugin.onLoad?.();\n }\n\n async registerAll(plugins: readonly AnyPlugin[], options: RegisterOptions = {}): Promise<void> {\n for (const plugin of plugins) {\n await this.register(plugin, options);\n }\n }\n\n async unregister(name: string): Promise<void> {\n const plugin = this.byName.get(name);\n if (!plugin) {\n return;\n }\n\n this.byName.delete(name);\n this.byType.get(plugin.type)?.delete(name);\n await plugin.onUnload?.();\n }\n\n get<T extends OboraPlugin>(type: PluginType, name: string): T {\n const plugin = this.byType.get(type)?.get(name);\n if (!plugin) {\n throw new Error(`Plugin '${name}' of type '${type}' was not found`);\n }\n\n return plugin as T;\n }\n\n has(type: PluginType, name: string): boolean {\n return this.byType.get(type)?.has(name) ?? false;\n }\n\n list(type?: PluginType): OboraPlugin[] {\n if (!type) {\n return [...this.byName.values()];\n }\n\n return [...(this.byType.get(type)?.values() ?? [])];\n }\n\n async clear(): Promise<void> {\n const names = [...this.byName.keys()];\n for (const name of names) {\n await this.unregister(name);\n }\n }\n}\n","import path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type { AnyPlugin } from \"./types.js\";\nimport { PluginRegistry } from \"./PluginRegistry.js\";\n\nexport class PluginLoader {\n private readonly loaded = new Map<string, AnyPlugin>();\n\n constructor(private readonly registry: PluginRegistry) {}\n\n async load(plugin: AnyPlugin, options: { replace?: boolean } = {}): Promise<void> {\n await this.registry.register(plugin, options);\n this.loaded.set(plugin.name, plugin);\n }\n\n async loadFromModule(modulePath: string, exportName = \"default\", options: { replace?: boolean } = {}): Promise<void> {\n const absolutePath = path.isAbsolute(modulePath) ? modulePath : path.resolve(process.cwd(), modulePath);\n const moduleUrl = pathToFileURL(absolutePath).href;\n const moduleExports = await import(moduleUrl);\n const candidate = moduleExports[exportName] as AnyPlugin | (() => AnyPlugin | Promise<AnyPlugin>);\n\n if (!candidate) {\n throw new Error(`Export '${exportName}' was not found in module '${modulePath}'`);\n }\n\n const plugin = typeof candidate === \"function\" ? await candidate() : candidate;\n await this.load(plugin, options);\n }\n\n async unload(name: string): Promise<void> {\n if (!this.loaded.has(name)) {\n return;\n }\n\n await this.registry.unregister(name);\n this.loaded.delete(name);\n }\n\n async unloadAll(): Promise<void> {\n const names = [...this.loaded.keys()];\n for (const name of names) {\n await this.unload(name);\n }\n }\n\n listLoaded(): string[] {\n return [...this.loaded.keys()];\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { InMemoryAuditStore } from \"../audit/InMemoryAuditStore.js\";\nimport type { AuditEvent, AuditFilter } from \"../audit/types.js\";\nimport { PipelinePattern } from \"../patterns/builtin/PipelinePattern.js\";\nimport { DiscussionPattern } from \"../patterns/builtin/DiscussionPattern.js\";\nimport { ConsensusPattern } from \"../patterns/builtin/ConsensusPattern.js\";\nimport { BrainstormPattern } from \"../patterns/builtin/BrainstormPattern.js\";\nimport { PeerReviewPattern } from \"../patterns/builtin/PeerReviewPattern.js\";\nimport { SupervisorPattern } from \"../patterns/builtin/SupervisorPattern.js\";\nimport { FanOutFanInPattern } from \"../patterns/builtin/FanOutFanInPattern.js\";\nimport { RedBluePattern } from \"../patterns/builtin/RedBluePattern.js\";\nimport { CompositePattern } from \"../patterns/builtin/CompositePattern.js\";\nimport type { PatternRegistry } from \"../patterns/PatternRegistry.js\";\nimport type {\n AgentPlugin,\n AnyPlugin,\n AuditStorePlugin,\n ConsensusRulePlugin,\n PatternPlugin,\n PolicyRulePlugin,\n RecoveryStrategyPlugin,\n StateTransformPlugin,\n ToolPlugin,\n} from \"./types.js\";\nimport type { PluginRegistry } from \"./PluginRegistry.js\";\n\nexport class BuiltinAgentPlugin implements AgentPlugin {\n readonly type = \"agent\" as const;\n readonly name = \"builtin-agent\";\n readonly version = \"1.0.0\";\n\n createAgent(config: unknown): unknown {\n return { kind: \"builtin-agent\", config };\n }\n}\n\nexport class FileWriteToolPlugin implements ToolPlugin {\n readonly type = \"tool\" as const;\n readonly name = \"file-write\";\n readonly version = \"1.0.0\";\n readonly schema = {\n type: \"object\",\n required: [\"path\", \"content\"],\n properties: {\n path: { type: \"string\" },\n content: { type: \"string\" },\n },\n };\n\n constructor(private readonly sandboxRoot = process.cwd()) {}\n\n async execute(params: unknown): Promise<{ path: string; bytes: number }> {\n if (!params || typeof params !== \"object\") {\n throw new Error(\"file-write params must be an object\");\n }\n\n const input = params as { path?: unknown; content?: unknown };\n if (typeof input.path !== \"string\" || input.path.trim().length === 0) {\n throw new Error(\"file-write params.path must be a non-empty string\");\n }\n\n if (typeof input.content !== \"string\") {\n throw new Error(\"file-write params.content must be a string\");\n }\n\n const resolved = path.resolve(this.sandboxRoot, input.path);\n const sandbox = path.resolve(this.sandboxRoot);\n\n if (!resolved.startsWith(`${sandbox}${path.sep}`) && resolved !== sandbox) {\n throw new Error(`Path '${input.path}' is outside sandbox root`);\n }\n\n await fs.mkdir(path.dirname(resolved), { recursive: true });\n await fs.writeFile(resolved, input.content, \"utf8\");\n\n return {\n path: resolved,\n bytes: Buffer.byteLength(input.content, \"utf8\"),\n };\n }\n}\n\nexport class PipelinePatternPlugin extends PipelinePattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"pipeline\";\n readonly version = \"1.0.0\";\n}\n\nexport class DiscussionPatternPlugin extends DiscussionPattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"discussion\";\n readonly version = \"1.0.0\";\n}\n\nexport class ConsensusPatternPlugin extends ConsensusPattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"consensus\";\n readonly version = \"1.0.0\";\n}\n\nexport class BrainstormPatternPlugin extends BrainstormPattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"brainstorming\";\n readonly version = \"1.0.0\";\n}\n\nexport class PeerReviewPatternPlugin extends PeerReviewPattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"peer-review\";\n readonly version = \"1.0.0\";\n}\n\nexport class SupervisorPatternPlugin extends SupervisorPattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"supervisor\";\n readonly version = \"1.0.0\";\n}\n\nexport class FanOutFanInPatternPlugin extends FanOutFanInPattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"fan-out-fan-in\";\n readonly version = \"1.0.0\";\n}\n\nexport class RedBluePatternPlugin extends RedBluePattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"red-blue\";\n readonly version = \"1.0.0\";\n}\n\nexport class CompositePatternPlugin extends CompositePattern implements PatternPlugin {\n readonly type = \"pattern\" as const;\n readonly name = \"composite\";\n readonly version = \"1.0.0\";\n\n constructor(registry: PatternRegistry) {\n super(registry);\n }\n}\n\nexport class AllowAllPolicyRulePlugin implements PolicyRulePlugin {\n readonly type = \"policy-rule\" as const;\n readonly name = \"allow-all-policy\";\n readonly version = \"1.0.0\";\n\n evaluate(): { type: \"allow\" } {\n return { type: \"allow\" };\n }\n}\n\nexport class RetryRecoveryStrategyPlugin implements RecoveryStrategyPlugin {\n readonly type = \"recovery-strategy\" as const;\n readonly name = \"retry-recovery\";\n readonly version = \"1.0.0\";\n\n async handle(): Promise<{ status: \"recovered\" }> {\n return { status: \"recovered\" };\n }\n}\n\nexport class MajorityConsensusRulePlugin implements ConsensusRulePlugin {\n readonly type = \"consensus-rule\" as const;\n readonly name = \"majority-consensus\";\n readonly version = \"1.0.0\";\n\n evaluate(votes: unknown[]): { status: \"pass\" | \"fail\"; approved: number; total: number } {\n const total = votes.length;\n const approved = votes.filter((vote) => !!vote && typeof vote === \"object\" && (vote as { approved?: boolean }).approved === true).length;\n\n return {\n status: approved >= Math.ceil(total / 2) ? \"pass\" : \"fail\",\n approved,\n total,\n };\n }\n}\n\nexport class InMemoryAuditStorePlugin implements AuditStorePlugin {\n readonly type = \"audit-store\" as const;\n readonly name = \"in-memory-audit-store\";\n readonly version = \"1.0.0\";\n\n private readonly store = new InMemoryAuditStore();\n\n async record(event: AuditEvent): Promise<void> {\n await this.store.record(event);\n }\n\n async query(filter: AuditFilter): Promise<AuditEvent[]> {\n return this.store.query(filter);\n }\n}\n\nexport class IdentityStateTransformPlugin implements StateTransformPlugin {\n readonly type = \"state-transform\" as const;\n readonly name = \"identity-transform\";\n readonly version = \"1.0.0\";\n\n transform(value: unknown): unknown {\n return value;\n }\n}\n\nexport function createBuiltinPlugins(options: { sandboxRoot?: string; patternRegistry?: PatternRegistry } = {}): AnyPlugin[] {\n const patternRegistry = options.patternRegistry;\n\n return [\n new BuiltinAgentPlugin(),\n new FileWriteToolPlugin(options.sandboxRoot),\n new PipelinePatternPlugin(),\n new DiscussionPatternPlugin(),\n new ConsensusPatternPlugin(),\n new BrainstormPatternPlugin(),\n new PeerReviewPatternPlugin(),\n new SupervisorPatternPlugin(),\n new FanOutFanInPatternPlugin(),\n new RedBluePatternPlugin(),\n ...(patternRegistry ? [new CompositePatternPlugin(patternRegistry)] : []),\n new AllowAllPolicyRulePlugin(),\n new RetryRecoveryStrategyPlugin(),\n new MajorityConsensusRulePlugin(),\n new InMemoryAuditStorePlugin(),\n new IdentityStateTransformPlugin(),\n ];\n}\n\nexport async function registerBuiltinPlugins(\n registry: PluginRegistry,\n options: { sandboxRoot?: string; replace?: boolean; patternRegistry?: PatternRegistry } = {}\n): Promise<void> {\n const builtins = createBuiltinPlugins({\n sandboxRoot: options.sandboxRoot,\n patternRegistry: options.patternRegistry,\n });\n for (const plugin of builtins) {\n await registry.register(plugin, { replace: options.replace });\n }\n}\n","/**\n * M6-01: InMemoryStorageAdapter — Test/dev adapter\n */\n\nimport type {\n StorageAdapter,\n RunRecord,\n StepRecord,\n ArtifactRecord,\n RunFilter,\n CheckpointRecord,\n CostRecord,\n CostSummary,\n StructuredAuditEvent,\n} from \"./types.js\";\n\nexport class InMemoryStorageAdapter implements StorageAdapter {\n private readonly runs = new Map<string, RunRecord>();\n private readonly steps: StepRecord[] = [];\n private readonly artifacts = new Map<string, ArtifactRecord>();\n private readonly checkpoints: CheckpointRecord[] = [];\n private readonly costs: CostRecord[] = [];\n private readonly auditEvents: StructuredAuditEvent[] = [];\n\n async saveRun(record: RunRecord): Promise<void> {\n this.runs.set(record.id, structuredClone(record));\n }\n\n async getRun(runId: string): Promise<RunRecord | null> {\n const r = this.runs.get(runId);\n return r ? structuredClone(r) : null;\n }\n\n async listRuns(filter: RunFilter): Promise<RunRecord[]> {\n let results = Array.from(this.runs.values());\n\n if (filter.status) {\n results = results.filter((r) => r.status === filter.status);\n }\n if (filter.workflowName) {\n results = results.filter((r) => r.workflowName === filter.workflowName);\n }\n if (filter.from) {\n results = results.filter((r) => r.startedAt >= filter.from!);\n }\n if (filter.to) {\n results = results.filter((r) => r.startedAt <= filter.to!);\n }\n\n // Sort by startedAt descending\n results.sort((a, b) => b.startedAt.localeCompare(a.startedAt));\n\n const offset = filter.offset ?? 0;\n const limit = filter.limit ?? 100;\n return results.slice(offset, offset + limit).map((r) => structuredClone(r));\n }\n\n async saveStep(record: StepRecord): Promise<void> {\n const idx = this.steps.findIndex((s) => s.id === record.id);\n if (idx >= 0) {\n this.steps[idx] = structuredClone(record);\n } else {\n this.steps.push(structuredClone(record));\n }\n }\n\n async getSteps(runId: string): Promise<StepRecord[]> {\n return this.steps\n .filter((s) => s.runId === runId)\n .map((s) => structuredClone(s));\n }\n\n async saveArtifact(record: ArtifactRecord): Promise<ArtifactRecord> {\n const clone = structuredClone(record);\n this.artifacts.set(clone.id, clone);\n return structuredClone(clone);\n }\n\n async getArtifacts(runId: string, stepName?: string): Promise<ArtifactRecord[]> {\n return Array.from(this.artifacts.values())\n .filter((a) => a.runId === runId && !a.deletedAt)\n .filter((a) => (stepName ? a.stepName === stepName : true))\n .map((a) => structuredClone(a));\n }\n\n async deleteArtifact(artifactId: string): Promise<void> {\n const a = this.artifacts.get(artifactId);\n if (a) {\n a.deletedAt = new Date().toISOString();\n }\n }\n\n async saveCheckpoint(record: CheckpointRecord): Promise<void> {\n this.checkpoints.push(structuredClone(record));\n }\n\n async getLatestCheckpoint(runId: string): Promise<CheckpointRecord | null> {\n const matching = this.checkpoints\n .filter((c) => c.runId === runId)\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n return matching.length > 0 ? structuredClone(matching[0]) : null;\n }\n\n async saveCost(record: CostRecord): Promise<void> {\n this.costs.push(structuredClone(record));\n }\n\n async getCosts(runId: string, stepName?: string): Promise<CostRecord[]> {\n return this.costs\n .filter((c) => c.runId === runId)\n .filter((c) => (stepName ? c.stepName === stepName : true))\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt))\n .map((c) => structuredClone(c));\n }\n\n async getRunCostSummary(runId: string): Promise<CostSummary> {\n const costs = await this.getCosts(runId);\n const byStep = new Map<string, { stepName: string; tokens: number; costUsd: number }>();\n const byModel = new Map<string, { model: string; tokens: number; costUsd: number }>();\n\n let totalTokens = 0;\n let totalCostUsd = 0;\n\n for (const c of costs) {\n totalTokens += c.totalTokens;\n totalCostUsd += c.costUsd;\n\n const step = byStep.get(c.stepName) ?? { stepName: c.stepName, tokens: 0, costUsd: 0 };\n step.tokens += c.totalTokens;\n step.costUsd += c.costUsd;\n byStep.set(c.stepName, step);\n\n const model = byModel.get(c.model) ?? { model: c.model, tokens: 0, costUsd: 0 };\n model.tokens += c.totalTokens;\n model.costUsd += c.costUsd;\n byModel.set(c.model, model);\n }\n\n return {\n totalTokens,\n totalCostUsd,\n byStep: Array.from(byStep.values()),\n byModel: Array.from(byModel.values()),\n };\n }\n\n async saveAuditEvent(event: StructuredAuditEvent): Promise<void> {\n this.auditEvents.push(structuredClone(event));\n }\n\n async getAuditTimeline(runId: string, stepName?: string): Promise<StructuredAuditEvent[]> {\n return this.auditEvents\n .filter((e) => e.runId === runId)\n .filter((e) => (stepName ? e.stepName === stepName : true))\n .sort((a, b) => a.timestamp.localeCompare(b.timestamp))\n .map((e) => structuredClone(e));\n }\n}\n","/**\n * M6-01: SQLiteStorageAdapter — Default persistence adapter using better-sqlite3\n */\n\nimport { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport type {\n StorageAdapter,\n RunRecord,\n StepRecord,\n ArtifactRecord,\n RunFilter,\n CheckpointRecord,\n CostRecord,\n CostSummary,\n StructuredAuditEvent,\n} from \"./types.js\";\n\n// Lazy import to keep better-sqlite3 optional at runtime\nlet Database: typeof import(\"better-sqlite3\").default;\n\nasync function loadDatabase() {\n if (!Database) {\n const mod = await import(\"better-sqlite3\");\n Database = mod.default;\n }\n return Database;\n}\n\nexport interface SQLiteStorageAdapterOptions {\n path: string;\n}\n\nexport class SQLiteStorageAdapter implements StorageAdapter {\n private db!: import(\"better-sqlite3\").Database;\n private initialized = false;\n\n constructor(private readonly options: SQLiteStorageAdapterOptions) {}\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n await mkdir(dirname(this.options.path), { recursive: true });\n const Ctor = await loadDatabase();\n this.db = new Ctor(this.options.path);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.createTables();\n this.initialized = true;\n }\n\n private createTables(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS runs (\n id TEXT PRIMARY KEY,\n workflow_name TEXT NOT NULL,\n status TEXT NOT NULL,\n input TEXT NOT NULL,\n started_at TEXT NOT NULL,\n completed_at TEXT,\n metadata TEXT\n );\n\n CREATE TABLE IF NOT EXISTS steps (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n step_name TEXT NOT NULL,\n status TEXT NOT NULL,\n input TEXT,\n output TEXT,\n error TEXT,\n started_at TEXT NOT NULL,\n completed_at TEXT,\n duration_ms INTEGER,\n FOREIGN KEY (run_id) REFERENCES runs(id)\n );\n\n CREATE TABLE IF NOT EXISTS artifacts (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n step_name TEXT NOT NULL,\n name TEXT NOT NULL,\n mime_type TEXT NOT NULL,\n size_bytes INTEGER NOT NULL,\n storage_ref TEXT NOT NULL,\n created_at TEXT NOT NULL,\n deleted_at TEXT,\n FOREIGN KEY (run_id) REFERENCES runs(id)\n );\n\n CREATE TABLE IF NOT EXISTS checkpoints (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n step_name TEXT NOT NULL,\n state_snapshot TEXT NOT NULL,\n completed_steps TEXT NOT NULL,\n policy_hash TEXT NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES runs(id)\n );\n\n CREATE TABLE IF NOT EXISTS costs (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n step_name TEXT NOT NULL,\n model TEXT NOT NULL,\n prompt_tokens INTEGER NOT NULL,\n completion_tokens INTEGER NOT NULL,\n total_tokens INTEGER NOT NULL,\n cost_usd REAL NOT NULL,\n latency_ms INTEGER NOT NULL,\n created_at TEXT NOT NULL,\n FOREIGN KEY (run_id) REFERENCES runs(id)\n );\n\n CREATE TABLE IF NOT EXISTS audit_events (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n step_name TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n category TEXT NOT NULL,\n action TEXT NOT NULL,\n actor TEXT NOT NULL,\n detail TEXT NOT NULL,\n vote TEXT,\n FOREIGN KEY (run_id) REFERENCES runs(id)\n );\n\n CREATE INDEX IF NOT EXISTS idx_steps_run_id ON steps(run_id);\n CREATE INDEX IF NOT EXISTS idx_artifacts_run_id ON artifacts(run_id);\n CREATE INDEX IF NOT EXISTS idx_runs_status ON runs(status);\n CREATE INDEX IF NOT EXISTS idx_runs_workflow ON runs(workflow_name);\n CREATE INDEX IF NOT EXISTS idx_checkpoints_run_id ON checkpoints(run_id);\n CREATE INDEX IF NOT EXISTS idx_costs_run_id ON costs(run_id);\n CREATE INDEX IF NOT EXISTS idx_costs_run_step ON costs(run_id, step_name);\n CREATE INDEX IF NOT EXISTS idx_audit_events_run_id ON audit_events(run_id);\n CREATE INDEX IF NOT EXISTS idx_audit_events_run_step ON audit_events(run_id, step_name);\n CREATE INDEX IF NOT EXISTS idx_audit_events_run_ts ON audit_events(run_id, timestamp);\n `);\n }\n\n async saveRun(record: RunRecord): Promise<void> {\n await this.ensureInitialized();\n this.db\n .prepare(\n `INSERT INTO runs (id, workflow_name, status, input, started_at, completed_at, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n status = excluded.status,\n completed_at = excluded.completed_at,\n metadata = excluded.metadata`\n )\n .run(\n record.id,\n record.workflowName,\n record.status,\n JSON.stringify(record.input),\n record.startedAt,\n record.completedAt ?? null,\n record.metadata ? JSON.stringify(record.metadata) : null\n );\n }\n\n async getRun(runId: string): Promise<RunRecord | null> {\n await this.ensureInitialized();\n const row = this.db\n .prepare(\"SELECT * FROM runs WHERE id = ?\")\n .get(runId) as Record<string, unknown> | undefined;\n return row ? this.toRunRecord(row) : null;\n }\n\n async listRuns(filter: RunFilter): Promise<RunRecord[]> {\n await this.ensureInitialized();\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter.status) {\n conditions.push(\"status = ?\");\n params.push(filter.status);\n }\n if (filter.workflowName) {\n conditions.push(\"workflow_name = ?\");\n params.push(filter.workflowName);\n }\n if (filter.from) {\n conditions.push(\"started_at >= ?\");\n params.push(filter.from);\n }\n if (filter.to) {\n conditions.push(\"started_at <= ?\");\n params.push(filter.to);\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const limit = filter.limit ?? 100;\n const offset = filter.offset ?? 0;\n\n const rows = this.db\n .prepare(\n `SELECT * FROM runs ${where} ORDER BY started_at DESC LIMIT ? OFFSET ?`\n )\n .all(...params, limit, offset) as Record<string, unknown>[];\n\n return rows.map((r) => this.toRunRecord(r));\n }\n\n async saveStep(record: StepRecord): Promise<void> {\n await this.ensureInitialized();\n this.db\n .prepare(\n `INSERT INTO steps (id, run_id, step_name, status, input, output, error, started_at, completed_at, duration_ms)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n status = excluded.status,\n output = excluded.output,\n error = excluded.error,\n completed_at = excluded.completed_at,\n duration_ms = excluded.duration_ms`\n )\n .run(\n record.id,\n record.runId,\n record.stepName,\n record.status,\n record.input ? JSON.stringify(record.input) : null,\n record.output ? JSON.stringify(record.output) : null,\n record.error ? JSON.stringify(record.error) : null,\n record.startedAt,\n record.completedAt ?? null,\n record.durationMs ?? null\n );\n }\n\n async getSteps(runId: string): Promise<StepRecord[]> {\n await this.ensureInitialized();\n const rows = this.db\n .prepare(\"SELECT * FROM steps WHERE run_id = ? ORDER BY started_at ASC\")\n .all(runId) as Record<string, unknown>[];\n return rows.map((r) => this.toStepRecord(r));\n }\n\n async saveArtifact(record: ArtifactRecord): Promise<ArtifactRecord> {\n await this.ensureInitialized();\n this.db\n .prepare(\n `INSERT INTO artifacts (id, run_id, step_name, name, mime_type, size_bytes, storage_ref, created_at, deleted_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n deleted_at = excluded.deleted_at`\n )\n .run(\n record.id,\n record.runId,\n record.stepName,\n record.name,\n record.mimeType,\n record.sizeBytes,\n record.storageRef,\n record.createdAt,\n record.deletedAt ?? null\n );\n return { ...record };\n }\n\n async getArtifacts(runId: string, stepName?: string): Promise<ArtifactRecord[]> {\n await this.ensureInitialized();\n if (stepName) {\n const rows = this.db\n .prepare(\n \"SELECT * FROM artifacts WHERE run_id = ? AND step_name = ? AND deleted_at IS NULL ORDER BY created_at ASC\"\n )\n .all(runId, stepName) as Record<string, unknown>[];\n return rows.map((r) => this.toArtifactRecord(r));\n }\n const rows = this.db\n .prepare(\n \"SELECT * FROM artifacts WHERE run_id = ? AND deleted_at IS NULL ORDER BY created_at ASC\"\n )\n .all(runId) as Record<string, unknown>[];\n return rows.map((r) => this.toArtifactRecord(r));\n }\n\n async deleteArtifact(artifactId: string): Promise<void> {\n await this.ensureInitialized();\n this.db\n .prepare(\"UPDATE artifacts SET deleted_at = ? WHERE id = ?\")\n .run(new Date().toISOString(), artifactId);\n }\n\n async saveCheckpoint(record: CheckpointRecord): Promise<void> {\n await this.ensureInitialized();\n this.db\n .prepare(\n `INSERT INTO checkpoints (id, run_id, step_name, state_snapshot, completed_steps, policy_hash, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n state_snapshot = excluded.state_snapshot,\n completed_steps = excluded.completed_steps,\n policy_hash = excluded.policy_hash`\n )\n .run(\n record.id,\n record.runId,\n record.stepName,\n JSON.stringify(record.stateSnapshot),\n JSON.stringify(record.completedSteps),\n record.policyHash,\n record.createdAt\n );\n }\n\n async getLatestCheckpoint(runId: string): Promise<CheckpointRecord | null> {\n await this.ensureInitialized();\n const row = this.db\n .prepare(\"SELECT * FROM checkpoints WHERE run_id = ? ORDER BY created_at DESC LIMIT 1\")\n .get(runId) as Record<string, unknown> | undefined;\n return row ? this.toCheckpointRecord(row) : null;\n }\n\n async saveCost(record: CostRecord): Promise<void> {\n await this.ensureInitialized();\n this.db\n .prepare(\n `INSERT INTO costs (id, run_id, step_name, model, prompt_tokens, completion_tokens, total_tokens, cost_usd, latency_ms, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(\n record.id,\n record.runId,\n record.stepName,\n record.model,\n record.promptTokens,\n record.completionTokens,\n record.totalTokens,\n record.costUsd,\n record.latencyMs,\n record.createdAt,\n );\n }\n\n async getCosts(runId: string, stepName?: string): Promise<CostRecord[]> {\n await this.ensureInitialized();\n const rows = stepName\n ? (this.db\n .prepare(\"SELECT * FROM costs WHERE run_id = ? AND step_name = ? ORDER BY created_at ASC\")\n .all(runId, stepName) as Record<string, unknown>[])\n : (this.db\n .prepare(\"SELECT * FROM costs WHERE run_id = ? ORDER BY created_at ASC\")\n .all(runId) as Record<string, unknown>[]);\n return rows.map((r) => this.toCostRecord(r));\n }\n\n async getRunCostSummary(runId: string): Promise<CostSummary> {\n await this.ensureInitialized();\n\n const total = this.db\n .prepare(\"SELECT COALESCE(SUM(total_tokens), 0) AS tokens, COALESCE(SUM(cost_usd), 0) AS cost FROM costs WHERE run_id = ?\")\n .get(runId) as { tokens: number; cost: number };\n\n const byStep = this.db\n .prepare(\n \"SELECT step_name, SUM(total_tokens) AS tokens, SUM(cost_usd) AS cost_usd FROM costs WHERE run_id = ? GROUP BY step_name ORDER BY step_name ASC\"\n )\n .all(runId) as Array<{ step_name: string; tokens: number; cost_usd: number }>;\n\n const byModel = this.db\n .prepare(\n \"SELECT model, SUM(total_tokens) AS tokens, SUM(cost_usd) AS cost_usd FROM costs WHERE run_id = ? GROUP BY model ORDER BY model ASC\"\n )\n .all(runId) as Array<{ model: string; tokens: number; cost_usd: number }>;\n\n return {\n totalTokens: total.tokens,\n totalCostUsd: total.cost,\n byStep: byStep.map((r) => ({ stepName: r.step_name, tokens: r.tokens, costUsd: r.cost_usd })),\n byModel: byModel.map((r) => ({ model: r.model, tokens: r.tokens, costUsd: r.cost_usd })),\n };\n }\n\n async saveAuditEvent(event: StructuredAuditEvent): Promise<void> {\n await this.ensureInitialized();\n this.db\n .prepare(\n `INSERT INTO audit_events (id, run_id, step_name, timestamp, category, action, actor, detail, vote)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n timestamp = excluded.timestamp,\n category = excluded.category,\n action = excluded.action,\n actor = excluded.actor,\n detail = excluded.detail,\n vote = excluded.vote`\n )\n .run(\n event.id,\n event.runId,\n event.stepName,\n event.timestamp,\n event.category,\n event.action,\n event.actor,\n JSON.stringify(event.detail),\n event.vote ? JSON.stringify(event.vote) : null,\n );\n }\n\n async getAuditTimeline(runId: string, stepName?: string): Promise<StructuredAuditEvent[]> {\n await this.ensureInitialized();\n const rows = stepName\n ? (this.db\n .prepare(\"SELECT * FROM audit_events WHERE run_id = ? AND step_name = ? ORDER BY timestamp ASC\")\n .all(runId, stepName) as Record<string, unknown>[])\n : (this.db\n .prepare(\"SELECT * FROM audit_events WHERE run_id = ? ORDER BY timestamp ASC\")\n .all(runId) as Record<string, unknown>[]);\n\n return rows.map((r) => this.toStructuredAuditEvent(r));\n }\n\n private toCheckpointRecord(row: Record<string, unknown>): CheckpointRecord {\n return {\n id: row.id as string,\n runId: row.run_id as string,\n stepName: row.step_name as string,\n stateSnapshot: this.safeJsonParse<unknown>(row.state_snapshot as string, `checkpoints.state_snapshot [id=${row.id}]`),\n completedSteps: this.safeJsonParse<string[]>(row.completed_steps as string, `checkpoints.completed_steps [id=${row.id}]`),\n policyHash: row.policy_hash as string,\n createdAt: row.created_at as string,\n };\n }\n\n /** Close the database connection */\n close(): void {\n if (this.initialized) {\n this.db.close();\n this.initialized = false;\n }\n }\n\n // ── Row mappers ──\n\n /**\n * Safely parse a JSON string, returning a descriptive error on failure\n * instead of crashing with a generic SyntaxError.\n */\n private safeJsonParse<T>(json: string, context: string): T {\n try {\n return JSON.parse(json) as T;\n } catch (cause) {\n const preview = json.length > 80 ? json.slice(0, 80) + \"…\" : json;\n throw new Error(\n `Corrupt JSON in ${context}: ${(cause as Error).message} (value: ${preview})`,\n { cause },\n );\n }\n }\n\n private toRunRecord(row: Record<string, unknown>): RunRecord {\n return {\n id: row.id as string,\n workflowName: row.workflow_name as string,\n status: row.status as RunRecord[\"status\"],\n input: this.safeJsonParse<Record<string, unknown>>(row.input as string, `runs.input [id=${row.id}]`),\n startedAt: row.started_at as string,\n completedAt: (row.completed_at as string) || undefined,\n metadata: row.metadata\n ? this.safeJsonParse<Record<string, unknown>>(row.metadata as string, `runs.metadata [id=${row.id}]`)\n : undefined,\n };\n }\n\n private toStepRecord(row: Record<string, unknown>): StepRecord {\n return {\n id: row.id as string,\n runId: row.run_id as string,\n stepName: row.step_name as string,\n status: row.status as StepRecord[\"status\"],\n input: row.input\n ? this.safeJsonParse<Record<string, unknown>>(row.input as string, `steps.input [id=${row.id}]`)\n : undefined,\n output: row.output\n ? this.safeJsonParse<Record<string, unknown>>(row.output as string, `steps.output [id=${row.id}]`)\n : undefined,\n error: row.error\n ? this.safeJsonParse<{ code: string; message: string; stack?: string }>(row.error as string, `steps.error [id=${row.id}]`)\n : undefined,\n startedAt: row.started_at as string,\n completedAt: (row.completed_at as string) || undefined,\n durationMs: row.duration_ms != null ? (row.duration_ms as number) : undefined,\n };\n }\n\n private toArtifactRecord(row: Record<string, unknown>): ArtifactRecord {\n return {\n id: row.id as string,\n runId: row.run_id as string,\n stepName: row.step_name as string,\n name: row.name as string,\n mimeType: row.mime_type as string,\n sizeBytes: row.size_bytes as number,\n storageRef: row.storage_ref as string,\n createdAt: row.created_at as string,\n deletedAt: (row.deleted_at as string) || undefined,\n };\n }\n\n private toCostRecord(row: Record<string, unknown>): CostRecord {\n return {\n id: row.id as string,\n runId: row.run_id as string,\n stepName: row.step_name as string,\n model: row.model as string,\n promptTokens: row.prompt_tokens as number,\n completionTokens: row.completion_tokens as number,\n totalTokens: row.total_tokens as number,\n costUsd: row.cost_usd as number,\n latencyMs: row.latency_ms as number,\n createdAt: row.created_at as string,\n };\n }\n\n private toStructuredAuditEvent(row: Record<string, unknown>): StructuredAuditEvent {\n return {\n id: row.id as string,\n runId: row.run_id as string,\n stepName: row.step_name as string,\n timestamp: row.timestamp as string,\n category: row.category as StructuredAuditEvent[\"category\"],\n action: row.action as string,\n actor: row.actor as string,\n detail: this.safeJsonParse<Record<string, unknown>>(row.detail as string, `audit_events.detail [id=${row.id}]`),\n vote: row.vote\n ? this.safeJsonParse<StructuredAuditEvent[\"vote\"]>(row.vote as string, `audit_events.vote [id=${row.id}]`)\n : undefined,\n };\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, readdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, join, normalize, relative, resolve } from \"node:path\";\n\nimport type { ArtifactRecord, ArtifactStore } from \"./types.js\";\n\ninterface LocalFileArtifactStoreOptions {\n basePath?: string;\n}\n\nconst META_SUFFIX = \".meta.json\";\n\nexport class LocalFileArtifactStore implements ArtifactStore {\n private readonly basePath: string;\n\n constructor(options: LocalFileArtifactStoreOptions = {}) {\n this.basePath = options.basePath ?? \"./data/artifacts\";\n }\n\n async save(runId: string, stepName: string, name: string, data: Buffer, mime: string): Promise<ArtifactRecord> {\n const id = randomUUID();\n const safeRunId = this.sanitizeSegment(runId, \"runId\");\n const safeStepName = this.sanitizeSegment(stepName, \"stepName\");\n const safeName = this.sanitizeSegment(name, \"name\", { allowDots: true });\n\n const dir = this.resolveInsideBase(safeRunId, safeStepName);\n const storedName = `${id}__${safeName}`;\n const filePath = this.resolveInsideBase(safeRunId, safeStepName, storedName);\n await mkdir(dir, { recursive: true });\n await writeFile(filePath, data);\n\n const record: ArtifactRecord = {\n id,\n runId,\n stepName,\n name,\n mime,\n size: data.byteLength,\n path: filePath,\n createdAt: new Date().toISOString(),\n };\n\n const metaPath = this.metaPath(filePath);\n const tempMetaPath = `${metaPath}.tmp`;\n await writeFile(tempMetaPath, JSON.stringify(record, null, 2), \"utf-8\");\n await rename(tempMetaPath, metaPath);\n return record;\n }\n\n async get(artifactId: string): Promise<{ record: ArtifactRecord; data: Buffer }> {\n const metas = await this.scanMetaFiles();\n const meta = metas.find((m) => m.id === artifactId);\n if (!meta) {\n throw new Error(`Artifact not found: ${artifactId}`);\n }\n const data = await readFile(meta.path);\n return { record: meta, data };\n }\n\n async list(runId: string, stepName?: string): Promise<ArtifactRecord[]> {\n const metas = await this.scanMetaFiles();\n return metas\n .filter((m) => m.runId === runId && (stepName ? m.stepName === stepName : true))\n .sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n }\n\n async delete(artifactId: string): Promise<void> {\n const metas = await this.scanMetaFiles();\n const meta = metas.find((m) => m.id === artifactId);\n if (!meta) {\n return;\n }\n\n await rm(meta.path, { force: true });\n await rm(this.metaPath(meta.path), { force: true });\n\n // best-effort empty directory cleanup\n const stepDir = dirname(meta.path);\n const runDir = dirname(stepDir);\n await this.cleanupIfEmpty(stepDir);\n await this.cleanupIfEmpty(runDir);\n }\n\n private async scanMetaFiles(): Promise<ArtifactRecord[]> {\n const records: ArtifactRecord[] = [];\n await this.walk(this.basePath, async (path) => {\n if (!path.endsWith(META_SUFFIX)) return;\n const raw = await readFile(path, \"utf-8\");\n try {\n const parsed = JSON.parse(raw) as ArtifactRecord;\n records.push(parsed);\n } catch {\n // ignore corrupted meta files; valid records remain accessible\n }\n });\n return records;\n }\n\n private async walk(path: string, onFile: (path: string) => Promise<void>): Promise<void> {\n let entries: string[];\n try {\n entries = await readdir(path);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n const full = join(path, entry);\n const st = await stat(full);\n if (st.isDirectory()) {\n await this.walk(full, onFile);\n } else if (st.isFile()) {\n await onFile(full);\n }\n }\n }\n\n private metaPath(filePath: string): string {\n return `${filePath}${META_SUFFIX}`;\n }\n\n private sanitizeSegment(value: string, field: string, options: { allowDots?: boolean } = {}): string {\n const normalized = normalize(value).replace(/\\\\/g, \"/\").trim();\n if (!normalized || normalized === \".\" || normalized === \"..\") {\n throw new Error(`Invalid artifact ${field}`);\n }\n\n const parts = normalized.split(\"/\").filter(Boolean);\n if (parts.length !== 1) {\n throw new Error(`Invalid artifact ${field}: path separators are not allowed`);\n }\n\n const [segment] = parts;\n if (segment === undefined) {\n throw new Error(`Invalid artifact ${field}: empty path segment`);\n }\n if (!options.allowDots && segment.includes(\".\")) {\n throw new Error(`Invalid artifact ${field}: dots are not allowed`);\n }\n if (segment.includes(\"..\")) {\n throw new Error(`Invalid artifact ${field}`);\n }\n\n return segment;\n }\n\n private resolveInsideBase(...segments: string[]): string {\n const base = resolve(this.basePath);\n const target = resolve(base, ...segments);\n const rel = relative(base, target);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n throw new Error(\"Artifact path escapes basePath\");\n }\n return target;\n }\n\n private async cleanupIfEmpty(path: string): Promise<void> {\n try {\n const entries = await readdir(path);\n if (entries.length === 0) {\n try {\n await rm(path, { recursive: true, force: true });\n } catch {\n // best-effort in concurrent delete scenarios\n }\n }\n } catch {\n // ignore\n }\n }\n}\n","/**\n * M6-02: CheckpointableFactory registry\n *\n * Manages type→factory mappings for restoring checkpointed state.\n */\n\nimport type { CheckpointableFactory } from \"../storage/types.js\";\n\nexport class CheckpointFactoryNotFoundError extends Error {\n constructor(public readonly typeName: string) {\n super(`CheckpointableFactory not registered for type: ${typeName}`);\n this.name = \"CheckpointFactoryNotFoundError\";\n }\n}\n\nexport class CheckpointFactoryRegistry {\n private readonly factories = new Map<string, CheckpointableFactory<unknown>>();\n\n register<T>(typeName: string, factory: CheckpointableFactory<T>): void {\n this.factories.set(typeName, factory as CheckpointableFactory<unknown>);\n }\n\n get<T>(typeName: string): CheckpointableFactory<T> {\n const factory = this.factories.get(typeName);\n if (!factory) {\n throw new CheckpointFactoryNotFoundError(typeName);\n }\n return factory as CheckpointableFactory<T>;\n }\n\n has(typeName: string): boolean {\n return this.factories.has(typeName);\n }\n}\n","import { getModel, EventStream, type AssistantMessage, type Message, type Model, type KnownProvider, Type } from \"@mariozechner/pi-ai\";\nimport { Agent, type AgentEvent, type AgentMessage, type AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport { mkdir, open, readdir, stat, unlink, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve, sep } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { LLMAdapter, ChatMessage } from \"../llm/adapter\";\nimport type { Blackboard } from \"../../blackboard/core/blackboard.js\";\nimport type { AgentId } from \"../types\";\n\nexport type { AgentId };\n\nexport enum AgentRole {\n ANALYST = \"analyst\",\n EXECUTOR = \"executor\",\n VERIFIER = \"verifier\",\n DIRECTOR = \"director\",\n}\n\nexport enum AgentState {\n IDLE = \"idle\",\n THINKING = \"thinking\",\n ACTING = \"acting\",\n WAITING = \"waiting\",\n ERROR = \"error\",\n}\n\nexport enum MeetingPhase {\n OPENING = \"opening\",\n DISCUSSION = \"discussion\",\n VOTING = \"voting\",\n CONSENSUS = \"consensus\",\n CLOSING = \"closing\",\n ESCALATION = \"escalation\",\n}\n\nexport interface AgentStatus {\n id: AgentId;\n role: AgentRole;\n state: AgentState;\n lastActivity: Date;\n currentTask?: string;\n errorCount: number;\n}\n\nexport interface AgentContext {\n sessionId: string;\n board: Blackboard;\n currentTask?: Task;\n history: ChatMessage[];\n signal?: AbortSignal;\n}\n\nexport interface Task {\n id: string;\n type: string;\n description: string;\n input: Record<string, unknown>;\n priority: number;\n deadline?: Date;\n metadata?: Record<string, unknown>;\n}\n\nexport interface TaskResult {\n taskId: string;\n success: boolean;\n output: unknown;\n error?: Error;\n duration: number;\n tokensUsed: {\n prompt: number;\n completion: number;\n total: number;\n };\n}\n\nexport interface RuntimeExtensions {\n tools?: AgentTool[];\n systemPromptAppend?: string;\n}\n\ninterface BoardReadParams {\n path: string;\n}\n\ninterface RoleActionParams {\n content: string;\n}\n\ninterface BoardWriteParams {\n result: unknown;\n}\n\ninterface FileWriteParams {\n path: string;\n content: string;\n}\n\ninterface FileReadParams {\n path: string;\n}\n\ninterface FileListParams {\n path: string;\n}\n\ninterface ShellExecParams {\n command: string;\n}\n\nexport abstract class BaseAgent {\n readonly id: AgentId;\n readonly role: AgentRole;\n protected state: AgentState = AgentState.IDLE;\n protected llm: LLMAdapter;\n protected systemPrompt: string;\n protected runtimeTools: AgentTool[] = [];\n protected runtimeSystemPromptAppend = \"\";\n protected errorCount: number = 0;\n protected maxErrors: number = 3;\n protected thinkMaxTokens: number;\n protected executeMaxTokens: number;\n\n private readonly BLOCKED_PATTERNS: RegExp[] = [\n // Destructive file operations\n /(?:^|\\s)rm\\s+-[a-z\\-\\s]*r[a-z\\-\\s]*f[a-z\\-\\s]*\\s+(?:--no-preserve-root\\s+)?(?:\\/|~|\\.)/i,\n /(?:^|\\s)rm\\s+--no-preserve-root\\s+-[a-z\\-\\s]*r[a-z\\-\\s]*f[a-z\\-\\s]*\\s+(?:\\/|~|\\.)/i,\n /(?:^|\\s)rm\\s+(?:-[a-zA-Z]+\\s+)+(?:\\/|~|\\.)/i,\n /(?:^|\\s)rm\\s+(?:--[a-zA-Z\\-]+\\s+)*(?:\\/|~|\\.)/i,\n // Pipe to shell execution\n /\\|\\s*(?:sh|bash|zsh|ksh|dash)(?:\\s|$)/i,\n // Shell wrapper execution (sh -c, bash -c, etc.)\n /(?:^|\\s)(?:sh|bash|zsh|ksh|dash)\\s+-[a-z]*c\\s+/i,\n // Command substitution with dangerous commands\n /\\$\\([^)]*(?:rm|curl|wget|chmod|sudo|mkfs|dd)[^)]*\\)/i,\n // Backtick command substitution with dangerous commands\n /`[^`]*(?:rm|curl|wget|chmod|sudo|mkfs|dd)[^`]*`/i,\n // Base64 decode to shell\n /base64\\s+(?:-d|--decode)\\s*\\|\\s*(?:sh|bash|zsh)/i,\n // Dangerous permissions\n /(?:^|\\s)chmod\\s+(?:777|a\\+rwx)(?:\\s|$)/i,\n // Privilege escalation\n /(?:^|\\s)sudo(?:\\s|$)/i,\n // Filesystem destruction\n /(?:^|\\s)mkfs(?:\\.|\\s|$)/i,\n /(?:^|\\s)dd\\s+(?:if|of)=/i,\n />\\s*\\/dev\\/sd[a-z](?:\\d+)?/i,\n // Fork bomb\n /:\\(\\)\\{:\\|:&\\};:/,\n // Standalone network I/O commands\n /^\\s*curl(?:\\s|$)/i,\n /^\\s*wget(?:\\s|$)/i,\n // Environment variable dump (exact match only)\n /^(?:env|printenv)$/i,\n ];\n\n private coreAgent?: Agent;\n private unsubscribe?: () => void;\n private currentContext?: AgentContext;\n private currentTask?: Task;\n private latestUsage = { prompt: 0, completion: 0, total: 0 };\n\n constructor(config: BaseAgentConfig) {\n this.id = config.id ?? `${config.role}-${Date.now()}`;\n this.role = config.role;\n this.llm = config.llm;\n this.systemPrompt = config.systemPrompt ?? this.getDefaultSystemPrompt();\n this.maxErrors = config.maxErrors ?? 3;\n this.thinkMaxTokens = config.thinkMaxTokens ?? 2048;\n this.executeMaxTokens = config.executeMaxTokens ?? 8192;\n\n this.coreAgent = this.createPiAgent(config);\n }\n\n async execute(task: Task, context: AgentContext): Promise<TaskResult> {\n if (this.hasExceededMaxErrors()) {\n this.state = AgentState.ERROR;\n return {\n taskId: task.id,\n success: false,\n output: null,\n error: new Error(`Agent ${this.id} has exceeded maximum error count (${this.maxErrors})`),\n duration: 0,\n tokensUsed: { prompt: 0, completion: 0, total: 0 },\n };\n }\n\n const startTime = Date.now();\n this.currentContext = context;\n this.currentTask = task;\n this.latestUsage = { prompt: 0, completion: 0, total: 0 };\n this.state = AgentState.THINKING;\n\n try {\n const observation = await this.observe(context);\n let output: unknown;\n\n if (this.coreAgent) {\n output = await this.executeWithPiAgent(task, observation, context);\n } else {\n const { action, usage } = await this.think(task, observation, context);\n this.state = AgentState.ACTING;\n output = await this.act(action, context);\n await this.report(task, output, context);\n this.latestUsage = {\n prompt: usage.promptTokens,\n completion: usage.completionTokens,\n total: usage.totalTokens,\n };\n }\n\n this.state = AgentState.IDLE;\n this.errorCount = 0;\n return {\n taskId: task.id,\n success: true,\n output,\n duration: Date.now() - startTime,\n tokensUsed: this.latestUsage,\n };\n } catch (error) {\n this.state = AgentState.ERROR;\n this.errorCount++;\n return {\n taskId: task.id,\n success: false,\n output: null,\n error: error as Error,\n duration: Date.now() - startTime,\n tokensUsed: { prompt: 0, completion: 0, total: 0 },\n };\n } finally {\n this.currentContext = undefined;\n this.currentTask = undefined;\n }\n }\n\n continue(): Promise<void> {\n if (!this.coreAgent) {\n throw new Error(\"continue() requires pi-agent-core runtime\");\n }\n return this.coreAgent.continue();\n }\n\n subscribe(listener: (event: AgentEvent) => void): () => void {\n if (!this.coreAgent) {\n return () => {};\n }\n return this.coreAgent.subscribe(listener);\n }\n\n protected async observe(context: AgentContext): Promise<Record<string, unknown>> {\n const state = (context.board.read(\"state\", { strict: false }) as Record<string, unknown>) ?? {};\n const knowledge =\n (context.board.read(\"knowledge\", { strict: false }) as Record<string, unknown>) ?? {};\n\n return {\n currentState: state,\n availableKnowledge: knowledge,\n currentTask: context.currentTask,\n sessionId: context.sessionId,\n };\n }\n\n protected async think(\n task: Task,\n observation: Record<string, unknown>,\n context: AgentContext\n ): Promise<{\n action: unknown;\n usage: { promptTokens: number; completionTokens: number; totalTokens: number };\n }> {\n const messages = this.buildMessages(task, observation, context);\n\n const result = await this.llm.chatCompletion({\n messages,\n temperature: 0.7,\n maxTokens: this.thinkMaxTokens,\n });\n\n return {\n action: this.parseResponse(result.message.content ?? \"\", task),\n usage: result.usage,\n };\n }\n\n protected abstract act(action: unknown, context: AgentContext): Promise<unknown>;\n\n protected async report(task: Task, result: unknown, context: AgentContext): Promise<void> {\n context.board.write(`state.agent.${this.id}.lastResult`, {\n taskId: task.id,\n timestamp: new Date(),\n result,\n });\n }\n\n protected buildMessages(\n task: Task,\n observation: Record<string, unknown>,\n context: AgentContext\n ): ChatMessage[] {\n const messages: ChatMessage[] = [{ role: \"system\", content: this.getEffectiveSystemPrompt() }];\n messages.push(...context.history.slice(-10));\n messages.push({ role: \"user\", content: this.formatTaskAndObservation(task, observation) });\n return messages;\n }\n\n protected formatTaskAndObservation(task: Task, observation: Record<string, unknown>): string {\n return `\nCurrent Task:\n- ID: ${task.id}\n- Type: ${task.type}\n- Description: ${task.description}\n- Input: ${JSON.stringify(task.input, null, 2)}\n\nCurrent Context:\n- Session ID: ${observation.sessionId}\n- Available: ${JSON.stringify(observation, null, 2)}\n\nUse board_read to inspect context, then perform role_action, and finish with board_write report.\n`.trim();\n }\n\n protected abstract parseResponse(content: string, task: Task): unknown;\n protected abstract getDefaultSystemPrompt(): string;\n\n configureRuntimeExtensions(extensions: RuntimeExtensions): void {\n this.runtimeTools = extensions.tools ?? [];\n this.runtimeSystemPromptAppend = extensions.systemPromptAppend ?? \"\";\n const state = this.coreAgent?.state as { systemPrompt?: string; tools?: AgentTool[] } | undefined;\n if (state) {\n state.systemPrompt = this.getEffectiveSystemPrompt();\n state.tools = this.createAgentTools();\n }\n }\n\n clearRuntimeExtensions(): void {\n this.configureRuntimeExtensions({ tools: [], systemPromptAppend: \"\" });\n }\n\n private getEffectiveSystemPrompt(): string {\n if (!this.runtimeSystemPromptAppend) {\n return this.systemPrompt;\n }\n return `${this.systemPrompt}\\n\\n${this.runtimeSystemPromptAppend}`;\n }\n\n getStatus(): AgentStatus {\n return {\n id: this.id,\n role: this.role,\n state: this.state,\n lastActivity: new Date(),\n currentTask: undefined,\n errorCount: this.errorCount,\n };\n }\n\n resetErrorCount(): void {\n this.errorCount = 0;\n }\n\n hasExceededMaxErrors(): boolean {\n return this.errorCount >= this.maxErrors;\n }\n\n private createPiAgent(config: BaseAgentConfig): Agent | undefined {\n if (!config.enablePiRuntime) {\n return undefined;\n }\n\n if (config.llm.id === \"mock-llm\") {\n return undefined;\n }\n\n if (!config.provider || !config.model) {\n return undefined;\n }\n\n try {\n const model = getModel(config.provider as KnownProvider, config.model as never) as Model<any> | undefined;\n if (!model) {\n return undefined;\n }\n const agent = new Agent({\n initialState: {\n model,\n systemPrompt: this.getEffectiveSystemPrompt(),\n thinkingLevel: config.thinkingLevel ?? \"medium\",\n tools: this.createAgentTools(),\n },\n streamFn: this.createStreamFn(),\n sessionId: config.sessionId,\n });\n return agent;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Defines tools available to the LLM via pi-agent-core's tool-calling mechanism.\n * These tools are registered with the Agent at creation time and executed\n * by pi-agent-core when the LLM issues tool calls through the API.\n *\n * Security:\n * - file_write/file_read/file_list: Path validated with fs.realpathSync (symlink-safe)\n * - shell_exec: Denylist blocks dangerous command patterns\n */\n private createAgentTools(): AgentTool[] {\n const baseTools: AgentTool[] = [\n {\n name: \"board_read\",\n label: \"Read blackboard context\",\n description: \"Read a path from workflow blackboard\",\n parameters: Type.Object({ path: Type.String() }),\n execute: async (_id, params: unknown) => {\n const parsedParams = this.parseBoardReadParams(params);\n const value = this.currentContext?.board.read(parsedParams.path, { strict: false });\n return {\n content: [{ type: \"text\", text: JSON.stringify(value ?? null) }],\n details: { value: value ?? null },\n };\n },\n },\n {\n name: \"role_action\",\n label: \"Execute role-specific action\",\n description: \"Execute the role specific act() with parsed result\",\n parameters: Type.Object({ content: Type.String() }),\n execute: async (_id, params: unknown) => {\n if (!this.currentContext || !this.currentTask) throw new Error(\"Missing task context\");\n const parsedParams = this.parseRoleActionParams(params);\n const parsed = this.parseResponse(parsedParams.content, this.currentTask);\n this.state = AgentState.ACTING;\n const result = await this.act(parsed, this.currentContext);\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n details: { result },\n };\n },\n },\n {\n name: \"board_write\",\n label: \"Write agent report\",\n description: \"Write task execution report to blackboard\",\n parameters: Type.Object({ result: Type.Any() }),\n execute: async (_id, params: unknown) => {\n if (!this.currentContext || !this.currentTask) throw new Error(\"Missing task context\");\n const parsedParams = this.parseBoardWriteParams(params);\n await this.report(this.currentTask, parsedParams.result, this.currentContext);\n return {\n content: [{ type: \"text\", text: \"ok\" }],\n details: { written: true },\n };\n },\n },\n ];\n\n const roleTools = this.role === AgentRole.EXECUTOR ? this.createExecutorTools() : [];\n return [...baseTools, ...roleTools, ...this.runtimeTools];\n }\n\n private createExecutorTools(): AgentTool[] {\n return [\n {\n name: \"file_write\",\n label: \"Write file to project\",\n description: \"Create or overwrite a file in the project directory. Use for generating source code, configs, etc.\",\n parameters: Type.Object({\n path: Type.String({ description: \"Relative path from project root\" }),\n content: Type.String({ description: \"File content to write\" }),\n }),\n execute: async (_id, params: unknown) => {\n const parsedParams = this.parseFileWriteParams(params);\n const filePath = this.resolveAndValidatePath(parsedParams.path, { allowNonExistentTarget: true });\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, parsedParams.content, \"utf-8\");\n\n const writtenRealPath = realpathSync(filePath);\n const projectRoot = realpathSync(process.cwd());\n if (!writtenRealPath.startsWith(projectRoot + sep) && writtenRealPath !== projectRoot) {\n await Promise.allSettled([\n unlink(filePath),\n writtenRealPath === filePath ? Promise.resolve() : unlink(writtenRealPath),\n ]);\n throw new Error(\"Security: file was written outside project boundary (TOCTOU detected)\");\n }\n\n return {\n content: [{ type: \"text\", text: `Written: ${parsedParams.path}` }],\n details: { path: parsedParams.path, bytesWritten: parsedParams.content.length },\n };\n },\n },\n {\n name: \"file_read\",\n label: \"Read file from project\",\n description: \"Read a file from the project directory\",\n parameters: Type.Object({\n path: Type.String({ description: \"Relative path from project root\" }),\n }),\n execute: async (_id, params: unknown) => {\n const parsedParams = this.parseFileReadParams(params);\n const filePath = this.resolveAndValidatePath(parsedParams.path);\n\n const fileHandle = await open(filePath, \"r\");\n let content = \"\";\n try {\n const projectRoot = realpathSync(process.cwd());\n const openedFdStat = await fileHandle.stat();\n const postOpenRealPath = realpathSync(filePath);\n if (!postOpenRealPath.startsWith(projectRoot + sep) && postOpenRealPath !== projectRoot) {\n throw new Error(\"Security: file read escaped project boundary (TOCTOU detected)\");\n }\n\n const postOpenPathStat = await stat(postOpenRealPath);\n if (openedFdStat.dev !== postOpenPathStat.dev || openedFdStat.ino !== postOpenPathStat.ino) {\n throw new Error(\"Security: file changed during open/read boundary validation (TOCTOU detected)\");\n }\n\n content = await fileHandle.readFile({ encoding: \"utf-8\" });\n } finally {\n await fileHandle.close();\n }\n\n return {\n content: [{ type: \"text\", text: content }],\n details: { path: parsedParams.path, bytesRead: content.length },\n };\n },\n },\n {\n name: \"file_list\",\n label: \"List directory contents\",\n description: \"List files and directories at a path\",\n parameters: Type.Object({\n path: Type.String({ description: \"Relative directory path from project root\" }),\n }),\n execute: async (_id, params: unknown) => {\n const parsedParams = this.parseFileListParams(params);\n const dirPath = this.resolveAndValidatePath(parsedParams.path);\n const entries = await readdir(dirPath, { withFileTypes: true });\n const list = entries.map((e) => `${e.isDirectory() ? \"d\" : \"f\"} ${e.name}`).join(\"\\n\");\n return {\n content: [{ type: \"text\", text: list }],\n details: { count: entries.length },\n };\n },\n },\n {\n name: \"shell_exec\",\n label: \"Execute shell command\",\n description: \"Run a shell command in the project directory. Use for npm init, test runs, etc.\",\n parameters: Type.Object({\n command: Type.String({ description: \"Shell command to execute\" }),\n }),\n execute: async (_id, params: unknown) => {\n const parsedParams = this.parseShellExecParams(params);\n if (this.isBlockedShellCommand(parsedParams.command)) {\n return {\n content: [{ type: \"text\", text: \"Error: Blocked by security policy (dangerous command pattern detected).\" }],\n details: { exitCode: 1, blocked: true },\n };\n }\n\n const { exec } = await import(\"node:child_process\");\n const execAsync = promisify(exec);\n const projectRoot = realpathSync(process.cwd());\n try {\n const { stdout, stderr } = await execAsync(parsedParams.command, {\n cwd: projectRoot,\n timeout: 30000,\n maxBuffer: 1024 * 1024,\n });\n const output = [stdout, stderr].filter(Boolean).join(\"\\n---stderr---\\n\");\n return {\n content: [{ type: \"text\", text: output.slice(0, 4000) }],\n details: { exitCode: 0 },\n };\n } catch (e: unknown) {\n const error = e as { message?: string; stdout?: string; stderr?: string; code?: number };\n const output = [\n `Error: ${error.message ?? \"Execution failed\"}`,\n error.stdout,\n error.stderr,\n ]\n .filter(Boolean)\n .join(\"\\n---stderr---\\n\");\n return {\n content: [{ type: \"text\", text: output.slice(0, 4000) }],\n details: { exitCode: error.code ?? 1 },\n };\n }\n },\n },\n ];\n }\n\n\n /**\n * Creates a stream function bridge for pi-agent-core's Agent runtime.\n *\n * ARCHITECTURE NOTE - Tool-Calling Loop:\n * The tool execution loop is fully delegated to pi-agent-core's Agent class.\n * This streamFn is called by pi-agent-core on each LLM turn. When the LLM\n * returns tool_calls (stopReason: \"toolUse\"), pi-agent-core automatically:\n * 1. Executes the matching tool from createAgentTools()\n * 2. Appends the tool result as a \"tool\" message\n * 3. Calls this streamFn again with the updated message history\n * 4. Repeats until the LLM returns stopReason: \"stop\"\n *\n * obora-kit does NOT implement its own tool loop — pi-agent-core handles it.\n */\n private createStreamFn() {\n return async (model: Model<any>, context: { systemPrompt?: string; messages: Message[] }) => {\n const stream = new EventStream<any, AssistantMessage>((e) => e.type === \"done\" || e.type === \"error\", (e) => e.message ?? e.error);\n queueMicrotask(async () => {\n try {\n const tools = this.createAgentTools().map((tool) => ({\n type: \"function\" as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: (tool.parameters ?? { type: \"object\", properties: {} }) as Record<string, unknown>,\n },\n }));\n\n const res = await this.llm.chatCompletion({\n messages: [\n ...(context.systemPrompt ? [{ role: \"system\", content: context.systemPrompt } as const] : []),\n ...context.messages.map((m): ChatMessage => {\n if (m.role === \"user\") {\n return { role: \"user\", content: typeof m.content === \"string\" ? m.content : JSON.stringify(m.content) };\n }\n if (m.role === \"assistant\") {\n const calls = m.content\n .filter((c) => c.type === \"toolCall\")\n .map((c) => ({\n id: c.id,\n type: \"function\" as const,\n function: {\n name: c.name,\n arguments: JSON.stringify(c.arguments ?? {}),\n },\n }));\n return {\n role: \"assistant\",\n content: m.content.filter((c) => c.type === \"text\").map((c) => c.text).join(\"\"),\n toolCalls: calls.length > 0 ? calls : undefined,\n };\n }\n return {\n role: \"tool\",\n toolCallId: m.toolCallId,\n content: m.content.filter((c) => c.type === \"text\").map((c) => c.text).join(\"\\n\"),\n };\n }),\n ],\n tools,\n toolChoice: \"auto\",\n temperature: 0.7,\n maxTokens: this.executeMaxTokens,\n });\n\n this.latestUsage = {\n prompt: res.usage.promptTokens,\n completion: res.usage.completionTokens,\n total: res.usage.totalTokens,\n };\n\n const textContent = res.message.content?.trim();\n const toolCallContent = (res.message.toolCalls ?? []).map((tc) => {\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(tc.function.arguments || \"{}\");\n } catch {\n args = { _raw: tc.function.arguments };\n }\n return {\n type: \"toolCall\" as const,\n id: tc.id,\n name: tc.function.name,\n arguments: args,\n };\n });\n\n const contentParts = [\n ...(textContent ? [{ type: \"text\" as const, text: textContent }] : []),\n ...toolCallContent,\n ];\n\n const assistant: AssistantMessage = {\n role: \"assistant\",\n content: contentParts.length > 0 ? contentParts : [{ type: \"text\", text: \"\" }],\n api: \"openai-completions\",\n provider: this.llm.id,\n model: res.model,\n usage: {\n input: res.usage.promptTokens,\n output: res.usage.completionTokens,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: res.usage.totalTokens,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n },\n stopReason: res.finishReason === \"tool_calls\" ? \"toolUse\" : \"stop\",\n timestamp: Date.now(),\n };\n\n stream.push({ type: \"start\", partial: assistant });\n stream.push({ type: \"done\", reason: assistant.stopReason === \"toolUse\" ? \"toolUse\" : \"stop\", message: assistant });\n stream.end(assistant);\n } catch (error) {\n const errMessage: AssistantMessage = {\n role: \"assistant\",\n content: [{ type: \"text\", text: (error as Error).message }],\n api: \"openai-completions\",\n provider: this.llm.id,\n model: \"unknown\",\n usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },\n stopReason: \"error\",\n errorMessage: (error as Error).message,\n timestamp: Date.now(),\n };\n stream.push({ type: \"error\", reason: \"error\", error: errMessage });\n stream.end(errMessage);\n }\n });\n return stream;\n };\n }\n\n /**\n * Delegates task execution to pi-agent-core's Agent runtime.\n * The Agent.prompt() call triggers the full tool-calling loop internally.\n * See createStreamFn() for the tool loop architecture.\n */\n private async executeWithPiAgent(\n task: Task,\n observation: Record<string, unknown>,\n context: AgentContext\n ): Promise<unknown> {\n const prompt = this.formatTaskAndObservation(task, observation);\n const unsubscribe = this.coreAgent!.subscribe(() => {});\n this.unsubscribe?.();\n this.unsubscribe = unsubscribe;\n\n await this.coreAgent!.prompt(prompt);\n\n const messages = this.coreAgent!.state.messages;\n const lastAssistant = [...messages]\n .reverse()\n .find((m): m is AssistantMessage => (m as { role?: string }).role === \"assistant\") as AssistantMessage | undefined;\n\n const text = lastAssistant?.content\n .filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n .map((c) => c.text)\n .join(\"\\n\") ?? \"\";\n\n const parsed = this.parseResponse(text, task);\n await this.report(task, parsed, context);\n return parsed;\n }\n\n private parseBoardReadParams(params: unknown): BoardReadParams {\n if (!this.isRecord(params) || typeof params.path !== \"string\") {\n throw new Error(\"Invalid params: board_read.path must be a string\");\n }\n return { path: params.path };\n }\n\n private parseRoleActionParams(params: unknown): RoleActionParams {\n if (!this.isRecord(params) || typeof params.content !== \"string\") {\n throw new Error(\"Invalid params: role_action.content must be a string\");\n }\n return { content: params.content };\n }\n\n private parseBoardWriteParams(params: unknown): BoardWriteParams {\n if (!this.isRecord(params) || !(\"result\" in params)) {\n throw new Error(\"Invalid params: board_write.result is required\");\n }\n return { result: params.result };\n }\n\n private parseFileWriteParams(params: unknown): FileWriteParams {\n if (!this.isRecord(params) || typeof params.path !== \"string\" || typeof params.content !== \"string\") {\n throw new Error(\"Invalid params: file_write.path/content must be strings\");\n }\n return { path: params.path, content: params.content };\n }\n\n private parseFileReadParams(params: unknown): FileReadParams {\n if (!this.isRecord(params) || typeof params.path !== \"string\") {\n throw new Error(\"Invalid params: file_read.path must be a string\");\n }\n return { path: params.path };\n }\n\n private parseFileListParams(params: unknown): FileListParams {\n if (!this.isRecord(params) || typeof params.path !== \"string\") {\n throw new Error(\"Invalid params: file_list.path must be a string\");\n }\n return { path: params.path };\n }\n\n private parseShellExecParams(params: unknown): ShellExecParams {\n if (!this.isRecord(params) || typeof params.command !== \"string\") {\n throw new Error(\"Invalid params: shell_exec.command must be a string\");\n }\n return { command: params.command };\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n }\n\n private resolveAndValidatePath(relativePath: string, options?: { allowNonExistentTarget?: boolean }): string {\n const projectRoot = realpathSync(process.cwd());\n const resolvedPath = resolve(projectRoot, relativePath);\n\n if (!options?.allowNonExistentTarget || existsSync(resolvedPath)) {\n const realTargetPath = realpathSync(resolvedPath);\n if (!(realTargetPath === projectRoot || realTargetPath.startsWith(`${projectRoot}/`))) {\n throw new Error(\"Path validation failed: target escapes project directory\");\n }\n return realTargetPath;\n }\n\n let nearestExistingAncestor = dirname(resolvedPath);\n\n while (!existsSync(nearestExistingAncestor)) {\n const nextAncestor = dirname(nearestExistingAncestor);\n if (nextAncestor === nearestExistingAncestor) {\n throw new Error(\"Path validation failed: no existing parent directory found\");\n }\n nearestExistingAncestor = nextAncestor;\n }\n\n let realAncestorPath: string;\n try {\n realAncestorPath = realpathSync(nearestExistingAncestor);\n } catch (error: unknown) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === \"ENOENT\") {\n throw new Error(\"Path validation failed: parent directory disappeared during validation\");\n }\n throw error;\n }\n\n if (!(realAncestorPath === projectRoot || realAncestorPath.startsWith(`${projectRoot}/`))) {\n throw new Error(\"Path validation failed: parent escapes project directory\");\n }\n\n return resolvedPath;\n }\n\n private isBlockedShellCommand(command: string): boolean {\n const trimmed = command.trim();\n const segments = command\n .split(/(?:;|&&|\\|\\||\\|)/)\n .map((segment) => segment.trim())\n .filter(Boolean);\n\n return (\n this.BLOCKED_PATTERNS.some((pattern) => pattern.test(trimmed)) ||\n segments.some((segment) => this.BLOCKED_PATTERNS.some((pattern) => pattern.test(segment)))\n );\n }\n\n}\n\n\nexport interface BaseAgentConfig {\n id?: AgentId;\n role: AgentRole;\n llm: LLMAdapter;\n systemPrompt?: string;\n maxErrors?: number;\n provider?: string;\n model?: string;\n sessionId?: string;\n thinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n enablePiRuntime?: boolean;\n thinkMaxTokens?: number;\n executeMaxTokens?: number;\n}\n\n// 역할별 입출력 타입 정의 (스펙 14-ai-agents.md와 일치)\n// ============================================\n\n/**\n * Analyst 입력 타입\n */\nexport interface AnalystInput {\n type: \"analysis\";\n content: string;\n goal?: string;\n constraints?: string[];\n resources?: string[];\n previousPlans?: Plan[];\n context?: Record<string, unknown>;\n}\n\n/**\n * Analyst 출력 타입\n */\nexport interface AnalystOutput {\n type: \"analysis\";\n content: string;\n summary: string;\n keyFindings: string[];\n recommendations: string[];\n confidence: number;\n reasoning: string;\n sources?: string[];\n}\n\n/**\n * Executor 입력 타입\n */\nexport interface ExecutorInput {\n type: \"execution\";\n content: string;\n taskDescription: string;\n inputs?: Record<string, unknown>;\n expectedOutput?: string;\n tools?: string[];\n context?: Record<string, unknown>;\n}\n\n/**\n * Executor 출력 타입\n */\nexport interface ExecutorOutput {\n type: \"execution\";\n content: string;\n action: string;\n tool?: string;\n parameters: Record<string, unknown>;\n steps: string[];\n expectedOutcome: string;\n}\n\n/**\n * Verifier 입력 타입\n */\nexport interface VerifierInput {\n type: \"verification\";\n content: string;\n artifact: Artifact;\n criteria?: string[];\n requirements?: string[];\n context?: Record<string, unknown>;\n}\n\n/**\n * Verifier 출력 타입\n */\nexport interface VerifierOutput {\n type: \"verification\";\n content: string;\n passed: boolean;\n score: number; // 0-100\n checks: VerificationCheck[];\n findings: Finding[];\n suggestions: string[];\n}\n\n/**\n * Director 입력 타입\n */\nexport interface DirectorInput {\n type: \"coordination\";\n content: string;\n agenda: string;\n participants: string[];\n currentOpinions?: string[];\n conflict?: Conflict;\n context?: Record<string, unknown>;\n}\n\n/**\n * Director 출력 타입 (스펙 14-ai-agents.md와 일치)\n */\nexport interface DirectorOutput {\n type: \"coordination\";\n content: string;\n agenda: string;\n participants: string[];\n steps: CoordinationStep[];\n timeline: string[];\n expectedOutcome: string;\n // 스펙에 없는 필드:\n // - phase: 테스트용 추가 필드, 구현에서는 불필요\n // - action: 테스트용 추가 필드, 구현에서는 불필요\n}\n\n/**\n * 검증 체크 항목\n */\nexport interface VerificationCheck {\n name: string;\n description: string;\n status: \"passed\" | \"failed\" | \"skipped\";\n evidence: string;\n}\n\n/**\n * 발견된 이슈\n */\nexport interface Finding {\n id: string;\n type: \"error\" | \"warning\" | \"info\";\n description: string;\n location?: string;\n severity: \"low\" | \"medium\" | \"high\" | \"critical\";\n}\n\n/**\n * 조율 단계\n */\nexport interface CoordinationStep {\n step: number;\n description: string;\n assignee?: string;\n dependencies: string[];\n estimatedDuration?: string;\n}\n\n/**\n * 갈등 정보\n */\nexport interface Conflict {\n id: string;\n topic: string;\n parties: string[];\n positions: Record<string, string>;\n severity: \"minor\" | \"moderate\" | \"major\";\n}\n\n/**\n * 아티팩트\n */\nexport interface Artifact {\n id: string;\n type: \"code\" | \"document\" | \"data\" | \"plan\" | \"review\";\n name: string;\n content: string | Record<string, unknown>;\n}\n\n/**\n * Plan 타입 (AnalystInput에서 참조)\n */\nexport interface Plan {\n id: string;\n description: string;\n steps: string[];\n status: \"draft\" | \"approved\" | \"completed\";\n}\n","import {\n BaseAgent,\n BaseAgentConfig,\n AgentContext,\n Task,\n AgentRole,\n AnalystInput,\n AnalystOutput,\n} from \"./base-agent\";\n\n/**\n * Analyst 에이전트\n * 역할: 데이터 분석, 위험 평가, 패턴 인식\n *\n * 입력: AnalystInput\n * 출력: AnalystOutput\n */\nexport class AnalystAgent extends BaseAgent {\n constructor(config: Omit<BaseAgentConfig, \"role\">) {\n super({ ...config, role: AgentRole.ANALYST });\n }\n\n protected getDefaultSystemPrompt(): string {\n return `You are an expert analyst with deep expertise in data analysis, risk assessment, and pattern recognition.\n\nYour responsibilities:\n1. Analyze the provided information thoroughly\n2. Identify key findings and patterns\n3. Provide actionable recommendations\n4. Assess confidence in your conclusions\n5. Support your findings with reasoning\n\nWhen providing analysis, structure your response as follows:\n- Summary: A concise overview of your analysis\n- Key Findings: Bullet points of important discoveries\n- Recommendations: Actionable suggestions based on findings\n- Confidence: A score from 0-100 indicating your certainty\n- Reasoning: Your thought process and evidence\n\nBe thorough, objective, and analytical in your approach.`;\n }\n\n protected async act(action: unknown, context: AgentContext): Promise<unknown> {\n const analysis = action as AnalystOutput;\n\n // 분석 결과를 지식 베이스에 저장\n context.board.write(`knowledge.analysis.${this.id}.${Date.now()}`, analysis);\n\n // 이벤트 발행\n context.board.emit(\"analysis.completed\", {\n agentId: this.id,\n result: analysis,\n });\n\n return analysis;\n }\n\n protected parseResponse(content: string, task: Task): AnalystOutput {\n // JSON 형식으로 파싱 시도\n try {\n const jsonMatch = content.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n if (jsonMatch) {\n const parsed = JSON.parse(jsonMatch[1]);\n const { type: _type, ...safeParsed } = parsed as Record<string, unknown>;\n return { ...safeParsed, type: \"analysis\", content } as AnalystOutput;\n }\n\n // JSON 블록 없으면 전체에서 파싱 시도\n const cleanContent = content.replace(/^[^{]*({[\\s\\S]*})[^}]*$/, \"$1\");\n const parsed = JSON.parse(cleanContent);\n const { type: _type, ...safeParsed } = parsed as Record<string, unknown>;\n return { ...safeParsed, type: \"analysis\", content } as AnalystOutput;\n } catch {\n // 파싱 실패 시 기본 형식으로 변환\n return {\n type: \"analysis\",\n content,\n summary: content,\n keyFindings: [],\n recommendations: [],\n confidence: 50,\n reasoning: content,\n };\n }\n }\n}\n\n/**\n * 분석 에이전트 생성\n */\nexport function createAnalystAgent(id: string, llm: BaseAgentConfig[\"llm\"]): AnalystAgent {\n return new AnalystAgent({ id, llm });\n}\n","import {\n BaseAgent,\n BaseAgentConfig,\n AgentContext,\n Task,\n AgentRole,\n ExecutorInput,\n ExecutorOutput,\n} from \"./base-agent\";\nimport { ToolRegistry, ToolContext as ToolCtx } from \"../tools\";\n\n/**\n * Executor 에이전트\n * 역할: 작업 실행, API 호출, 파일 처리\n *\n * 입력: ExecutorInput\n * 출력: ExecutorOutput\n */\nexport class ExecutorAgent extends BaseAgent {\n private toolRegistry?: ToolRegistry;\n\n constructor(\n config: Omit<BaseAgentConfig, \"role\"> & {\n toolRegistry?: ToolRegistry;\n }\n ) {\n super({ ...config, role: AgentRole.EXECUTOR });\n this.toolRegistry = config.toolRegistry;\n }\n\n protected getDefaultSystemPrompt(): string {\n const runtimeTools = [\"file_write\", \"file_read\", \"file_list\", \"shell_exec\"];\n const availableTools = this.toolRegistry\n ? [...new Set([...this.toolRegistry.listTools().map((t) => t.name), ...runtimeTools])].join(\", \")\n : runtimeTools.join(\", \");\n\n return `You are an executor agent responsible for taking action and executing tasks.\n\nYour responsibilities:\n1. Understand the task requirements clearly\n2. Determine the best approach to complete the task\n3. Execute the action using available tools\n4. Report the outcome accurately\n5. Handle errors gracefully\n\nAvailable tools: ${availableTools}\n\nWhen implementing a feature:\n1. Use board_read to understand the task context\n2. Use file_write to create actual source code files\n3. Use shell_exec to run build/test commands\n4. Use board_write to report what you created\n\nIMPORTANT: Generate ACTUAL code files, not just descriptions. Use file_write for each source file.\n\nBackend implementation requirement (critical):\n- When the plan includes a backend server, you MUST create the server entry file (e.g., server.js or index.js) with actual Express/HTTP server code, not just a static frontend.\n- Ensure the backend entry file starts a listening server on the required port and wires the API routes specified in the plan.\n\nTool invocation policy (critical):\n- Always invoke tools via structured tool-calling API.\n- Never emit XML/inline pseudo tool calls in plain text.\n- Prefer file_write/file_read/file_list/shell_exec calls over descriptive prose when implementation is requested.\n\nWhen planning execution, structure your response as follows:\n- Action: What action will you take?\n- Tool: Which tool will you use? (if applicable)\n- Parameters: What parameters are needed for the tool?\n- Steps: Break down the execution into steps\n- Expected Outcome: What result do you expect?\n\nBe precise, efficient, and safety-conscious in your execution.`;\n }\n\n protected async act(action: unknown, context: AgentContext): Promise<unknown> {\n const plan = action as ExecutorOutput;\n\n if (plan.tool && this.toolRegistry) {\n // 도구 레지스트리에서 도구 실행\n const toolContext: ToolCtx = {\n sessionId: context.sessionId,\n agentId: this.id,\n taskId: context.currentTask?.id,\n metadata: context.currentTask?.metadata,\n permissions: new Set([\"*\"]),\n };\n const toolResult = await this.toolRegistry.execute(plan.tool, plan.parameters, toolContext);\n\n // 실행 결과를 상태에 저장\n context.board.write(`state.execution.${this.id}.${Date.now()}`, {\n plan,\n toolResult,\n timestamp: new Date(),\n });\n\n // 도구 실행 결과를 반환\n return toolResult;\n }\n\n // 도구 없는 경우 기본 실행\n const result = {\n action: plan.action,\n steps: plan.steps,\n outcome: plan.expectedOutcome,\n timestamp: new Date(),\n };\n\n context.board.write(`state.execution.${this.id}.${Date.now()}`, {\n plan,\n result,\n timestamp: new Date(),\n });\n\n // 계획(ExecutorOutput)을 반환\n return plan;\n }\n\n protected parseResponse(content: string, task: Task): ExecutorOutput {\n try {\n const jsonMatch = content.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n if (jsonMatch) {\n const parsed = JSON.parse(jsonMatch[1]);\n const { type: _type, ...safeParsed } = parsed as Record<string, unknown>;\n return { ...safeParsed, type: \"execution\", content } as ExecutorOutput;\n }\n\n const cleanContent = content.replace(/^[^{]*({[\\s\\S]*})[^}]*$/, \"$1\");\n const parsed = JSON.parse(cleanContent);\n const { type: _type, ...safeParsed } = parsed as Record<string, unknown>;\n return { ...safeParsed, type: \"execution\", content } as ExecutorOutput;\n } catch {\n return {\n type: \"execution\",\n content,\n action: content,\n parameters: {},\n steps: [content],\n expectedOutcome: \"Task execution\",\n };\n }\n }\n\n /**\n * 도구 레지스트리 설정\n */\n setToolRegistry(registry: ToolRegistry): void {\n this.toolRegistry = registry;\n }\n}\n\n/**\n * 실행 에이전트 생성\n */\nexport function createExecutorAgent(\n id: string,\n llm: BaseAgentConfig[\"llm\"],\n toolRegistry?: ToolRegistry\n): ExecutorAgent {\n return new ExecutorAgent({ id, llm, toolRegistry });\n}\n","import {\n BaseAgent,\n BaseAgentConfig,\n AgentContext,\n Task,\n AgentRole,\n VerifierOutput,\n} from \"./base-agent\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Verifier 에이전트\n * 역할: 결과 검증, 품질 체크, 정확성 확인\n *\n * 입력: VerifierInput\n * 출력: VerifierOutput\n */\nexport class VerifierAgent extends BaseAgent {\n constructor(config: Omit<BaseAgentConfig, \"role\">) {\n super({ ...config, role: AgentRole.VERIFIER });\n }\n\n protected getDefaultSystemPrompt(): string {\n return `You are a verifier agent responsible for validating results and ensuring quality.\n\nYour responsibilities:\n1. Review the provided work thoroughly\n2. Check against requirements and specifications\n3. Identify any issues or discrepancies\n4. Provide specific feedback for improvements\n5. Verify correctness and completeness\n\nWhen conducting verification, structure your response as follows:\n- Type: Must be \"verification\"\n- Passed: Overall pass/fail status (true/false)\n- Score: Numeric quality score (0-100)\n- Checks: List of specific verification checks performed\n- Findings: Detailed list of findings, with severity levels\n- Suggestions: Recommendations for improvement\n\nIssue severity levels:\n- Critical: Must be fixed before proceeding\n- High: Should be fixed soon\n- Medium: Can be addressed later\n- Low: Minor improvements or suggestions\n\nBe thorough, objective, and constructive in your verification.`;\n }\n\n protected async act(action: unknown, context: AgentContext): Promise<unknown> {\n const verification = action as VerifierOutput;\n\n // 검증 결과를 지식 베이스에 저장\n context.board.write(`knowledge.verification.${this.id}.${Date.now()}`, verification);\n\n // 이벤트 발행\n context.board.emit(\"verification.completed\", {\n agentId: this.id,\n result: verification,\n });\n\n // Critical 이슈가 있는 경우 경고 이벤트\n const findings = Array.isArray(verification.findings)\n ? verification.findings.filter((f): f is VerifierOutput[\"findings\"][number] => {\n if (!isRecord(f)) {\n return false;\n }\n return (\n typeof f.id === \"string\" &&\n typeof f.type === \"string\" &&\n typeof f.description === \"string\" &&\n typeof f.severity === \"string\"\n );\n })\n : [];\n const criticalFindings = findings.filter(\n (f) => String(f.severity).trim().toLowerCase() === \"critical\"\n );\n if (criticalFindings.length > 0) {\n context.board.emit(\"verification.critical\", {\n agentId: this.id,\n findings: criticalFindings,\n });\n }\n\n return verification;\n }\n\n protected parseResponse(content: string, task: Task): VerifierOutput {\n try {\n const jsonMatch = content.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n const raw = jsonMatch ? jsonMatch[1] : content.replace(/^[^{]*({[\\s\\S]*})[^}]*$/, \"$1\");\n const parsedRaw = JSON.parse(raw) as unknown;\n if (!isRecord(parsedRaw)) {\n throw new Error(\"Verifier response must be an object\");\n }\n const parsed = parsedRaw;\n\n const scoreRaw = parsed.score;\n const numericScore =\n typeof scoreRaw === \"number\"\n ? scoreRaw\n : typeof scoreRaw === \"string\"\n ? Number(scoreRaw)\n : 0;\n const score = Number.isFinite(numericScore) ? Math.max(0, Math.min(100, numericScore)) : 0;\n\n const checks = Array.isArray(parsed.checks)\n ? parsed.checks.filter((item): item is VerifierOutput[\"checks\"][number] => {\n if (!isRecord(item)) {\n return false;\n }\n return (\n typeof item.name === \"string\" &&\n typeof item.description === \"string\" &&\n typeof item.evidence === \"string\" &&\n (item.status === \"passed\" || item.status === \"failed\" || item.status === \"skipped\")\n );\n })\n : [];\n const rawFindings = Array.isArray(parsed.findings)\n ? parsed.findings\n : Array.isArray(parsed.issues)\n ? parsed.issues\n : [];\n const findings = rawFindings.filter((item): item is VerifierOutput[\"findings\"][number] => {\n if (!isRecord(item)) {\n return false;\n }\n return (\n typeof item.id === \"string\" &&\n typeof item.type === \"string\" &&\n typeof item.description === \"string\" &&\n typeof item.severity === \"string\"\n );\n });\n const suggestions = Array.isArray(parsed.suggestions)\n ? parsed.suggestions.filter((item): item is string => typeof item === \"string\")\n : [];\n const passed = typeof parsed.passed === \"boolean\" ? parsed.passed : false;\n\n return {\n type: \"verification\",\n content,\n passed,\n score,\n checks,\n findings,\n suggestions,\n };\n } catch {\n return {\n type: \"verification\",\n content,\n passed: false,\n score: 0,\n checks: [],\n findings: [],\n suggestions: [],\n };\n }\n }\n}\n\n/**\n * 검증 에이전트 생성\n */\nexport function createVerifierAgent(id: string, llm: BaseAgentConfig[\"llm\"]): VerifierAgent {\n return new VerifierAgent({ id, llm });\n}\n","import {\n BaseAgent,\n BaseAgentConfig,\n AgentContext,\n Task,\n AgentRole,\n DirectorInput,\n DirectorOutput,\n} from \"./base-agent\";\n\n/**\n * Director 에이전트\n * 역할: 조율, 진행 관리, 합의 도출\n *\n * 입력: DirectorInput\n * 출력: DirectorOutput\n */\nexport class DirectorAgent extends BaseAgent {\n constructor(config: Omit<BaseAgentConfig, \"role\">) {\n super({ ...config, role: AgentRole.DIRECTOR });\n }\n\n protected getDefaultSystemPrompt(): string {\n return `You are a director agent responsible for coordinating activities and facilitating collaboration.\n\nYour responsibilities:\n1. Understand the overall goal and requirements\n2. Coordinate between different agents and stakeholders\n3. Facilitate discussions and consensus-building\n4. Monitor progress and adjust plans as needed\n5. Provide clear direction and guidance\n\nWhen creating a coordination plan, structure your response as follows (JSON format):\n{\n \"type\": \"coordination\",\n \"content\": \"Description of the coordination plan\",\n \"agenda\": \"Main goal or purpose\",\n \"participants\": [\"participant1\", \"participant2\", ...],\n \"steps\": [\n {\n \"step\": 1,\n \"description\": \"First step description\",\n \"assignee\": \"who handles this step\",\n \"dependencies\": [],\n \"estimatedDuration\": \"time estimate\"\n },\n ...\n ],\n \"timeline\": [\"step1 timeline\", \"step2 timeline\", ...],\n \"expectedOutcome\": \"What should be achieved\"\n}\n\nKey principles for effective coordination:\n- Clear communication\n- Inclusive participation\n- Transparent decision-making\n- Agile adaptation to changes\n- Focus on results\n\nBe diplomatic, organized, and results-oriented in your coordination.`;\n }\n\n protected async act(action: unknown, context: AgentContext): Promise<unknown> {\n const plan = action as DirectorOutput;\n\n // 조율 계획을 결정 섹션에 저장\n context.board.write(`decisions.coordination.${this.id}.${Date.now()}`, plan);\n\n // 이벤트 발행\n context.board.emit(\"coordination.started\", {\n agentId: this.id,\n plan,\n });\n\n return plan;\n }\n\n protected parseResponse(content: string, task: Task): DirectorOutput {\n try {\n const jsonMatch = content.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n if (jsonMatch) {\n const parsed = JSON.parse(jsonMatch[1]);\n const { type: _type, ...safeParsed } = parsed as Record<string, unknown>;\n return { ...safeParsed, type: \"coordination\", content } as DirectorOutput;\n }\n\n const cleanContent = content.replace(/^[^{]*({[\\s\\S]*})[^}]*$/, \"$1\");\n const parsed = JSON.parse(cleanContent);\n const { type: _type, ...safeParsed } = parsed as Record<string, unknown>;\n return { ...safeParsed, type: \"coordination\", content } as DirectorOutput;\n } catch {\n return {\n type: \"coordination\",\n content,\n agenda: content,\n participants: [],\n steps: [],\n timeline: [],\n expectedOutcome: \"Coordination complete\",\n };\n }\n }\n\n /**\n * 투표 세션 시작\n */\n async startVotingSession(\n agendaId: string,\n participants: string[],\n context: AgentContext\n ): Promise<void> {\n context.board.write(`decisions.voting.${agendaId}`, {\n started: new Date(),\n participants,\n votes: {},\n status: \"in-progress\",\n });\n\n context.board.emit(\"voting.started\", {\n agendaId,\n participants,\n });\n }\n\n /**\n * 투표 집계\n */\n async tallyVotes(agendaId: string, context: AgentContext): Promise<Record<string, number>> {\n const session = context.board.read<Record<string, unknown>>(`decisions.voting.${agendaId}`, {\n strict: false,\n });\n\n if (!session) {\n throw new Error(`Voting session ${agendaId} not found`);\n }\n if (session.status !== \"completed\") {\n throw new Error(`Voting session ${agendaId} not completed`);\n }\n\n return session.votes as Record<string, number>;\n }\n}\n\n/**\n * 디렉터 에이전트 생성\n */\nexport function createDirectorAgent(id: string, llm: BaseAgentConfig[\"llm\"]): DirectorAgent {\n return new DirectorAgent({ id, llm });\n}\n","import { BaseAgent } from \"./base-agent\";\nimport { AnalystAgent } from \"./analyst-agent\";\nimport { ExecutorAgent } from \"./executor-agent\";\nimport { VerifierAgent } from \"./verifier-agent\";\nimport { DirectorAgent } from \"./director-agent\";\nimport type { LLMAdapter } from \"../llm/adapter\";\nimport type { ToolRegistry } from \"../tools\";\n\n/**\n * 에이전트 생성 설정\n */\nexport interface CreateAgentConfig {\n id: string;\n role: \"analyst\" | \"executor\" | \"verifier\" | \"director\";\n llm: LLMAdapter;\n toolRegistry?: ToolRegistry;\n systemPrompt?: string;\n provider?: string;\n model?: string;\n sessionId?: string;\n enablePiRuntime?: boolean;\n}\n\n/**\n * 에이전트 생성\n */\nexport function createAgent(config: CreateAgentConfig): BaseAgent {\n switch (config.role) {\n case \"analyst\":\n return new AnalystAgent({\n id: config.id,\n llm: config.llm,\n ...(config.systemPrompt ? { systemPrompt: config.systemPrompt } : {}),\n ...(config.provider ? { provider: config.provider } : {}),\n ...(config.model ? { model: config.model } : {}),\n ...(config.sessionId ? { sessionId: config.sessionId } : {}),\n ...(config.enablePiRuntime !== undefined ? { enablePiRuntime: config.enablePiRuntime } : {}),\n });\n\n case \"executor\":\n return new ExecutorAgent({\n id: config.id,\n llm: config.llm,\n toolRegistry: config.toolRegistry,\n ...(config.systemPrompt ? { systemPrompt: config.systemPrompt } : {}),\n ...(config.provider ? { provider: config.provider } : {}),\n ...(config.model ? { model: config.model } : {}),\n ...(config.sessionId ? { sessionId: config.sessionId } : {}),\n ...(config.enablePiRuntime !== undefined ? { enablePiRuntime: config.enablePiRuntime } : {}),\n });\n\n case \"verifier\":\n return new VerifierAgent({\n id: config.id,\n llm: config.llm,\n ...(config.systemPrompt ? { systemPrompt: config.systemPrompt } : {}),\n ...(config.provider ? { provider: config.provider } : {}),\n ...(config.model ? { model: config.model } : {}),\n ...(config.sessionId ? { sessionId: config.sessionId } : {}),\n ...(config.enablePiRuntime !== undefined ? { enablePiRuntime: config.enablePiRuntime } : {}),\n });\n\n case \"director\":\n return new DirectorAgent({\n id: config.id,\n llm: config.llm,\n ...(config.systemPrompt ? { systemPrompt: config.systemPrompt } : {}),\n ...(config.provider ? { provider: config.provider } : {}),\n ...(config.model ? { model: config.model } : {}),\n ...(config.sessionId ? { sessionId: config.sessionId } : {}),\n ...(config.enablePiRuntime !== undefined ? { enablePiRuntime: config.enablePiRuntime } : {}),\n });\n\n default:\n throw new Error(`Unknown agent role: ${config.role}`);\n }\n}\n\n/**\n * 에이전트 팀 생성\n */\nexport function createAgentTeam(\n config: Omit<CreateAgentConfig, \"id\" | \"role\"> & {\n analysts?: number;\n executors?: number;\n verifiers?: number;\n directors?: number;\n }\n): BaseAgent[] {\n const agents: BaseAgent[] = [];\n const baseConfig = {\n llm: config.llm,\n toolRegistry: config.toolRegistry,\n };\n\n const hasAnyRoleSpecified =\n config.analysts !== undefined ||\n config.executors !== undefined ||\n config.verifiers !== undefined ||\n config.directors !== undefined;\n\n const defaultCount = hasAnyRoleSpecified ? 0 : 1;\n\n const count = config.analysts ?? defaultCount;\n for (let i = 0; i < count; i++) {\n agents.push(\n createAgent({\n id: `analyst-${i + 1}`,\n role: \"analyst\",\n ...baseConfig,\n })\n );\n }\n\n const executorCount = config.executors ?? defaultCount;\n for (let i = 0; i < executorCount; i++) {\n agents.push(\n createAgent({\n id: `executor-${i + 1}`,\n role: \"executor\",\n ...baseConfig,\n })\n );\n }\n\n const verifierCount = config.verifiers ?? defaultCount;\n for (let i = 0; i < verifierCount; i++) {\n agents.push(\n createAgent({\n id: `verifier-${i + 1}`,\n role: \"verifier\",\n ...baseConfig,\n })\n );\n }\n\n const directorCount = config.directors ?? defaultCount;\n for (let i = 0; i < directorCount; i++) {\n agents.push(\n createAgent({\n id: `director-${i + 1}`,\n role: \"director\",\n ...baseConfig,\n })\n );\n }\n\n return agents;\n}\n","/**\n * JudgmentEngine — core state-transition and precedence logic.\n * TASK-M1-25\n */\n\nimport type {\n EngineOptions,\n EngineResult,\n HumanResolution,\n JudgmentStatus,\n RunState,\n StepInput,\n TransitionLog,\n} from './types.js';\n\nexport interface JudgeFn {\n (stepId: string): Promise<JudgmentStatus>;\n}\n\nexport interface EngineLogger {\n transition(log: TransitionLog): void;\n}\n\nconst noopLogger: EngineLogger = { transition() {} };\n\nexport class JudgmentEngine {\n private readonly opts: EngineOptions;\n private readonly judge: JudgeFn;\n private readonly logger: EngineLogger;\n\n constructor(opts: EngineOptions, judge: JudgeFn, logger?: EngineLogger) {\n this.opts = opts;\n this.judge = judge;\n this.logger = logger ?? noopLogger;\n }\n\n async run(input: StepInput): Promise<EngineResult> {\n const runId = `run-${input.stepId}-${Date.now()}`;\n const trace: string[] = [];\n let runState: RunState = 'queued';\n let retryCount = 0;\n let consecutiveFails = 0;\n let nextStep: string | undefined;\n let errorCode: EngineResult['errorCode'];\n let lastWasTimeout = false;\n\n const transition = (to: RunState, reason: string) => {\n const from = runState;\n trace.push(`${from}->${to}: ${reason}`);\n this.logger.transition({ runId, from, to, reason, timestamp: Date.now() });\n runState = to;\n };\n\n const batchStart = Date.now();\n\n const isBatchExpired = () =>\n this.opts.batchDeadlineMs > 0 && Date.now() - batchStart >= this.opts.batchDeadlineMs;\n\n const applyBatchDeadline = (): boolean => {\n if (!isBatchExpired()) return false;\n // Only running|retried|timeout get converted\n if (runState === 'running' || runState === 'retried' || runState === 'timeout') {\n transition('timeout', 'batchDeadline exceeded');\n return true;\n }\n // skipped|needs-human-review|done|failed — keep as-is\n return true; // still expired, stop loop\n };\n\n // --- Skip check ---\n if (input.skipCondition) {\n transition('running', 'start');\n transition('skipped', 'skip_condition=true');\n return { runId, runState, retryCount, decisionTrace: trace };\n }\n\n transition('running', 'start');\n\n // Main execution loop\n while (true) {\n // Batch deadline check before each attempt\n if (applyBatchDeadline()) {\n if (runState === 'timeout') errorCode = 'TIMEOUT';\n break;\n }\n\n // Execute judgment with timeout\n let status: JudgmentStatus;\n let timedOut = false;\n\n try {\n status = await this.executeWithTimeout(input.stepId);\n } catch {\n timedOut = true;\n lastWasTimeout = true;\n status = 'fail';\n transition('timeout', `step elapsed > timeoutMs(${this.opts.timeoutMs})`);\n }\n\n // Enforce batchDeadline AFTER judge execution (not only at loop-top)\n if (applyBatchDeadline()) {\n if (runState === 'timeout') errorCode = 'TIMEOUT';\n break;\n }\n\n if (!timedOut && status === 'pass') {\n lastWasTimeout = false;\n transition('done', 'judgmentStatus=pass');\n break;\n }\n\n if (!timedOut && status === 'fail') {\n consecutiveFails++;\n lastWasTimeout = false;\n }\n if (timedOut) {\n consecutiveFails++;\n }\n\n // Can retry?\n if (retryCount < this.opts.maxRetries) {\n retryCount++;\n transition('retried', `retry ${retryCount}/${this.opts.maxRetries}`);\n\n // Backoff\n if (this.opts.backoffMs > 0) {\n await this.sleep(this.opts.backoffMs);\n }\n\n // After backoff, set back to running for next attempt\n transition('running', 'retry attempt');\n continue;\n }\n\n // Retry exhausted — transition to failed first\n if (runState !== 'failed') {\n transition('failed', 'retries exhausted');\n }\n\n // Set TIMEOUT errorCode if last attempt was a timeout\n if (lastWasTimeout) {\n errorCode = 'TIMEOUT';\n }\n\n // Precedence: goto > escalation\n if (this.opts.onFail?.goto) {\n const target = this.opts.onFail.goto;\n if (input.validTargets?.includes(target)) {\n nextStep = target;\n transition('done', `goto(${target})`);\n } else {\n errorCode = 'GOTO_TARGET_NOT_FOUND';\n trace.push(`goto target \"${target}\" not found in validTargets`);\n }\n break;\n }\n\n // Escalation check (only if goto not applied)\n const threshold = this.opts.onFail?.escalateAfterConsecutiveFails ?? 2;\n if (consecutiveFails >= threshold) {\n transition('needs-human-review', `consecutiveFails(${consecutiveFails}) >= threshold(${threshold})`);\n } else if (this.opts.onFail?.escalateAfterConsecutiveFails !== undefined) {\n // Escalation was configured but threshold not met\n errorCode = 'ESCALATION_FAILED';\n }\n\n break;\n }\n\n return { runId, runState, retryCount, nextStep, errorCode, decisionTrace: trace };\n }\n\n /**\n * Resolve a needs-human-review state.\n */\n resolveHuman(result: EngineResult, resolution: HumanResolution): EngineResult {\n if (result.runState !== 'needs-human-review') return result;\n\n const trace = [...result.decisionTrace];\n const to: RunState = resolution.action === 'approve' ? 'done' : 'failed';\n trace.push(`needs-human-review->${to}: human ${resolution.action}`);\n this.logger.transition({\n runId: result.runId,\n from: 'needs-human-review',\n to,\n reason: `human ${resolution.action}`,\n timestamp: Date.now(),\n });\n\n return { ...result, runState: to, decisionTrace: trace };\n }\n\n private async executeWithTimeout(stepId: string): Promise<JudgmentStatus> {\n if (this.opts.timeoutMs <= 0) return this.judge(stepId);\n\n return new Promise<JudgmentStatus>((resolve, reject) => {\n const timer = setTimeout(() => reject(new Error('TIMEOUT')), this.opts.timeoutMs);\n this.judge(stepId).then(\n (r) => { clearTimeout(timer); resolve(r); },\n (e) => { clearTimeout(timer); reject(e); },\n );\n });\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n }\n}\n","/**\n * JudgmentPolicy — schema/policy resolve + snapshot hash.\n * TASK-M1-26\n */\n\nimport { createHash } from 'node:crypto';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ResolveInput {\n policyRef: string;\n schemaRef: string;\n runId: string;\n engineVersion: string;\n}\n\nexport type ResolveSource = 'memory' | 'local';\n\nexport interface ResolveOutput {\n policy: object;\n schema: object;\n snapshotHash: string;\n source: ResolveSource;\n}\n\nexport interface ResolveError {\n errorCode: 'RESOLVE_ERROR';\n message: string;\n}\n\nexport type ResolveResult =\n | { ok: true; value: ResolveOutput }\n | { ok: false; error: ResolveError };\n\n/**\n * Store abstraction — implemented by callers.\n */\nexport interface PolicyStore {\n get(ref: string): object | undefined;\n}\n\n/**\n * Structured log entry for resolve operations (observability).\n */\nexport interface ResolveLogEntry {\n event: 'resolve_success' | 'resolve_fallback' | 'resolve_error';\n source?: ResolveSource;\n policyRef: string;\n schemaRef: string;\n snapshotHash?: string;\n errorCode?: string;\n message?: string;\n}\n\n/**\n * Logger interface — callers can provide a structured logger.\n * Defaults to console.log JSON if not provided.\n */\nexport interface StructuredLogger {\n log(entry: ResolveLogEntry): void;\n}\n\nconst defaultLogger: StructuredLogger = {\n log(entry: ResolveLogEntry) {\n // eslint-disable-next-line no-console\n console.log(JSON.stringify(entry));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Canonicalization\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively sort object keys (ascending) while preserving array order.\n */\nfunction canonicalize(value: unknown): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value === 'string') {\n return value.normalize('NFC');\n }\n if (typeof value !== 'object') return value;\n\n if (Array.isArray(value)) {\n return value.map(canonicalize);\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(value as Record<string, unknown>).sort();\n for (const k of keys) {\n sorted[k] = canonicalize((value as Record<string, unknown>)[k]);\n }\n return sorted;\n}\n\n/**\n * Canonical JSON string (no whitespace, sorted keys, NFC strings).\n */\nexport function canonicalJson(value: unknown): string {\n return JSON.stringify(canonicalize(value));\n}\n\n// ---------------------------------------------------------------------------\n// Snapshot hash\n// ---------------------------------------------------------------------------\n\nexport function computeSnapshotHash(\n policyRef: string,\n schemaRef: string,\n policy: object,\n schema: object,\n engineVersion: string,\n): string {\n const parts = [\n policyRef,\n schemaRef,\n canonicalJson(policy),\n canonicalJson(schema),\n engineVersion,\n ];\n const payload = parts.join('\\n');\n return createHash('sha256').update(payload, 'utf-8').digest('hex');\n}\n\n// ---------------------------------------------------------------------------\n// Resolver\n// ---------------------------------------------------------------------------\n\nexport class JudgmentPolicyResolver {\n private readonly memoryStore: PolicyStore;\n private readonly localStore: PolicyStore;\n private readonly logger: StructuredLogger;\n\n constructor(memoryStore: PolicyStore, localStore: PolicyStore, logger?: StructuredLogger) {\n this.memoryStore = memoryStore;\n this.localStore = localStore;\n this.logger = logger ?? defaultLogger;\n }\n\n /**\n * Resolve policy+schema with memory->local fallback.\n *\n * Cross-store semantics: memory store is checked first for BOTH policyRef\n * and schemaRef. If either is missing from memory, the resolver falls back\n * to local store for BOTH (no cross-store mixing). If local also fails,\n * RESOLVE_ERROR is returned.\n */\n resolve(input: ResolveInput): ResolveResult {\n const memPolicy = this.memoryStore.get(input.policyRef);\n const memSchema = this.memoryStore.get(input.schemaRef);\n if (memPolicy !== undefined && memSchema !== undefined) {\n const result = this.buildSuccess(input, memPolicy, memSchema, 'memory');\n if (result.ok) {\n this.logger.log({\n event: 'resolve_success',\n source: 'memory',\n policyRef: input.policyRef,\n schemaRef: input.schemaRef,\n snapshotHash: result.value.snapshotHash,\n });\n }\n return result;\n }\n\n const localPolicy = this.localStore.get(input.policyRef);\n const localSchema = this.localStore.get(input.schemaRef);\n if (localPolicy !== undefined && localSchema !== undefined) {\n const result = this.buildSuccess(input, localPolicy, localSchema, 'local');\n if (result.ok) {\n this.logger.log({\n event: 'resolve_fallback',\n source: 'local',\n policyRef: input.policyRef,\n schemaRef: input.schemaRef,\n snapshotHash: result.value.snapshotHash,\n });\n }\n return result;\n }\n\n const errorMsg = `Failed to resolve policyRef=\"${input.policyRef}\" and/or schemaRef=\"${input.schemaRef}\" from memory or local stores`;\n this.logger.log({\n event: 'resolve_error',\n policyRef: input.policyRef,\n schemaRef: input.schemaRef,\n errorCode: 'RESOLVE_ERROR',\n message: errorMsg,\n });\n\n return {\n ok: false,\n error: {\n errorCode: 'RESOLVE_ERROR',\n message: errorMsg,\n },\n };\n }\n\n private buildSuccess(\n input: ResolveInput,\n policy: object,\n schema: object,\n source: ResolveSource,\n ): ResolveResult {\n const snapshotHash = computeSnapshotHash(\n input.policyRef,\n input.schemaRef,\n policy,\n schema,\n input.engineVersion,\n );\n return { ok: true, value: { policy, schema, snapshotHash, source } };\n }\n}\n","/**\n * JudgmentNormalizer — normalize raw model output + duplicate latest selection.\n * TASK-M1-26\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type NormalizeErrorCode = 'RESOLVE_ERROR' | 'VALIDATION_ERROR' | 'MALFORMED_JSON';\n\nexport interface IssueEntry {\n level: 'P0' | 'P1' | 'P2';\n message: string;\n}\n\nexport interface NormalizeInput {\n rawModelOutput: unknown;\n attempt: number;\n receivedAt?: string;\n ingestSeq: number;\n}\n\nexport interface NormalizeOutput {\n judgmentStatus: 'pass' | 'fail';\n score: number;\n issues: IssueEntry[];\n errorCode?: NormalizeErrorCode;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Half-up rounding to 2 decimal places.\n */\nfunction roundHalfUp2(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction clampScore(raw: number): number {\n const clamped = Math.max(0, Math.min(100, raw));\n return roundHalfUp2(clamped);\n}\n\n/**\n * Strict ISO-8601 UTC Z regex: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DDTHH:MM:SS.nnnZ\n */\nconst ISO_UTC_Z_RE = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$/;\n\n/**\n * Parse ISO-8601 receivedAt. Accepts ONLY UTC Z format (e.g. '2026-01-01T00:00:00Z').\n * Returns epoch ms or -Infinity on failure/missing/non-Z format.\n */\nexport function parseReceivedAt(value?: string): number {\n if (value === undefined || value === null) return -Infinity;\n if (!ISO_UTC_Z_RE.test(value)) return -Infinity;\n const d = new Date(value);\n if (isNaN(d.getTime())) return -Infinity;\n return d.getTime();\n}\n\n// ---------------------------------------------------------------------------\n// Error-path helper\n// ---------------------------------------------------------------------------\n\nfunction errorOutput(code: NormalizeErrorCode, message: string): NormalizeOutput {\n return {\n judgmentStatus: 'fail',\n score: 0,\n issues: [{ level: 'P1', message }],\n errorCode: code,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Normalizer\n// ---------------------------------------------------------------------------\n\nexport class JudgmentNormalizer {\n /**\n * Normalize a single raw model output into deterministic NormalizeOutput.\n */\n normalize(input: NormalizeInput): NormalizeOutput {\n const { rawModelOutput } = input;\n\n // 1. Parse rawModelOutput\n let parsed: Record<string, unknown>;\n if (rawModelOutput === null || rawModelOutput === undefined ||\n typeof rawModelOutput === 'number' || typeof rawModelOutput === 'boolean') {\n return errorOutput('MALFORMED_JSON', `rawModelOutput has invalid type: ${String(rawModelOutput)}`);\n }\n\n if (typeof rawModelOutput === 'string') {\n try {\n const result = JSON.parse(rawModelOutput);\n if (typeof result !== 'object' || result === null || Array.isArray(result)) {\n return errorOutput('MALFORMED_JSON', 'Parsed JSON is not a plain object');\n }\n parsed = result as Record<string, unknown>;\n } catch {\n return errorOutput('MALFORMED_JSON', 'Failed to parse rawModelOutput as JSON');\n }\n } else if (typeof rawModelOutput === 'object' && !Array.isArray(rawModelOutput)) {\n parsed = rawModelOutput as Record<string, unknown>;\n } else {\n return errorOutput('MALFORMED_JSON', 'rawModelOutput is not a string or object');\n }\n\n // 2. Validate judgmentStatus\n const status = parsed['judgmentStatus'] ?? parsed['status'];\n if (status !== 'pass' && status !== 'fail') {\n return errorOutput('VALIDATION_ERROR', `Invalid or missing judgmentStatus: ${JSON.stringify(status)}`);\n }\n\n // 3. Normalize score\n const rawScore = parsed['score'];\n let score = 0;\n if (typeof rawScore === 'number' && !isNaN(rawScore)) {\n score = clampScore(rawScore);\n } else if (rawScore !== undefined && rawScore !== null) {\n score = 0;\n }\n\n // 4. Collect issues\n const rawIssues = parsed['issues'];\n const issues: IssueEntry[] = [];\n if (Array.isArray(rawIssues)) {\n for (const item of rawIssues) {\n if (item && typeof item === 'object' && 'level' in item && 'message' in item) {\n const lvl = (item as Record<string, unknown>)['level'];\n const msg = (item as Record<string, unknown>)['message'];\n if ((lvl === 'P0' || lvl === 'P1' || lvl === 'P2') && typeof msg === 'string') {\n issues.push({ level: lvl, message: msg });\n }\n }\n }\n }\n\n return {\n judgmentStatus: status as 'pass' | 'fail',\n score,\n issues,\n };\n }\n\n /**\n * Select the latest entry among duplicates.\n * Tie-break: attempt > receivedAt > ingestSeq (all descending / largest wins).\n */\n selectLatest(entries: NormalizeInput[]): NormalizeInput {\n if (entries.length === 0) throw new Error('No entries to select from');\n if (entries.length === 1) return entries[0]!;\n\n return entries.reduce((best, current) => {\n // 1. attempt — larger wins\n if (current.attempt !== best.attempt) {\n return current.attempt > best.attempt ? current : best;\n }\n // 2. receivedAt — later wins\n const bestRa = parseReceivedAt(best.receivedAt);\n const currRa = parseReceivedAt(current.receivedAt);\n if (currRa !== bestRa) {\n return currRa > bestRa ? current : best;\n }\n // 3. ingestSeq — larger wins\n return current.ingestSeq > best.ingestSeq ? current : best;\n });\n }\n}\n","/**\n * JudgmentReporter — JSON & Markdown report generation.\n * TASK-M1-27\n */\n\nimport type { RunState, JudgmentStatus } from './types.js';\nimport type { IssueEntry } from './JudgmentNormalizer.js';\n\n// ---------------------------------------------------------------------------\n// Report types\n// ---------------------------------------------------------------------------\n\nexport interface ModelResult {\n model: string;\n score: number;\n judgmentStatus: JudgmentStatus;\n runState: RunState;\n issues: IssueEntry[];\n}\n\nexport interface JudgmentReport {\n runId: string;\n workflow: string;\n responses: number;\n avgScore: number;\n p0Count: number;\n p1Count: number;\n runState: RunState;\n finalPass: boolean;\n decisionReason: string;\n results: ModelResult[];\n}\n\n// ---------------------------------------------------------------------------\n// Required fields (used for validation)\n// ---------------------------------------------------------------------------\n\nconst REQUIRED_JSON_FIELDS: readonly (keyof JudgmentReport)[] = [\n 'runId', 'workflow', 'responses', 'avgScore',\n 'p0Count', 'p1Count', 'runState', 'finalPass',\n 'decisionReason', 'results',\n] as const;\n\nconst REQUIRED_MD_SECTIONS = [\n '# Judgment Report',\n 'runId', 'workflow', 'runState', 'finalPass', 'decisionReason',\n] as const;\n\nconst REQUIRED_TABLE_COLUMNS = ['model', 'score', 'judgmentStatus', 'runState', 'issues'] as const;\n\nexport { REQUIRED_JSON_FIELDS, REQUIRED_MD_SECTIONS, REQUIRED_TABLE_COLUMNS };\n\n// ---------------------------------------------------------------------------\n// Logger\n// ---------------------------------------------------------------------------\n\nexport interface ReporterLogger {\n log(entry: { event: string; runId: string; workflow: string; size: number }): void;\n}\n\nconst noopLogger: ReporterLogger = { log() {} };\n\n// ---------------------------------------------------------------------------\n// Reporter\n// ---------------------------------------------------------------------------\n\nexport class JudgmentReporter {\n private readonly logger: ReporterLogger;\n\n constructor(logger?: ReporterLogger) {\n this.logger = logger ?? noopLogger;\n }\n\n /**\n * Build a JudgmentReport from model results and workflow metadata.\n */\n buildReport(params: {\n runId: string;\n workflow: string;\n results: ModelResult[];\n runState: RunState;\n decisionReason: string;\n }): JudgmentReport {\n const { runId, workflow, results, runState, decisionReason } = params;\n const responses = results.length;\n const avgScore = responses > 0\n ? Math.round((results.reduce((s, r) => s + r.score, 0) / responses) * 100) / 100\n : 0;\n const p0Count = results.reduce((c, r) => c + r.issues.filter(i => i.level === 'P0').length, 0);\n const p1Count = results.reduce((c, r) => c + r.issues.filter(i => i.level === 'P1').length, 0);\n const finalPass = runState === 'done' && p0Count === 0 && p1Count === 0;\n\n return {\n runId,\n workflow,\n responses,\n avgScore,\n p0Count,\n p1Count,\n runState,\n finalPass,\n decisionReason,\n results,\n };\n }\n\n /**\n * Serialize report to JSON string.\n */\n toJSON(report: JudgmentReport): string {\n const json = JSON.stringify(report, null, 2);\n this.logger.log({\n event: 'report_generated',\n runId: report.runId,\n workflow: report.workflow,\n size: json.length,\n });\n return json;\n }\n\n /**\n * Serialize report to Markdown string.\n */\n toMarkdown(report: JudgmentReport): string {\n const lines: string[] = [];\n lines.push('# Judgment Report');\n lines.push('');\n lines.push(`- **runId**: ${report.runId}`);\n lines.push(`- **workflow**: ${report.workflow}`);\n lines.push(`- **responses**: ${report.responses}`);\n lines.push(`- **avgScore**: ${report.avgScore}`);\n lines.push(`- **p0Count**: ${report.p0Count}`);\n lines.push(`- **p1Count**: ${report.p1Count}`);\n lines.push(`- **runState**: ${report.runState}`);\n lines.push(`- **finalPass**: ${report.finalPass}`);\n lines.push(`- **decisionReason**: ${report.decisionReason}`);\n lines.push('');\n lines.push('## Results');\n lines.push('');\n lines.push('| model | score | judgmentStatus | runState | issues |');\n lines.push('|-------|-------|----------------|----------|--------|');\n for (const r of report.results) {\n const issuesStr = r.issues.length > 0\n ? r.issues.map(i => `${i.level}: ${i.message}`).join('; ')\n : 'none';\n lines.push(`| ${r.model} | ${r.score} | ${r.judgmentStatus} | ${r.runState} | ${issuesStr} |`);\n }\n lines.push('');\n\n const md = lines.join('\\n');\n this.logger.log({\n event: 'report_generated',\n runId: report.runId,\n workflow: report.workflow,\n size: md.length,\n });\n return md;\n }\n\n /**\n * Validate that a JSON report object contains all required fields.\n */\n static validateJsonFields(report: Record<string, unknown>): string[] {\n const missing: string[] = [];\n for (const field of REQUIRED_JSON_FIELDS) {\n if (!(field in report) || report[field] === undefined) {\n missing.push(field);\n }\n }\n return missing;\n }\n\n /**\n * Validate that a Markdown string contains all required sections and table columns.\n */\n static validateMarkdown(md: string): { missingSections: string[]; missingColumns: string[] } {\n const missingSections: string[] = [];\n for (const section of REQUIRED_MD_SECTIONS) {\n if (!md.includes(section)) {\n missingSections.push(section);\n }\n }\n const missingColumns: string[] = [];\n for (const col of REQUIRED_TABLE_COLUMNS) {\n if (!md.includes(col)) {\n missingColumns.push(col);\n }\n }\n return { missingSections, missingColumns };\n }\n}\n","/**\n * OperationalLogger — standardized operational logging for judgment runtime.\n * TASK-M1-28\n *\n * All judgment runtime events are emitted with required fields:\n * runId, workflow, runState, errorCode, snapshotHash, durationMs\n *\n * Event types:\n * resolve_success, resolve_fallback, resolve_error,\n * state_transition, report_generated\n */\n\nimport type { RunState, ErrorCode } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type OperationalEventType =\n | 'resolve_success'\n | 'resolve_fallback'\n | 'resolve_error'\n | 'state_transition'\n | 'report_generated';\n\n/**\n * Standard operational log entry — every event emitted by the judgment\n * runtime MUST include all of these fields (nullable ones may be null).\n */\nexport interface OperationalLogEntry {\n /** ISO-8601 timestamp */\n timestamp: string;\n /** Event type */\n event: OperationalEventType;\n /** Unique run identifier */\n runId: string;\n /** Workflow name (e.g. \"review\", \"qa\", \"release\") */\n workflow: string;\n /** Current run state */\n runState: RunState;\n /** Error code if applicable, null otherwise */\n errorCode: ErrorCode | string | null;\n /** Snapshot hash of policy+schema, null if not yet resolved */\n snapshotHash: string | null;\n /** Duration in milliseconds since run start, -1 if unknown */\n durationMs: number;\n /** Optional extra metadata */\n meta?: Record<string, unknown>;\n}\n\nexport const REQUIRED_LOG_FIELDS: readonly (keyof OperationalLogEntry)[] = [\n 'timestamp',\n 'event',\n 'runId',\n 'workflow',\n 'runState',\n 'errorCode',\n 'snapshotHash',\n 'durationMs',\n] as const;\n\n// ---------------------------------------------------------------------------\n// Sink interface\n// ---------------------------------------------------------------------------\n\nexport interface LogSink {\n write(entry: OperationalLogEntry): void;\n}\n\nexport const stdoutSink: LogSink = {\n write(entry: OperationalLogEntry) {\n // eslint-disable-next-line no-console\n console.log(JSON.stringify(entry));\n },\n};\n\n// ---------------------------------------------------------------------------\n// OperationalLogger\n// ---------------------------------------------------------------------------\n\nexport interface OperationalLoggerOptions {\n workflow: string;\n sink?: LogSink;\n}\n\nexport class OperationalLogger {\n private readonly workflow: string;\n private readonly sink: LogSink;\n private runStartMs: number = Date.now();\n\n constructor(opts: OperationalLoggerOptions) {\n this.workflow = opts.workflow;\n this.sink = opts.sink ?? stdoutSink;\n }\n\n resetTimer(): void {\n this.runStartMs = Date.now();\n }\n\n emit(params: {\n event: OperationalEventType;\n runId: string;\n runState: RunState;\n errorCode?: ErrorCode | string | null;\n snapshotHash?: string | null;\n durationMs?: number;\n meta?: Record<string, unknown>;\n }): OperationalLogEntry {\n const entry: OperationalLogEntry = {\n timestamp: new Date().toISOString(),\n event: params.event,\n runId: params.runId,\n workflow: this.workflow,\n runState: params.runState,\n errorCode: params.errorCode ?? null,\n snapshotHash: params.snapshotHash ?? null,\n durationMs: params.durationMs ?? (Date.now() - this.runStartMs),\n ...(params.meta ? { meta: params.meta } : {}),\n };\n this.sink.write(entry);\n return entry;\n }\n\n resolveSuccess(runId: string, runState: RunState, snapshotHash: string, meta?: Record<string, unknown>) {\n return this.emit({ event: 'resolve_success', runId, runState, snapshotHash, meta });\n }\n\n resolveFallback(runId: string, runState: RunState, snapshotHash: string, meta?: Record<string, unknown>) {\n return this.emit({ event: 'resolve_fallback', runId, runState, snapshotHash, meta });\n }\n\n resolveError(runId: string, runState: RunState, errorCode: string, meta?: Record<string, unknown>) {\n return this.emit({ event: 'resolve_error', runId, runState, errorCode, meta });\n }\n\n stateTransition(runId: string, runState: RunState, from: RunState, to: RunState, reason: string) {\n return this.emit({\n event: 'state_transition',\n runId,\n runState: to,\n meta: { from, to, reason },\n });\n }\n\n reportGenerated(runId: string, runState: RunState, snapshotHash: string | null, meta?: Record<string, unknown>) {\n return this.emit({ event: 'report_generated', runId, runState, snapshotHash, meta });\n }\n\n static validateEntry(entry: Record<string, unknown>): string[] {\n const missing: string[] = [];\n for (const field of REQUIRED_LOG_FIELDS) {\n if (!(field in entry) || entry[field] === undefined) {\n missing.push(field);\n }\n }\n return missing;\n }\n}\n","/**\n * @module base\n * @description 기본 타입 정의 - ID 타입, 공통 인터페이스\n */\n\n/**\n * 고유 식별자 타입들\n * @description 브랜드 타입을 사용하여 타입 안전성을 확보\n */\n\n/** 에이전트 고유 ID 타입 */\nexport type AgentId = string & { readonly __brand: 'AgentId' };\n\n/** 작업 고유 ID 타입 */\nexport type TaskId = string & { readonly __brand: 'TaskId' };\n\n/** 안건 고유 ID 타입 */\nexport type AgendaId = string & { readonly __brand: 'AgendaId' };\n\n/** 세션 고유 ID 타입 */\nexport type SessionId = string & { readonly __brand: 'SessionId' };\n\n/** 사실 고유 ID 타입 */\nexport type FactId = string & { readonly __brand: 'FactId' };\n\n/** 추론 고유 ID 타입 */\nexport type InferenceId = string & { readonly __brand: 'InferenceId' };\n\n/** 패턴 고유 ID 타입 */\nexport type PatternId = string & { readonly __brand: 'PatternId' };\n\n/** 의견 고유 ID 타입 */\nexport type OpinionId = string & { readonly __brand: 'OpinionId' };\n\n/**\n * 타입 가드 및 생성 함수\n */\n\n/**\n * 에이전트 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 AgentId\n * @example\n * ```typescript\n * const agentId = createAgentId('agent-001');\n * // 타입: AgentId\n * ```\n */\nexport function createAgentId(id: string): AgentId {\n return id as AgentId;\n}\n\n/**\n * 작업 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 TaskId\n * @example\n * ```typescript\n * const taskId = createTaskId('task-001');\n * // 타입: TaskId\n * ```\n */\nexport function createTaskId(id: string): TaskId {\n return id as TaskId;\n}\n\n/**\n * 안건 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 AgendaId\n * @example\n * ```typescript\n * const agendaId = createAgendaId('agenda-001');\n * // 타입: AgendaId\n * ```\n */\nexport function createAgendaId(id: string): AgendaId {\n return id as AgendaId;\n}\n\n/**\n * 세션 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 SessionId\n * @example\n * ```typescript\n * const sessionId = createSessionId('session-001');\n * // 타입: SessionId\n * ```\n */\nexport function createSessionId(id: string): SessionId {\n return id as SessionId;\n}\n\n/**\n * 사실 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 FactId\n * @example\n * ```typescript\n * const factId = createFactId('fact-001');\n * // 타입: FactId\n * ```\n */\nexport function createFactId(id: string): FactId {\n return id as FactId;\n}\n\n/**\n * 추론 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 InferenceId\n * @example\n * ```typescript\n * const inferenceId = createInferenceId('inference-001');\n * // 타입: InferenceId\n * ```\n */\nexport function createInferenceId(id: string): InferenceId {\n return id as InferenceId;\n}\n\n/**\n * 패턴 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 PatternId\n * @example\n * ```typescript\n * const patternId = createPatternId('pattern-001');\n * // 타입: PatternId\n * ```\n */\nexport function createPatternId(id: string): PatternId {\n return id as PatternId;\n}\n\n/**\n * 의견 ID 생성 함수\n * @param id - 원본 문자열 ID\n * @returns 브랜드 타입이 적용된 OpinionId\n * @example\n * ```typescript\n * const opinionId = createOpinionId('opinion-001');\n * // 타입: OpinionId\n * ```\n */\nexport function createOpinionId(id: string): OpinionId {\n return id as OpinionId;\n}\n\n/**\n * 에이전트 ID 타입 가드\n * @param value - 확인할 값\n * @returns AgentId 여부\n * @example\n * ```typescript\n * const value = 'agent-001';\n * if (isAgentId(value)) {\n * // value는 AgentId로 취급됨\n * }\n * ```\n */\nexport function isAgentId(value: unknown): value is AgentId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 작업 ID 타입 가드\n * @param value - 확인할 값\n * @returns TaskId 여부\n * @example\n * ```typescript\n * const value = 'task-001';\n * if (isTaskId(value)) {\n * // value는 TaskId로 취급됨\n * }\n * ```\n */\nexport function isTaskId(value: unknown): value is TaskId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 안건 ID 타입 가드\n * @param value - 확인할 값\n * @returns AgendaId 여부\n * @example\n * ```typescript\n * const value = 'agenda-001';\n * if (isAgendaId(value)) {\n * // value는 AgendaId로 취급됨\n * }\n * ```\n */\nexport function isAgendaId(value: unknown): value is AgendaId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 세션 ID 타입 가드\n * @param value - 확인할 값\n * @returns SessionId 여부\n * @example\n * ```typescript\n * const value = 'session-001';\n * if (isSessionId(value)) {\n * // value는 SessionId로 취급됨\n * }\n * ```\n */\nexport function isSessionId(value: unknown): value is SessionId {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * 공통 인터페이스\n */\n\n/**\n * 타임스탬프가 포함된 기본 엔티티\n * @description 생성 및 수정 시간을 추적하는 엔티티\n */\nexport interface Timestamped {\n /** 생성 시간 */\n readonly createdAt: Date;\n /** 마지막 수정 시간 */\n readonly updatedAt: Date;\n}\n\n/**\n * 버전 관리가 포함된 엔티티\n * @description optimistic locking 및 변경 이력 추적용 버전 필드\n */\nexport interface Versioned {\n /** 버전 번호 */\n readonly version: number;\n}\n\n/**\n * 식별 가능한 엔티티\n * @description 고유 ID를 가진 엔티티\n * @typeParam T - ID 타입 (기본값: string)\n */\nexport interface Identifiable<T extends string = string> {\n /** 고유 식별자 */\n readonly id: T;\n}\n","/**\n * @module versioning\n * @description 버전 관리 (optimistic locking)\n */\n\n// Global setTimeout declaration for non-Node environments\ndeclare const setTimeout: (callback: () => void, ms: number) => unknown;\n\n/**\n * 버전 관리 설정\n */\nexport interface VersioningConfig {\n /** 충돌 시 재시도 횟수 */\n maxRetries: number;\n /** 재시도 간격 (ms) */\n retryDelay: number;\n /** 지수 백오프 사용 여부 */\n exponentialBackoff: boolean;\n}\n\n/**\n * 기본 버전 관리 설정\n */\nexport const DEFAULT_VERSIONING_CONFIG: VersioningConfig = {\n maxRetries: 3,\n retryDelay: 100,\n exponentialBackoff: true,\n};\n\n/**\n * 버전 충돌 에러\n */\nexport class VersionConflictError extends Error {\n constructor(\n public readonly expectedVersion: number,\n public readonly actualVersion: number,\n public readonly path: string\n ) {\n super(`Version conflict at ${path}: expected ${expectedVersion}, got ${actualVersion}`);\n this.name = \"VersionConflictError\";\n }\n}\n\n/**\n * Optimistic Locking 관리자\n * @description 동시 쓰기 충돌을 감지하고 처리\n */\nexport class VersionManager {\n constructor(private config: VersioningConfig = DEFAULT_VERSIONING_CONFIG) {}\n\n /**\n * 버전 검증\n * @param currentVersion - 현재 버전\n * @param expectedVersion - 예상 버전\n * @param path - 경로 (에러 메시지용)\n * @throws {VersionConflictError} 버전 불일치 시\n */\n validateVersion(currentVersion: number, expectedVersion: number, path: string): void {\n if (currentVersion !== expectedVersion) {\n throw new VersionConflictError(expectedVersion, currentVersion, path);\n }\n }\n\n /**\n * 버전 증가\n * @param currentVersion - 현재 버전\n * @returns 새 버전\n */\n incrementVersion(currentVersion: number): number {\n if (currentVersion < 0) {\n throw new Error(`Invalid version: ${currentVersion}`);\n }\n return currentVersion + 1;\n }\n\n /**\n * 재시도 가능한 쓰기 실행\n * @param operation - 실행할 쓰기 연산\n * @param context - 컨텍스트 정보 (로그용)\n * @returns 최종 결과\n */\n async executeWithRetry<T>(\n operation: () => T | Promise<T>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _context?: string\n ): Promise<T> {\n let lastError: Error | null = null;\n\n // 최대 maxRetries번 시도 (첫 시도 + 재시도 maxRetries-1번)\n for (let attempt = 0; attempt < this.config.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // VersionConflictError가 아니면 바로 throw\n if (!(lastError instanceof VersionConflictError)) {\n throw lastError;\n }\n\n // 마지막 시도면 throw\n if (attempt === this.config.maxRetries - 1) {\n throw lastError;\n }\n\n // 재시도 지연\n const delay = this.calculateDelay(attempt);\n await this.sleep(delay);\n }\n }\n\n throw lastError;\n }\n\n /**\n * 재시도 지연 계산\n * @param attempt - 현재 시도 횟수 (0부터)\n * @returns 지연 시간 (ms)\n */\n calculateDelay(attempt: number): number {\n if (this.config.exponentialBackoff) {\n // 지수 백오프: delay * 2^attempt + random jitter\n const baseDelay = this.config.retryDelay * Math.pow(2, attempt);\n const jitter = Math.random() * this.config.retryDelay * 0.5;\n return Math.floor(baseDelay + jitter);\n }\n return this.config.retryDelay;\n }\n\n /**\n * 지연 (내부 유틸리티)\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * 설정 업데이트\n * @param partialConfig - 업데이트할 설정 (부분)\n */\n updateConfig(partialConfig: Partial<VersioningConfig>): void {\n this.config = { ...this.config, ...partialConfig };\n }\n\n /**\n * 현재 설정 조회\n */\n getConfig(): Readonly<VersioningConfig> {\n return { ...this.config };\n }\n}\n\n/**\n * 기본 버전 관리자 인스턴스\n */\nexport const defaultVersionManager = new VersionManager();\n","/**\n * @module immutable\n * @description 딥 클론 및 불변성 유틸리티\n */\n\n/**\n * 깊은 복사\n * @param obj - 복사할 객체\n * @param cloneMap - 순환 참조 추적용 WeakMap (낮은용)\n * @returns 깊은 복사본\n */\nexport function deepClone<T>(obj: T, cloneMap = new WeakMap<object, object>()): T {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n // 순환 참조 감지 - 이미 복사한 객체가 있으면 해당 복사본 반환\n if (cloneMap.has(obj as object)) {\n return cloneMap.get(obj as object) as T;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n if (obj instanceof Map) {\n const clonedMap = new Map();\n cloneMap.set(obj as object, clonedMap);\n for (const [key, value] of obj.entries()) {\n clonedMap.set(deepClone(key, cloneMap), deepClone(value, cloneMap));\n }\n return clonedMap as T;\n }\n\n if (obj instanceof Set) {\n const clonedSet = new Set();\n cloneMap.set(obj as object, clonedSet);\n for (const value of obj) {\n clonedSet.add(deepClone(value, cloneMap));\n }\n return clonedSet as T;\n }\n\n if (obj instanceof Array) {\n const clonedArray: unknown[] = [];\n cloneMap.set(obj as object, clonedArray);\n for (let i = 0; i < obj.length; i++) {\n clonedArray[i] = deepClone(obj[i], cloneMap);\n }\n return clonedArray as T;\n }\n\n // 일반 객체\n const clonedObj = {} as T;\n cloneMap.set(obj as object, clonedObj as object);\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n (clonedObj as Record<string, unknown>)[key] = deepClone(\n (obj as Record<string, unknown>)[key],\n cloneMap\n );\n }\n }\n return clonedObj;\n}\n\n/**\n * 깊은 동결 (불변 객체 생성)\n * @param obj - 동결할 객체\n * @returns 동결된 객체\n */\nexport function deepFreeze<T>(obj: T): Readonly<T> {\n if (obj === null || typeof obj !== \"object\") {\n return obj as Readonly<T>;\n }\n\n Object.freeze(obj);\n\n const propNames = Object.getOwnPropertyNames(obj);\n\n for (const name of propNames) {\n const value = (obj as Record<string, unknown>)[name];\n if (value !== null && typeof value === \"object\") {\n deepFreeze(value);\n }\n }\n\n return obj as Readonly<T>;\n}\n\n/**\n * 불변 업데이트\n * @description 중첩된 객체를 불변성을 유지하며 업데이트\n * @param obj - 원본 객체\n * @param path - 업데이트할 경로\n * @param updater - 업데이트 함수\n * @returns 새 객체\n */\nexport function immutableUpdate<T>(obj: T, path: string, updater: (value: unknown) => unknown): T {\n const segments = path.split(\".\");\n const newObj = deepClone(obj);\n\n let current: Record<string, unknown> = newObj as Record<string, unknown>;\n const pathStack: string[] = [];\n\n // 해당 경로까지 이동\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n pathStack.push(segment);\n\n if (!(segment in current)) {\n (current[segment] as Record<string, unknown>) = {};\n } else {\n // 불변성 유지를 위해 복사\n current[segment] = deepClone(current[segment]);\n }\n current = current[segment] as Record<string, unknown>;\n }\n\n // 마지막 경로에 업데이트\n const lastSegment = segments[segments.length - 1];\n current[lastSegment] = updater(current[lastSegment]);\n\n return newObj;\n}\n\n/**\n * Map을 일반 객체로 변환\n * @param map - 변환할 Map\n * @returns 일반 객체\n */\nexport function mapToObject<K extends string, V>(map: Map<K, V>): Record<K, V> {\n const obj = {} as Record<K, V>;\n for (const [key, value] of map.entries()) {\n obj[key] = value;\n }\n return obj;\n}\n\n/**\n * 일반 객체를 Map으로 변환\n * @param obj - 변환할 객체\n * @returns Map\n */\nexport function objectToMap<K extends string, V>(obj: Record<K, V>): Map<K, V> {\n return new Map(Object.entries(obj) as [K, V][]);\n}\n\n/**\n * 객체 병합 (불변)\n * @param target - 대상 객체\n * @param sources - 병합할 소스들\n * @returns 병합된 새 객체\n */\nexport function merge<T extends Record<string, unknown>>(target: T, ...sources: Partial<T>[]): T {\n const result = deepClone(target);\n\n for (const source of sources) {\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const value = source[key];\n if (value !== null && typeof value === \"object\") {\n const existingValue = (result as Record<string, unknown>)[key];\n if (existingValue !== null && typeof existingValue === \"object\") {\n (result as Record<string, unknown>)[key] = merge(\n existingValue as Record<string, unknown>,\n value as Record<string, unknown>\n );\n } else {\n (result as Record<string, unknown>)[key] = deepClone(value);\n }\n } else {\n (result as Record<string, unknown>)[key] = value;\n }\n }\n }\n }\n\n return result;\n}\n","/**\n * @module path-utils\n * @description 경로 유틸리티\n */\n\nimport { deepClone } from \"./immutable\";\n\n/**\n * 경로 파싱 결과\n */\nexport interface ParsedPath {\n /** 섹션 (meta, state, knowledge, decisions) */\n section: \"meta\" | \"state\" | \"knowledge\" | \"decisions\";\n /** 나머지 경로 세그먼트 */\n segments: string[];\n /** 전체 경로 */\n full: string;\n}\n\n/**\n * 유효한 섹션 이름들\n */\nconst VALID_SECTIONS = [\"meta\", \"state\", \"knowledge\", \"decisions\"] as const;\n\n/**\n * 프로토타입 오염 방지: 위험한 키 목록\n */\nconst DANGEROUS_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/**\n * 섹션인지 확인\n */\nfunction isValidSection(section: string): section is (typeof VALID_SECTIONS)[number] {\n return VALID_SECTIONS.includes(section as (typeof VALID_SECTIONS)[number]);\n}\n\n/**\n * 프로토타입 오염 방지: 경로 세그먼트 검증\n * @param segments - 검증할 경로 세그먼트 배열\n * @throws {Error} 위험한 키가 포함된 경우\n */\nfunction validatePathSegments(segments: string[]): void {\n for (const segment of segments) {\n if (DANGEROUS_KEYS.has(segment)) {\n throw new Error(`Invalid path segment: ${segment} is not allowed`);\n }\n }\n}\n\n/**\n * 경로 기반 값 접근\n * @param obj - 대상 객체\n * @param path - 점(.)으로 구분된 경로\n * @returns 해당 경로의 값\n */\nexport function getByPath<T = unknown>(obj: unknown, path: string): T | undefined {\n if (typeof obj !== \"object\" || obj === null) {\n return undefined;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n validatePathSegments(segments);\n\n if (segments.length === 0) {\n return obj as T;\n }\n\n let current: unknown = obj;\n\n for (const segment of segments) {\n if (typeof current !== \"object\" || current === null) {\n return undefined;\n }\n\n // Map 처리\n if (current instanceof Map) {\n current = current.get(segment);\n continue;\n }\n\n // 배열 처리 (숫자 인덱스)\n if (Array.isArray(current)) {\n const index = parseInt(segment, 10);\n if (!isNaN(index) && index >= 0 && index < current.length) {\n current = current[index];\n continue;\n }\n return undefined;\n }\n\n // 일반 객체\n if (!(segment in current)) {\n return undefined;\n }\n\n current = (current as Record<string, unknown>)[segment];\n }\n\n return current as T;\n}\n\n/**\n * 경로 기반 값 설정 (불변)\n * @param obj - 대상 객체\n * @param path - 점(.)으로 구분된 경로\n * @param value - 설정할 값\n * @returns 수정된 객체 (불변성 유지)\n */\nexport function setByPath<T>(obj: T, path: string, value: unknown): T {\n if (typeof obj !== \"object\" || obj === null) {\n return obj;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n validatePathSegments(segments);\n\n if (segments.length === 0) {\n return value as T;\n }\n\n const newObj = deepClone(obj) as Record<string, unknown>;\n\n let current: Record<string, unknown> = newObj;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n\n if (!(segment in current)) {\n current[segment] = {};\n } else {\n current[segment] = deepClone(current[segment]);\n }\n\n if (typeof current[segment] !== \"object\" || current[segment] === null) {\n current[segment] = {};\n }\n\n current = current[segment] as Record<string, unknown>;\n }\n\n const lastSegment = segments[segments.length - 1];\n current[lastSegment] = deepClone(value);\n\n return newObj as T;\n}\n\n/**\n * 경로 기반 값 삭제\n * @param obj - 대상 객체\n * @param path - 점(.)으로 구분된 경로\n * @returns 수정된 객체 (불변성 유지)\n */\nexport function deleteByPath<T>(obj: T, path: string): T {\n if (typeof obj !== \"object\" || obj === null) {\n return obj;\n }\n\n const segments = path.split(\".\").filter(Boolean);\n validatePathSegments(segments);\n\n if (segments.length === 0) {\n return obj;\n }\n\n const newObj = deepClone(obj) as Record<string, unknown>;\n\n // 단일 세그먼트인 경우 바로 삭제\n if (segments.length === 1) {\n delete newObj[segments[0]];\n return newObj as T;\n }\n\n let current: Record<string, unknown> = newObj;\n\n // 마지막 전까지 이동\n for (let i = 0; i < segments.length - 1; i++) {\n const segment = segments[i];\n\n if (!(segment in current)) {\n return obj; // 경로가 존재하지 않으면 원본 반환\n }\n\n current[segment] = deepClone(current[segment]);\n\n if (typeof current[segment] !== \"object\" || current[segment] === null) {\n return obj;\n }\n\n current = current[segment] as Record<string, unknown>;\n }\n\n const lastSegment = segments[segments.length - 1];\n delete current[lastSegment];\n\n return newObj as T;\n}\n\n/**\n * 경로 파싱\n * @param path - 전체 경로\n * @returns 파싱된 경로 정보\n */\nexport function parsePath(path: string): ParsedPath {\n const normalized = normalizePath(path);\n const segments = normalized.split(\".\").filter(Boolean);\n\n if (segments.length === 0) {\n throw new Error(`Invalid path: ${path}`);\n }\n\n validatePathSegments(segments);\n\n const section = segments[0];\n\n if (!isValidSection(section)) {\n throw new Error(`Invalid section: ${section}. Valid sections: ${VALID_SECTIONS.join(\", \")}`);\n }\n\n return {\n section,\n segments: segments.slice(1),\n full: normalized,\n };\n}\n\n/**\n * 경로 검증\n * @param path - 검증할 경로\n * @returns 유효 여부\n */\nexport function isValidPath(path: string): boolean {\n try {\n const parsed = parsePath(path);\n return parsed.section !== undefined;\n } catch {\n return false;\n }\n}\n\n/**\n * 경로 정규화\n * @param path - 정규화할 경로\n * @returns 정규화된 경로\n */\nexport function normalizePath(path: string): string {\n return path\n .trim()\n .replace(/\\s+/g, \"\")\n .replace(/\\.+/g, \".\")\n .replace(/^\\.+|\\.+$/g, \"\");\n}\n\n/**\n * 경로 결합\n * @param parts - 결합할 경로들\n * @returns 결합된 경로\n */\nexport function joinPath(...parts: string[]): string {\n return parts\n .map((p) => normalizePath(p))\n .filter(Boolean)\n .join(\".\");\n}\n\n/**\n * 경로가 다른 경로의 하위 경로인지 확인\n * @param parent - 부모 경로\n * @param child - 자식 경로\n * @returns 하위 경로 여부\n */\nexport function isSubPath(parent: string, child: string): boolean {\n const normalizedParent = normalizePath(parent);\n const normalizedChild = normalizePath(child);\n\n if (normalizedParent === normalizedChild) {\n return false;\n }\n\n return normalizedChild.startsWith(normalizedParent + \".\");\n}\n\n/**\n * 경로의 상위 경로 반환\n * @param path - 경로\n * @param levels - 올라갈 레벨 수 (기본: 1)\n * @returns 상위 경로\n */\nexport function getParentPath(path: string, levels: number = 1): string {\n const normalized = normalizePath(path);\n const segments = normalized.split(\".\").filter(Boolean);\n\n if (segments.length <= levels) {\n return \"\";\n }\n\n return segments.slice(0, segments.length - levels).join(\".\");\n}\n","/**\n * @module types/tkg\n * @description Temporal Knowledge Graph(TKG) 타입/계약 (spec/12 정렬)\n */\n\nimport type { AgentId } from './base';\n\n/** TKG 노드 ID */\nexport type NodeId = string & { readonly __brand: 'NodeId' };\n\n/** TKG 엣지 ID */\nexport type EdgeId = string & { readonly __brand: 'EdgeId' };\n\n/** 노드 ID 생성기 */\nexport function createNodeId(id: string): NodeId {\n if (id.trim().length === 0) {\n throw new Error('NodeId must be a non-empty string');\n }\n return id as NodeId;\n}\n\n/** 엣지 ID 생성기 */\nexport function createEdgeId(id: string): EdgeId {\n if (id.trim().length === 0) {\n throw new Error('EdgeId must be a non-empty string');\n }\n return id as EdgeId;\n}\n\n/** 노드 종류 */\nexport type TemporalNodeType = 'entity' | 'fact' | 'decision' | 'task' | 'pattern';\n\n/** 엣지 종류 */\nexport type EdgeType =\n | 'relates_to' | 'part_of' | 'contains'\n | 'supports' | 'contradicts' | 'explains' | 'based_on'\n | 'decided_by' | 'decided_on' | 'leads_to'\n | 'assigned_to' | 'depends_on' | 'blocks' | 'precedes'\n | 'exemplifies' | 'generalizes' | 'specializes';\n\nexport interface EntityData {\n readonly name: string;\n readonly entityType: 'agent' | 'task' | 'resource' | 'concept';\n readonly attributes: Readonly<Record<string, unknown>>;\n}\n\nexport interface FactData {\n readonly statement: string;\n readonly context?: string;\n readonly evidence?: readonly NodeId[];\n readonly verified: boolean;\n}\n\nexport interface DecisionData {\n readonly agendaId: string;\n readonly outcome: 'approve' | 'reject' | 'deferred';\n readonly reason: string;\n readonly participants: readonly AgentId[];\n}\n\nexport interface TaskData {\n readonly description: string;\n readonly status: 'pending' | 'running' | 'completed' | 'failed';\n readonly assignedTo?: AgentId;\n readonly result?: unknown;\n}\n\nexport interface PatternData {\n readonly description: string;\n readonly frequency: number;\n readonly examples: readonly string[];\n readonly accuracy?: number;\n}\n\nexport type NodeData = EntityData | FactData | DecisionData | TaskData | PatternData;\n\n/**\n * 시간축을 가진 TKG 노드\n */\nexport interface TemporalNode {\n readonly id: NodeId;\n readonly type: TemporalNodeType;\n readonly valid_from: Date;\n readonly valid_to?: Date;\n readonly observed_at: Date;\n readonly updated_at: Date;\n readonly confidence: number;\n readonly source: AgentId;\n readonly version: number;\n readonly tags?: readonly string[];\n readonly data: NodeData;\n}\n\n/**\n * 시간축을 가진 TKG 엣지\n */\nexport interface TemporalEdge {\n readonly id: EdgeId;\n readonly from: NodeId;\n readonly to: NodeId;\n readonly type: EdgeType;\n readonly valid_from: Date;\n readonly valid_to?: Date;\n readonly observed_at: Date;\n readonly confidence: number;\n readonly source: AgentId;\n readonly weight?: number;\n}\n\n/**\n * TKG 조회 쿼리\n */\nexport interface GraphQuery {\n readonly nodeTypes?: readonly TemporalNodeType[];\n readonly nodeIds?: readonly NodeId[];\n readonly tags?: readonly string[];\n readonly minConfidence?: number;\n readonly edgeTypes?: readonly EdgeType[];\n readonly from?: NodeId;\n readonly to?: NodeId;\n readonly depth?: number;\n}\n\n/**\n * TKG 조회 결과\n */\nexport interface QueryResult {\n readonly nodes: readonly TemporalNode[];\n readonly edges: readonly TemporalEdge[];\n readonly metadata: {\n readonly queryTime: Date;\n readonly resultCount: number;\n readonly confidenceRange: readonly [number, number];\n };\n}\n\nexport interface ValidationError {\n readonly field: string;\n readonly message: string;\n readonly code: string;\n}\n\nexport interface ValidationWarning {\n readonly field: string;\n readonly message: string;\n readonly code: string;\n}\n\n/**\n * 유효성 검사 결과\n */\nexport interface ValidationResult {\n readonly valid: boolean;\n readonly errors: readonly ValidationError[];\n readonly warnings: readonly ValidationWarning[];\n}\n\nexport type ConflictResolution =\n | 'pending'\n | 'supersedes'\n | 'higher_confidence'\n | 'merge'\n | 'discard'\n | 'soft_delete';\n\nexport interface Conflict {\n readonly id: string;\n readonly type: 'version' | 'contradiction' | 'supersedes' | 'confidence';\n readonly nodes: readonly [TemporalNode, TemporalNode];\n readonly detectedAt: Date;\n readonly status: 'pending' | 'resolved' | 'deferred';\n readonly resolution?: ConflictResolution;\n readonly metadata?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * 승격(Promotion) 메타데이터\n */\nexport interface PromotionMeta {\n readonly promotedBy?: string;\n readonly reason?: string;\n readonly promotedAt?: Date;\n}\n\n/**\n * 개별 승격 결과\n */\nexport interface PromotionResult {\n readonly nodeId: NodeId;\n readonly success: boolean;\n readonly timestamp: Date;\n readonly reason?: string;\n readonly conflict?: Conflict;\n}\n\n/**\n * 병합 옵션\n */\nexport interface ReflectionOptions {\n readonly minConfidence?: number;\n readonly resolveConflicts?: boolean;\n readonly softDeleteOnConflict?: boolean;\n readonly maxAge?: number;\n}\n\n/**\n * Staging/Production 병합 결과\n */\nexport interface MergeResult {\n readonly mergeId: string;\n readonly timestamp: Date;\n readonly nodesPromoted: number;\n readonly nodesSkipped: number;\n readonly nodesFailed: number;\n readonly edgesPromoted: number;\n readonly edgesSkipped: number;\n readonly conflicts: readonly Conflict[];\n readonly duration: number;\n}\n\n/**\n * Production 승격 전용 Port 계약.\n * Reflector는 ProductionTKG 내부 맵에 직접 쓰지 않고 반드시 이 포트를 사용해야 합니다.\n */\nexport interface IProductionPromotionPort {\n promoteNode(node: TemporalNode, meta?: PromotionMeta): PromotionResult;\n promoteEdge(edge: TemporalEdge, meta?: PromotionMeta): PromotionResult;\n promoteBatch(payload: {\n nodes: readonly TemporalNode[];\n edges: readonly TemporalEdge[];\n meta?: PromotionMeta;\n }): MergeResult;\n}\n","/**\n * @module state-accessor\n * @description 상태 섹션 접근자\n */\n\nimport type { Blackboard } from \"../blackboard\";\nimport type { BoardPhase, StateSection } from \"../../types\";\nimport type { AgentStatus, AgentRole } from \"../../types\";\nimport { AgentStatusEnum } from \"../../types\";\nimport type { Task, TaskId, TaskError } from \"../../types\";\nimport { TaskStatus, TaskPriority } from \"../../types\";\nimport type { AgentId } from \"../../types\";\nimport { BlackboardError, BlackboardErrorCode, PathNotFoundError } from \"../blackboard\";\n\n/**\n * 상태 섹션 접근자\n * @description state 섹션에 대한 타입 안전한 접근 제공\n */\nexport class StateSectionAccessor {\n constructor(private readonly board: Blackboard) {}\n\n // === 단계 관리 ===\n\n /** 현재 단계 */\n get phase(): BoardPhase {\n return this.board.read<StateSection>(\"state\").phase;\n }\n\n set phase(value: BoardPhase) {\n const currentPhase = this.phase;\n if (currentPhase === value) {\n return; // No change, don't emit event\n }\n this.board.write(\"state.phase\", value);\n this.board.emit(\"state.phase.changed\", {\n type: \"state.phase.changed\",\n previousPhase: currentPhase,\n newPhase: value,\n });\n }\n\n /** 컨텍스트 데이터 */\n get context(): Record<string, unknown> {\n return this.board.read<StateSection>(\"state\").context;\n }\n\n setContext(key: string, value: unknown): void {\n this.board.write(`state.context.${key}`, value);\n }\n\n /**\n * 컨텍스트 값 조회 (기본값 포함)\n */\n getContext<T>(key: string, defaultValue?: T): T | undefined {\n try {\n const value = this.board.read<T>(`state.context.${key}`);\n return value !== undefined ? value : defaultValue;\n } catch (e) {\n if (e instanceof PathNotFoundError) {\n return defaultValue;\n }\n throw e;\n }\n }\n\n /**\n * 컨텍스트 값 조회 (기본값 포함) - 별칭 메서드\n */\n getContextValue<T>(key: string, defaultValue?: T): T | undefined {\n return this.getContext(key, defaultValue);\n }\n\n /**\n * 컨텍스트 항목 삭제\n */\n deleteContext(key: string): void {\n try {\n const state = this.board.read<StateSection>(\"state\");\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { [key]: _, ...remaining } = state.context;\n this.board.write(\"state.context\", remaining);\n } catch (e) {\n if (e instanceof PathNotFoundError) {\n // 이미 존재하지 않는 키면 무시\n return;\n }\n throw e;\n }\n }\n\n /**\n * 컨텍스트 병합\n */\n mergeContext(partial: Record<string, unknown>): void {\n const state = this.board.read<StateSection>(\"state\");\n this.board.write(\"state.context\", { ...state.context, ...partial });\n }\n\n /**\n * 컨텍스트 초기화\n */\n clearContext(): void {\n this.board.write(\"state.context\", {});\n }\n\n // === 에이전트 관리 ===\n\n /**\n * 에이전트 등록\n * @param agent - 에이전트 상태 정보\n */\n registerAgent(agent: AgentStatus): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (state.agents.has(agent.id)) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENT_ALREADY_REGISTERED,\n `Agent ${agent.id} already registered`\n );\n }\n\n const updatedAgents = new Map(state.agents);\n updatedAgents.set(agent.id, agent);\n\n this.board.write(\"state.agents\", updatedAgents);\n this.board.emit(\"agent_joined\", { agentId: agent.id, agent });\n }\n\n /**\n * 에이전트 상태 업데이트\n * @param agentId - 에이전트 ID\n * @param updates - 업데이트할 필드\n */\n updateAgent(agentId: AgentId, updates: Partial<AgentStatus>): void {\n const state = this.board.read<StateSection>(\"state\");\n const agent = state.agents.get(agentId);\n\n if (!agent) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${agentId} not found`);\n }\n\n const updatedAgent = {\n ...agent,\n ...updates,\n updatedAt: new Date(),\n };\n\n const updatedAgents = new Map(state.agents);\n updatedAgents.set(agentId, updatedAgent);\n\n this.board.write(\"state.agents\", updatedAgents);\n\n if (updates.status !== undefined && updates.status !== agent.status) {\n this.board.emit(\"agent_status_changed\", {\n agentId,\n previousStatus: agent.status,\n newStatus: updates.status,\n });\n }\n }\n\n /**\n * 에이전트 제거\n * @param agentId - 에이전트 ID\n */\n removeAgent(agentId: AgentId): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (!state.agents.has(agentId)) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${agentId} not found`);\n }\n\n const updatedAgents = new Map(state.agents);\n updatedAgents.delete(agentId);\n\n this.board.write(\"state.agents\", updatedAgents);\n this.board.emit(\"agent_left\", { agentId });\n }\n\n /**\n * 에이전트 조회\n * @param agentId - 에이전트 ID\n */\n getAgent(agentId: AgentId): AgentStatus | undefined {\n const state = this.board.read<StateSection>(\"state\");\n return state.agents.get(agentId);\n }\n\n /**\n * 모든 에이전트 조회\n * @param filter - 필터 조건\n */\n getAgents(filter?: { role?: AgentRole; status?: AgentStatusEnum }): AgentStatus[] {\n const state = this.board.read<StateSection>(\"state\");\n const agents = Array.from(state.agents.values());\n\n if (!filter) {\n return agents;\n }\n\n return agents.filter((agent) => {\n if (filter.role !== undefined && agent.role !== filter.role) {\n return false;\n }\n if (filter.status !== undefined && agent.status !== filter.status) {\n return false;\n }\n return true;\n });\n }\n\n /**\n * 에이전트 수 조회 (getter)\n */\n get agentCount(): number {\n return this.board.read<StateSection>(\"state\").agents.size;\n }\n\n /**\n * 에이전트 수 조회 (호환성 메서드)\n */\n getAgentCount(): number {\n return this.agentCount;\n }\n\n /**\n * 에이전트 존재 여부 확인\n */\n hasAgent(id: AgentId): boolean {\n return this.board.read<StateSection>(\"state\").agents.has(id);\n }\n\n /**\n * 에이전트 하트비트 업데이트\n */\n updateAgentHeartbeat(id: AgentId): void {\n const agent = this.getAgent(id);\n if (!agent) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${id} not found`);\n }\n\n this.updateAgent(id, {\n lastHeartbeat: new Date(),\n });\n }\n\n /**\n * 활성 에이전트 수 조회 (BUSY 상태 에이전트)\n * @description 현재 작업을 수행 중인(BUSY 상태) 에이전트의 수를 반환합니다.\n * @deprecated 이름이 혼동스러울 수 있으므로 {@link getBusyAgentCount()} 사용 권장\n */\n getActiveAgentCount(): number {\n return this.getAgents({ status: AgentStatusEnum.BUSY }).length;\n }\n\n /**\n * BUSY 상태 에이전트 수 조회\n * @description 현재 작업을 수행 중인(BUSY 상태) 에이전트의 수를 반환합니다.\n */\n getBusyAgentCount(): number {\n return this.getAgents({ status: AgentStatusEnum.BUSY }).length;\n }\n\n // === 작업 관리 ===\n\n /**\n * 작업 추가\n */\n addTask(task: Task): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (state.tasks.has(task.id)) {\n throw new BlackboardError(\n BlackboardErrorCode.TASK_ALREADY_ASSIGNED,\n `Task ${task.id} already exists`\n );\n }\n\n const updatedTasks = new Map(state.tasks);\n updatedTasks.set(task.id, task);\n\n this.board.write(\"state.tasks\", updatedTasks);\n this.board.emit(\"task_created\", { taskId: task.id, task });\n }\n\n /**\n * 작업 업데이트\n */\n updateTask(taskId: TaskId, updates: Partial<Task>): void {\n const state = this.board.read<StateSection>(\"state\");\n const task = state.tasks.get(taskId);\n\n if (!task) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n\n const updatedTask = {\n ...task,\n ...updates,\n updatedAt: new Date(),\n version: task.version + 1,\n };\n\n const updatedTasks = new Map(state.tasks);\n updatedTasks.set(taskId, updatedTask);\n\n this.board.write(\"state.tasks\", updatedTasks);\n this.board.emit(\"task_updated\", { taskId, task: updatedTask });\n }\n\n /**\n * 작업 조회\n */\n getTask(taskId: TaskId): Task | undefined {\n const state = this.board.read<StateSection>(\"state\");\n return state.tasks.get(taskId);\n }\n\n /**\n * 작업 목록 조회\n */\n getTasks(filter?: {\n status?: TaskStatus;\n assignedTo?: AgentId;\n priority?: TaskPriority;\n }): Task[] {\n const state = this.board.read<StateSection>(\"state\");\n const tasks = Array.from(state.tasks.values());\n\n if (!filter) {\n return tasks;\n }\n\n return tasks.filter((task) => {\n if (filter.status !== undefined && task.status !== filter.status) {\n return false;\n }\n if (filter.assignedTo !== undefined && task.assignedTo !== filter.assignedTo) {\n return false;\n }\n if (filter.priority !== undefined && task.priority !== filter.priority) {\n return false;\n }\n return true;\n });\n }\n\n /**\n * 작업 삭제\n */\n removeTask(taskId: TaskId): void {\n const state = this.board.read<StateSection>(\"state\");\n\n if (!state.tasks.has(taskId)) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n\n const updatedTasks = new Map(state.tasks);\n updatedTasks.delete(taskId);\n\n this.board.write(\"state.tasks\", updatedTasks);\n }\n\n /**\n * 다음 실행 가능한 작업들\n * @param completedTasks - 완료된 작업 ID 목록\n */\n getNextTasks(completedTasks: Set<TaskId> = new Set()): Task[] {\n const tasks = this.getTasks({ status: TaskStatus.PENDING });\n\n return tasks\n .filter((task) => {\n // 모든 의존 작업이 완료되어야 함\n return task.dependsOn.every((depId) => completedTasks.has(depId));\n })\n .sort((a, b) => b.priority - a.priority); // 우선순위 내림차순\n }\n\n /**\n * 에이전트의 현재 작업 조회\n */\n getAgentCurrentTask(agentId: AgentId): Task | undefined {\n const tasks = this.getTasks({ assignedTo: agentId, status: TaskStatus.RUNNING });\n return tasks[0];\n }\n\n /**\n * 작업 수 조회 (getter)\n */\n get taskCount(): number {\n return this.board.read<StateSection>(\"state\").tasks.size;\n }\n\n /**\n * 작업 수 조회 (호환성 메서드)\n */\n getTaskCount(): number {\n return this.taskCount;\n }\n\n /**\n * 작업 존재 여부 확인\n */\n hasTask(id: TaskId): boolean {\n return this.board.read<StateSection>(\"state\").tasks.has(id);\n }\n\n /**\n * 작업 할당\n * @description 에이전트 존재 여부와 상태를 검증 후 작업을 할당합니다.\n * @param taskId - 할당할 작업 ID\n * @param agentId - 할당받을 에이전트 ID\n */\n assignTask(taskId: TaskId, agentId: AgentId): void {\n // 에이전트 존재 여부 확인\n const agent = this.getAgent(agentId);\n if (!agent) {\n throw new BlackboardError(BlackboardErrorCode.AGENT_NOT_FOUND, `Agent ${agentId} not found`);\n }\n\n // 에이전트 상태 확인 (BUSY 상태인 에이전트에는 할당하지 않음)\n if (agent.status === AgentStatusEnum.BUSY) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENT_NOT_AVAILABLE,\n `Agent ${agentId} is busy and cannot accept new tasks`\n );\n }\n\n // 작업 업데이트\n this.updateTask(taskId, {\n assignedTo: agentId,\n status: TaskStatus.RUNNING,\n startedAt: new Date(),\n });\n\n // 에이전트 상태도 BUSY로 변경\n this.updateAgent(agentId, {\n status: AgentStatusEnum.BUSY,\n currentTask: taskId,\n });\n }\n\n /**\n * 작업 할당 해제\n */\n unassignTask(taskId: TaskId): void {\n const task = this.getTask(taskId);\n if (!task) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n\n const agentId = task.assignedTo;\n\n this.updateTask(taskId, {\n assignedTo: null,\n status: TaskStatus.PENDING,\n startedAt: null,\n });\n\n // agent 상태 리셋 (에이전트가 존재하는 경우에만)\n if (agentId && this.hasAgent(agentId)) {\n this.updateAgent(agentId, {\n status: AgentStatusEnum.IDLE,\n currentTask: null,\n });\n }\n }\n\n /**\n * 작업 완료 처리\n */\n completeTask(taskId: TaskId, outputs: Record<string, unknown>): void {\n const task = this.getTask(taskId);\n if (!task) {\n throw new BlackboardError(BlackboardErrorCode.TASK_NOT_FOUND, `Task ${taskId} not found`);\n }\n const agentId = task.assignedTo;\n\n this.updateTask(taskId, {\n status: TaskStatus.COMPLETED,\n outputs,\n completedAt: new Date(),\n });\n\n // agent 상태 리셋 (에이전트가 존재하는 경우에만)\n if (agentId && this.hasAgent(agentId)) {\n this.updateAgent(agentId, {\n status: AgentStatusEnum.IDLE,\n currentTask: null,\n });\n }\n }\n\n /**\n * 작업 실패 처리\n */\n failTask(taskId: TaskId, error: TaskError): void {\n const task = this.getTask(taskId);\n const agentId = task?.assignedTo;\n\n this.updateTask(taskId, {\n status: TaskStatus.FAILED,\n error,\n completedAt: new Date(),\n });\n\n // agent 상태 리셋 (에이전트가 존재하는 경우에만)\n if (agentId && this.hasAgent(agentId)) {\n this.updateAgent(agentId, {\n status: AgentStatusEnum.IDLE,\n currentTask: null,\n });\n }\n }\n\n /**\n * 실행 중인 작업 수 조회\n */\n getRunningTaskCount(): number {\n return this.getTasks({ status: TaskStatus.RUNNING }).length;\n }\n\n /**\n * 대기 중인 작업 수 조회\n */\n getPendingTaskCount(): number {\n return this.getTasks({ status: TaskStatus.PENDING }).length;\n }\n}\n","/**\n * @module knowledge-accessor\n * @description 지식 섹션 접근자\n */\n\nimport type { Blackboard } from '../blackboard';\nimport type { KnowledgeSection } from '../../types';\nimport type {\n Fact,\n FactCreateInput,\n Inference,\n InferenceCreateInput,\n Pattern,\n PatternCreateInput,\n KnowledgeQuery,\n InferenceQuery,\n PatternQuery,\n} from '../../types';\nimport type { AgentId } from '../../types';\nimport { BlackboardError, BlackboardErrorCode } from '../blackboard';\n\n/**\n * 지식 섹션 접근자\n * @description knowledge 섹션에 대한 타입 안전한 접근 제공\n */\nexport class KnowledgeSectionAccessor {\n constructor(private readonly board: Blackboard) {}\n\n // === 헬퍼 메서드 ===\n\n /**\n * confidence 값 검증\n * @private\n */\n private validateConfidence(value: number | undefined, fieldName = 'confidence'): void {\n if (value !== undefined) {\n if (typeof value !== 'number' || value < 0 || value > 1 || Number.isNaN(value)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n `${fieldName} must be a number between 0 and 1`\n );\n }\n }\n }\n\n // === Getters ===\n\n /**\n * 전체 사실 목록\n */\n get facts(): Fact[] {\n return this.board.read<KnowledgeSection>('knowledge').facts;\n }\n\n /**\n * 전체 추론 목록\n */\n get inferences(): Inference[] {\n return this.board.read<KnowledgeSection>('knowledge').inferences;\n }\n\n /**\n * 전체 패턴 목록\n */\n get patterns(): Pattern[] {\n return this.board.read<KnowledgeSection>('knowledge').patterns;\n }\n\n /**\n * 사실 수\n */\n get factCount(): number {\n return this.board.read<KnowledgeSection>('knowledge').facts.length;\n }\n\n /**\n * 추론 수\n */\n get inferenceCount(): number {\n return this.board.read<KnowledgeSection>('knowledge').inferences.length;\n }\n\n /**\n * 패턴 수\n */\n get patternCount(): number {\n return this.board.read<KnowledgeSection>('knowledge').patterns.length;\n }\n\n // === 사실 관리 ===\n\n /**\n * 사실 추가\n * @param factInput - 새 사실 입력\n */\n addFact(factInput: FactCreateInput): Fact {\n // 필수 필드 검증\n if (!factInput.content || factInput.content.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Fact content is required'\n );\n }\n if (!factInput.source) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Fact source is required'\n );\n }\n if (!factInput.category || factInput.category.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Fact category is required'\n );\n }\n this.validateConfidence(factInput.confidence, 'Fact confidence');\n\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const fact: Fact = {\n id: `fact-${crypto.randomUUID()}`,\n content: factInput.content,\n source: factInput.source,\n confidence: factInput.confidence,\n category: factInput.category,\n tags: factInput.tags || [],\n expiresAt: factInput.expiresAt ?? null,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedFacts = [...knowledge.facts, fact];\n this.board.write('knowledge.facts', updatedFacts);\n\n return fact;\n }\n\n /**\n * 사실 조회\n */\n getFact(factId: string): Fact | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.facts.find(f => f.id === factId);\n }\n\n /**\n * 사실 업데이트\n */\n updateFact(factId: string, updates: Partial<Omit<Fact, 'id' | 'createdAt'>>): Fact | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const factIndex = knowledge.facts.findIndex(f => f.id === factId);\n\n if (factIndex === -1) {\n return undefined;\n }\n\n const existingFact = knowledge.facts[factIndex];\n const updatedFact: Fact = {\n ...existingFact,\n ...updates,\n id: existingFact.id,\n createdAt: existingFact.createdAt,\n updatedAt: new Date(),\n };\n\n const updatedFacts = [...knowledge.facts];\n updatedFacts[factIndex] = updatedFact;\n this.board.write('knowledge.facts', updatedFacts);\n\n return updatedFact;\n }\n\n /**\n * 사실 검색\n */\n findFacts(query: KnowledgeQuery): Fact[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n return knowledge.facts.filter(fact => {\n // 유효 기간 필터\n if (query.validOnly && fact.expiresAt && fact.expiresAt < now) {\n return false;\n }\n\n // 카테고리 필터\n if (query.category !== undefined && fact.category !== query.category) {\n return false;\n }\n\n // 출처 필터\n if (query.source !== undefined && fact.source !== query.source) {\n return false;\n }\n\n // 최소 신뢰도 필터\n if (query.minConfidence !== undefined) {\n if (fact.confidence === undefined || fact.confidence < query.minConfidence) {\n return false;\n }\n }\n\n // 단일 태그 필터\n if (query.tag !== undefined && !fact.tags.includes(query.tag)) {\n return false;\n }\n\n // 태그 필터 (모든 태그가 포함되어야 함)\n if (query.tags && query.tags.length > 0) {\n const hasAllTags = query.tags.every(tag => fact.tags.includes(tag));\n if (!hasAllTags) {\n return false;\n }\n }\n\n // 텍스트 검색\n if (query.text && !fact.content.toLowerCase().includes(query.text.toLowerCase())) {\n return false;\n }\n\n return true;\n });\n }\n\n /**\n * 만료된 사실 정리\n */\n cleanupExpiredFacts(): number {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const validFacts = knowledge.facts.filter(\n fact => !fact.expiresAt || fact.expiresAt >= now\n );\n\n const removedCount = knowledge.facts.length - validFacts.length;\n\n if (removedCount > 0) {\n this.board.write('knowledge.facts', validFacts);\n }\n\n return removedCount;\n }\n\n /**\n * 사실 삭제\n */\n removeFact(factId: string): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const updatedFacts = knowledge.facts.filter(f => f.id !== factId);\n\n if (updatedFacts.length === knowledge.facts.length) {\n throw new BlackboardError(\n BlackboardErrorCode.FACT_NOT_FOUND,\n `Fact ${factId} not found`\n );\n }\n\n this.board.write('knowledge.facts', updatedFacts);\n }\n\n /**\n * 사실 수 조회 (deprecated: factCount getter 사용)\n */\n getFactCount(): number {\n return this.factCount;\n }\n\n // === 추론 관리 ===\n\n /**\n * 추론 추가\n */\n addInference(inferenceInput: InferenceCreateInput): Inference {\n // 필수 필드 검증\n if (!inferenceInput.conclusion || inferenceInput.conclusion.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Inference conclusion is required'\n );\n }\n if (!inferenceInput.source) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Inference source is required'\n );\n }\n if (!Array.isArray(inferenceInput.premises)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Inference premises must be an array'\n );\n }\n this.validateConfidence(inferenceInput.confidence, 'Inference confidence');\n\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const inference: Inference = {\n id: `inference-${crypto.randomUUID()}`,\n conclusion: inferenceInput.conclusion,\n premises: inferenceInput.premises,\n source: inferenceInput.source,\n method: inferenceInput.method,\n confidence: inferenceInput.confidence,\n tags: inferenceInput.tags || [],\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedInferences = [...knowledge.inferences, inference];\n this.board.write('knowledge.inferences', updatedInferences);\n\n return inference;\n }\n\n /**\n * 추론 조회\n */\n getInference(inferenceId: string): Inference | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.inferences.find(i => i.id === inferenceId);\n }\n\n /**\n * 추론 업데이트\n */\n updateInference(\n inferenceId: string,\n updates: Partial<Omit<Inference, 'id' | 'createdAt'>>\n ): Inference | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const inferenceIndex = knowledge.inferences.findIndex(i => i.id === inferenceId);\n\n if (inferenceIndex === -1) {\n return undefined;\n }\n\n const existingInference = knowledge.inferences[inferenceIndex];\n const updatedInference: Inference = {\n ...existingInference,\n ...updates,\n id: existingInference.id,\n createdAt: existingInference.createdAt,\n updatedAt: new Date(),\n };\n\n const updatedInferences = [...knowledge.inferences];\n updatedInferences[inferenceIndex] = updatedInference;\n this.board.write('knowledge.inferences', updatedInferences);\n\n return updatedInference;\n }\n\n /**\n * 추론 검색\n */\n findInferences(query: InferenceQuery): Inference[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n\n return knowledge.inferences.filter(inference => {\n // 출처 필터\n if (query.source !== undefined && inference.source !== query.source) {\n return false;\n }\n\n // 전제 필터 (모든 전제 포함)\n if (query.premises && query.premises.length > 0) {\n const hasAllPremises = query.premises.every(p => inference.premises.includes(p));\n if (!hasAllPremises) {\n return false;\n }\n }\n\n // 최소 신뢰도 필터\n if (query.minConfidence !== undefined) {\n if (inference.confidence === undefined || inference.confidence < query.minConfidence) {\n return false;\n }\n }\n\n return true;\n });\n }\n\n /**\n * 특정 사실을 전제로 하는 추론 찾기\n */\n findInferencesByPremise(factId: string): Inference[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.inferences.filter(i => i.premises.includes(factId));\n }\n\n /**\n * 에이전트별 추론 조회\n */\n findInferencesByAgent(agentId: AgentId): Inference[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.inferences.filter(i => i.source === agentId);\n }\n\n /**\n * 추론 삭제\n */\n removeInference(inferenceId: string): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const updatedInferences = knowledge.inferences.filter(i => i.id !== inferenceId);\n\n if (updatedInferences.length === knowledge.inferences.length) {\n throw new BlackboardError(\n BlackboardErrorCode.INFERENCE_NOT_FOUND,\n `Inference ${inferenceId} not found`\n );\n }\n\n this.board.write('knowledge.inferences', updatedInferences);\n }\n\n /**\n * 추론 수 조회 (deprecated: inferenceCount getter 사용)\n */\n getInferenceCount(): number {\n return this.inferenceCount;\n }\n\n // === 패턴 관리 ===\n\n /**\n * 패턴 추가\n */\n addPattern(patternInput: PatternCreateInput): Pattern {\n // 필수 필드 검증\n if (!patternInput.name || patternInput.name.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern name is required'\n );\n }\n if (!patternInput.description || patternInput.description.trim().length === 0) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern description is required'\n );\n }\n if (!Array.isArray(patternInput.conditions)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern conditions must be an array'\n );\n }\n if (!Array.isArray(patternInput.consequences)) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n 'Pattern consequences must be an array'\n );\n }\n this.validateConfidence(patternInput.confidence, 'Pattern confidence');\n\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const pattern: Pattern = {\n id: `pattern-${crypto.randomUUID()}`,\n name: patternInput.name,\n description: patternInput.description,\n conditions: patternInput.conditions,\n consequences: patternInput.consequences,\n confidence: patternInput.confidence,\n tags: patternInput.tags || [],\n discoveredBy: patternInput.discoveredBy,\n usageCount: patternInput.usageCount ?? 0,\n successRate: patternInput.successRate ?? 0,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedPatterns = [...knowledge.patterns, pattern];\n this.board.write('knowledge.patterns', updatedPatterns);\n\n return pattern;\n }\n\n /**\n * 패턴 추가/업데이트\n */\n upsertPattern(patternInput: PatternCreateInput): Pattern {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n // 기존 패턴 확인 (같은 이름의 패턴)\n const existingPattern = knowledge.patterns.find(\n p => p.name === patternInput.name\n );\n\n if (existingPattern) {\n // 업데이트\n const updatedPattern: Pattern = {\n ...existingPattern,\n description: patternInput.description,\n conditions: patternInput.conditions,\n consequences: patternInput.consequences,\n confidence: patternInput.confidence,\n tags: patternInput.tags || existingPattern.tags,\n discoveredBy: patternInput.discoveredBy ?? existingPattern.discoveredBy,\n updatedAt: now,\n };\n\n const updatedPatterns = knowledge.patterns.map(p =>\n p.id === existingPattern.id ? updatedPattern : p\n );\n\n this.board.write('knowledge.patterns', updatedPatterns);\n return updatedPattern;\n }\n\n // 새 패턴 생성\n return this.addPattern(patternInput);\n }\n\n /**\n * 패턴 조회\n */\n getPattern(patternId: string): Pattern | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.patterns.find(p => p.id === patternId);\n }\n\n /**\n * 패턴 업데이트\n */\n updatePattern(\n patternId: string,\n updates: Partial<Omit<Pattern, 'id' | 'createdAt'>>\n ): Pattern | undefined {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const patternIndex = knowledge.patterns.findIndex(p => p.id === patternId);\n\n if (patternIndex === -1) {\n return undefined;\n }\n\n const existingPattern = knowledge.patterns[patternIndex];\n const updatedPattern: Pattern = {\n ...existingPattern,\n ...updates,\n id: existingPattern.id,\n createdAt: existingPattern.createdAt,\n updatedAt: new Date(),\n };\n\n const updatedPatterns = [...knowledge.patterns];\n updatedPatterns[patternIndex] = updatedPattern;\n this.board.write('knowledge.patterns', updatedPatterns);\n\n return updatedPattern;\n }\n\n /**\n * 패턴 검색\n */\n findPatterns(query: PatternQuery): Pattern[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n\n return knowledge.patterns.filter(pattern => {\n // 태그 필터\n if (query.tag !== undefined && !pattern.tags.includes(query.tag)) {\n return false;\n }\n\n // 최소 신뢰도 필터\n if (query.minConfidence !== undefined) {\n if (pattern.confidence === undefined || pattern.confidence < query.minConfidence) {\n return false;\n }\n }\n\n return true;\n });\n }\n\n /**\n * 에이전트가 발견한 패턴 조회\n */\n findPatternsByAgent(agentId: AgentId): Pattern[] {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n return knowledge.patterns.filter(p => p.discoveredBy === agentId);\n }\n\n /**\n * 패턴 사용 기록\n */\n recordPatternUsage(patternId: string, success: boolean): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const pattern = knowledge.patterns.find(p => p.id === patternId);\n\n if (!pattern) {\n throw new BlackboardError(\n BlackboardErrorCode.PATTERN_NOT_FOUND,\n `Pattern ${patternId} not found`\n );\n }\n\n const currentUsageCount = pattern.usageCount ?? 0;\n const currentSuccessRate = pattern.successRate ?? 0;\n const newUsageCount = currentUsageCount + 1;\n const newSuccessRate = (currentSuccessRate * currentUsageCount + (success ? 1 : 0)) / newUsageCount;\n\n const updatedPattern: Pattern = {\n ...pattern,\n usageCount: newUsageCount,\n successRate: newSuccessRate,\n updatedAt: new Date(),\n };\n\n const updatedPatterns = knowledge.patterns.map(p =>\n p.id === patternId ? updatedPattern : p\n );\n\n this.board.write('knowledge.patterns', updatedPatterns);\n }\n\n /**\n * 패턴 삭제\n */\n removePattern(patternId: string): void {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const updatedPatterns = knowledge.patterns.filter(p => p.id !== patternId);\n\n if (updatedPatterns.length === knowledge.patterns.length) {\n throw new BlackboardError(\n BlackboardErrorCode.PATTERN_NOT_FOUND,\n `Pattern ${patternId} not found`\n );\n }\n\n this.board.write('knowledge.patterns', updatedPatterns);\n }\n\n /**\n * 패턴 수 조회 (deprecated: patternCount getter 사용)\n */\n getPatternCount(): number {\n return this.patternCount;\n }\n\n // === 전체 관리 ===\n\n /**\n * 모든 지식 초기화\n */\n clearAll(): void {\n this.board.write('knowledge.facts', []);\n this.board.write('knowledge.inferences', []);\n this.board.write('knowledge.patterns', []);\n }\n\n // === 통계 ===\n\n /**\n * 지식 섹션 통계\n */\n getStats(): {\n facts: number;\n inferences: number;\n patterns: number;\n expiredFacts: number;\n } {\n const knowledge = this.board.read<KnowledgeSection>('knowledge');\n const now = new Date();\n\n const expiredFacts = knowledge.facts.filter(\n f => f.expiresAt && f.expiresAt < now\n ).length;\n\n return {\n facts: knowledge.facts.length,\n inferences: knowledge.inferences.length,\n patterns: knowledge.patterns.length,\n expiredFacts,\n };\n }\n}\n","/**\n * @module decisions-accessor\n * @description 의사결정 섹션 접근자\n */\n\nimport type { Blackboard } from \"../blackboard\";\nimport type { DecisionsSection } from \"../../types\";\nimport type {\n Agenda,\n AgendaCreateInput,\n Opinion,\n OpinionCreateInput,\n Resolution,\n DecisionType,\n OpinionId,\n AgendaId,\n} from \"../../types\";\nimport type { AgentId } from \"../../types\";\nimport { AgendaStatus, createOpinionId, createAgendaId } from \"../../types\";\nimport { BlackboardError, BlackboardErrorCode } from \"../blackboard\";\n\n/**\n * 의사결정 섹션 접근자\n * @description decisions 섹션에 대한 타입 안전한 접근 제공\n */\nexport class DecisionsSectionAccessor {\n constructor(private readonly board: Blackboard) {}\n\n /**\n * 의견 키 생성 (agendaId + agentId 조합)\n * @private\n */\n private getOpinionKey(agendaId: AgendaId, agentId: AgentId): string {\n return `${agendaId}:${agentId}`;\n }\n\n /**\n * opinionId로 opinionKey 찾기\n * @private\n */\n private findOpinionKey(opinionId: OpinionId): string | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n for (const [key, opinion] of decisions.opinions.entries()) {\n if (opinion.id === opinionId) {\n return key;\n }\n }\n return undefined;\n }\n\n // === 안건 관리 ===\n\n /** 현재 안건 */\n get current(): Agenda | null {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.current;\n }\n\n /** 대기 중인 안건들 */\n get pending(): Agenda[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.pending.filter((a) => a.status === AgendaStatus.SUBMITTED);\n }\n\n /** 모든 대기 안건 */\n get allPending(): Agenda[] {\n return this.board.read<DecisionsSection>(\"decisions\").pending;\n }\n\n /** 결정 이력 전체 */\n get history(): Resolution[] {\n return this.board.read<DecisionsSection>(\"decisions\").history;\n }\n\n /** 대기 중인 안건 수 */\n get pendingCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").pending.length;\n }\n\n /** 결정 이력 수 */\n get historyCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").history.length;\n }\n\n /**\n * 안건 제출\n * @param agendaInput - 새 안건 입력\n */\n submitAgenda(agendaInput: AgendaCreateInput): Agenda {\n // 필수 필드 검증\n if (!agendaInput.title?.trim()) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Title is required\");\n }\n if (!agendaInput.description?.trim()) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Description is required\");\n }\n if (!agendaInput.proposer) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Proposer is required\");\n }\n\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n const agenda: Agenda = {\n id: createAgendaId(`agenda-${crypto.randomUUID()}`),\n title: agendaInput.title,\n description: agendaInput.description,\n proposer: agendaInput.proposer,\n status: AgendaStatus.SUBMITTED,\n deadline: agendaInput.deadline ?? null,\n requiredQuorum: agendaInput.requiredQuorum ?? 3,\n votingMethod: agendaInput.votingMethod ?? \"majority\",\n priority: agendaInput.priority ?? 1,\n tags: agendaInput.tags ?? [],\n attachments: agendaInput.attachments ?? [],\n createdAt: now,\n updatedAt: now,\n version: 1,\n };\n\n const updatedPending = [...decisions.pending, agenda];\n this.board.write(\"decisions.pending\", updatedPending);\n this.board.emit(\"agenda_submitted\", { agendaId: agenda.id, agenda });\n\n return agenda;\n }\n\n /**\n * 안건 상태 변경\n */\n updateAgendaStatus(agendaId: AgendaId, status: AgendaStatus): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // pending에서 찾기\n let targetIndex = -1;\n let targetPending = false;\n\n for (let i = 0; i < decisions.pending.length; i++) {\n if (decisions.pending[i].id === agendaId) {\n targetIndex = i;\n targetPending = true;\n break;\n }\n }\n\n if (targetIndex === -1 && decisions.current?.id === agendaId) {\n targetIndex = 0;\n targetPending = false;\n }\n\n if (targetIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n if (targetPending) {\n const updatedAgenda = {\n ...decisions.pending[targetIndex],\n status,\n updatedAt: new Date(),\n version: decisions.pending[targetIndex].version + 1,\n };\n\n const updatedPending = [...decisions.pending];\n updatedPending[targetIndex] = updatedAgenda;\n\n this.board.write(\"decisions.pending\", updatedPending);\n } else if (decisions.current) {\n const updatedAgenda = {\n ...decisions.current,\n status,\n updatedAt: new Date(),\n version: decisions.current.version + 1,\n };\n\n this.board.write(\"decisions.current\", updatedAgenda);\n }\n\n this.board.emit(\"agenda_updated\", { agendaId, status });\n }\n\n /**\n * 현재 안건 설정\n */\n setCurrentAgenda(agendaId: AgendaId): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // 현재 안건이 있으면 pending으로 이동\n const updatedPending = [...decisions.pending];\n if (decisions.current) {\n updatedPending.push(decisions.current);\n }\n\n // pending에서 해당 안건 찾기\n const agendaIndex = updatedPending.findIndex((a) => a.id === agendaId);\n if (agendaIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found in pending`\n );\n }\n\n const [agenda] = updatedPending.splice(agendaIndex, 1);\n\n // 안건 상태 업데이트\n const updatedAgenda: Agenda = {\n ...agenda,\n status: AgendaStatus.DISCUSSING,\n updatedAt: new Date(),\n version: agenda.version + 1,\n };\n\n this.board.write(\"decisions.current\", updatedAgenda);\n this.board.write(\"decisions.pending\", updatedPending);\n }\n\n /**\n * 안건 취소\n */\n cancelAgenda(agendaId: AgendaId, reason: string): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // current 안건인 경우\n if (decisions.current?.id === agendaId) {\n this.board.write(\"decisions.current\", null);\n this.board.emit(\"agenda_updated\", { agendaId, status: AgendaStatus.CANCELLED, reason });\n return;\n }\n\n // pending 안건인 경우\n const agendaIndex = decisions.pending.findIndex((a) => a.id === agendaId);\n if (agendaIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const updatedPending = decisions.pending.filter((a) => a.id !== agendaId);\n this.board.write(\"decisions.pending\", updatedPending);\n this.board.emit(\"agenda_updated\", { agendaId, status: AgendaStatus.CANCELLED, reason });\n }\n\n /**\n * 안건 조회\n */\n getAgenda(agendaId: AgendaId): Agenda | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n if (decisions.current?.id === agendaId) {\n return decisions.current;\n }\n\n const pendingAgenda = decisions.pending.find((a) => a.id === agendaId);\n if (pendingAgenda) {\n return pendingAgenda;\n }\n\n // 해결된 안건도 조회 (resolution에 연결된 agenda 정보)\n // 실제로는 agenda가 history에 저장되지 않으므로 null 반환\n return undefined;\n }\n\n /**\n * 모든 안건 조회\n */\n getAllAgendas(): Agenda[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const result: Agenda[] = [];\n\n if (decisions.current) {\n result.push(decisions.current);\n }\n\n result.push(...decisions.pending);\n return result;\n }\n\n // === 의견 관리 ===\n\n /**\n * 의견 제출\n * @param opinionInput - 의견 생성 입력 (agentId 포함)\n */\n submitOpinion(opinionInput: OpinionCreateInput & { agentId: AgentId }): Opinion {\n // 필수 필드 검증\n if (!opinionInput.stance) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_INPUT, \"Stance is required\");\n }\n if (\n opinionInput.confidence !== undefined &&\n (opinionInput.confidence < 0 ||\n opinionInput.confidence > 1 ||\n Number.isNaN(opinionInput.confidence))\n ) {\n throw new BlackboardError(\n BlackboardErrorCode.INVALID_INPUT,\n \"Confidence must be between 0 and 1\"\n );\n }\n\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n // 안건 확인\n const agenda = this.getAgenda(opinionInput.agendaId);\n if (!agenda) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${opinionInput.agendaId} not found`\n );\n }\n\n // 중복 의견 확인\n const opinionKey = this.getOpinionKey(opinionInput.agendaId, opinionInput.agentId);\n if (decisions.opinions.has(opinionKey)) {\n throw new BlackboardError(\n BlackboardErrorCode.DUPLICATE_OPINION,\n `Agent ${opinionInput.agentId} already submitted an opinion for agenda ${opinionInput.agendaId}`\n );\n }\n\n const fullOpinion: Opinion = {\n id: createOpinionId(`opinion-${crypto.randomUUID()}`),\n agentId: opinionInput.agentId,\n agendaId: opinionInput.agendaId,\n stance: opinionInput.stance,\n reason: opinionInput.reason,\n conditions: opinionInput.conditions ?? [],\n confidence: opinionInput.confidence ?? 0.5,\n references: opinionInput.references ?? [],\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedOpinions = new Map(decisions.opinions);\n updatedOpinions.set(opinionKey, fullOpinion);\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n this.board.emit(\"opinion_added\", { opinion: fullOpinion });\n\n return fullOpinion;\n }\n\n /**\n * 특정 안건의 모든 의견 조회\n */\n getOpinions(agendaId: AgendaId): Opinion[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const opinions: Opinion[] = [];\n\n for (const opinion of decisions.opinions.values()) {\n if (opinion.agendaId === agendaId) {\n opinions.push(opinion);\n }\n }\n\n return opinions;\n }\n\n /**\n * 에이전트의 의견 조회 (agendaId 먼저)\n * @deprecated getAgentOpinion() 사용 권장\n */\n getOpinionByAgent(agendaId: AgendaId, agentId: AgentId): Opinion | undefined {\n return this.getAgentOpinion(agentId, agendaId);\n }\n\n /**\n * 에이전트의 의견 조회\n * @param agentId - 에이전트 ID\n * @param agendaId - 안건 ID (필수)\n */\n getAgentOpinion(agentId: AgentId, agendaId: AgendaId): Opinion | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n // agendaId + agentId 조합으로 키 조회\n const opinionKey = this.getOpinionKey(agendaId, agentId);\n const opinion = decisions.opinions.get(opinionKey);\n\n return opinion;\n }\n\n /**\n * 의견 요약\n */\n summarizeOpinions(agendaId: AgendaId): {\n total: number;\n approve: number;\n reject: number;\n conditional: number;\n abstain: number;\n approvalRate: number;\n quorumReached: boolean;\n } {\n const opinions = this.getOpinions(agendaId);\n\n const summary = {\n total: opinions.length,\n approve: 0,\n reject: 0,\n conditional: 0,\n abstain: 0,\n approvalRate: 0,\n quorumReached: false,\n };\n\n // 유효한 stance 값인지 확인 후 처리\n const validStances: readonly string[] = [\"approve\", \"reject\", \"conditional\", \"abstain\"];\n\n for (const opinion of opinions) {\n if (validStances.includes(opinion.stance)) {\n summary[opinion.stance as keyof typeof summary]++;\n }\n }\n\n // 승인률 계산 (찬성 / 총 투표수)\n summary.approvalRate =\n summary.total > 0 ? (summary.approve + summary.conditional) / summary.total : 0;\n\n // 정족수 도달 여부 확인\n const agenda = this.getAgenda(agendaId);\n if (agenda) {\n summary.quorumReached = summary.total >= agenda.requiredQuorum;\n }\n\n return summary;\n }\n\n /**\n * 모든 의견 초기화 (재투표 시)\n */\n clearOpinions(agendaId: AgendaId): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const updatedOpinions = new Map(decisions.opinions);\n\n for (const [key, opinion] of decisions.opinions.entries()) {\n if (opinion.agendaId === agendaId) {\n updatedOpinions.delete(key);\n }\n }\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n }\n\n /**\n * 의견 업데이트\n */\n updateOpinion(opinionId: OpinionId, updates: Partial<Omit<Opinion, \"id\" | \"createdAt\">>): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const opinionKey = this.findOpinionKey(opinionId);\n\n if (!opinionKey) {\n throw new BlackboardError(\n BlackboardErrorCode.OPINION_NOT_FOUND,\n `Opinion ${opinionId} not found`\n );\n }\n\n const existingOpinion = decisions.opinions.get(opinionKey);\n if (!existingOpinion) {\n throw new BlackboardError(\n BlackboardErrorCode.OPINION_NOT_FOUND,\n `Opinion ${opinionId} not found`\n );\n }\n\n const updatedOpinion: Opinion = {\n ...existingOpinion,\n ...updates,\n id: existingOpinion.id, // ID 변경 불가\n createdAt: existingOpinion.createdAt, // 생성 시간 변경 불가\n updatedAt: new Date(),\n };\n\n const updatedOpinions = new Map(decisions.opinions);\n updatedOpinions.set(opinionKey, updatedOpinion);\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n this.board.emit(\"opinion_updated\", { opinion: updatedOpinion });\n }\n\n /**\n * 의견 삭제\n */\n removeOpinion(opinionId: OpinionId): void {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const opinionKey = this.findOpinionKey(opinionId);\n\n if (!opinionKey) {\n throw new BlackboardError(\n BlackboardErrorCode.OPINION_NOT_FOUND,\n `Opinion ${opinionId} not found`\n );\n }\n\n const updatedOpinions = new Map(decisions.opinions);\n updatedOpinions.delete(opinionKey);\n\n this.board.write(\"decisions.opinions\", updatedOpinions);\n this.board.emit(\"opinion_removed\", { opinionId });\n }\n\n // === 결정 관리 ===\n\n /**\n * 결정 기록 (안건 제거)\n * @description 새 결정을 기록하고 관련 안건을 제거합니다.\n * @warning closeAgenda()를 사용하면 안건이 RESOLVED 상태로 유지됩니다.\n * 이 메서드는 안건을 완전히 제거합니다.\n */\n recordResolution(\n resolutionInput: Omit<Resolution, \"id\" | \"createdAt\" | \"updatedAt\">\n ): Resolution {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n const resolution: Resolution = {\n id: `resolution-${crypto.randomUUID()}`,\n agendaId: resolutionInput.agendaId,\n decision: resolutionInput.decision,\n summary: resolutionInput.summary,\n voteSummary: resolutionInput.voteSummary,\n conditions: resolutionInput.conditions,\n dissent: resolutionInput.dissent,\n decidedBy: resolutionInput.decidedBy,\n nextActions: resolutionInput.nextActions,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedHistory = [...decisions.history, resolution];\n this.board.write(\"decisions.history\", updatedHistory);\n\n // 현재 안건 초기화\n if (decisions.current?.id === resolution.agendaId) {\n this.board.write(\"decisions.current\", null);\n } else {\n // pending에서 제거\n const updatedPending = decisions.pending.filter((a) => a.id !== resolution.agendaId);\n this.board.write(\"decisions.pending\", updatedPending);\n }\n\n this.board.emit(\"resolution_created\", { resolution });\n\n return resolution;\n }\n\n /**\n * 결정 기록 (안건 유지)\n * @description 안건을 제거하지 않고 결정만 기록합니다.\n * @private\n */\n private recordResolutionKeepAgenda(\n resolutionInput: Omit<Resolution, \"id\" | \"createdAt\" | \"updatedAt\">\n ): Resolution {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n const now = new Date();\n\n const resolution: Resolution = {\n id: `resolution-${crypto.randomUUID()}`,\n agendaId: resolutionInput.agendaId,\n decision: resolutionInput.decision,\n summary: resolutionInput.summary,\n voteSummary: resolutionInput.voteSummary,\n conditions: resolutionInput.conditions,\n dissent: resolutionInput.dissent,\n decidedBy: resolutionInput.decidedBy,\n nextActions: resolutionInput.nextActions,\n createdAt: now,\n updatedAt: now,\n };\n\n const updatedHistory = [...decisions.history, resolution];\n this.board.write(\"decisions.history\", updatedHistory);\n this.board.emit(\"resolution_created\", { resolution });\n\n return resolution;\n }\n\n /**\n * 결정 이력 조회\n */\n getHistory(filter?: { agendaId?: AgendaId; decision?: DecisionType }): Resolution[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n let history = [...decisions.history];\n\n if (!filter) {\n return history;\n }\n\n if (filter.agendaId) {\n history = history.filter((r) => r.agendaId === filter.agendaId);\n }\n\n if (filter.decision) {\n history = history.filter((r) => r.decision === filter.decision);\n }\n\n return history;\n }\n\n /**\n * 최근 N개 결정 조회\n */\n getRecentResolutions(count: number): Resolution[] {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.history.slice(-count).reverse();\n }\n\n /**\n * 결정 조회\n */\n getResolution(resolutionId: string): Resolution | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.history.find((r) => r.id === resolutionId);\n }\n\n /**\n * 안건에 대한 결정 조회\n */\n getResolutionByAgenda(agendaId: AgendaId): Resolution | undefined {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n return decisions.history.find((r) => r.agendaId === agendaId);\n }\n\n // === 통계 ===\n\n /**\n * 결정 수 조회\n */\n getResolutionCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").history.length;\n }\n\n /**\n * 안건 수 조회\n */\n getAgendaCount(): number {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n let count = decisions.current ? 1 : 0;\n count += decisions.pending.length;\n return count;\n }\n\n /**\n * 의견 수 조회\n */\n getOpinionCount(): number {\n return this.board.read<DecisionsSection>(\"decisions\").opinions.size;\n }\n\n // === 투표 ===\n\n /**\n * 투표 결과 확인\n * @note conditional은 승인으로 카운트됩니다 (찬성 = approve + conditional)\n */\n checkVotingResult(agendaId: AgendaId): {\n passed: boolean;\n method: \"majority\" | \"unanimous\" | \"weighted\" | \"supermajority\";\n summary: {\n total: number;\n approve: number;\n reject: number;\n conditional: number;\n abstain: number;\n approvalRate: number;\n quorumReached: boolean;\n };\n } {\n const agenda = this.getAgenda(agendaId);\n if (!agenda) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const summary = this.summarizeOpinions(agendaId);\n let passed = false;\n\n switch (agenda.votingMethod) {\n case \"unanimous\":\n // 전체 찬성 (반대 없음)\n passed = summary.reject === 0 && summary.total > 0;\n break;\n case \"majority\": {\n // 단순 과반수 (50% 초과)\n const approveCount = summary.approve + summary.conditional;\n passed = approveCount > summary.total / 2;\n break;\n }\n case \"supermajority\": {\n // 2/3 이상 찬성\n const superMajorityCount = summary.approve + summary.conditional;\n passed = superMajorityCount >= (summary.total * 2) / 3;\n break;\n }\n case \"weighted\": {\n // 가중치 투표 (현재는 과반수와 동일하게 처리)\n const weightedCount = summary.approve + summary.conditional;\n passed = weightedCount > summary.total / 2;\n break;\n }\n }\n\n return {\n passed: summary.quorumReached && passed,\n method: agenda.votingMethod,\n summary,\n };\n }\n\n // === 안건 관리 추가 ===\n\n /**\n * 안건 종료 (결정 기록)\n * @description 안건을 RESOLVED 상태로 변경하고 결정을 기록합니다.\n *\n * **정책:** 안건은 RESOLVED 상태로 변경 후에도 pending/current에 유지됩니다.\n * 이는 결정 이력 추적 및 후속 조치 관리를 위함입니다.\n * 안건을 완전히 제거하려면 {@link recordResolution()}을 직접 호출하세요.\n *\n * @param agendaId - 종료할 안건 ID\n * @param decision - 결정 유형 (기본: approved)\n */\n closeAgenda(\n agendaId: AgendaId,\n decision: \"approved\" | \"rejected\" | \"deferred\" = \"approved\"\n ): void {\n const agenda = this.getAgenda(agendaId);\n if (!agenda) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const summary = this.summarizeOpinions(agendaId);\n\n // 먼저 안건 상태 업데이트 (agenda를 찾을 수 있도록)\n this.updateAgendaStatus(agendaId, AgendaStatus.RESOLVED);\n\n // 결정 기록 생성 (안건 유지 - 정책에 따름)\n this.recordResolutionKeepAgenda({\n agendaId,\n decision: decision as DecisionType,\n summary: `Agenda ${agenda.title} ${decision}`,\n voteSummary: {\n total: summary.total,\n approve: summary.approve,\n reject: summary.reject,\n conditional: summary.conditional,\n abstain: summary.abstain,\n },\n conditions: [],\n dissent: [],\n decidedBy: agenda.proposer,\n nextActions: [],\n });\n }\n\n /**\n * 안건 업데이트\n */\n updateAgenda(agendaId: AgendaId, updates: Partial<Omit<Agenda, \"id\" | \"createdAt\">>): Agenda {\n const decisions = this.board.read<DecisionsSection>(\"decisions\");\n\n // current 안건 확인\n if (decisions.current?.id === agendaId) {\n const updatedAgenda: Agenda = {\n ...decisions.current,\n ...updates,\n id: decisions.current.id, // ID 변경 불가\n createdAt: decisions.current.createdAt, // 생성 시간 변경 불가\n updatedAt: new Date(),\n version: decisions.current.version + 1,\n };\n\n this.board.write(\"decisions.current\", updatedAgenda);\n this.board.emit(\"agenda_updated\", { agendaId, agenda: updatedAgenda });\n return updatedAgenda;\n }\n\n // pending 안건 확인\n const pendingIndex = decisions.pending.findIndex((a) => a.id === agendaId);\n if (pendingIndex === -1) {\n throw new BlackboardError(\n BlackboardErrorCode.AGENDA_NOT_FOUND,\n `Agenda ${agendaId} not found`\n );\n }\n\n const existingAgenda = decisions.pending[pendingIndex];\n const updatedAgenda: Agenda = {\n ...existingAgenda,\n ...updates,\n id: existingAgenda.id, // ID 변경 불가\n createdAt: existingAgenda.createdAt, // 생성 시간 변경 불가\n updatedAt: new Date(),\n version: existingAgenda.version + 1,\n };\n\n const updatedPending = [...decisions.pending];\n updatedPending[pendingIndex] = updatedAgenda;\n\n this.board.write(\"decisions.pending\", updatedPending);\n this.board.emit(\"agenda_updated\", { agendaId, agenda: updatedAgenda });\n return updatedAgenda;\n }\n\n // === 초기화 ===\n\n /**\n * 모든 결정 초기화\n */\n clearAll(): void {\n this.board.write(\"decisions.current\", null);\n this.board.write(\"decisions.pending\", []);\n this.board.write(\"decisions.opinions\", new Map());\n this.board.write(\"decisions.history\", []);\n this.board.emit(\"decisions_cleared\", {});\n }\n}\n","/**\n * @module snapshot/types\n * @description 스냅샷 타입 정의\n */\n\nimport type { SessionId } from \"../types\";\n\n/**\n * 스냅샷 형식 버전\n * @description 역직렬화 시 호환성 체크에 사용\n */\nexport const SNAPSHOT_FORMAT_VERSION = \"1.0.0\";\n\n/**\n * 스냅샷 메타데이터\n */\nexport interface SnapshotMeta {\n /** 스냅샷 ID */\n readonly id: string;\n /** 스냅샷 형식 버전 */\n readonly formatVersion: string;\n /** 생성 시간 */\n readonly createdAt: Date;\n /** 원본 세션 ID */\n readonly sessionId: SessionId;\n /** 원본 상태 버전 */\n readonly stateVersion: number;\n /** 스냅샷 설명 (선택) */\n readonly description?: string;\n /** 스냅샷 태그 (선택) */\n readonly tags?: string[];\n /** 체크섬 (무결성 검증용) */\n readonly checksum: string;\n /** 압축 데이터 체크섬 */\n readonly compressedChecksum?: string;\n /** 압축 여부 */\n readonly compressed: boolean;\n /** 원본 크기 (바이트) */\n readonly originalSize: number;\n /** 압축 크기 (바이트, 압축 시) */\n readonly compressedSize?: number;\n}\n\n/**\n * 직렬화된 상태\n * @description Map, Date 등이 JSON 호환 형식으로 변환됨\n */\nexport interface SerializedState {\n meta: {\n version: number;\n lastUpdated: string; // ISO 8601\n sessionId: string;\n createdAt: string;\n };\n state: {\n phase: string;\n context: Record<string, unknown>;\n agents: Array<[string, unknown]>; // Map<AgentId, AgentStatus> entries\n tasks: Array<[string, unknown]>; // Map<TaskId, Task> entries\n };\n knowledge: {\n facts: unknown[]; // Fact[]\n inferences: unknown[]; // Inference[]\n patterns: unknown[]; // Pattern[]\n };\n decisions: {\n current: unknown | null; // Agenda | null\n pending: unknown[]; // Agenda[]\n opinions: Array<[string, unknown]>; // Map<string, Opinion> entries\n history: unknown[]; // Resolution[]\n voting?: Record<string, unknown>; // VotingSession map\n };\n}\n\n/**\n * 전체 스냅샷 구조\n */\nexport interface Snapshot {\n /** 메타데이터 */\n meta: SnapshotMeta;\n /** 직렬화된 상태 데이터 */\n data: SerializedState | string; // string when compressed\n}\n\n/**\n * 스냅샷 생성 옵션\n */\nexport interface CreateSnapshotOptions {\n /** 스냅샷 설명 */\n description?: string;\n /** 태그 */\n tags?: string[];\n /** 압축 사용 여부 (기본: false) */\n compress?: boolean;\n /** 특정 섹션만 포함 */\n includeSections?: (\"state\" | \"knowledge\" | \"decisions\")[];\n /** 메타만 포함 (상태 제외) */\n metaOnly?: boolean;\n /** 내부 저장소에 저장 여부 */\n store?: boolean;\n}\n\n/**\n * 스냅샷 복원 옵션\n */\nexport interface RestoreSnapshotOptions {\n /** 버전 체크 건너뛰기 */\n skipVersionCheck?: boolean;\n /** 구조적 검증 건너뛰기 (validateSync) */\n skipStructuralValidation?: boolean;\n /** 검증 건너뛰기 (별칭: skipStructuralValidation) */\n skipValidation?: boolean;\n /** 특정 섹션만 복원 */\n restoreSections?: (\"state\" | \"knowledge\" | \"decisions\")[];\n /** 복원 후 버전 리셋 여부 (기본: true) */\n resetVersion?: boolean;\n /** 새 세션 ID 발급 (기본: true) */\n newSessionId?: boolean;\n}\n\n/**\n * 스냅샷 검증 결과\n */\nexport interface SnapshotValidationResult {\n /** 유효 여부 */\n valid: boolean;\n /** 에러 목록 */\n errors: SnapshotValidationError[];\n /** 경고 목록 */\n warnings: SnapshotValidationWarning[];\n}\n\n/**\n * 검증 에러\n */\nexport interface SnapshotValidationError {\n code:\n | \"VERSION_MISMATCH\"\n | \"CHECKSUM_INVALID\"\n | \"DATA_CORRUPTED\"\n | \"FORMAT_INVALID\"\n | \"MISSING_FIELD\";\n message: string;\n details?: unknown;\n}\n\n/**\n * 검증 경고\n */\nexport interface SnapshotValidationWarning {\n code: \"DEPRECATED_FORMAT\" | \"UNKNOWN_FIELDS\" | \"PARTIAL_DATA\";\n message: string;\n details?: unknown;\n}\n\n/**\n * 스냅샷 마이그레이션 인터페이스\n * @description 스냅샷 데이터 버전 간 마이그레이션을 위한 인터페이스\n */\nexport interface SnapshotMigration {\n /** 원본 버전 */\n fromVersion: number;\n /** 대상 버전 */\n toVersion: number;\n /** 마이그레이션 함수 */\n migrate(data: unknown): unknown;\n}\n","/**\n * @module snapshot/id-utils\n * @description ID 생성 유틸리티 (브라우저/Node.js 호환)\n */\n\n/**\n * 기본 ID 생성 함수\n * @returns 고유 ID 문자열\n * @description Node.js 환경에서는 crypto.randomUUID(), 브라우저 환경에서는 fallback 사용\n */\nexport function createDefaultId(): string {\n // Node.js 환경\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n\n // 브라우저 환경 fallback\n return `snap-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * ID 생성자 타입\n */\nexport type IdGenerator = () => string;\n\n/**\n * 기본 ID 생성자 생성\n * @param customGenerator - 사용자 정의 ID 생성 함수 (선택)\n * @returns ID 생성 함수\n */\nexport function createIdGenerator(\n customGenerator?: IdGenerator\n): IdGenerator {\n return customGenerator ?? createDefaultId;\n}\n","/**\n * @module snapshot/compression\n * @description 압축 유틸리티 (브라우저/Node.js 호환)\n */\n\nimport { gzip, ungzip, type InflateFunctionOptions } from 'pako';\n\n/**\n * 압축 알고리즘\n * @note brotli는 pako에서 지원하지 않음\n */\nexport type CompressionAlgorithm = 'gzip' | 'none';\n\n/**\n * 압축 레벨 (테스트 호환 타입)\n */\nexport type CompressionLevel = 'none' | 'fast' | 'balanced' | 'max';\n\n/**\n * 내부 pako 압축 레벨 숫자 타입\n */\ntype PakoCompressionLevel = -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;\n\n/**\n * 압축 옵션\n */\nexport interface CompressionOptions {\n /** 알고리즘 (기본: 'gzip') */\n algorithm?: CompressionAlgorithm;\n /** 압축 레벨 (기본: 'balanced') */\n level?: CompressionLevel | PakoCompressionLevel;\n /** 출력 형식 (기본: 'base64') */\n outputFormat?: 'base64' | 'buffer' | 'uint8array';\n /** 메타데이터 포함 여부 */\n includeMetadata?: boolean;\n}\n\n/**\n * 압축 해제 옵션\n */\nexport interface DecompressionOptions {\n /** 압축 알고리즘 */\n algorithm?: CompressionAlgorithm;\n /** 입력 형식 (기본: 'base64') */\n inputFormat?: 'base64' | 'buffer' | 'uint8array';\n /** 유효성 검사 건너뛰기 (algorithm='none'인 경우 자동 true) */\n skipValidation?: boolean;\n}\n\n/**\n * 압축 메타데이터\n */\nexport interface CompressionMetadata {\n /** 원본 크기 */\n originalSize: number;\n /** 압축된 크기 */\n compressedSize: number;\n /** 사용된 알고리즘 */\n algorithm: CompressionAlgorithm;\n /** 사용된 압축 레벨 */\n level: CompressionLevel | PakoCompressionLevel;\n /** 타임스탬프 */\n timestamp: string;\n}\n\n/**\n * 메타데이터가 포함된 압축 결과\n */\nexport interface CompressedWithMeta {\n /** 압축된 데이터 */\n data: string;\n /** 메타데이터 */\n metadata: CompressionMetadata;\n}\n\n/**\n * 압축 통계\n */\nexport interface CompressionStats {\n /** 원본 크기 */\n originalSize: number;\n /** 압축된 크기 */\n compressedSize: number;\n /** 압축 비율 (originalSize / compressedSize) */\n ratio: number;\n /** 절감된 크기 (bytes) */\n savings: number;\n /** 절감 비율 (%) */\n savingsPercent: number;\n}\n\n/**\n * Pako 압축 해제 옵션 타입 정의\n */\ninterface PakoUngzipOptions extends InflateFunctionOptions {\n windowBits?: number;\n}\n\n/**\n * 문자열 압축 레벨을 pako 레벨로 변환\n */\nfunction normalizeCompressionLevel(\n level?: CompressionLevel | PakoCompressionLevel\n): PakoCompressionLevel {\n if (level === undefined || level === 'balanced') {\n return 6;\n }\n if (level === 'none') {\n return 0;\n }\n if (level === 'fast') {\n return 1;\n }\n if (level === 'max') {\n return 9;\n }\n // 이미 숫자인 경우 (PakoCompressionLevel)\n return level as PakoCompressionLevel;\n}\n\n/**\n * 문자열을 Uint8Array로 변환\n */\nfunction stringToUint8Array(str: string): Uint8Array {\n const encoder = new TextEncoder();\n return encoder.encode(str);\n}\n\n/**\n * Uint8Array를 문자열로 변환\n */\nfunction uint8ArrayToString(bytes: Uint8Array): string {\n const decoder = new TextDecoder();\n return decoder.decode(bytes);\n}\n\n/**\n * Uint8Array를 Base64로 변환\n */\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n // Node.js 환경에서는 Buffer가 더 효율적\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(bytes).toString('base64');\n }\n // 브라우저 환경\n let binary = '';\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Base64를 Uint8Array로 변환\n */\nfunction base64ToUint8Array(base64: string): Uint8Array {\n // Node.js 환경\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(base64, 'base64'));\n }\n // 브라우저 환경\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * 입력 데이터를 Uint8Array로 변환\n */\nfunction inputToUint8Array(data: string | Uint8Array | Buffer): Uint8Array {\n if (typeof data === 'string') {\n return stringToUint8Array(data);\n }\n if (data instanceof Uint8Array) {\n return data;\n }\n if (Buffer.isBuffer(data)) {\n return new Uint8Array(data);\n }\n throw new Error(`Unsupported input type: ${typeof data}`);\n}\n\n/**\n * 출력 데이터 변환\n */\nfunction formatOutput(\n data: Uint8Array,\n format: 'base64' | 'buffer' | 'uint8array'\n): string | Uint8Array | Buffer {\n if (format === 'base64') {\n return uint8ArrayToBase64(data);\n }\n if (format === 'buffer' && typeof Buffer !== 'undefined') {\n return Buffer.from(data);\n }\n return data;\n}\n\n/**\n * 입력 데이터를 Uint8Array로 변환 (decompression용)\n */\nfunction inputToUint8ArrayForDecompress(\n data: string | Uint8Array | Buffer,\n format?: 'base64' | 'buffer' | 'uint8array'\n): Uint8Array {\n // format이 지정된 경우 해당 형식으로 처리\n if (format === 'base64' && typeof data === 'string') {\n return base64ToUint8Array(data);\n }\n if (format === 'buffer' && Buffer.isBuffer(data)) {\n return new Uint8Array(data);\n }\n if (format === 'uint8array' && data instanceof Uint8Array) {\n return data;\n }\n\n // format이 지정되지 않은 경우 자동 감지\n if (typeof data === 'string') {\n // string이면 base64로 처리 (gzip 압축된 데이터는 항상 base64 인코딩됨)\n try {\n return base64ToUint8Array(data);\n } catch {\n // base64 디코딩 실패시 일반 문자열로 처리\n return stringToUint8Array(data);\n }\n }\n\n return inputToUint8Array(data);\n}\n\n/**\n * 체크섬 계산 (간단한 해시)\n */\nfunction calculateChecksum(data: string): string {\n let hash = 0;\n for (let i = 0; i < data.length; i++) {\n const char = data.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(16);\n}\n\n/**\n * 데이터 압축\n * @param data - 압축할 데이터 (string | Uint8Array | Buffer)\n * @param options - 압축 옵션\n * @returns 압축된 데이터 (string | Uint8Array | Buffer)\n */\nexport function compress(\n data: string | Uint8Array | Buffer,\n options?: CompressionOptions\n): string | Uint8Array | Buffer {\n // 빈 데이터 처리 - 빈 문자열은 허용\n if (data === null || data === undefined) {\n throw new Error('compress(): input data must not be null or undefined');\n }\n\n const algorithm = options?.algorithm ?? 'gzip';\n const outputFormat = options?.outputFormat ?? 'base64';\n const level = options?.level ?? 'balanced';\n\n // level: 'none'인 경우 압축하지 않음 - 원본 타입 유지\n if (level === 'none' || algorithm === 'none') {\n if (typeof data === 'string') {\n return data;\n }\n if (Buffer.isBuffer(data)) {\n return data;\n }\n if (data instanceof Uint8Array) {\n return data;\n }\n return data;\n }\n\n try {\n const input = inputToUint8Array(data);\n const normalizedLevel = normalizeCompressionLevel(level);\n\n // pako gzip 압축 옵션 (동기)\n const compressed = gzip(input, { level: normalizedLevel });\n\n // 원본 타입에 따라 반환 형식 결정 (outputFormat이 명시된 경우 제외)\n if (options?.outputFormat) {\n return formatOutput(compressed, outputFormat);\n }\n if (typeof data === 'string') {\n return uint8ArrayToBase64(compressed);\n }\n if (Buffer.isBuffer(data) && typeof Buffer !== 'undefined') {\n return Buffer.from(compressed);\n }\n return compressed;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`Failed to compress data: ${msg}`);\n }\n}\n\n/**\n * 데이터 압축 해제\n * @param compressed - 압축된 데이터\n * @param options - 압축 해제 옵션\n * @returns 원본 데이터\n * @throws {Error} 데이터 크기 제한 초과 시\n */\nexport function decompress(\n compressed: string | Uint8Array | Buffer,\n options?: DecompressionOptions\n): string | Uint8Array | Buffer {\n // 빈 데이터 처리\n if (compressed === null || compressed === undefined) {\n throw new Error('decompress(): input data must not be null or undefined');\n }\n\n const algorithm = options?.algorithm ?? 'gzip';\n const skipValidation = options?.skipValidation ?? false;\n\n // 빈 데이터 처리 (압축하지 않은 경우)\n if (\n (typeof compressed === 'string' && compressed === '') ||\n (Buffer.isBuffer(compressed) && compressed.length === 0) ||\n (compressed instanceof Uint8Array && compressed.length === 0)\n ) {\n return compressed;\n }\n\n // algorithm이 'none'인 경우 또는 skipValidation이 true인 경우\n if (algorithm === 'none' || skipValidation) {\n if (typeof compressed === 'string') {\n return compressed;\n }\n if (Buffer.isBuffer(compressed)) {\n return compressed;\n }\n return compressed;\n }\n\n try {\n const buffer = inputToUint8ArrayForDecompress(compressed, options?.inputFormat);\n\n // gzip 헤더 확인\n if (buffer.length >= 2) {\n if (!(buffer[0] === 0x1f && buffer[1] === 0x8b)) {\n // string 입력이고 gzip 헤더가 없으면 원본 반환 (level: 'none'으로 압축된 경우)\n if (typeof compressed === 'string') {\n return compressed;\n }\n // Buffer/Uint8Array 입력이고 gzip 헤더가 없으면 에러\n throw new Error('Invalid gzip header: data does not appear to be gzip-compressed');\n }\n }\n\n // pako gzip 압축 해제 옵션 (동기)\n const ungzipOptions: PakoUngzipOptions = {};\n const decompressed = ungzip(buffer, ungzipOptions);\n\n // 원본 타입에 따라 반환\n if (typeof compressed === 'string') {\n return uint8ArrayToString(decompressed);\n }\n if (Buffer.isBuffer(compressed) && typeof Buffer !== 'undefined') {\n return Buffer.from(decompressed);\n }\n return decompressed;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`Failed to decompress data: ${msg}`);\n }\n}\n\n/**\n * 압축 여부 감지\n * @param data - 검사할 데이터\n * @returns 압축 알고리즘 또는 null\n */\nexport function detectCompression(data: string): CompressionAlgorithm | null {\n // Base64 디코딩 시도\n try {\n const buffer = base64ToUint8Array(data);\n\n // 최소 2바이트 필요\n if (buffer.length < 2) {\n return null;\n }\n\n // Gzip magic number: 0x1f 0x8b\n if (buffer[0] === 0x1f && buffer[1] === 0x8b) {\n return 'gzip';\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * 체크섬 계산 (비동기)\n */\nexport async function calculateChecksumAsync(data: string): Promise<string> {\n return calculateChecksum(data);\n}\n\n/**\n * 체크섬 검증\n */\nexport async function verifyChecksum(\n data: string,\n expectedChecksum: string\n): Promise<boolean> {\n const checksum = await calculateChecksumAsync(data);\n return checksum === expectedChecksum;\n}\n\n/**\n * Compressor 클래스 - 상태 저장형 압축\n */\nexport class Compressor {\n private options: CompressionOptions;\n private history: CompressionStats[] = [];\n\n constructor(options?: CompressionOptions) {\n this.options = {\n algorithm: options?.algorithm ?? 'gzip',\n level: options?.level ?? 'balanced',\n outputFormat: options?.outputFormat ?? 'base64',\n includeMetadata: options?.includeMetadata ?? false,\n };\n }\n\n /**\n * 데이터 압축\n */\n compress(data: string | Uint8Array | Buffer): Uint8Array {\n const bytes = inputToUint8Array(data);\n const level = normalizeCompressionLevel(this.options.level);\n\n if (this.options.algorithm === 'none') {\n return bytes;\n }\n\n const compressed = gzip(bytes, { level });\n\n // 통계 기록\n const stats = this.calculateStatsInternal(bytes.length, compressed.length);\n this.history.push(stats);\n\n return compressed;\n }\n\n /**\n * 데이터 압축 해제\n */\n decompress(data: Uint8Array): string {\n if (this.options.algorithm === 'none') {\n return uint8ArrayToString(data);\n }\n\n const decompressed = ungzip(data);\n return uint8ArrayToString(decompressed);\n }\n\n /**\n * 비동기 압축\n */\n async compressAsync(data: string | Uint8Array | Buffer): Promise<Uint8Array> {\n return this.compress(data);\n }\n\n /**\n * 비동기 압축 해제\n */\n async decompressAsync(data: Uint8Array): Promise<string> {\n return this.decompress(data);\n }\n\n /**\n * 압축 비율 계산\n */\n ratio(originalSize: number, compressedSize: number): number {\n if (compressedSize === 0) {\n return originalSize === 0 ? 1 : Infinity;\n }\n return originalSize / compressedSize;\n }\n\n /**\n * 압축 통계 계산\n */\n stats(originalSize: number, compressedSize: number): CompressionStats {\n return this.calculateStatsInternal(originalSize, compressedSize);\n }\n\n /**\n * 내부 통계 계산\n */\n private calculateStatsInternal(\n originalSize: number,\n compressedSize: number\n ): CompressionStats {\n const ratio = this.ratio(originalSize, compressedSize);\n const savings = originalSize - compressedSize;\n const savingsPercent = originalSize > 0 ? (savings / originalSize) * 100 : 0;\n\n return {\n originalSize,\n compressedSize,\n ratio,\n savings,\n savingsPercent,\n };\n }\n\n /**\n * 메타데이터 포함 압축\n */\n compressWithMeta(data: string | Uint8Array | Buffer): CompressedWithMeta {\n const bytes = inputToUint8Array(data);\n const compressed = this.compress(bytes);\n\n const metadata: CompressionMetadata = {\n originalSize: bytes.length,\n compressedSize: compressed.length,\n algorithm: this.options.algorithm ?? 'gzip',\n level: this.options.level ?? 'balanced',\n timestamp: new Date().toISOString(),\n };\n\n // 메타데이터와 데이터를 결합하여 base64로 변환\n const metaJson = JSON.stringify(metadata);\n const metaBytes = stringToUint8Array(metaJson);\n\n // 포맷: [metaLength(4 bytes)][metadata][compressed data]\n const combined = new Uint8Array(4 + metaBytes.length + compressed.length);\n const view = new DataView(combined.buffer);\n\n view.setUint32(0, metaBytes.length, false); // big endian\n combined.set(metaBytes, 4);\n combined.set(compressed, 4 + metaBytes.length);\n\n return {\n data: uint8ArrayToBase64(combined),\n metadata,\n };\n }\n\n /**\n * 메타데이터 포함 압축 해제\n */\n decompressWithMeta(compressed: CompressedWithMeta | string): string {\n let base64Data: string;\n\n if (typeof compressed === 'string') {\n base64Data = compressed;\n } else {\n base64Data = compressed.data;\n }\n\n const combined = base64ToUint8Array(base64Data);\n const view = new DataView(combined.buffer);\n\n const metaLength = view.getUint32(0, false);\n const metaBytes = combined.slice(4, 4 + metaLength);\n const compressedData = combined.slice(4 + metaLength);\n\n // 메타데이터 파싱 (검증용)\n try {\n const metaJson = uint8ArrayToString(metaBytes);\n JSON.parse(metaJson);\n } catch {\n // 메타데이터 파싱 실패 시 무시하고 계속 진행\n }\n\n // 압축 해제\n return this.decompress(compressedData);\n }\n\n /**\n * 기록된 압축 통계 가져오기\n */\n getHistory(): CompressionStats[] {\n return [...this.history];\n }\n\n /**\n * 기록된 통계 지우기\n */\n clearHistory(): void {\n this.history = [];\n }\n\n /**\n * 옵션 업데이트\n */\n setOptions(options: Partial<CompressionOptions>): void {\n this.options = { ...this.options, ...options };\n }\n\n /**\n * 현재 옵션 가져오기\n */\n getOptions(): CompressionOptions {\n return { ...this.options };\n }\n}\n","/**\n * @module snapshot/type-guards\n * @description 타입 가드 함수들 (중복 제거)\n */\n\nimport type { SerializedState } from './types';\n\n/**\n * 타입 가드: SerializedState 여부 확인\n * @description P1: 검증 범위 확대 - state/knowledge/decisions 필드 검증 추가\n * @param value - 확인할 값\n * @returns SerializedState 타입 여부\n */\nexport function isSerializedState(value: unknown): value is SerializedState {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const obj = value as Partial<SerializedState>;\n\n // meta 필드 필수 확인\n if (!obj.meta || typeof obj.meta !== 'object') {\n return false;\n }\n\n // meta의 필수 필드 확인\n const meta = obj.meta;\n if (!meta.sessionId || typeof meta.sessionId !== 'string') {\n return false;\n }\n if (typeof meta.version !== 'number') {\n return false;\n }\n\n // P1: state 섹션 필드 검증\n if (!obj.state || typeof obj.state !== 'object') {\n return false;\n }\n const state = obj.state;\n if (typeof state.phase !== 'string') {\n return false;\n }\n if (!state.context || typeof state.context !== 'object') {\n return false;\n }\n if (!Array.isArray(state.agents)) {\n return false;\n }\n if (!Array.isArray(state.tasks)) {\n return false;\n }\n\n // P1: knowledge 섹션 필드 검증\n if (!obj.knowledge || typeof obj.knowledge !== 'object') {\n return false;\n }\n const knowledge = obj.knowledge;\n if (!Array.isArray(knowledge.facts)) {\n return false;\n }\n if (!Array.isArray(knowledge.inferences)) {\n return false;\n }\n if (!Array.isArray(knowledge.patterns)) {\n return false;\n }\n\n // P1: decisions 섹션 필드 검증\n if (!obj.decisions || typeof obj.decisions !== 'object') {\n return false;\n }\n const decisions = obj.decisions;\n if (!Array.isArray(decisions.pending)) {\n return false;\n }\n if (!Array.isArray(decisions.opinions)) {\n return false;\n }\n if (!Array.isArray(decisions.history)) {\n return false;\n }\n\n return true;\n}\n","/**\n * @module snapshot/utils\n * @description 유틸리티 함수들 (중복 제거)\n */\n\nimport type { Snapshot, SerializedState } from \"./types\";\nimport { decompress, detectCompression } from \"./compression\";\nimport { isSerializedState } from \"./type-guards\";\n\n/**\n * JSON.stringify replacer for key sorting\n * @param key - Property key\n * @param value - Property value\n * @returns Value with sorted keys for objects\n */\nexport function sortedKeyReplacer(key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && !Array.isArray(value) && !(value instanceof Date)) {\n const sortedObj: Record<string, unknown> = {};\n Object.keys(value as Record<string, unknown>)\n .sort()\n .forEach((k) => {\n sortedObj[k] = (value as Record<string, unknown>)[k];\n });\n return sortedObj;\n }\n return value;\n}\n\n/**\n * 스냅샷 데이터 압축 해제 (공통 헬퍼)\n * @description P0: decompressData 로직 중복 제거를 위한 공통 함수\n * @param snapshot - 스냅샷\n * @returns 역직렬화된 상태 데이터\n * @throws {Error} 압축 해제 실패 또는 타입 불일치 시\n */\nexport function decompressSnapshotData(snapshot: Snapshot): SerializedState {\n if (!snapshot.meta.compressed) {\n if (!isSerializedState(snapshot.data)) {\n throw new Error(\"Invalid snapshot data: not a SerializedState\");\n }\n return snapshot.data;\n }\n\n if (typeof snapshot.data !== \"string\") {\n throw new Error(\"Invalid compressed data: expected string\");\n }\n\n const algorithm = detectCompression(snapshot.data) ?? \"gzip\";\n const json = decompress(snapshot.data, { algorithm }) as string;\n const parsed = JSON.parse(json);\n\n if (!isSerializedState(parsed)) {\n throw new Error(\"Invalid snapshot data: deserialized data is not a SerializedState\");\n }\n\n return parsed;\n}\n","/**\n * @module snapshot/serializer\n * @description 직렬화/역직렬화 (브라우저/Node.js 호환)\n */\n\nimport type {\n BlackboardState,\n AgentId,\n TaskId,\n SessionId,\n Fact,\n Inference,\n Pattern,\n Agenda,\n Opinion,\n Resolution,\n AgentStatus,\n Task,\n BoardPhase,\n VotingSession,\n} from \"../types\";\nimport type { SerializedState } from \"./types\";\nimport { sortedKeyReplacer } from \"./utils\";\n\n/**\n * 직렬화 옵션\n */\nexport interface SerializeOptions {\n /** 날짜 형식 (기본: 'iso') */\n dateFormat?: \"iso\" | \"timestamp\";\n /** 정렬된 키 (재현 가능한 출력용) */\n sortKeys?: boolean;\n /** 들여쓰기 (기본: 0 = 압축) */\n indent?: number;\n}\n\n/**\n * 섹션 데이터 유효성 검증 결과\n */\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Fact 구조 검증\n */\nfunction validateFactArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"facts must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`facts[${i}]: must be an object`);\n continue;\n }\n\n const fact = item as Record<string, unknown>;\n\n if (typeof fact.id !== \"string\") {\n errors.push(`facts[${i}].id: must be a string`);\n }\n\n if (typeof fact.content !== \"string\") {\n errors.push(`facts[${i}].content: must be a string`);\n }\n\n if (typeof fact.confidence !== \"number\" || fact.confidence < 0 || fact.confidence > 1) {\n errors.push(`facts[${i}].confidence: must be a number between 0 and 1`);\n }\n\n // createdAt은 문자열(ISO) 또는 Date 객체 허용\n if (typeof fact.createdAt !== \"string\" && !(fact.createdAt instanceof Date)) {\n errors.push(`facts[${i}].createdAt: must be a string or Date`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Inference 구조 검증\n */\nfunction validateInferenceArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"inferences must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`inferences[${i}]: must be an object`);\n continue;\n }\n\n const inference = item as Record<string, unknown>;\n\n if (typeof inference.id !== \"string\") {\n errors.push(`inferences[${i}].id: must be a string`);\n }\n\n if (typeof inference.conclusion !== \"string\") {\n errors.push(`inferences[${i}].conclusion: must be a string`);\n }\n\n if (\n typeof inference.confidence !== \"number\" ||\n inference.confidence < 0 ||\n inference.confidence > 1\n ) {\n errors.push(`inferences[${i}].confidence: must be a number between 0 and 1`);\n }\n\n // createdAt은 선택적 (문자열 또는 Date 객체)\n if (\n inference.createdAt !== undefined &&\n typeof inference.createdAt !== \"string\" &&\n !(inference.createdAt instanceof Date)\n ) {\n errors.push(`inferences[${i}].createdAt: must be a string, Date, or undefined`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Pattern 구조 검증\n */\nfunction validatePatternArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"patterns must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`patterns[${i}]: must be an object`);\n continue;\n }\n\n const pattern = item as Record<string, unknown>;\n\n if (typeof pattern.id !== \"string\") {\n errors.push(`patterns[${i}].id: must be a string`);\n }\n\n if (typeof pattern.name !== \"string\") {\n errors.push(`patterns[${i}].name: must be a string`);\n }\n\n // createdAt은 선택적 (문자열 또는 Date 객체)\n if (\n pattern.createdAt !== undefined &&\n typeof pattern.createdAt !== \"string\" &&\n !(pattern.createdAt instanceof Date)\n ) {\n errors.push(`patterns[${i}].createdAt: must be a string, Date, or undefined`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Resolution 구조 검증\n */\nfunction validateResolutionArray(value: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (!Array.isArray(value)) {\n return { valid: false, errors: [\"history must be an array\"] };\n }\n\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (!item || typeof item !== \"object\") {\n errors.push(`history[${i}]: must be an object`);\n continue;\n }\n\n const resolution = item as Record<string, unknown>;\n\n if (typeof resolution.agendaId !== \"string\") {\n errors.push(`history[${i}].agendaId: must be a string`);\n }\n\n if (typeof resolution.decision !== \"string\") {\n errors.push(`history[${i}].decision: must be a string`);\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * Agenda 구조 검증\n */\nfunction validateAgenda(value: unknown, fieldName: string): ValidationResult {\n const errors: string[] = [];\n\n if (value === null) {\n return { valid: true, errors };\n }\n\n if (!value || typeof value !== \"object\") {\n return { valid: false, errors: [`${fieldName}: must be an object or null`] };\n }\n\n const agenda = value as Record<string, unknown>;\n\n if (typeof agenda.id !== \"string\") {\n errors.push(`${fieldName}.id: must be a string`);\n }\n\n if (typeof agenda.title !== \"string\") {\n errors.push(`${fieldName}.title: must be a string`);\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n/**\n * 상태 직렬화기\n * @description Map, Date 등을 JSON 호환 형식으로 변환\n */\nexport class StateSerializer {\n constructor(private options: SerializeOptions = {}) {}\n\n /**\n * BlackboardState → SerializedState\n * @param state - 원본 상태\n * @returns 직렬화된 상태\n */\n serialize(state: BlackboardState): SerializedState {\n return {\n meta: {\n version: state.meta.version,\n lastUpdated: this.serializeDate(state.meta.lastUpdated),\n sessionId: state.meta.sessionId,\n createdAt: this.serializeDate(state.meta.createdAt),\n },\n state: {\n phase: state.state.phase,\n context: state.state.context,\n agents: this.serializeMap(state.state.agents),\n tasks: this.serializeMap(state.state.tasks),\n },\n knowledge: {\n facts: state.knowledge.facts,\n inferences: state.knowledge.inferences,\n patterns: state.knowledge.patterns,\n },\n decisions: {\n current: state.decisions.current,\n pending: state.decisions.pending,\n opinions: this.serializeMap(state.decisions.opinions),\n history: state.decisions.history,\n voting: state.decisions.voting,\n },\n };\n }\n\n /**\n * 임의의 객체를 JSON 문자열로 직렬화\n * @param obj - 직렬화할 객체\n * @returns JSON 문자열\n * @description Date, Map, Set 등을 포함한 일반 객체 직렬화\n */\n serializeJSON(obj: unknown): string {\n const indent = this.options.indent ?? 0;\n const replacer = this.options.sortKeys\n ? (sortedKeyReplacer as (key: string, value: unknown) => unknown)\n : undefined;\n\n // JSON.stringify 직렬화\n return JSON.stringify(obj, replacer, indent);\n }\n\n /**\n * JSON 문자열을 객체로 역직렬화\n * @param json - JSON 문자열\n * @returns 역직렬화된 객체\n * @throws {Error} JSON 파싱 실패 시\n * @description JSON.parse를 사용한 기본 역직렬화\n */\n deserializeJSON<T = unknown>(json: string): T {\n try {\n return JSON.parse(json) as T;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Invalid JSON: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * SerializedState → BlackboardState\n * @param serialized - 직렬화된 상태\n * @returns 복원된 상태\n */\n deserialize(serialized: SerializedState): BlackboardState {\n // 구조 검증 (P1: 입력 검증 강화)\n if (!serialized || typeof serialized !== \"object\") {\n throw new Error(\"Invalid serialized state: must be an object\");\n }\n\n // 필수 필드 검증\n const requiredSections = [\"meta\", \"state\", \"knowledge\", \"decisions\"] as const;\n for (const section of requiredSections) {\n if (!serialized[section]) {\n throw new Error(`Invalid serialized state: missing section '${section}'`);\n }\n }\n\n // P1: 런타임 타입 검증 - facts\n const factsValidation = validateFactArray(serialized.knowledge.facts);\n if (!factsValidation.valid) {\n throw new Error(`Invalid facts data: ${factsValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - inferences\n const inferencesValidation = validateInferenceArray(serialized.knowledge.inferences);\n if (!inferencesValidation.valid) {\n throw new Error(`Invalid inferences data: ${inferencesValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - patterns\n const patternsValidation = validatePatternArray(serialized.knowledge.patterns);\n if (!patternsValidation.valid) {\n throw new Error(`Invalid patterns data: ${patternsValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - current\n const currentValidation = validateAgenda(serialized.decisions.current, \"decisions.current\");\n if (!currentValidation.valid) {\n throw new Error(`Invalid current agenda: ${currentValidation.errors.join(\", \")}`);\n }\n\n // P1: 런타임 타입 검증 - pending\n if (!Array.isArray(serialized.decisions.pending)) {\n throw new Error(\"Invalid pending agendas: must be an array\");\n }\n for (let i = 0; i < serialized.decisions.pending.length; i++) {\n const pendingValidation = validateAgenda(\n serialized.decisions.pending[i],\n `decisions.pending[${i}]`\n );\n if (!pendingValidation.valid) {\n throw new Error(\n `Invalid pending agenda at index ${i}: ${pendingValidation.errors.join(\", \")}`\n );\n }\n }\n\n // P1: 런타임 타입 검증 - history\n const historyValidation = validateResolutionArray(serialized.decisions.history);\n if (!historyValidation.valid) {\n throw new Error(`Invalid history data: ${historyValidation.errors.join(\", \")}`);\n }\n\n // 런타임 검증 완료 후 타입 어서션 사용 (TypeScript는 런타임 검증을 이해하지 못함)\n return {\n meta: {\n version: serialized.meta.version,\n lastUpdated: this.deserializeDate(serialized.meta.lastUpdated),\n sessionId: this.restoreIds<SessionId>(serialized.meta.sessionId),\n createdAt: this.deserializeDate(serialized.meta.createdAt),\n },\n state: {\n phase: serialized.state.phase as BoardPhase,\n context: serialized.state.context,\n agents: this.deserializeMap(serialized.state.agents as Array<[AgentId, AgentStatus]>),\n tasks: this.deserializeMap(serialized.state.tasks as Array<[TaskId, Task]>),\n },\n knowledge: {\n facts: serialized.knowledge.facts as Fact[],\n inferences: serialized.knowledge.inferences as Inference[],\n patterns: serialized.knowledge.patterns as Pattern[],\n },\n decisions: {\n current: serialized.decisions.current as Agenda | null,\n pending: serialized.decisions.pending as Agenda[],\n opinions: this.deserializeMap(serialized.decisions.opinions as Array<[string, Opinion]>),\n history: serialized.decisions.history as Resolution[],\n voting: (serialized.decisions.voting ?? {}) as Record<string, VotingSession>,\n },\n };\n }\n\n /**\n * JSON 문자열로 변환\n * @param state - 원본 상태\n * @returns JSON 문자열\n */\n toJSON(state: BlackboardState): string {\n const serialized = this.serialize(state);\n const indent = this.options.indent ?? 0;\n\n // P1: sortKeys 옵션 구현\n // Note: JSON.stringify는 null을 허용하지 않으므로 조건부 처리\n if (this.options.sortKeys) {\n return JSON.stringify(\n serialized,\n sortedKeyReplacer as (key: string, value: unknown) => unknown,\n indent\n );\n }\n return JSON.stringify(serialized, null, indent);\n }\n\n /**\n * JSON 문자열에서 복원\n * @param json - JSON 문자열\n * @returns 복원된 상태\n * @throws {Error} JSON 파싱 실패 시 명확한 에러 메시지 (P1: JSON.parse 에러 처리)\n */\n fromJSON(json: string): BlackboardState {\n try {\n const parsed = JSON.parse(json) as SerializedState | null | undefined;\n // P1: null/undefined 검증 추가 (parsed.meta 접근 전)\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Invalid serialized state: parsed data is null or undefined\");\n }\n return this.deserialize(parsed);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Invalid JSON in serialized state: ${error.message}`);\n }\n throw error;\n }\n }\n\n // === 내부 헬퍼 ===\n\n /**\n * Map → Array 변환\n */\n private serializeMap<K extends string, V>(map: Map<K, V>): Array<[K, V]> {\n return Array.from(map.entries());\n }\n\n /**\n * Array → Map 변환\n */\n private deserializeMap<K extends string, V>(entries: Array<[K, V]>): Map<K, V> {\n // P1: 입력 검증 강화\n if (!Array.isArray(entries)) {\n throw new Error(`Invalid map data: expected array, got ${typeof entries}`);\n }\n // 브랜드 타입으로 인한 타입 어서션 필요 (런타임 문자열 → 브랜드 타입)\n return new Map(entries) as Map<K, V>;\n }\n\n /**\n * Date → string 변환\n */\n private serializeDate(date: Date): string {\n if (this.options.dateFormat === \"timestamp\") {\n return date.getTime().toString();\n }\n return date.toISOString();\n }\n\n /**\n * string → Date 변환\n */\n private deserializeDate(str: string): Date {\n // P1: 입력 검증 강화\n if (typeof str !== \"string\") {\n throw new Error(`Invalid date value: expected string, got ${typeof str}`);\n }\n\n // P1: 빈 문자열 입력 검증 추가\n if (!str || str.trim() === \"\") {\n throw new Error(\"Invalid date value: string must not be empty or whitespace-only\");\n }\n\n const asNum = Number(str);\n if (!isNaN(asNum) && asNum > 1000000000) {\n return new Date(asNum);\n }\n const date = new Date(str);\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date value: \"${str}\"`);\n }\n return date;\n }\n\n /**\n * Branded ID 복원\n * @param obj - 원본 ID 값 (일반적으로 문자열)\n * @returns 브랜드 타입으로 캐스팅된 ID\n * @description 문자열 타입 안전성 검증 후 반환\n */\n private restoreIds<T extends string>(obj: unknown): T {\n if (typeof obj !== \"string\") {\n throw new TypeError(`Expected string ID, got ${typeof obj}`);\n }\n return obj as T;\n }\n}\n\n/**\n * Node.js crypto 모듈 fallback (WebCrypto 없는 환경)\n */\nasync function calculateChecksumNodeJS(data: string): Promise<string> {\n // P0: Node.js require → ESM import 변경\n if (typeof process === \"object\") {\n try {\n // Dynamic import for Node.js crypto module (ESM compatible)\n const { createHash } = await import(\"crypto\");\n return createHash(\"sha256\").update(data).digest(\"hex\");\n } catch {\n // Import 실패 시 fallback\n }\n }\n throw new Error(\n \"No crypto implementation available. Please use a browser environment or Node.js with crypto support.\"\n );\n}\n\n/**\n * Web Crypto API를 사용한 체크섬 계산 (비동기)\n * @param data - 대상 데이터\n * @returns SHA-256 해시\n */\nexport async function calculateChecksum(data: unknown): Promise<string> {\n let str: string;\n if (typeof data === \"string\") {\n str = data;\n } else {\n // 순서 독립적 체크섬 계산을 위해 키 정렬\n str = JSON.stringify(data, sortedKeyReplacer as (key: string, value: unknown) => unknown);\n }\n const encoder = new TextEncoder();\n const bytes = encoder.encode(str);\n\n // P1: crypto.subtle fallback - Web Crypto API 우선, Node.js fallback\n if (typeof crypto !== \"undefined\" && typeof crypto.subtle !== \"undefined\") {\n // Web Crypto API 사용 (브라우저/Node.js 호환)\n try {\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", bytes);\n\n // ArrayBuffer → hex string 변환\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n\n return hashHex;\n } catch {\n // Web Crypto 실패 시 Node.js fallback 시도\n return calculateChecksumNodeJS(str);\n }\n } else {\n // Web Crypto 없는 환경에서 Node.js fallback\n return calculateChecksumNodeJS(str);\n }\n}\n\n/**\n * Web Crypto API를 사용한 체크섬 검증 (비동기)\n * @param data - 대상 데이터\n * @param expectedChecksum - 예상 체크섬\n * @returns 일치 여부\n */\nexport async function verifyChecksum(data: unknown, expectedChecksum: string): Promise<boolean> {\n const actualChecksum = await calculateChecksum(data);\n return actualChecksum === expectedChecksum;\n}\n\n/**\n * 동기 체크섬 계산 (Node.js 전용)\n * @param data - 대상 데이터\n * @returns SHA-256 해시\n * @description 테스트 환경 등에서 동기 체크섬이 필요한 경우 사용\n */\nexport function calculateChecksumSync(data: unknown): string {\n let str: string;\n if (typeof data === \"string\") {\n str = data;\n } else {\n // 순서 독립적 체크섬 계산을 위해 키 정렬\n str = JSON.stringify(data, sortedKeyReplacer as (key: string, value: unknown) => unknown);\n }\n\n // Node.js 환경에서 동기 해싱\n if (typeof process === \"object\") {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { createHash } = require(\"crypto\");\n return createHash(\"sha256\").update(str).digest(\"hex\");\n } catch {\n throw new Error(\n \"Failed to calculate checksum synchronously. Ensure Node.js crypto module is available.\"\n );\n }\n }\n\n throw new Error(\"Synchronous checksum calculation is only supported in Node.js environments.\");\n}\n\n/**\n * 동기 체크섬 검증 (Node.js 전용)\n * @param data - 대상 데이터\n * @param expectedChecksum - 예상 체크섬\n * @returns 일치 여부\n * @description 테스트 환경 등에서 동기 체크섬이 필요한 경우 사용\n */\nexport function verifyChecksumSync(data: unknown, expectedChecksum: string): boolean {\n const actualChecksum = calculateChecksumSync(data);\n return actualChecksum === expectedChecksum;\n}\n","/**\n * @module snapshot/snapshot-creator\n * @description 스냅샷 생성 담당\n */\n\nimport type { BlackboardState } from \"../types\";\nimport type { Snapshot, SnapshotMeta, CreateSnapshotOptions, SerializedState } from \"./types\";\nimport { StateSerializer, calculateChecksumSync } from \"./serializer\";\nimport { compress } from \"./compression\";\nimport { SNAPSHOT_FORMAT_VERSION } from \"./types\";\nimport { createIdGenerator, type IdGenerator } from \"./id-utils\";\n\n/**\n * 스냅샷 생성자 설정\n */\nexport interface SnapshotCreatorOptions {\n /** 자동 압축 임계값 (바이트, 기본: 10KB) */\n autoCompressThreshold?: number;\n /** 기본 압축 사용 */\n defaultCompress?: boolean;\n /** ID 생성 함수 */\n idGenerator?: IdGenerator;\n}\n\n/**\n * 스냅샷 생성자\n * @description 스냅샷 생성 전담 클래스\n */\nexport class SnapshotCreator {\n private serializer: StateSerializer;\n private options: Required<SnapshotCreatorOptions>;\n\n constructor(options: SnapshotCreatorOptions = {}) {\n this.options = this.normalizeOptions(options);\n this.serializer = new StateSerializer({ sortKeys: true });\n }\n\n /**\n * 옵션 정규화\n */\n private normalizeOptions(options: SnapshotCreatorOptions): Required<SnapshotCreatorOptions> {\n return {\n autoCompressThreshold: options.autoCompressThreshold ?? 10_240, // 10KB\n defaultCompress: options.defaultCompress ?? false,\n idGenerator: createIdGenerator(options.idGenerator),\n };\n }\n\n /**\n * ID 생성자 가져오기\n */\n getIdGenerator(): IdGenerator {\n return this.options.idGenerator;\n }\n\n /**\n * 스냅샷 생성 (동기)\n * @param state - 현재 Blackboard 상태\n * @param options - 생성 옵션\n * @returns 스냅샷\n */\n createSnapshot(state: BlackboardState, options?: CreateSnapshotOptions): Snapshot {\n const serialized = this.serializer.serialize(state);\n const metaOnly = options?.metaOnly ?? false;\n\n // P1: 섹션 필터링 타입 안전성 개선 - 명시적 구조 사용\n let stateData: SerializedState = serialized;\n\n if (options?.includeSections) {\n const sections = options.includeSections;\n // 명시적 구조로 타입 안전성 확보\n const filteredState: SerializedState = {\n meta: serialized.meta,\n state: sections.includes(\"state\")\n ? serialized.state\n : {\n phase: serialized.state.phase,\n context: serialized.state.context,\n agents: [],\n tasks: [],\n },\n knowledge: sections.includes(\"knowledge\")\n ? serialized.knowledge\n : {\n facts: [],\n inferences: [],\n patterns: [],\n },\n decisions: sections.includes(\"decisions\")\n ? serialized.decisions\n : {\n current: null,\n pending: [],\n opinions: [],\n history: [],\n },\n };\n stateData = filteredState;\n }\n\n // 압축 결정\n const shouldCompress = options?.compress ?? this.options.defaultCompress;\n const threshold = this.options.autoCompressThreshold;\n const originalSize = JSON.stringify(stateData, null, 0).length;\n const autoCompress = shouldCompress || originalSize >= threshold;\n\n let data: SerializedState | string;\n let compressedSize: number | undefined;\n let compressedChecksum: string | undefined;\n const compressed = autoCompress && !metaOnly;\n\n // 체크섬 계산 (metaOnly 모드에서는 빈 객체 기준)\n let checksum: string;\n try {\n if (metaOnly) {\n const emptyState: SerializedState = {\n meta: { version: 0, lastUpdated: \"\", sessionId: \"\", createdAt: \"\" },\n state: { phase: \"\", context: {}, agents: [], tasks: [] },\n knowledge: { facts: [], inferences: [], patterns: [] },\n decisions: { current: null, pending: [], opinions: [], history: [] },\n };\n checksum = calculateChecksumSync(emptyState);\n } else {\n checksum = calculateChecksumSync(stateData);\n }\n } catch (e) {\n throw new Error(\n `Failed to calculate checksum: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n\n if (metaOnly) {\n // metaOnly 모드에서는 데이터를 포함하지 않음\n data = {\n meta: { version: 0, lastUpdated: \"\", sessionId: \"\", createdAt: \"\" },\n state: { phase: \"\", context: {}, agents: [], tasks: [] },\n knowledge: { facts: [], inferences: [], patterns: [] },\n decisions: { current: null, pending: [], opinions: [], history: [] },\n };\n } else if (compressed) {\n const json = JSON.stringify(stateData);\n try {\n const compressedString = compress(json, { level: 6 }) as string;\n data = compressedString;\n compressedSize = compressedString.length;\n\n // 압축 데이터 체크섬 검증\n compressedChecksum = calculateChecksumSync(compressedString);\n } catch (e) {\n throw new Error(\n `Failed to compress snapshot data: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n } else {\n data = stateData;\n }\n\n // 메타데이터 생성\n const meta: SnapshotMeta = {\n id: this.options.idGenerator(),\n formatVersion: SNAPSHOT_FORMAT_VERSION,\n createdAt: new Date(),\n sessionId: state.meta.sessionId,\n stateVersion: state.meta.version,\n description: options?.description,\n tags: options?.tags,\n checksum,\n compressedChecksum,\n compressed,\n originalSize,\n compressedSize,\n };\n\n return { meta, data };\n }\n\n /**\n * 메타데이터만 포함된 스냅샷 생성 (동기)\n * @param state - 현재 상태\n * @param description - 설명\n * @returns 메타 전용 스냅샷\n */\n createMetaSnapshot(state: BlackboardState, description?: string): SnapshotMeta {\n const snapshot = this.createSnapshot(state, { metaOnly: true, description });\n return snapshot.meta;\n }\n}\n","/**\n * @module snapshot/snapshot-validator\n * @description 스냅샷 검증 담당\n */\n\nimport type {\n Snapshot,\n SnapshotValidationResult,\n SnapshotValidationError,\n SnapshotValidationWarning,\n SerializedState,\n} from \"./types\";\nimport { StateSerializer, verifyChecksum, verifyChecksumSync } from \"./serializer\";\nimport { decompress, detectCompression } from \"./compression\";\nimport { decompressSnapshotData } from \"./utils\";\nimport { SNAPSHOT_FORMAT_VERSION } from \"./types\";\nimport { isSerializedState } from \"./type-guards\";\n\n/**\n * 스냅샷 검증자\n * @description 스냅샷 검증 전담 클래스\n */\nexport class SnapshotValidator {\n private serializer: StateSerializer;\n\n constructor(serializer?: StateSerializer) {\n this.serializer = serializer ?? new StateSerializer({ sortKeys: true });\n }\n\n /**\n * 스냅샷 검증 (비동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n async validate(snapshot: Snapshot): Promise<SnapshotValidationResult> {\n const errors: SnapshotValidationError[] = [];\n const warnings: SnapshotValidationWarning[] = [];\n\n // 1. 기본 구조 검증\n if (!snapshot.meta || !snapshot.data) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot missing required fields (meta or data)\",\n });\n return { valid: false, errors, warnings };\n }\n\n // 2. 필수 메타데이터 필드 검증\n const { meta } = snapshot;\n if (!meta.id || !meta.formatVersion || !meta.sessionId || !meta.checksum) {\n errors.push({\n code: \"MISSING_FIELD\",\n message: \"Snapshot metadata missing required fields\",\n details: meta,\n });\n }\n\n // 3. 형식 버전 호환성 체크\n const versionCheck = this.checkVersionCompatibility(meta.formatVersion);\n if (!versionCheck.compatible) {\n if (versionCheck.migrationRequired) {\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n } else {\n // 미래 버전: 경고 + 에러 모두 추가\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} is from future version (current: ${versionCheck.current})`,\n });\n errors.push({\n code: \"VERSION_MISMATCH\",\n message: `Incompatible snapshot format: ${versionCheck.snapshot} (current: ${versionCheck.current})`,\n });\n }\n } else if (versionCheck.migrationRequired) {\n // 호환되지만 마이그레이션이 필요한 이전 버전\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n }\n\n // 4. 데이터 무결성 검증\n if (!meta.compressed && typeof snapshot.data === \"object\" && snapshot.data !== null) {\n const isValid = await verifyChecksum(snapshot.data, meta.checksum);\n if (!isValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Snapshot data checksum does not match metadata\",\n details: { expected: meta.checksum },\n });\n }\n }\n\n // 5. 압축 데이터 검증\n if (meta.compressed && typeof snapshot.data === \"string\") {\n try {\n const algorithm = detectCompression(snapshot.data);\n if (!algorithm) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot marked as compressed but data is not valid compressed format\",\n });\n }\n\n // 압축 데이터 체크섬 검증\n if (meta.compressedChecksum) {\n const checksumValid = await verifyChecksum(snapshot.data, meta.compressedChecksum);\n if (!checksumValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Compressed data checksum does not match metadata\",\n details: { expected: meta.compressedChecksum },\n });\n }\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to detect compression format\",\n details: e,\n });\n }\n }\n\n // 6. 런타임 검증 (P0: agents/tasks/opinions 구조 검증)\n if (errors.length === 0) {\n const runtimeValidation = this.validateRuntimeStructure(snapshot);\n if (!runtimeValidation.valid) {\n errors.push(...runtimeValidation.errors);\n warnings.push(...runtimeValidation.warnings);\n }\n }\n\n // 7. 역직렬화 테스트\n if (errors.length === 0) {\n try {\n const state = decompressSnapshotData(snapshot);\n\n if (!state.meta || !state.state) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Deserialized state is missing required fields\",\n });\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to deserialize snapshot data\",\n details: e,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * 스냅샷 검증 (동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n * @description 테스트 환경 등에서 동기 검증이 필요한 경우 사용\n */\n validateSync(snapshot: Snapshot): SnapshotValidationResult {\n const errors: SnapshotValidationError[] = [];\n const warnings: SnapshotValidationWarning[] = [];\n\n // 1. 기본 구조 검증\n if (!snapshot.meta || !snapshot.data) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot missing required fields (meta or data)\",\n });\n return { valid: false, errors, warnings };\n }\n\n // 2. 필수 메타데이터 필드 검증\n const { meta } = snapshot;\n if (!meta.id || !meta.formatVersion || !meta.sessionId || !meta.checksum) {\n errors.push({\n code: \"MISSING_FIELD\",\n message: \"Snapshot metadata missing required fields\",\n details: meta,\n });\n }\n\n // 3. 형식 버전 호환성 체크\n const versionCheck = this.checkVersionCompatibility(meta.formatVersion);\n if (!versionCheck.compatible) {\n if (versionCheck.migrationRequired) {\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n } else {\n // 미래 버전: 경고 + 에러 모두 추가\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} is from future version (current: ${versionCheck.current})`,\n });\n errors.push({\n code: \"VERSION_MISMATCH\",\n message: `Incompatible snapshot format: ${versionCheck.snapshot} (current: ${versionCheck.current})`,\n });\n }\n } else if (versionCheck.migrationRequired) {\n // 호환되지만 마이그레이션이 필요한 이전 버전\n warnings.push({\n code: \"DEPRECATED_FORMAT\",\n message: `Snapshot format ${versionCheck.snapshot} may require migration to ${versionCheck.current}`,\n });\n }\n\n // 4. 데이터 무결성 검증 (동기)\n if (!meta.compressed && typeof snapshot.data === \"object\" && snapshot.data !== null) {\n const isValid = verifyChecksumSync(snapshot.data, meta.checksum);\n if (!isValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Snapshot data checksum does not match metadata\",\n details: { expected: meta.checksum },\n });\n }\n }\n\n // 5. 압축 데이터 검증\n if (meta.compressed && typeof snapshot.data === \"string\") {\n try {\n const algorithm = detectCompression(snapshot.data);\n if (!algorithm) {\n errors.push({\n code: \"FORMAT_INVALID\",\n message: \"Snapshot marked as compressed but data is not valid compressed format\",\n });\n }\n\n // 압축 데이터 체크섬 검증 (동기)\n if (meta.compressedChecksum) {\n const checksumValid = verifyChecksumSync(snapshot.data, meta.compressedChecksum);\n if (!checksumValid) {\n errors.push({\n code: \"CHECKSUM_INVALID\",\n message: \"Compressed data checksum does not match metadata\",\n details: { expected: meta.compressedChecksum },\n });\n }\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to detect compression format\",\n details: e,\n });\n }\n }\n\n // 6. 런타임 검증 (P0: agents/tasks/opinions 구조 검증)\n if (errors.length === 0) {\n const runtimeValidation = this.validateRuntimeStructure(snapshot);\n if (!runtimeValidation.valid) {\n errors.push(...runtimeValidation.errors);\n warnings.push(...runtimeValidation.warnings);\n }\n }\n\n // 7. 역직렬화 테스트\n if (errors.length === 0) {\n try {\n const state = decompressSnapshotData(snapshot);\n\n if (!state.meta || !state.state) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Deserialized state is missing required fields\",\n });\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to deserialize snapshot data\",\n details: e,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * 버전 호환성 체크\n * @param formatVersion - 스냅샷 형식 버전\n * @returns 호환 여부 및 상세 정보\n */\n checkVersionCompatibility(formatVersion: string): {\n compatible: boolean;\n current: string;\n snapshot: string;\n migrationRequired: boolean;\n } {\n const current = SNAPSHOT_FORMAT_VERSION;\n const snapshot = formatVersion;\n\n // 동일 버전\n if (current === snapshot) {\n return { compatible: true, current, snapshot, migrationRequired: false };\n }\n\n // 메이저 버전 체크 (semver 간단 구현)\n const currentMajor = parseInt(current.split(\".\")[0], 10);\n const snapshotMajor = parseInt(snapshot.split(\".\")[0], 10);\n\n if (snapshotMajor > currentMajor) {\n // 미래 버전 - 호환 불가\n return { compatible: false, current, snapshot, migrationRequired: false };\n }\n\n // 이전 버전 - 마이그레이션 필요 (현재는 미구현)\n return { compatible: true, current, snapshot, migrationRequired: true };\n }\n\n /**\n * 동기 체크섬 검증 (구조적 검증만, 체크섬 제외)\n * @description restore()에서 사용하는 동기 검증 메서드\n * 체크섬 검증은 비동기이므로 validate()에서 수행해야 함\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n validateSyncStructure(snapshot: Snapshot): {\n valid: boolean;\n errors: string[];\n } {\n const errors: string[] = [];\n\n // 1. 기본 구조 검증\n if (!snapshot.meta || !snapshot.data) {\n errors.push(\"Snapshot missing required fields (meta or data)\");\n return { valid: false, errors };\n }\n\n // 2. 필수 메타데이터 필드 검증\n const { meta } = snapshot;\n if (!meta.id || !meta.formatVersion || !meta.sessionId || !meta.checksum) {\n errors.push(\"Snapshot metadata missing required fields\");\n }\n\n // 3. 형식 버전 호환성 체크\n const versionCheck = this.checkVersionCompatibility(meta.formatVersion);\n if (!versionCheck.compatible) {\n errors.push(\n `Incompatible snapshot format: ${versionCheck.snapshot} (current: ${versionCheck.current})`\n );\n }\n\n // 4. 데이터 타입 검증\n if (!meta.compressed && typeof snapshot.data !== \"object\") {\n errors.push(\"Snapshot data must be an object when not compressed\");\n }\n\n if (meta.compressed && typeof snapshot.data !== \"string\") {\n errors.push(\"Snapshot data must be a string when compressed\");\n }\n\n // 5. 압축 데이터 형식 검증\n if (meta.compressed && typeof snapshot.data === \"string\") {\n try {\n const algorithm = detectCompression(snapshot.data);\n if (!algorithm) {\n errors.push(\"Snapshot marked as compressed but data is not valid compressed format\");\n }\n } catch {\n errors.push(\"Failed to detect compression format\");\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * 런타임 구조 검증 (P0: agents/tasks/opinions)\n * @description 역직렬화 후 실제 데이터 구조 검증\n * P1: 에러 수집 모드 (break 제거)\n */\n private validateRuntimeStructure(snapshot: Snapshot): {\n valid: boolean;\n errors: SnapshotValidationError[];\n warnings: SnapshotValidationWarning[];\n } {\n const errors: SnapshotValidationError[] = [];\n const warnings: SnapshotValidationWarning[] = [];\n\n try {\n let serializedState: SerializedState | undefined;\n\n // 압축 데이터 처리\n if (snapshot.meta.compressed && typeof snapshot.data === \"string\") {\n const algorithm = detectCompression(snapshot.data) ?? \"gzip\";\n const json = decompress(snapshot.data, { algorithm }) as string;\n const parsed = JSON.parse(json);\n serializedState = isSerializedState(parsed) ? parsed : undefined;\n } else if (typeof snapshot.data === \"object\" && isSerializedState(snapshot.data)) {\n serializedState = snapshot.data;\n }\n\n // 타입 가드 실패 시 에러 반환\n if (!serializedState) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to parse serialized state data\",\n });\n return { valid: false, errors, warnings };\n }\n\n // state 섹션 검증\n if (serializedState.state) {\n const stateSection = serializedState.state;\n\n // agents 검증: Array<[string, unknown]> 형식\n if (stateSection.agents) {\n if (!Array.isArray(stateSection.agents)) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"state.agents must be an array of [id, data] tuples\",\n });\n } else {\n for (let i = 0; i < stateSection.agents.length; i++) {\n const item = stateSection.agents[i];\n if (!Array.isArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: `state.agents[${i}] must be a [string, unknown] tuple`,\n });\n // P1: break 제거 - 전체 에러 수집\n }\n }\n }\n }\n\n // tasks 검증: Array<[string, unknown]> 형식\n if (stateSection.tasks) {\n if (!Array.isArray(stateSection.tasks)) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"state.tasks must be an array of [id, data] tuples\",\n });\n } else {\n for (let i = 0; i < stateSection.tasks.length; i++) {\n const item = stateSection.tasks[i];\n if (!Array.isArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: `state.tasks[${i}] must be a [string, unknown] tuple`,\n });\n // P1: break 제거 - 전체 에러 수집\n }\n }\n }\n }\n }\n\n // decisions 섹션 검증\n if (serializedState?.decisions) {\n const decisionsSection = serializedState.decisions;\n\n // opinions 검증: Array<[string, unknown]> 형식\n if (decisionsSection.opinions) {\n if (!Array.isArray(decisionsSection.opinions)) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"decisions.opinions must be an array of [id, data] tuples\",\n });\n } else {\n for (let i = 0; i < decisionsSection.opinions.length; i++) {\n const item = decisionsSection.opinions[i];\n if (!Array.isArray(item) || item.length !== 2 || typeof item[0] !== \"string\") {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: `decisions.opinions[${i}] must be a [string, unknown] tuple`,\n });\n // P1: break 제거 - 전체 에러 수집\n }\n }\n }\n }\n }\n } catch (e) {\n errors.push({\n code: \"DATA_CORRUPTED\",\n message: \"Failed to validate runtime structure\",\n details: e,\n });\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n}\n","/**\n * @module snapshot/snapshot-restorer\n * @description 스냅샷 복원 담당\n */\n\nimport type { BlackboardState, SessionId } from '../types';\nimport type {\n Snapshot,\n RestoreSnapshotOptions,\n} from './types';\nimport type { SerializedState } from './types';\nimport { StateSerializer } from './serializer';\nimport { decompressSnapshotData } from './utils';\nimport { SnapshotValidator } from './snapshot-validator';\nimport { createIdGenerator, type IdGenerator } from './id-utils';\n\n/**\n * 스냅샷 복원 에러\n */\nexport class SnapshotRestoreError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = 'SnapshotRestoreError';\n }\n}\n\n/**\n * 스냅샷 복원자 설정\n */\nexport interface SnapshotRestorerOptions {\n /** ID 생성 함수 */\n idGenerator?: () => string;\n}\n\n/**\n * 스냅샷 복원자\n * @description 스냅샷 복원 전담 클래스\n */\nexport class SnapshotRestorer {\n private serializer: StateSerializer;\n private validator: SnapshotValidator;\n private idGenerator: IdGenerator;\n\n constructor(options: SnapshotRestorerOptions = {}) {\n this.serializer = new StateSerializer({ sortKeys: true });\n this.validator = new SnapshotValidator(this.serializer);\n this.idGenerator = createIdGenerator(options.idGenerator);\n }\n\n /**\n * 스냅샷에서 상태 복원\n * @param snapshot - 스냅샷\n * @param options - 복원 옵션\n * @returns 복원된 상태\n * @throws {SnapshotRestoreError} 복원 실패 시\n * @description\n * **옵션 동작:**\n * - `skipVersionCheck`: 포맷 버전 호환성 검사 건너뜀\n * - `skipStructuralValidation`: 구조적 검증 건너뜀 (validateSync)\n * - 참고: 체크섬 검증은 validate()에서 수행됨\n * - `resetVersion`: 상태 버전 0으로 초기화 (기본: true)\n * - `newSessionId`: 새 세션 ID 생성 (기본: true)\n */\n restore(\n snapshot: Snapshot,\n options?: RestoreSnapshotOptions\n ): BlackboardState {\n const opts = options ?? {};\n\n // skipValidation은 skipStructuralValidation의 별칭\n const shouldSkipStructuralValidation =\n opts.skipValidation || opts.skipStructuralValidation;\n\n // 1. 버전 호환성 체크\n if (!opts.skipVersionCheck) {\n const versionCheck = this.validator.checkVersionCompatibility(snapshot.meta.formatVersion);\n if (!versionCheck.compatible) {\n throw new SnapshotRestoreError(\n `Incompatible snapshot format: ${versionCheck.snapshot}`,\n 'VERSION_MISMATCH',\n { current: versionCheck.current, snapshot: versionCheck.snapshot }\n );\n }\n }\n\n // 2. 구조/타입 검증 (체크섬 X)\n if (!shouldSkipStructuralValidation) {\n const syncValidation = this.validator.validateSyncStructure(snapshot);\n if (!syncValidation.valid) {\n throw new SnapshotRestoreError(\n `Snapshot validation failed: ${syncValidation.errors.join(', ')}`,\n 'VALIDATION_FAILED',\n syncValidation.errors\n );\n }\n }\n\n // 3. 체크섬 검증 (skipValidation이 false일 때만)\n if (!shouldSkipStructuralValidation) {\n const fullValidation = this.validator.validateSync(snapshot);\n if (!fullValidation.valid) {\n throw new SnapshotRestoreError(\n `Snapshot checksum validation failed: ${fullValidation.errors.map(e => e.message).join(', ')}`,\n 'CHECKSUM_INVALID',\n fullValidation.errors\n );\n }\n }\n\n // 4. 데이터 역직렬화\n let serialized: SerializedState;\n\n try {\n serialized = decompressSnapshotData(snapshot);\n } catch (e) {\n // P2: catch 블록 타입 명시\n const error = e instanceof Error ? e : new Error(String(e));\n throw new SnapshotRestoreError(\n `Failed to deserialize snapshot data: ${error.message}`,\n 'DATA_CORRUPTED',\n error\n );\n }\n\n // 4. State 역직렬화\n const state = this.serializer.deserialize(serialized);\n\n // 5. 버전/세션 ID 처리\n if (opts.resetVersion !== false) {\n state.meta.version = 0;\n state.meta.lastUpdated = new Date();\n }\n\n if (opts.newSessionId !== false) {\n const newId = this.idGenerator();\n if (typeof newId !== 'string') {\n throw new SnapshotRestoreError(\n 'idGenerator must return a string',\n 'INVALID_SESSION_ID'\n );\n }\n state.meta.sessionId = newId as SessionId;\n }\n\n return state;\n }\n\n /**\n * 부분 복원 (특정 섹션만)\n * @param snapshot - 스냅샷\n * @param currentState - 현재 상태\n * @param sections - 복원할 섹션\n * @returns 병합된 상태\n */\n partialRestore(\n snapshot: Snapshot,\n currentState: BlackboardState,\n sections: ('state' | 'knowledge' | 'decisions')[]\n ): BlackboardState {\n // 스냅샷 복원\n const snapshotState = this.restore(snapshot, {\n skipVersionCheck: true,\n skipStructuralValidation: true,\n resetVersion: false,\n newSessionId: false,\n });\n\n // 깊은 복사\n const result: BlackboardState = structuredClone(currentState);\n\n // 섹션별 병합\n if (sections.includes('state') && snapshotState.state) {\n result.state = snapshotState.state;\n result.meta.version = snapshotState.meta.version;\n result.meta.lastUpdated = snapshotState.meta.lastUpdated;\n }\n\n if (sections.includes('knowledge') && snapshotState.knowledge) {\n result.knowledge = snapshotState.knowledge;\n }\n\n if (sections.includes('decisions') && snapshotState.decisions) {\n result.decisions = snapshotState.decisions;\n }\n\n return result;\n }\n}\n","/**\n * @module snapshot/snapshot-serializer\n * @description 스냅샷 직렬화 담당\n */\n\nimport type { Snapshot } from './types';\n\n/**\n * 스냅샷 직렬화 옵션\n */\nexport interface SnapshotSerializeOptions {\n /** 예쁜 출력 여부 */\n pretty?: boolean;\n}\n\n/**\n * 스냅샷 직렬화자\n * @description 스냅샷 직렬화/역직렬화 전담 클래스\n */\nexport class SnapshotSerializer {\n /**\n * 스냅샷 → JSON 문자열\n * @param snapshot - 스냅샷\n * @param pretty - 예쁜 출력 여부\n * @returns JSON 문자열\n */\n toJSON(snapshot: Snapshot, pretty: boolean = false): string {\n // Date 객체 직렬화 처리\n const json = JSON.stringify(snapshot, (key, value) => {\n if (value instanceof Date) {\n return value.toISOString();\n }\n return value;\n }, pretty ? 2 : 0);\n\n return json;\n }\n\n /**\n * JSON 문자열 → 스냅샷\n * @param json - JSON 문자열\n * @returns 스냅샷\n * @throws {Error} JSON 파싱 실패 시 명확한 에러 메시지\n */\n fromJSON(json: string): Snapshot {\n // P1: 빈 문자열 입력 검증 추가\n if (!json || json.trim() === '') {\n throw new Error('fromJSON(): input JSON must not be empty or whitespace-only');\n }\n\n try {\n const parsed = JSON.parse(json);\n\n // Date 역직렬화\n const snapshot: Snapshot = {\n meta: {\n ...parsed.meta,\n createdAt: new Date(parsed.meta.createdAt),\n },\n data: parsed.data,\n };\n\n return snapshot;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(`Invalid JSON in snapshot: ${error.message}`);\n }\n throw error;\n }\n }\n\n /**\n * 스냅샷 → Uint8Array (바이너리)\n * @param snapshot - 스냅샷\n * @returns Uint8Array\n */\n toUint8Array(snapshot: Snapshot): Uint8Array {\n const json = this.toJSON(snapshot);\n const encoder = new TextEncoder();\n return encoder.encode(json);\n }\n\n /**\n * Uint8Array → 스냅샷\n * @param bytes - 바이트 배열\n * @returns 스냅샷\n * @throws {Error} 디코딩 실패 시 명확한 에러 메시지\n */\n fromUint8Array(bytes: Uint8Array): Snapshot {\n try {\n const decoder = new TextDecoder();\n const json = decoder.decode(bytes);\n return this.fromJSON(json);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to decode Uint8Array to snapshot: ${error.message}`);\n }\n throw error;\n }\n }\n}\n","/**\n * @module snapshot/snapshot-comparer\n * @description 스냅샷 비교 담당\n */\n\nimport type { Snapshot } from './types';\nimport { sortedKeyReplacer, decompressSnapshotData } from './utils';\nimport type { SerializedState } from './types';\n\n/**\n * 스냅샷 차이점\n */\nexport interface SnapshotDiff {\n /** 메타데이터 차이 */\n meta: {\n versionDiff: number;\n timeDiff: number;\n };\n /** 섹션별 차이 */\n sections: {\n state: SectionDiff;\n knowledge: SectionDiff;\n decisions: SectionDiff;\n };\n /** 차이점 존재 여부 */\n hasDifferences: boolean;\n /** 상세 변경 정보 */\n details?: {\n phase?: { before: unknown; after: unknown };\n [key: string]: unknown;\n };\n}\n\n/**\n * 섹션 데이터 타입\n */\nexport type SectionData = Record<string, unknown>;\n\n/**\n * 섹션 차이점\n */\nexport interface SectionDiff {\n /** 추가된 항목 수 */\n added: number;\n /** 제거된 항목 수 */\n removed: number;\n /** 변경된 항목 수 */\n modified: number;\n /** 상세 변경 목록 (경로 → [이전, 이후]) */\n changes: Map<string, [unknown, unknown]>;\n}\n\n/**\n * 스냅샷 비교자\n * @description 스냅샷 비교 전담 클래스\n */\nexport class SnapshotComparer {\n /**\n * Optional logger for error reporting\n * If not provided, errors are silently ignored (fail-safe)\n */\n private logger?: (msg: string, error?: string) => void;\n\n /**\n * Set the logger for error reporting\n */\n setLogger(logger: (msg: string, error?: string) => void): void {\n this.logger = logger;\n }\n\n /**\n * 스냅샷 비교\n * @param a - 첫 번째 스냅샷\n * @param b - 두 번째 스냅샷\n * @returns 차이점 목록\n */\n compare(a: Snapshot, b: Snapshot): SnapshotDiff {\n const metaDiff = {\n versionDiff: b.meta.stateVersion - a.meta.stateVersion,\n timeDiff: b.meta.createdAt.getTime() - a.meta.createdAt.getTime(),\n };\n\n // 섹션별 비교\n const stateSection = this.createSectionDiff(\n this.extractStateData(a),\n this.extractStateData(b)\n );\n\n const knowledgeSection = this.createSectionDiff(\n this.extractKnowledgeData(a),\n this.extractKnowledgeData(b)\n );\n\n const decisionsSection = this.createSectionDiff(\n this.extractDecisionsData(a),\n this.extractDecisionsData(b)\n );\n\n // 차이점 존재 여부 계산\n const hasDifferences =\n metaDiff.versionDiff !== 0 ||\n stateSection.added > 0 ||\n stateSection.removed > 0 ||\n stateSection.modified > 0 ||\n knowledgeSection.added > 0 ||\n knowledgeSection.removed > 0 ||\n knowledgeSection.modified > 0 ||\n decisionsSection.added > 0 ||\n decisionsSection.removed > 0 ||\n decisionsSection.modified > 0;\n\n // 상세 변경 정보 추출\n const details: Record<string, unknown> = {};\n for (const [key, [before, after]] of stateSection.changes.entries()) {\n details[key] = { before, after };\n }\n\n return {\n meta: metaDiff,\n sections: {\n state: stateSection,\n knowledge: knowledgeSection,\n decisions: decisionsSection,\n },\n hasDifferences,\n details: Object.keys(details).length > 0 ? details : undefined,\n };\n }\n\n /**\n * 섹션 차이점 생성\n * @param data1 - 첫 번째 데이터\n * @param data2 - 두 번째 데이터\n * @returns 섹션 차이점\n */\n createSectionDiff(data1: SectionData, data2: SectionData): SectionDiff {\n const changes = new Map<string, [unknown, unknown]>();\n const keys1 = new Set(Object.keys(data1 ?? {}));\n const keys2 = new Set(Object.keys(data2 ?? {}));\n\n let added = 0;\n let removed = 0;\n let modified = 0;\n\n // 추가/변경된 항목\n for (const key of keys2) {\n if (!keys1.has(key)) {\n added++;\n changes.set(key, [undefined, data2[key]]);\n } else {\n // JSON.stringify 순서 독립적 비교 (sortedKeyReplacer 사용)\n const json1 = JSON.stringify(data1[key], sortedKeyReplacer);\n const json2 = JSON.stringify(data2[key], sortedKeyReplacer);\n if (json1 !== json2) {\n modified++;\n changes.set(key, [data1[key], data2[key]]);\n }\n }\n }\n\n // 제거된 항목\n for (const key of keys1) {\n if (!keys2.has(key)) {\n removed++;\n changes.set(key, [data1[key], undefined]);\n }\n }\n\n return { added, removed, modified, changes };\n }\n\n /**\n * Generic section data extraction\n * @param snapshot - 스냅샷\n * @param section - 섹션 이름\n * @returns 섹션 데이터\n */\n private extractSection<T>(snapshot: Snapshot, section: keyof SerializedState): T {\n try {\n const serialized = decompressSnapshotData(snapshot);\n return (serialized?.[section] as T) ?? ({} as T);\n } catch (error) {\n // Safe error handling: only log error.message to avoid exposing sensitive info\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger?.(`[SnapshotComparer] extractSection (${section}) failed: ${errorMessage}`);\n return {} as T;\n }\n }\n\n /**\n * 상태 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 상태 데이터\n */\n extractStateData(snapshot: Snapshot): SectionData {\n return this.extractSection<SectionData>(snapshot, 'state');\n }\n\n /**\n * 지식 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 지식 데이터\n */\n extractKnowledgeData(snapshot: Snapshot): SectionData {\n return this.extractSection<SectionData>(snapshot, 'knowledge');\n }\n\n /**\n * 의사결정 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 의사결정 데이터\n */\n extractDecisionsData(snapshot: Snapshot): SectionData {\n return this.extractSection<SectionData>(snapshot, 'decisions');\n }\n}\n","/**\n * @module snapshot/snapshot-manager\n * @description 스냅샷 관리자 (파사드 패턴)\n */\n\nimport type { BlackboardState } from '../types';\nimport type {\n Snapshot,\n SnapshotMeta,\n CreateSnapshotOptions,\n RestoreSnapshotOptions,\n SnapshotValidationResult,\n} from './types';\nimport type {\n SnapshotCreatorOptions,\n} from './snapshot-creator';\nimport type {\n SnapshotRestorerOptions,\n} from './snapshot-restorer';\nimport type {\n SnapshotDiff,\n SectionDiff,\n SectionData,\n} from './snapshot-comparer';\n\nimport { SnapshotCreator } from './snapshot-creator';\nimport { SnapshotValidator } from './snapshot-validator';\nimport {\n SnapshotRestorer,\n SnapshotRestoreError,\n} from './snapshot-restorer';\nimport { SnapshotSerializer } from './snapshot-serializer';\nimport {\n SnapshotComparer,\n} from './snapshot-comparer';\n\n/**\n * 스냅샷 목록 필터 옵션\n */\nexport interface ListSnapshotOptions {\n /** 태그로 필터링 */\n tags?: string[];\n /** 세션 ID로 필터링 */\n sessionId?: string;\n /** 정렬 기준 */\n sortBy?: 'date' | 'id';\n /** 정렬 순서 */\n order?: 'asc' | 'desc';\n}\n\n/**\n * 스냅샷 관리자 설정\n */\nexport interface SnapshotManagerOptions extends SnapshotCreatorOptions, SnapshotRestorerOptions {\n /** 자동 압축 임계값 (바이트, 기본: 10KB) */\n autoCompressThreshold?: number;\n /** 기본 압축 사용 */\n defaultCompress?: boolean;\n /** ID 생성 함수 */\n idGenerator?: () => string;\n}\n\n/**\n * 스냅샷 복원 에러\n */\nexport { SnapshotRestoreError };\n\n/**\n * 스냅샷 관리자\n * @description Blackboard 상태의 스냅샷 생성, 검증, 복원 담당\n *\n * 파사드 패턴으로 각 전문 클래스를 조합하여 기존 API 유지\n *\n * @example\n * ```typescript\n * const manager = new SnapshotManager();\n *\n * // 스냅샷 생성\n * const snapshot = await manager.createSnapshot(board.getState(), {\n * description: 'Before major decision',\n * tags: ['checkpoint', 'decision-001'],\n * compress: true,\n * });\n *\n * // JSON으로 저장\n * const json = manager.toJSON(snapshot);\n * fs.writeFileSync('snapshot.json', json);\n *\n * // JSON에서 로드\n * const loaded = manager.fromJSON(fs.readFileSync('snapshot.json', 'utf-8'));\n *\n * // 검증\n * const validation = await manager.validate(loaded);\n * if (!validation.valid) {\n * console.error('Invalid snapshot:', validation.errors);\n * }\n *\n * // 복원\n * const restoredState = manager.restore(loaded, {\n * newSessionId: true,\n * });\n * board.replaceState(restoredState);\n * ```\n */\nexport class SnapshotManager {\n private creator: SnapshotCreator;\n private validator: SnapshotValidator;\n private restorer: SnapshotRestorer;\n private serializer: SnapshotSerializer;\n private comparer: SnapshotComparer;\n private storage: Map<string, Snapshot> = new Map();\n\n constructor(options: SnapshotManagerOptions = {}) {\n // 각 전문 클래스 초기화\n this.creator = new SnapshotCreator(options);\n this.validator = new SnapshotValidator();\n this.restorer = new SnapshotRestorer(options);\n this.serializer = new SnapshotSerializer();\n this.comparer = new SnapshotComparer();\n }\n\n // === 내부 저장소 관리 ===\n\n /**\n * 스냅샷 저장 (내부)\n */\n private storeSnapshot(snapshot: Snapshot): void {\n this.storage.set(snapshot.meta.id, snapshot);\n }\n\n /**\n * 저장된 스냅샷 목록 조회\n * @param options - 필터 및 정렬 옵션\n * @returns 스냅샷 목록\n */\n list(options?: ListSnapshotOptions): Snapshot[] {\n let snapshots = Array.from(this.storage.values());\n\n // 필터링\n if (options?.tags && options.tags.length > 0) {\n snapshots = snapshots.filter(snapshot =>\n options.tags!.some(tag =>\n snapshot.meta.tags?.includes(tag)\n )\n );\n }\n\n if (options?.sessionId) {\n snapshots = snapshots.filter(snapshot =>\n snapshot.meta.sessionId === options.sessionId\n );\n }\n\n // 정렬\n if (options?.sortBy) {\n snapshots.sort((a, b) => {\n let comparison = 0;\n\n if (options.sortBy === 'date') {\n comparison = a.meta.createdAt.getTime() - b.meta.createdAt.getTime();\n } else if (options.sortBy === 'id') {\n comparison = a.meta.id.localeCompare(b.meta.id);\n }\n\n return options.order === 'desc' ? -comparison : comparison;\n });\n }\n\n return snapshots;\n }\n\n /**\n * ID로 스냅샷 조회\n * @param id - 스냅샷 ID\n * @returns 스냅샷 또는 undefined\n */\n get(id: string): Snapshot | undefined {\n return this.storage.get(id);\n }\n\n /**\n * ID로 스냅샷 삭제\n * @param id - 스냅샷 ID\n * @returns 삭제 성공 여부\n */\n delete(id: string): boolean {\n return this.storage.delete(id);\n }\n\n // === 생성 (SnapshotCreator 위임) ===\n\n /**\n * 스냅샷 생성 (동기)\n * @param state - 현재 Blackboard 상태\n * @param options - 생성 옵션\n * @returns 스냅샷\n */\n createSnapshot(\n state: BlackboardState,\n options?: CreateSnapshotOptions\n ): Snapshot {\n const snapshot = this.creator.createSnapshot(state, options);\n\n // store 옵션이 true면 내부 저장소에 저장\n if (options?.store === true) {\n this.storeSnapshot(snapshot);\n }\n\n return snapshot;\n }\n\n /**\n * 메타데이터만 포함된 스냅샷 생성 (동기)\n * @param state - 현재 상태\n * @param description - 설명\n * @returns 메타 전용 스냅샷\n */\n createMetaSnapshot(\n state: BlackboardState,\n description?: string\n ): SnapshotMeta {\n return this.creator.createMetaSnapshot(state, description);\n }\n\n // === 검증 (SnapshotValidator 위임) ===\n\n /**\n * 스냅샷 검증 (동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n validate(snapshot: Snapshot): SnapshotValidationResult {\n return this.validator.validateSync(snapshot);\n }\n\n /**\n * 스냅샷 검증 (비동기)\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n async validateAsync(snapshot: Snapshot): Promise<SnapshotValidationResult> {\n return this.validator.validate(snapshot);\n }\n\n /**\n * 버전 호환성 체크\n * @param formatVersion - 스냅샷 형식 버전\n * @returns 호환 여부 및 상세 정보\n */\n checkVersionCompatibility(formatVersion: string): {\n compatible: boolean;\n current: string;\n snapshot: string;\n migrationRequired: boolean;\n } {\n return this.validator.checkVersionCompatibility(formatVersion);\n }\n\n /**\n * 동기 체크섬 검증 (구조적 검증만, 체크섬 제외)\n * @description restore()에서 사용하는 동기 검증 메서드\n * @param snapshot - 검증할 스냅샷\n * @returns 검증 결과\n */\n validateSyncStructure(snapshot: Snapshot): {\n valid: boolean;\n errors: string[];\n } {\n return this.validator.validateSyncStructure(snapshot);\n }\n\n // === 복원 (SnapshotRestorer 위임) ===\n\n /**\n * 스냅샷에서 상태 복원\n * @param snapshot - 스냅샷\n * @param options - 복원 옵션\n * @returns 복원된 상태\n * @throws {SnapshotRestoreError} 복원 실패 시\n * @description\n * **옵션 동작:**\n * - `skipVersionCheck`: 포맷 버전 호환성 검사 건너뜀\n * - `skipStructuralValidation`: 구조적 검증 건너뜀 (validateSync)\n * - `resetVersion`: 상태 버전 0으로 초기화 (기본: true)\n * - `newSessionId`: 새 세션 ID 생성 (기본: true)\n */\n restore(\n snapshot: Snapshot,\n options?: RestoreSnapshotOptions\n ): BlackboardState {\n return this.restorer.restore(snapshot, options);\n }\n\n /**\n * 부분 복원 (특정 섹션만)\n * @param snapshot - 스냅샷\n * @param currentState - 현재 상태\n * @param sections - 복원할 섹션\n * @returns 병합된 상태\n */\n partialRestore(\n snapshot: Snapshot,\n currentState: BlackboardState,\n sections: ('state' | 'knowledge' | 'decisions')[]\n ): BlackboardState {\n return this.restorer.partialRestore(snapshot, currentState, sections);\n }\n\n // === 직렬화 (SnapshotSerializer 위임) ===\n\n /**\n * 스냅샷 → JSON 문자열\n * @param snapshot - 스냅샷\n * @param pretty - 예쁜 출력 여부\n * @returns JSON 문자열\n */\n toJSON(snapshot: Snapshot, pretty = false): string {\n return this.serializer.toJSON(snapshot, pretty);\n }\n\n /**\n * JSON 문자열 → 스냅샷\n * @param json - JSON 문자열\n * @returns 스냅샷\n * @throws {Error} JSON 파싱 실패 시 명확한 에러 메시지\n */\n fromJSON(json: string): Snapshot {\n return this.serializer.fromJSON(json);\n }\n\n /**\n * 스냅샷 → Uint8Array (바이너리)\n * @param snapshot - 스냅샷\n * @returns Uint8Array\n */\n toUint8Array(snapshot: Snapshot): Uint8Array {\n return this.serializer.toUint8Array(snapshot);\n }\n\n /**\n * Uint8Array → 스냅샷\n * @param bytes - 바이트 배열\n * @returns 스냅샷\n * @throws {Error} 디코딩 실패 시 명확한 에러 메시지\n */\n fromUint8Array(bytes: Uint8Array): Snapshot {\n return this.serializer.fromUint8Array(bytes);\n }\n\n // === 비교 (SnapshotComparer 위임) ===\n\n /**\n * 스냅샷 비교\n * @param a - 첫 번째 스냅샷\n * @param b - 두 번째 스냅샷\n * @returns 차이점 목록\n */\n compare(a: Snapshot, b: Snapshot): SnapshotDiff {\n return this.comparer.compare(a, b);\n }\n\n /**\n * 섹션 차이점 생성\n * @param data1 - 첫 번째 데이터\n * @param data2 - 두 번째 데이터\n * @returns 섹션 차이점\n */\n createSectionDiff(data1: SectionData, data2: SectionData): SectionDiff {\n return this.comparer.createSectionDiff(data1, data2);\n }\n\n /**\n * 상태 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 상태 데이터\n */\n extractStateData(snapshot: Snapshot): SectionData {\n return this.comparer.extractStateData(snapshot);\n }\n\n /**\n * 지식 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 지식 데이터\n */\n extractKnowledgeData(snapshot: Snapshot): SectionData {\n return this.comparer.extractKnowledgeData(snapshot);\n }\n\n /**\n * 의사결정 데이터 추출\n * @param snapshot - 스냅샷\n * @returns 의사결정 데이터\n */\n extractDecisionsData(snapshot: Snapshot): SectionData {\n return this.comparer.extractDecisionsData(snapshot);\n }\n\n // === 유틸리티 ===\n\n /**\n * 스냅샷 메타데이터만 추출\n */\n extractMeta(snapshot: Snapshot): SnapshotMeta {\n return snapshot.meta;\n }\n\n /**\n * 스냅샷 크기 계산 (숫자)\n * @param snapshot - 스냅샷\n * @returns 바이트 크기\n */\n size(snapshot: Snapshot): number {\n const metaSize = JSON.stringify(snapshot.meta).length;\n const dataSize =\n typeof snapshot.data === 'string'\n ? snapshot.data.length\n : JSON.stringify(snapshot.data).length;\n\n return metaSize + dataSize;\n }\n\n /**\n * 스냅샷 크기 계산 (상세)\n */\n calculateSize(snapshot: Snapshot): {\n total: number;\n data: number;\n meta: number;\n compressed: boolean;\n } {\n const metaSize = JSON.stringify(snapshot.meta).length;\n const dataSize =\n typeof snapshot.data === 'string'\n ? snapshot.data.length\n : JSON.stringify(snapshot.data).length;\n\n return {\n total: metaSize + dataSize,\n data: dataSize,\n meta: metaSize,\n compressed: snapshot.meta.compressed,\n };\n }\n}\n","/**\n * @module blackboard\n * @description 메인 Blackboard 클래스\n */\n\nimport type {\n BlackboardState,\n BlackboardMeta,\n KnowledgeSection,\n BoardPhase,\n DecisionsSection,\n SessionId,\n StateSection,\n VotingSession,\n Opinion,\n Task,\n AgentStatus,\n} from \"../types\";\nimport { createSessionId } from \"../types/base\";\n\nimport { VersionManager, VersionConflictError } from \"./versioning\";\nimport { getByPath, setByPath, deleteByPath, isValidPath } from \"./path-utils\";\nimport { deepClone, mapToObject, objectToMap } from \"./immutable\";\n\nimport { StateSectionAccessor } from \"./accessors/state-accessor\";\nimport { KnowledgeSectionAccessor } from \"./accessors/knowledge-accessor\";\nimport { DecisionsSectionAccessor } from \"./accessors/decisions-accessor\";\n\n// Snapshot imports\nimport { SnapshotManager } from \"../snapshot\";\nimport type {\n Snapshot,\n CreateSnapshotOptions,\n RestoreSnapshotOptions,\n SnapshotValidationResult,\n} from \"../snapshot\";\n\n// Re-export types for convenience\nexport { BoardPhase };\n\n/**\n * 간단한 EventEmitter 구현\n */\ntype EventListener = (...args: unknown[]) => void;\n\nclass SimpleEventEmitter {\n private _listeners: Map<string, EventListener[]> = new Map();\n\n on(event: string, listener: EventListener): this {\n const listeners = this._listeners.get(event) ?? [];\n listeners.push(listener);\n this._listeners.set(event, listeners);\n return this;\n }\n\n off(event: string, listener: EventListener): this {\n const listeners = this._listeners.get(event) ?? [];\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n return this;\n }\n\n once(event: string, listener: EventListener): this {\n const onceWrapper = (...args: unknown[]) => {\n this.off(event, onceWrapper);\n listener(...args);\n };\n return this.on(event, onceWrapper);\n }\n\n emit(event: string, ...args: unknown[]): boolean {\n const listeners = this._listeners.get(event) ?? [];\n for (const listener of listeners) {\n listener(...args);\n }\n\n // 와일드카드 지원 (예: 'state.*' -> 'state.updated' 매칭)\n for (const [pattern, wildcardListeners] of this._listeners.entries()) {\n if (pattern.endsWith(\"*\") && event.startsWith(pattern.slice(0, -1))) {\n for (const listener of wildcardListeners) {\n listener(...args);\n }\n }\n }\n\n return listeners.length > 0;\n }\n\n removeAllListeners(event?: string): this {\n if (event) {\n this._listeners.delete(event);\n } else {\n this._listeners.clear();\n }\n return this;\n }\n\n listenerCount(event: string): number {\n return this._listeners.get(event)?.length ?? 0;\n }\n}\n\n/**\n * Blackboard 설정 옵션\n */\nexport interface BlackboardOptions {\n /** 세션 ID (자동 생성되지 않으면 필수) */\n sessionId?: SessionId;\n /** 초기 상태 (스냅샷 복원 시 사용) */\n initialState?: Partial<BlackboardState>;\n /** 버전 충돌 시 재시도 횟수 */\n maxRetries?: number;\n /** 재시도 간격 (ms) */\n retryDelay?: number;\n /** 이벤트 리스너 */\n onEvent?: (event: { type: string; timestamp: Date }) => void;\n}\n\n/**\n * 쿼리 옵션\n */\nexport interface QueryOptions {\n /** 깊은 복사 반환 여부 (기본: true) */\n deep?: boolean;\n /** 필터 조건 */\n filter?: Record<string, unknown>;\n /** 정렬 기준 */\n sort?: { field: string; order: \"asc\" | \"desc\" };\n /** 결과 제한 */\n limit?: number;\n /** 오프셋 */\n offset?: number;\n}\n\n/**\n * 쓰기 결과\n */\nexport interface WriteResult {\n /** 성공 여부 */\n success: boolean;\n /** 새 버전 */\n version: number;\n /** 변경된 경로 */\n path: string;\n /** 이전 값 */\n previousValue: unknown;\n /** 에러 (실패 시) */\n error?: Error;\n}\n\n/**\n * 트랜잭션 연산\n */\nexport interface Operation {\n /** 연산 타입 */\n type: \"read\" | \"write\" | \"delete\";\n /** 섹션 */\n section: string;\n /** 키/경로 */\n key: string;\n /** 값 (write 연산 시) */\n value?: unknown;\n}\n\n/**\n * Blackboard 에러 코드\n */\nexport enum BlackboardErrorCode {\n UNKNOWN_ERROR = 1000,\n INVALID_INPUT = 1001,\n NOT_IMPLEMENTED = 1002,\n PATH_NOT_FOUND = 1003,\n INVALID_PATH = 1004,\n\n SLOT_NOT_FOUND = 2000,\n SLOT_ALREADY_EXISTS = 2001,\n SLOT_TYPE_MISMATCH = 2002,\n SLOT_VERSION_CONFLICT = 2003,\n\n ENTRY_NOT_FOUND = 2100,\n ENTRY_ALREADY_EXISTS = 2101,\n ENTRY_LOCKED = 2102,\n\n AGENT_NOT_FOUND = 3000,\n AGENT_ALREADY_REGISTERED = 3001,\n AGENT_NOT_AVAILABLE = 3002,\n TASK_NOT_FOUND = 3003,\n TASK_ALREADY_ASSIGNED = 3004,\n TASK_IN_PROGRESS = 3005,\n\n FACT_NOT_FOUND = 4000,\n INFERENCE_NOT_FOUND = 4001,\n PATTERN_NOT_FOUND = 4002,\n INVALID_PREMISES = 4003,\n\n AGENDA_NOT_FOUND = 5000,\n AGENDA_ALREADY_IN_PROGRESS = 5001,\n AGENDA_ALREADY_RESOLVED = 5002,\n VOTING_NOT_STARTED = 5003,\n VOTING_ALREADY_ENDED = 5004,\n QUORUM_NOT_REACHED = 5005,\n ALREADY_VOTED = 5006,\n CONSENSUS_NOT_REACHED = 5007,\n DUPLICATE_OPINION = 5008,\n OPINION_NOT_FOUND = 5009,\n\n SNAPSHOT_NOT_FOUND = 6000,\n SNAPSHOT_CORRUPTED = 6001,\n SNAPSHOT_VERSION_MISMATCH = 6002,\n\n EVENT_HANDLER_ERROR = 7000,\n SUBSCRIPTION_NOT_FOUND = 7001,\n}\n\n/**\n * 경로 에러\n */\nexport class PathNotFoundError extends Error {\n public readonly code = BlackboardErrorCode.PATH_NOT_FOUND;\n\n constructor(public readonly path: string) {\n super(`Path not found: ${path}`);\n this.name = \"PathNotFoundError\";\n }\n}\n\n/**\n * Blackboard 에러 클래스\n */\nexport class BlackboardError extends Error {\n constructor(\n public readonly code: BlackboardErrorCode,\n message: string,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"BlackboardError\";\n }\n}\n\n/**\n * Blackboard 메인 클래스\n * @description 시스템의 단일 진실 소스(SSOT)를 관리하는 핵심 클래스\n *\n * @example\n * ```typescript\n * const board = new Blackboard({ sessionId: createSessionId('session-001') });\n *\n * // 읽기\n * const phase = board.read('state.phase');\n *\n * // 쓰기 (버전 관리 포함)\n * const result = board.write('state.phase', 'discussion');\n *\n * // 섹션 접근\n * const stateSection = board.state;\n * const knowledgeSection = board.knowledge;\n * const decisionsSection = board.decisions;\n * ```\n */\nexport class Blackboard extends SimpleEventEmitter {\n private _state: BlackboardState;\n private readonly versionManager: VersionManager;\n private readonly options: Required<Omit<BlackboardOptions, \"onEvent\">> &\n Pick<BlackboardOptions, \"onEvent\">;\n private _snapshotManager: SnapshotManager;\n\n // 섹션 접근자\n private _stateAccessor?: StateSectionAccessor;\n private _knowledgeAccessor?: KnowledgeSectionAccessor;\n private _decisionsAccessor?: DecisionsSectionAccessor;\n\n constructor(options: BlackboardOptions = {}) {\n super();\n this.options = this.normalizeOptions(options);\n this._state = this.createInitialState();\n this.versionManager = new VersionManager({\n maxRetries: this.options.maxRetries,\n retryDelay: this.options.retryDelay,\n exponentialBackoff: true,\n });\n this._snapshotManager = new SnapshotManager();\n\n // 접근자 초기화\n this._stateAccessor = new StateSectionAccessor(this);\n this._knowledgeAccessor = new KnowledgeSectionAccessor(this);\n this._decisionsAccessor = new DecisionsSectionAccessor(this);\n\n // state.initialized 이벤트 발생 (onEvent 옵션이 있는 경우)\n if (options.onEvent) {\n options.onEvent({ type: \"state.initialized\", timestamp: new Date() });\n }\n }\n\n /**\n * 옵션 정규화\n */\n private normalizeOptions(\n options: BlackboardOptions\n ): Required<Omit<BlackboardOptions, \"onEvent\">> & Pick<BlackboardOptions, \"onEvent\"> {\n return {\n sessionId: options.sessionId ?? createSessionId(`session-${Date.now()}`),\n initialState: options.initialState ?? {},\n maxRetries: options.maxRetries ?? 3,\n retryDelay: options.retryDelay ?? 100,\n onEvent: options.onEvent,\n };\n }\n\n /**\n * 초기 상태 생성\n */\n private createInitialState(): BlackboardState {\n const now = new Date();\n const sessionId = this.options.sessionId;\n\n // 초기 상태 복원\n if (this.options.initialState.meta) {\n return {\n meta: {\n version: this.options.initialState.meta?.version ?? 1,\n lastUpdated: this.options.initialState.meta?.lastUpdated ?? now,\n sessionId: this.options.initialState.meta?.sessionId ?? sessionId,\n createdAt: this.options.initialState.meta?.createdAt ?? now,\n },\n state: this.options.initialState.state ?? {\n phase: \"idle\",\n context: {},\n agents: new Map(),\n tasks: new Map(),\n },\n knowledge: this.options.initialState.knowledge ?? {\n facts: [],\n inferences: [],\n patterns: [],\n },\n decisions: this.options.initialState.decisions ?? {\n current: null,\n pending: [],\n opinions: new Map(),\n history: [],\n voting: {},\n },\n };\n }\n\n // 새 상태 생성\n return {\n meta: {\n version: 1,\n lastUpdated: now,\n sessionId,\n createdAt: now,\n },\n state: {\n phase: \"idle\",\n context: {},\n agents: new Map(),\n tasks: new Map(),\n },\n knowledge: {\n facts: [],\n inferences: [],\n patterns: [],\n },\n decisions: {\n current: null,\n pending: [],\n opinions: new Map(),\n history: [],\n voting: {},\n },\n };\n }\n\n // === Getters for sections ===\n\n /** 메타데이터 섹션 (읽기 전용) */\n get meta(): Readonly<BlackboardMeta> {\n return {\n version: this._state.meta.version,\n lastUpdated: new Date(this._state.meta.lastUpdated.getTime()),\n sessionId: this._state.meta.sessionId,\n createdAt: new Date(this._state.meta.createdAt.getTime()),\n };\n }\n\n /** 상태 섹션 접근자 */\n get state(): StateSectionAccessor {\n if (!this._stateAccessor) {\n this._stateAccessor = new StateSectionAccessor(this);\n }\n return this._stateAccessor;\n }\n\n /** 지식 섹션 접근자 */\n get knowledge(): KnowledgeSectionAccessor {\n if (!this._knowledgeAccessor) {\n this._knowledgeAccessor = new KnowledgeSectionAccessor(this);\n }\n return this._knowledgeAccessor;\n }\n\n /** 의사결정 섹션 접근자 */\n get decisions(): DecisionsSectionAccessor {\n if (!this._decisionsAccessor) {\n this._decisionsAccessor = new DecisionsSectionAccessor(this);\n }\n return this._decisionsAccessor;\n }\n\n /** 현재 버전 */\n get version(): number {\n return this._state.meta.version;\n }\n\n /** 세션 ID */\n get sessionId(): SessionId {\n return this._state.meta.sessionId;\n }\n\n /** 스냅샷 관리자 (public) */\n get snapshotManager(): SnapshotManager {\n return this._snapshotManager;\n }\n\n // === Core API ===\n\n /**\n * 현재 전체 상태 조회\n * @returns 현재 Blackboard 상태 (스냅샷용)\n */\n getState(): BlackboardState {\n return {\n meta: {\n version: this._state.meta.version,\n lastUpdated: new Date(this._state.meta.lastUpdated.getTime()),\n sessionId: this._state.meta.sessionId,\n createdAt: new Date(this._state.meta.createdAt.getTime()),\n },\n state: {\n phase: this._state.state.phase,\n context: deepClone(this._state.state.context),\n agents: new Map(this._state.state.agents.entries()),\n tasks: new Map(this._state.state.tasks.entries()),\n },\n knowledge: {\n facts: this._state.knowledge.facts.map((f) => deepClone(f)),\n inferences: this._state.knowledge.inferences.map((i) => deepClone(i)),\n patterns: this._state.knowledge.patterns.map((p) => deepClone(p)),\n },\n decisions: {\n current: this._state.decisions.current ? deepClone(this._state.decisions.current) : null,\n pending: this._state.decisions.pending.map((d) => deepClone(d)),\n opinions: new Map(this._state.decisions.opinions.entries()),\n history: this._state.decisions.history.map((h) => deepClone(h)),\n voting: deepClone(this._state.decisions.voting),\n },\n };\n }\n\n /**\n * 경로 기반 읽기\n * @param path - 점(.)으로 구분된 경로 (예: 'state.phase', 'decisions.current')\n * @param options - 쿼리 옵션\n * @returns 해당 경로의 값\n */\n read<T = unknown>(path: string, options?: QueryOptions & { strict?: boolean }): T {\n const shouldDeepClone = options?.deep !== false;\n const strict = options?.strict !== false;\n const value = getByPath(this._state, path);\n\n if (value === undefined && strict) {\n throw new PathNotFoundError(path);\n }\n\n return (shouldDeepClone ? deepClone(value) : value) as T;\n }\n\n /**\n * 경로 기반 쓰기 (동기)\n * @param path - 점(.)으로 구분된 경로\n * @param value - 새 값\n * @param options - 쓰기 옵션 (expectedVersion 포함)\n * @returns 쓰기 결과\n */\n write(path: string, value: unknown, options?: { expectedVersion?: number }): WriteResult {\n // 경로 검증\n if (!isValidPath(path)) {\n throw new BlackboardError(BlackboardErrorCode.INVALID_PATH, `Invalid path: ${path}`);\n }\n\n // 버전 검증\n if (options?.expectedVersion !== undefined) {\n this.versionManager.validateVersion(this.version, options.expectedVersion, path);\n }\n\n const previousValue = getByPath(this._state, path);\n\n const newState = setByPath(this._state, path, value);\n this._state = newState;\n\n // 메타데이터 업데이트\n const newVersion = this.versionManager.incrementVersion(this.version);\n this._state.meta.version = newVersion;\n this._state.meta.lastUpdated = new Date();\n\n // state.updated 이벤트 발생\n this.emit(\"state.updated\", { type: \"state.updated\", path, value, timestamp: new Date() });\n\n return {\n success: true,\n version: newVersion,\n path,\n previousValue,\n };\n }\n\n /**\n * 경로 기반 삭제\n * @param path - 삭제할 경로\n * @param options - 삭제 옵션\n * @returns 삭제 결과\n */\n delete(path: string, options?: { expectedVersion?: number; strict?: boolean }): WriteResult {\n // 경로 검증\n if (!isValidPath(path)) {\n return {\n success: false,\n version: this.version,\n path,\n previousValue: undefined,\n error: new BlackboardError(BlackboardErrorCode.INVALID_PATH, `Invalid path: ${path}`),\n };\n }\n\n // 경로가 존재하는지 확인\n const previousValue = getByPath(this._state, path);\n if (previousValue === undefined) {\n if (options?.strict !== false) {\n throw new PathNotFoundError(path);\n }\n return {\n success: false,\n version: this.version,\n path,\n previousValue: undefined,\n };\n }\n\n // 버전 검증\n if (options?.expectedVersion !== undefined) {\n try {\n this.versionManager.validateVersion(this.version, options.expectedVersion, path);\n } catch (error) {\n return {\n success: false,\n version: this.version,\n path,\n previousValue,\n error: error as Error,\n };\n }\n }\n\n try {\n const newState = deleteByPath(this._state, path);\n this._state = newState;\n\n // 메타데이터 업데이트\n const newVersion = this.versionManager.incrementVersion(this.version);\n this._state.meta.version = newVersion;\n this._state.meta.lastUpdated = new Date();\n\n return {\n success: true,\n version: newVersion,\n path,\n previousValue,\n };\n } catch (error) {\n return {\n success: false,\n version: this.version,\n path,\n previousValue,\n error: error as Error,\n };\n }\n }\n\n /**\n * 경로 존재 여부 확인\n * @param path - 확인할 경로\n */\n exists(path: string): boolean {\n return getByPath(this._state, path) !== undefined;\n }\n\n /**\n * 트랜잭션 실행\n * @description 여러 쓰기를 원자적으로 실행\n * @param operations - 실행할 연산 목록\n * @returns 전체 트랜잭션 결과\n */\n transaction(\n operations: Array<{\n type: \"write\" | \"delete\";\n path: string;\n value?: unknown;\n expectedVersion?: number;\n }>\n ): WriteResult[] {\n const originalVersion = this._state.meta.version;\n const results: WriteResult[] = [];\n const backup = {\n meta: {\n version: this._state.meta.version,\n lastUpdated: new Date(this._state.meta.lastUpdated.getTime()),\n sessionId: this._state.meta.sessionId,\n createdAt: new Date(this._state.meta.createdAt.getTime()),\n },\n state: {\n phase: this._state.state.phase,\n context: deepClone(this._state.state.context),\n agents: new Map(this._state.state.agents.entries()),\n tasks: new Map(this._state.state.tasks.entries()),\n },\n knowledge: {\n facts: this._state.knowledge.facts.map((f) => deepClone(f)),\n inferences: this._state.knowledge.inferences.map((i) => deepClone(i)),\n patterns: this._state.knowledge.patterns.map((p) => deepClone(p)),\n },\n decisions: {\n current: this._state.decisions.current ? deepClone(this._state.decisions.current) : null,\n pending: this._state.decisions.pending.map((d) => deepClone(d)),\n opinions: new Map(this._state.decisions.opinions.entries()),\n history: this._state.decisions.history.map((h) => deepClone(h)),\n voting: deepClone(this._state.decisions.voting),\n },\n };\n\n try {\n // 버전 검증 (모든 연산 전에 수행)\n for (const op of operations) {\n if (op.expectedVersion !== undefined) {\n this.versionManager.validateVersion(originalVersion, op.expectedVersion, op.path);\n }\n }\n\n // 모든 연산 실행 (버전 증가 없이)\n for (const op of operations) {\n // 내�的方法를 사용하여 버전 증가 없이 쓰기/삭제 수행\n if (op.type === \"write\") {\n const previousValue = getByPath(this._state, op.path);\n this._state = setByPath(this._state, op.path, op.value);\n results.push({\n success: true,\n version: originalVersion, // 아직 버전 증가 안 함\n path: op.path,\n previousValue,\n });\n } else {\n const previousValue = getByPath(this._state, op.path);\n this._state = deleteByPath(this._state, op.path);\n results.push({\n success: true,\n version: originalVersion, // 아직 버전 증가 안 함\n path: op.path,\n previousValue,\n });\n }\n }\n\n // 모든 성공 시 한 번만 버전 증가\n this._state.meta.version = originalVersion + 1;\n this._state.meta.lastUpdated = new Date();\n\n // 결과에 최종 버전 업데이트\n return results.map((r) => ({ ...r, version: this._state.meta.version }));\n } catch (error) {\n // 롤백: 상태 복원 및 버전 복원\n this._state = backup;\n this._state.meta.version = originalVersion;\n\n return operations.map(() => ({\n success: false,\n version: originalVersion,\n path: \"\",\n previousValue: undefined,\n error: error as Error,\n }));\n }\n }\n\n // === Snapshot Methods ===\n\n /**\n * 현재 상태 스냅샷 생성 (비동기)\n * @param options - 스냅샷 옵션\n * @returns 스냅샷\n */\n async createSnapshot(options?: CreateSnapshotOptions): Promise<Snapshot> {\n const state = this.getState();\n return this._snapshotManager.createSnapshot(state, options);\n }\n\n /**\n * 스냅샷에서 상태 복원\n * @param snapshot - 복원할 스냅샷\n * @param options - 복원 옵션\n */\n restoreSnapshot(snapshot: Snapshot, options?: RestoreSnapshotOptions): void {\n const restoredState = this._snapshotManager.restore(snapshot, options);\n this.replaceState(restoredState);\n }\n\n /**\n * 스냅샷 검증 (비동기)\n * @param snapshot - 검증할 스냅샷\n */\n async validateSnapshot(snapshot: Snapshot): Promise<SnapshotValidationResult> {\n return this._snapshotManager.validate(snapshot);\n }\n\n /**\n * 전체 상태 교체 (내부용)\n * @param newState - 새 상태\n */\n private replaceState(newState: BlackboardState): void {\n this._state = deepClone(newState);\n\n // 접근자 재초기화\n this._stateAccessor = new StateSectionAccessor(this);\n this._knowledgeAccessor = new KnowledgeSectionAccessor(this);\n this._decisionsAccessor = new DecisionsSectionAccessor(this);\n }\n\n /**\n * 스냅샷 생성 (JSON 직렬화용) - 하위 호환성 유지\n */\n toJSON(): unknown {\n return {\n meta: this._state.meta,\n state: {\n phase: this._state.state.phase,\n context: this._state.state.context,\n agents: mapToObject(this._state.state.agents),\n tasks: mapToObject(this._state.state.tasks),\n },\n knowledge: this._state.knowledge,\n decisions: {\n current: this._state.decisions.current,\n pending: this._state.decisions.pending,\n opinions: mapToObject(this._state.decisions.opinions),\n history: this._state.decisions.history,\n voting: this._state.decisions.voting,\n },\n };\n }\n\n /**\n * 스냅샷에서 복원 - 하위 호환성 유지\n */\n static fromJSON(json: {\n meta?: unknown;\n state?: unknown;\n knowledge?: unknown;\n decisions?: unknown;\n }): Blackboard {\n type SerializableStateSection = Partial<Omit<StateSection, \"agents\" | \"tasks\">> & {\n agents?: Record<string, AgentStatus>;\n tasks?: Record<string, Task>;\n };\n\n type SerializableDecisionsSection = Partial<Omit<DecisionsSection, \"opinions\" | \"voting\">> & {\n opinions?: Record<string, Opinion>;\n voting?: Record<string, VotingSession>;\n };\n\n const stateJson = (json.state ?? undefined) as SerializableStateSection | undefined;\n const decisionsJson = (json.decisions ?? undefined) as SerializableDecisionsSection | undefined;\n\n const state: Partial<BlackboardState> = {\n meta: json.meta as BlackboardMeta,\n state: stateJson\n ? {\n ...stateJson,\n agents: objectToMap(stateJson.agents ?? {}),\n tasks: objectToMap(stateJson.tasks ?? {}),\n }\n : undefined,\n knowledge: json.knowledge as KnowledgeSection,\n decisions: decisionsJson\n ? {\n ...decisionsJson,\n opinions: objectToMap(decisionsJson.opinions ?? {}),\n voting: decisionsJson.voting ?? {},\n }\n : undefined,\n };\n\n return new Blackboard({ initialState: state });\n }\n}\n\n// Re-export error classes\nexport { VersionConflictError };\n","/**\n * @module events/event-bus\n * @description Event Bus 구현 - Pub/Sub 패턴, 와일드카드 구독, 이벤트 필터링 지원\n */\n\nimport type { Event, EventType, EventByType, EventCategory } from \"./types\";\nimport type { AgentId } from \"../types\";\n\n/**\n * 이벤트 핸들러 타입\n */\nexport type EventHandler<T extends Event = Event> = (event: T) => void | Promise<void>;\n\n/**\n * 구독 정보 인터페이스\n */\ninterface Subscription<T extends Event = Event> {\n handler: EventHandler<T>;\n eventType: string;\n once: boolean;\n filter?: EventFilter;\n}\n\n/**\n * 구독 해제 함수\n */\nexport type Unsubscribe = () => void;\n\n/**\n * 이벤트 필터 조건\n */\nexport interface EventFilter {\n /** 소스 에이전트 ID */\n source?: AgentId | \"system\";\n /** 상관 ID */\n correlationId?: string;\n /** 커스텀 필터 함수 */\n predicate?: (event: Event) => boolean;\n}\n\n/**\n * Event Bus 설정\n */\nexport interface EventBusOptions {\n /** 최대 리스너 수 (기본: 100) */\n maxListeners?: number;\n /** 비동기 핸들러 에러 시 throw 여부 (기본: false) */\n throwOnAsyncError?: boolean;\n /** 비동기 핸들러 에러 시 에러 이벤트 발행 여부 (기본: true) */\n emitErrorEvent?: boolean;\n /** 이벤트 히스토리 유지 개수 (기본: 0 = 유지 안함) */\n historySize?: number;\n /** 디버그 모드 */\n debug?: boolean;\n}\n\n/**\n * Event Bus 통계\n */\nexport interface EventBusStats {\n /** 총 발행된 이벤트 수 */\n totalEmitted: number;\n /** 타입별 발행 수 */\n emittedByType: Map<string, number>;\n /** 현재 구독자 수 */\n subscriberCount: number;\n /** 타입별 구독자 수 */\n subscribersByType: Map<string, number>;\n}\n\n/**\n * 이벤트 대기용 타임아웃 에러\n */\nexport class EventTimeoutError extends Error {\n constructor(eventType: string, timeout: number) {\n super(`Timeout waiting for event '${eventType}' after ${timeout}ms`);\n this.name = \"EventTimeoutError\";\n }\n}\n\n/**\n * Event Bus\n * @description Blackboard 이벤트를 위한 Pub/Sub 시스템\n * @description EventEmitter 상속하지 않고 자체 구현 (브라우저 호환)\n *\n * @example\n * ```typescript\n * const bus = new EventBus({ historySize: 100 });\n *\n * // 특정 이벤트 구독\n * const unsub = bus.subscribe('task.completed', (event) => {\n * console.log('Task completed:', event.payload.taskId);\n * });\n *\n * // 와일드카드 구독\n * bus.subscribe('task.*', (event) => {\n * console.log('Task event:', event.type);\n * });\n *\n * // 모든 이벤트 구독\n * bus.subscribe('*', (event) => {\n * console.log('Any event:', event.type);\n * });\n *\n * // 필터와 함께 구독\n * bus.subscribeWithFilter('decision.*',\n * { source: createAgentId('ceo') },\n * (event) => console.log('CEO decision event')\n * );\n *\n * // 이벤트 발행\n * bus.emit({\n * id: generateId(),\n * type: 'task.completed',\n * timestamp: new Date(),\n * source: 'system',\n * payload: { taskId: createTaskId('task-1'), result: {}, duration: 5000 }\n * });\n *\n * // 구독 해제\n * unsub();\n * ```\n */\nexport class EventBus {\n private readonly options: Required<EventBusOptions>;\n private history: Event[];\n private stats: EventBusStats;\n private subscriptions: Set<Subscription<Event>>;\n private nextSubscriptionId = 0;\n /** 에러 이벤트 발행 중인지 체크 (재귀 방지) */\n private isEmittingError = false;\n\n constructor(options: EventBusOptions = {}) {\n this.options = {\n maxListeners: options.maxListeners ?? 100,\n throwOnAsyncError: options.throwOnAsyncError ?? false,\n emitErrorEvent: options.emitErrorEvent ?? true,\n historySize: options.historySize ?? 0,\n debug: options.debug ?? false,\n };\n this.history = [];\n this.stats = this.createInitialStats();\n this.subscriptions = new Set();\n }\n\n // === 구독 API ===\n\n /**\n * 이벤트 구독\n * @param eventType - 이벤트 타입 (와일드카드 지원: 'task.*', '*')\n * @param handler - 이벤트 핸들러\n * @returns 구독 해제 함수\n */\n subscribe<T extends EventType>(\n eventType: T | `${EventCategory}.*` | \"*\",\n handler: EventHandler<EventByType<T>>\n ): Unsubscribe {\n this.debugLog(`Subscribing to event type: ${eventType}`);\n\n const subscription: Subscription<Event> = {\n handler: handler as EventHandler<Event>,\n eventType,\n once: false,\n };\n\n this.subscriptions.add(subscription);\n this.updateSubscriberStats();\n\n return () => {\n this.subscriptions.delete(subscription);\n this.updateSubscriberStats();\n this.debugLog(`Unsubscribed from event type: ${eventType}`);\n };\n }\n\n /**\n * 필터와 함께 구독\n * @param eventType - 이벤트 타입\n * @param filter - 필터 조건\n * @param handler - 이벤트 핸들러\n * @returns 구독 해제 함수\n */\n subscribeWithFilter<T extends EventType>(\n eventType: T | `${EventCategory}.*` | \"*\",\n filter: EventFilter,\n handler: EventHandler<EventByType<T>>\n ): Unsubscribe {\n this.debugLog(`Subscribing with filter to event type: ${eventType}`, filter);\n\n const subscription: Subscription<Event> = {\n handler: handler as EventHandler<Event>,\n eventType,\n once: false,\n filter,\n };\n\n this.subscriptions.add(subscription);\n this.updateSubscriberStats();\n\n return () => {\n this.subscriptions.delete(subscription);\n this.updateSubscriberStats();\n this.debugLog(`Unsubscribed (with filter) from event type: ${eventType}`);\n };\n }\n\n /**\n * 일회성 구독\n * @param eventType - 이벤트 타입\n * @param handler - 이벤트 핸들러\n * @returns 구독 해제 함수\n */\n subscribeOnce<T extends EventType>(\n eventType: T,\n handler: EventHandler<EventByType<T>>\n ): Unsubscribe {\n this.debugLog(`Subscribing once to event type: ${eventType}`);\n\n const subscription: Subscription<Event> = {\n handler: handler as EventHandler<Event>,\n eventType,\n once: true,\n };\n\n this.subscriptions.add(subscription);\n this.updateSubscriberStats();\n\n return () => {\n this.subscriptions.delete(subscription);\n this.updateSubscriberStats();\n };\n }\n\n /**\n * 구독 해제\n * @param eventType - 이벤트 타입\n * @param handler - 제거할 핸들러\n */\n unsubscribe<T extends EventType>(\n eventType: T | `${EventCategory}.*` | \"*\",\n handler: EventHandler<EventByType<T>>\n ): void {\n for (const sub of this.subscriptions) {\n if (sub.eventType === eventType && sub.handler === handler) {\n this.subscriptions.delete(sub);\n this.updateSubscriberStats();\n this.debugLog(`Unsubscribed from event type: ${eventType}`);\n return;\n }\n }\n }\n\n /**\n * 모든 구독 해제\n * @param eventType - 특정 이벤트 타입만 해제 (선택)\n */\n unsubscribeAll<T extends EventType>(eventType?: T | `${EventCategory}.*` | \"*\"): void {\n if (eventType) {\n // 특정 타입의 구독만 해제\n const toRemove: Subscription<Event>[] = [];\n for (const sub of this.subscriptions) {\n if (sub.eventType === eventType) {\n toRemove.push(sub);\n }\n }\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n }\n this.debugLog(`Unsubscribed all from event type: ${eventType}`);\n } else {\n // 모든 구독 해제\n this.subscriptions.clear();\n this.debugLog(\"Unsubscribed all subscribers\");\n }\n this.updateSubscriberStats();\n }\n\n /**\n * 이벤트 버스 초기화 (히스토리만 지움, 구독자는 유지)\n */\n clear(): void {\n this.history = [];\n this.stats = this.createInitialStats();\n this.updateSubscriberStats();\n this.debugLog(\"EventBus history cleared\");\n }\n\n // === 발행 API ===\n\n /**\n * 이벤트 발행\n * @param event - 발행할 이벤트\n */\n emit<T extends Event>(event: T): void {\n this.debugLog(`Emitting event: ${event.type}`, event);\n\n // 통계 업데이트\n this.updateStats(event);\n\n // 히스토리에 추가\n this.addToHistory(event);\n\n // 구독자들에게 이벤트 전달\n const toRemove: Subscription<Event>[] = [];\n\n for (const sub of this.subscriptions) {\n // 패턴 매칭 확인\n if (!this.matchesPattern(sub.eventType, event.type)) {\n continue;\n }\n\n // 필터 확인\n if (sub.filter && !this.applyFilter(event, sub.filter)) {\n continue;\n }\n\n // 핸들러 실행\n try {\n const result = sub.handler(event);\n\n // 비동기 핸들러 처리\n if (result instanceof Promise) {\n result.catch((error) => {\n // 에러 이벤트 핸들러 실패 시 별도 경고 로그 (에러 이벤트 재발행 방지)\n if (event.type === \"system.error\") {\n console.warn(\"[EventBus] Error handler failed:\", error);\n // 에러 이벤트의 에러는 재발행하지 않음 (무한 루프 방지)\n } else {\n if (this.options.throwOnAsyncError) {\n throw error;\n }\n console.error(`Error in async event handler:`, error);\n\n // 에러 이벤트 발행\n if (this.options.emitErrorEvent) {\n this.emitError(error, event, sub.eventType);\n }\n }\n });\n }\n } catch (error) {\n console.error(`Error in event handler:`, error);\n\n // 에러 이벤트 발행\n if (this.options.emitErrorEvent) {\n this.emitError(error, event, sub.eventType);\n }\n }\n\n // 일회성 구독인 경우 제거 대기열에 추가\n if (sub.once) {\n toRemove.push(sub);\n }\n }\n\n // 일회성 구독 제거\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n this.updateSubscriberStats();\n }\n }\n\n /**\n * 이벤트 발행 (비동기 핸들러 완료 대기)\n * @param event - 발행할 이벤트\n * @returns 모든 핸들러 완료 시 resolve\n */\n async emitAsync<T extends Event>(event: T): Promise<void> {\n this.debugLog(`Emitting async event: ${event.type}`, event);\n\n // 통계 업데이트\n this.updateStats(event);\n\n // 히스토리에 추가\n this.addToHistory(event);\n\n // 구독자들에게 이벤트 전달 (비동기)\n const promises: Promise<unknown>[] = [];\n const toRemove: Subscription<Event>[] = [];\n\n for (const sub of this.subscriptions) {\n // 패턴 매칭 확인\n if (!this.matchesPattern(sub.eventType, event.type)) {\n continue;\n }\n\n // 필터 확인\n if (sub.filter && !this.applyFilter(event, sub.filter)) {\n continue;\n }\n\n // 핸들러 실행\n try {\n const result = sub.handler(event);\n\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n console.error(`Error in event handler:`, error);\n }\n\n // 일회성 구독인 경우 제거 대기열에 추가\n if (sub.once) {\n toRemove.push(sub);\n }\n }\n\n // 일회성 구독 제거\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n this.updateSubscriberStats();\n }\n\n // 모든 비동기 핸들러 완료 대기\n await Promise.allSettled(promises);\n }\n\n /**\n * 배치 이벤트 발행\n * @param events - 발행할 이벤트 목록\n */\n emitBatch(events: Event[]): void {\n this.debugLog(`Emitting batch of ${events.length} events`);\n\n for (const event of events) {\n this.emit(event);\n }\n }\n\n // === 히스토리 API ===\n\n /**\n * 이벤트 히스토리 조회\n * @param filter - 필터 조건\n * @param limit - 최대 개수\n * @returns 필터링된 이벤트 목록\n */\n getHistory(\n filter?: {\n type?: EventType | `${EventCategory}.*`;\n source?: AgentId | \"system\";\n since?: Date;\n until?: Date;\n limit?: number;\n },\n limitArg?: number\n ): Event[] {\n let events = this.history;\n\n // 타입 필터링\n if (filter?.type) {\n events = events.filter((e) => this.matchesPattern(filter.type!, e.type));\n }\n\n // 소스 필터링\n if (filter?.source) {\n events = events.filter((e) => e.source === filter.source);\n }\n\n // 시간 필터링\n if (filter?.since) {\n events = events.filter((e) => e.timestamp >= filter.since!);\n }\n\n if (filter?.until) {\n events = events.filter((e) => e.timestamp <= filter.until!);\n }\n\n // 제한 (filter.limit 또는 두 번째 인자 사용)\n const limit = filter?.limit ?? limitArg;\n if (limit !== undefined && limit > 0) {\n events = events.slice(-limit);\n }\n\n return events;\n }\n\n /**\n * 히스토리 재생\n * @description 지정된 이벤트들을 다시 발행\n * @param events - 재생할 이벤트 목록\n */\n replay(events: Event[]): void {\n this.debugLog(`Replaying ${events.length} events`);\n\n for (const event of events) {\n this.emit(event);\n }\n }\n\n /**\n * 히스토리 클리어\n */\n clearHistory(): void {\n this.history = [];\n this.debugLog(\"History cleared\");\n }\n\n // === 유틸리티 API ===\n\n /**\n * 통계 조회\n */\n getStats(): Readonly<EventBusStats> & { eventsByType: Record<string, number> } {\n const eventsByType: Record<string, number> = {};\n for (const [type, count] of this.stats.emittedByType.entries()) {\n eventsByType[type] = count;\n }\n\n return {\n totalEmitted: this.stats.totalEmitted,\n emittedByType: new Map(this.stats.emittedByType),\n subscriberCount: this.stats.subscriberCount,\n subscribersByType: new Map(this.stats.subscribersByType),\n eventsByType,\n };\n }\n\n /**\n * 모든 구독 해제\n */\n removeAllSubscribers(): void {\n this.subscriptions.clear();\n this.stats.subscriberCount = 0;\n this.stats.subscribersByType.clear();\n this.debugLog(\"All subscribers removed\");\n }\n\n /**\n * 특정 타입의 모든 구독 해제\n */\n removeSubscribersForType(eventType: EventType | `${EventCategory}.*` | \"*\"): void {\n const toRemove: Subscription<Event>[] = [];\n\n for (const sub of this.subscriptions) {\n if (sub.eventType === eventType) {\n toRemove.push(sub);\n }\n }\n\n for (const sub of toRemove) {\n this.subscriptions.delete(sub);\n }\n\n this.updateSubscriberStats();\n this.debugLog(`Removed all subscribers for event type: ${eventType}`);\n }\n\n /**\n * 이벤트 대기 (Promise 기반)\n * @param eventType - 대기할 이벤트 타입\n * @param timeout - 타임아웃 (ms)\n * @returns 발생한 이벤트\n */\n waitFor<T extends EventType>(\n eventType: T,\n timeout: number = 30000,\n predicate?: (event: EventByType<T>) => boolean\n ): Promise<EventByType<T>> {\n return new Promise((resolve, reject) => {\n let unsubscribe: Unsubscribe | null = null;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const cleanup = () => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n if (predicate) {\n // 필터가 있는 경우 subscribe 사용 (한 번만 호출)\n unsubscribe = this.subscribe(eventType, (event) => {\n if (predicate(event as EventByType<T>)) {\n cleanup();\n resolve(event as EventByType<T>);\n }\n });\n } else {\n // 필터가 없는 경우 subscribeOnce 사용\n unsubscribe = this.subscribeOnce(eventType, (event) => {\n cleanup();\n resolve(event as EventByType<T>);\n });\n }\n\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new EventTimeoutError(eventType, timeout));\n }, timeout);\n });\n }\n\n /**\n * 이벤트 대기 (조건 충족 시)\n * @param eventType - 대기할 이벤트 타입\n * @param predicate - 조건 함수\n * @param timeout - 타임아웃 (ms)\n */\n waitForCondition<T extends EventType>(\n eventType: T,\n predicate: (event: EventByType<T>) => boolean,\n timeout: number = 30000\n ): Promise<EventByType<T>> {\n return new Promise((resolve, reject) => {\n let unsubscribe: Unsubscribe | null = null;\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const cleanup = () => {\n if (unsubscribe) {\n unsubscribe();\n unsubscribe = null;\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n unsubscribe = this.subscribe(eventType, (event) => {\n const typedEvent = event as EventByType<T>;\n if (predicate(typedEvent)) {\n cleanup();\n resolve(typedEvent);\n }\n });\n\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new EventTimeoutError(eventType, timeout));\n }, timeout);\n });\n }\n\n // === 내부 메서드 ===\n\n /**\n * 에러 이벤트 발행\n * @description 핸들러 에러 발생 시 시스템 에러 이벤트 발행\n * @private\n */\n private emitError(error: unknown, originalEvent: Event, handlerEventType: string): void {\n // 재귀 방지: 이미 에러 이벤트 발행 중이면 추가 발행을 막음\n if (this.isEmittingError) {\n console.error(\"Suppressing recursive error event:\", error);\n return;\n }\n\n this.isEmittingError = true;\n try {\n // 에러 객체 정제 (민감 데이터 노출 방지)\n const sanitizedError = {\n message: error instanceof Error ? error.message : String(error),\n name: error instanceof Error ? error.name : \"Error\",\n stack: error instanceof Error ? error.stack : undefined,\n };\n\n const errorEvent = {\n id: `evt-error-${crypto.randomUUID()}`,\n type: \"system.error\" as const,\n timestamp: new Date(),\n source: \"system\" as const,\n payload: {\n code: \"EVENT_HANDLER_ERROR\",\n message: sanitizedError.message,\n details: {\n originalEventType: originalEvent.type,\n handlerEventType,\n error: sanitizedError,\n },\n },\n };\n\n // emit()을 통해서만 발행 (emit() 내에서 히스토리/통계 처리)\n this.emit(errorEvent as Event);\n } catch (e) {\n // 에러 이벤트 발행 자체가 실패하면 무시\n console.error(\"Failed to emit error event:\", e);\n } finally {\n this.isEmittingError = false;\n }\n }\n\n /**\n * 와일드카드 패턴 매칭\n * @param pattern - 패턴 (예: 'task.*')\n * @param eventType - 실제 이벤트 타입\n */\n private matchesPattern(pattern: string, eventType: string): boolean {\n if (pattern === \"*\") {\n return true;\n }\n\n if (pattern.endsWith(\"*\")) {\n const prefix = pattern.slice(0, -1); // '*' 제거\n return eventType.startsWith(prefix);\n }\n\n return pattern === eventType;\n }\n\n /**\n * 필터 적용\n * @param event - 이벤트\n * @param filter - 필터 조건\n */\n private applyFilter(event: Event, filter: EventFilter): boolean {\n if (filter.source && event.source !== filter.source) {\n return false;\n }\n\n if (filter.correlationId && event.correlationId !== filter.correlationId) {\n return false;\n }\n\n if (filter.predicate && !filter.predicate(event)) {\n return false;\n }\n\n return true;\n }\n\n /**\n * 히스토리에 이벤트 추가\n */\n private addToHistory(event: Event): void {\n if (this.options.historySize === 0) {\n return;\n }\n\n this.history.push(event);\n\n // 제한 초과 시 오래된 이벤트 제거\n if (this.history.length > this.options.historySize) {\n this.history.shift();\n }\n }\n\n /**\n * 통계 업데이트\n */\n private updateStats(event: Event): void {\n this.stats.totalEmitted++;\n\n const current = this.stats.emittedByType.get(event.type) ?? 0;\n this.stats.emittedByType.set(event.type, current + 1);\n }\n\n /**\n * 구독자 통계 업데이트\n */\n private updateSubscriberStats(): void {\n this.stats.subscriberCount = this.subscriptions.size;\n\n // 타입별 구독자 수 계산\n const countByType = new Map<string, number>();\n for (const sub of this.subscriptions) {\n const current = countByType.get(sub.eventType) ?? 0;\n countByType.set(sub.eventType, current + 1);\n }\n\n this.stats.subscribersByType = countByType;\n }\n\n /**\n * 초기 통계 생성\n */\n private createInitialStats(): EventBusStats {\n return {\n totalEmitted: 0,\n emittedByType: new Map(),\n subscriberCount: 0,\n subscribersByType: new Map(),\n };\n }\n\n /**\n * 디버그 로그\n */\n private debugLog(message: string, data?: unknown): void {\n if (this.options.debug) {\n if (data !== undefined) {\n console.debug(`[EventBus] ${message}`, data);\n } else {\n console.debug(`[EventBus] ${message}`);\n }\n }\n }\n}\n","import type { Event } from './events';\nimport { EventBus, type Unsubscribe } from './events';\nimport { createAgentId } from './types';\nimport { createNodeId, type IProductionPromotionPort, type TemporalNode } from './types/tkg';\nimport type { InMemoryStagingTKG } from '../_legacy/blackboard/domains/tkg/InMemoryTKG';\n\nexport interface ObserverOptions {\n readonly stagingThreshold?: number;\n}\n\nexport class TKGObserver {\n private readonly stagingThreshold: number;\n private unsubscribeFromSource: Unsubscribe | null = null;\n\n constructor(\n private readonly staging: InMemoryStagingTKG,\n private readonly eventBus = new EventBus(),\n options: ObserverOptions = {},\n ) {\n this.stagingThreshold = options.stagingThreshold ?? 0.3;\n }\n\n subscribeTo(eventPattern: string = '*'): void {\n this.unsubscribeFromSource?.();\n this.unsubscribeFromSource = (this.eventBus.subscribe as (type: string, handler: (event: Event) => void) => Unsubscribe)(\n eventPattern,\n (event: Event) => {\n if (event.type.startsWith('tkg.')) return;\n this.observe(event);\n },\n );\n }\n\n stopSubscription(): void {\n this.unsubscribeFromSource?.();\n this.unsubscribeFromSource = null;\n }\n\n observe(event: Event): TemporalNode | null {\n const node = this.mapEventToNode(event);\n if (node.confidence < this.stagingThreshold) {\n this.eventBus.emit({\n id: `evt-tkg-observer-${crypto.randomUUID()}`,\n type: 'tkg.observer.validation.failed',\n source: 'system',\n timestamp: new Date(),\n payload: { nodeId: node.id, confidence: node.confidence },\n } as unknown as Event);\n return null;\n }\n\n this.staging.addNode(node);\n this.eventBus.emit({\n id: `evt-tkg-observer-${crypto.randomUUID()}`,\n type: 'tkg.observer.node.added',\n source: 'system',\n timestamp: new Date(),\n payload: { node },\n } as unknown as Event);\n\n return node;\n }\n\n private mapEventToNode(event: Event): TemporalNode {\n const timestamp = event.timestamp ?? new Date();\n const eventPayload = event as unknown as { payload?: unknown };\n const payloadStatement =\n typeof eventPayload.payload === 'object' && eventPayload.payload !== null\n ? (eventPayload.payload as { statement?: unknown }).statement\n : undefined;\n\n let context = '{}';\n try {\n context = JSON.stringify(eventPayload.payload ?? {});\n } catch {\n context = '[unserializable payload]';\n }\n\n return {\n id: createNodeId(`tkg-${event.id}`),\n type: 'fact',\n valid_from: timestamp,\n observed_at: timestamp,\n updated_at: timestamp,\n confidence: this.deriveConfidence(eventPayload.payload),\n source: event.source === 'system' ? createAgentId('system') : event.source,\n version: 1,\n tags: [event.type],\n data: {\n statement: typeof payloadStatement === 'string' && payloadStatement.length > 0 ? payloadStatement : event.type,\n verified: false,\n context,\n },\n };\n }\n\n private deriveConfidence(payload: unknown): number {\n if (!payload || typeof payload !== 'object') {\n return 0.5;\n }\n\n const maybeConfidence = (payload as { confidence?: unknown }).confidence;\n return typeof maybeConfidence === 'number' ? Math.max(0, Math.min(1, maybeConfidence)) : 0.7;\n }\n}\n\nexport type ConflictType = 'contradiction' | 'version' | 'confidence';\nexport type ResolutionPolicy = 'auto' | 'manual' | 'defer';\n\nexport interface ConflictResolutionPolicy {\n readonly contradiction?: ResolutionPolicy;\n readonly version?: ResolutionPolicy;\n readonly confidence?: ResolutionPolicy;\n}\n\nexport interface ReflectorOptions {\n readonly minConfidence?: number;\n readonly autoResolveConfidenceGap?: number;\n readonly conflictPolicy?: ConflictResolutionPolicy;\n readonly rollbackSnapshotDepth?: number;\n readonly reportHistoryDepth?: number;\n readonly stateStore?: ReflectorStateStore;\n}\n\nexport interface ReflectorOperationalMetrics {\n readonly totalMerges: number;\n readonly totalConflicts: number;\n readonly autoResolved: number;\n readonly deferred: number;\n readonly manualReview: number;\n readonly rollbacks: number;\n}\n\nexport interface ReflectorOperationalReport {\n readonly generatedAt: Date;\n readonly mergeId: string;\n readonly promoted: number;\n readonly blockedByConflict: number;\n readonly conflictSummary: Record<ConflictType, number>;\n readonly policySummary: Record<ResolutionPolicy, number>;\n}\n\nexport interface ManualReviewItem {\n readonly id: string;\n readonly conflictType: ConflictType;\n readonly nodeIds: readonly string[];\n readonly queuedAt: Date;\n}\n\nexport interface ReflectorPersistedState {\n readonly metrics: ReflectorOperationalMetrics;\n readonly manualReviewQueue: readonly ManualReviewItem[];\n readonly deferredQueue: readonly ManualReviewItem[];\n readonly reportHistory: readonly ReflectorOperationalReport[];\n readonly rollbackSnapshots: readonly { mergeId: string; nodes: readonly TemporalNode[] }[];\n}\n\nexport interface ReflectorStateStore {\n load(): ReflectorPersistedState | null;\n save(state: ReflectorPersistedState): void;\n}\n\nexport class TKGReflector {\n private readonly minConfidence: number;\n private readonly autoResolveConfidenceGap: number;\n private readonly conflictPolicy: Record<ConflictType, ResolutionPolicy>;\n private readonly rollbackSnapshotDepth: number;\n private readonly reportHistoryDepth: number;\n private readonly stateStore?: ReflectorStateStore;\n private metrics: ReflectorOperationalMetrics = {\n totalMerges: 0,\n totalConflicts: 0,\n autoResolved: 0,\n deferred: 0,\n manualReview: 0,\n rollbacks: 0,\n };\n private lastReport: ReflectorOperationalReport | null = null;\n private readonly manualReviewQueue: ManualReviewItem[] = [];\n private readonly deferredQueue: ManualReviewItem[] = [];\n private readonly rollbackSnapshots = new Map<string, readonly TemporalNode[]>();\n private readonly reportHistory: ReflectorOperationalReport[] = [];\n\n constructor(private readonly eventBus = new EventBus(), options: ReflectorOptions = {}) {\n this.minConfidence = options.minConfidence ?? 0.7;\n this.autoResolveConfidenceGap = options.autoResolveConfidenceGap ?? 0.2;\n this.conflictPolicy = {\n contradiction: options.conflictPolicy?.contradiction ?? 'manual',\n version: options.conflictPolicy?.version ?? 'manual',\n confidence: options.conflictPolicy?.confidence ?? 'auto',\n };\n this.rollbackSnapshotDepth = Math.max(1, options.rollbackSnapshotDepth ?? 20);\n this.reportHistoryDepth = Math.max(1, options.reportHistoryDepth ?? 50);\n this.stateStore = options.stateStore;\n\n const loaded = this.stateStore?.load();\n if (loaded) {\n this.importOperationalState(loaded);\n }\n }\n\n reflect(staging: InMemoryStagingTKG, production: IProductionPromotionPort) {\n this.eventBus.emit({\n id: `evt-tkg-reflector-${crypto.randomUUID()}`,\n type: 'tkg.reflector.merge.started',\n source: 'system',\n timestamp: new Date(),\n payload: {},\n } as unknown as Event);\n\n const candidates = Array.from(staging.nodes.values());\n const eligible = candidates.filter((node) => node.confidence >= this.minConfidence);\n const conflicts = this.detectConflicts(candidates);\n const resolution = this.resolveConflicts(conflicts);\n const mergeSnapshot = Array.from(staging.nodes.values());\n const blockedNodeIds = new Set(resolution.blockedNodeIds);\n const nodes = eligible.filter((node) => !blockedNodeIds.has(node.id));\n\n const mergeResult = production.promoteBatch({ nodes, edges: [], meta: { promotedBy: 'reflector' } });\n this.rollbackSnapshots.set(mergeResult.mergeId, mergeSnapshot);\n this.pruneRollbackSnapshots();\n\n this.metrics = {\n ...this.metrics,\n totalMerges: this.metrics.totalMerges + 1,\n totalConflicts: this.metrics.totalConflicts + conflicts.length,\n autoResolved: this.metrics.autoResolved + resolution.policySummary.auto,\n deferred: this.metrics.deferred + resolution.policySummary.defer,\n manualReview: this.metrics.manualReview + resolution.policySummary.manual,\n };\n\n this.lastReport = {\n generatedAt: new Date(),\n mergeId: mergeResult.mergeId,\n promoted: nodes.length,\n blockedByConflict: blockedNodeIds.size,\n conflictSummary: this.summarizeConflicts(conflicts),\n policySummary: resolution.policySummary,\n };\n this.reportHistory.push(this.lastReport);\n this.pruneReportHistory();\n this.persistOperationalState();\n\n this.eventBus.emit({\n id: `evt-tkg-reflector-${crypto.randomUUID()}`,\n type: 'tkg.reflector.merge.completed',\n source: 'system',\n timestamp: new Date(),\n payload: { ...mergeResult, report: this.lastReport, metrics: this.metrics },\n } as unknown as Event);\n\n return mergeResult;\n }\n\n detectConflicts(nodes: readonly TemporalNode[]) {\n const conflicts: Array<{ left: TemporalNode; right: TemporalNode; type: ConflictType }> = [];\n\n for (let i = 0; i < nodes.length; i += 1) {\n for (let j = i + 1; j < nodes.length; j += 1) {\n const left = nodes[i];\n const right = nodes[j];\n const sameStatement =\n left.type === 'fact' &&\n right.type === 'fact' &&\n 'statement' in left.data &&\n 'statement' in right.data &&\n left.data.statement === right.data.statement;\n\n if (!sameStatement) continue;\n\n if (left.data.verified !== right.data.verified) {\n conflicts.push({ left, right, type: 'contradiction' });\n } else if (left.version !== right.version) {\n conflicts.push({ left, right, type: 'version' });\n } else if (Math.abs(left.confidence - right.confidence) > this.autoResolveConfidenceGap) {\n conflicts.push({ left, right, type: 'confidence' });\n }\n }\n }\n\n return conflicts;\n }\n\n getOperationalMetrics(): ReflectorOperationalMetrics {\n return { ...this.metrics };\n }\n\n getLastReport(): ReflectorOperationalReport | null {\n return this.lastReport ? { ...this.lastReport, generatedAt: new Date(this.lastReport.generatedAt) } : null;\n }\n\n getManualReviewQueue(): readonly ManualReviewItem[] {\n return this.manualReviewQueue.map((item) => ({ ...item, nodeIds: [...item.nodeIds], queuedAt: new Date(item.queuedAt) }));\n }\n\n getDeferredQueue(): readonly ManualReviewItem[] {\n return this.deferredQueue.map((item) => ({ ...item, nodeIds: [...item.nodeIds], queuedAt: new Date(item.queuedAt) }));\n }\n\n getReportHistory(): readonly ReflectorOperationalReport[] {\n return this.reportHistory.map((report) => ({ ...report, generatedAt: new Date(report.generatedAt) }));\n }\n\n resolveManualReview(nodeId: string): boolean {\n const index = this.manualReviewQueue.findIndex((item) => item.nodeIds.includes(nodeId));\n if (index < 0) return false;\n this.manualReviewQueue.splice(index, 1);\n this.persistOperationalState();\n return true;\n }\n\n resolveManualReviewById(itemId: string): boolean {\n const index = this.manualReviewQueue.findIndex((item) => item.id === itemId);\n if (index < 0) return false;\n this.manualReviewQueue.splice(index, 1);\n this.persistOperationalState();\n return true;\n }\n\n resolveDeferred(nodeId: string): boolean {\n const index = this.deferredQueue.findIndex((item) => item.nodeIds.includes(nodeId));\n if (index < 0) return false;\n this.deferredQueue.splice(index, 1);\n this.persistOperationalState();\n return true;\n }\n\n resolveDeferredById(itemId: string): boolean {\n const index = this.deferredQueue.findIndex((item) => item.id === itemId);\n if (index < 0) return false;\n this.deferredQueue.splice(index, 1);\n this.persistOperationalState();\n return true;\n }\n\n exportOperationalState(): ReflectorPersistedState {\n return {\n metrics: { ...this.metrics },\n manualReviewQueue: this.getManualReviewQueue(),\n deferredQueue: this.getDeferredQueue(),\n reportHistory: this.getReportHistory(),\n rollbackSnapshots: Array.from(this.rollbackSnapshots.entries()).map(([mergeId, nodes]) => ({ mergeId, nodes: [...nodes] })),\n };\n }\n\n importOperationalState(state: ReflectorPersistedState): void {\n this.metrics = { ...state.metrics };\n this.manualReviewQueue.splice(0, this.manualReviewQueue.length, ...state.manualReviewQueue.map((item) => ({\n ...item,\n nodeIds: [...item.nodeIds],\n queuedAt: new Date(item.queuedAt),\n })));\n this.deferredQueue.splice(0, this.deferredQueue.length, ...state.deferredQueue.map((item) => ({\n ...item,\n nodeIds: [...item.nodeIds],\n queuedAt: new Date(item.queuedAt),\n })));\n this.reportHistory.splice(0, this.reportHistory.length, ...state.reportHistory.map((report) => ({\n ...report,\n generatedAt: new Date(report.generatedAt),\n })));\n this.rollbackSnapshots.clear();\n for (const snapshot of state.rollbackSnapshots ?? []) {\n this.rollbackSnapshots.set(snapshot.mergeId, [...snapshot.nodes]);\n }\n this.pruneReportHistory();\n this.pruneRollbackSnapshots();\n this.lastReport = this.reportHistory.at(-1) ?? null;\n this.persistOperationalState();\n }\n\n rollback(staging: InMemoryStagingTKG, mergeResultId?: string) {\n const timestamp = new Date();\n const before = Array.from(staging.nodes.values()).length;\n const snapshot = mergeResultId ? this.rollbackSnapshots.get(mergeResultId) : undefined;\n\n if (mergeResultId && !snapshot) {\n return { mergeResultId, rolledBack: 0, timestamp };\n }\n\n if (snapshot) {\n staging.restoreNodes(snapshot);\n } else {\n staging.clearNodes();\n }\n\n this.metrics = { ...this.metrics, rollbacks: this.metrics.rollbacks + 1 };\n this.persistOperationalState();\n\n return {\n mergeResultId,\n rolledBack: snapshot ? snapshot.length : before,\n timestamp,\n };\n }\n\n private persistOperationalState(): void {\n this.stateStore?.save(this.exportOperationalState());\n }\n\n private pruneRollbackSnapshots(): void {\n while (this.rollbackSnapshots.size > this.rollbackSnapshotDepth) {\n const oldest = this.rollbackSnapshots.keys().next().value;\n if (!oldest) break;\n this.rollbackSnapshots.delete(oldest);\n }\n }\n\n private pruneReportHistory(): void {\n while (this.reportHistory.length > this.reportHistoryDepth) {\n this.reportHistory.shift();\n }\n }\n\n private summarizeConflicts(conflicts: Array<{ left: TemporalNode; right: TemporalNode; type: ConflictType }>) {\n return conflicts.reduce<Record<ConflictType, number>>(\n (acc, conflict) => ({ ...acc, [conflict.type]: acc[conflict.type] + 1 }),\n { contradiction: 0, version: 0, confidence: 0 },\n );\n }\n\n private resolveConflicts(conflicts: Array<{ left: TemporalNode; right: TemporalNode; type: ConflictType }>) {\n const blockedNodeIds = new Set<string>();\n const policySummary: Record<ResolutionPolicy, number> = { auto: 0, manual: 0, defer: 0 };\n\n for (const conflict of conflicts) {\n const policy = this.conflictPolicy[conflict.type];\n policySummary[policy] += 1;\n\n if (policy === 'auto') {\n const winner = this.pickAutoResolvedWinner(conflict);\n const loser = winner.id === conflict.left.id ? conflict.right : conflict.left;\n blockedNodeIds.add(loser.id);\n continue;\n }\n\n const reviewItem: ManualReviewItem = {\n id: `review-${crypto.randomUUID()}`,\n conflictType: conflict.type,\n nodeIds: [conflict.left.id, conflict.right.id],\n queuedAt: new Date(),\n };\n\n if (policy === 'manual') {\n this.manualReviewQueue.push(reviewItem);\n }\n\n if (policy === 'defer') {\n this.deferredQueue.push(reviewItem);\n }\n\n blockedNodeIds.add(conflict.left.id);\n blockedNodeIds.add(conflict.right.id);\n }\n\n return { blockedNodeIds, policySummary };\n }\n\n private pickAutoResolvedWinner(conflict: { left: TemporalNode; right: TemporalNode; type: ConflictType }) {\n if (conflict.type === 'version') {\n return conflict.left.version >= conflict.right.version ? conflict.left : conflict.right;\n }\n\n return conflict.left.confidence >= conflict.right.confidence ? conflict.left : conflict.right;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAAA;AAAA,EAAA,uBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAAC;AAAA,EAAA;AAAA,wBAAAC;AAAA,EAAA,sBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAAC;AAAA,EAAA,oBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["Blackboard","MessageType","NoOpMessageBus","TKGObserver","TKGReflector","createSessionId","now","resolve","resolve","path","resolve","NoOpMessageBus","NoOpMessageBus","now","resolve","NoOpMessageBus","path","import_node_crypto","OboraErrorCode","path","path","isObject","getExpressionAst","relative","path","MAX_CACHE_SIZE","expressionCache","getExpressionAst","now","path","delay","resolve","path","AgentStatusEnum","TaskStatus","TaskPriority","AgendaStatus","MessageType","now","now","updatedAgenda","createHash","path","now","parsePath","path","getByPath","result","Blackboard","path","now","now","resolve","now","path","isObject","path","isObject","getStepName","stableStringify","isObject","diffReport","resolve","path","import_node_path","import_events","RestartStrategy","RestartDirective","BackoffPolicy","now","delay","resolve","resolve","delay","import_node_crypto","import_yaml","path","path","parseYaml","ValidationErrorCode","Ajv","addFormats","path","import_node_crypto","import_node_crypto","defaultWait","resolve","record","parseConfig","path","resolve","formatOutput","delay","Blackboard","path","import_node_fs","import_yaml","parseYaml","now","now","parseTimeoutToMs","clampScore","now","ranked","DEFAULT_MAX_ROUNDS","parseTimeoutToMs","now","resolveStartTime","import_node_crypto","DEFAULT_MAX_ROUNDS","DEFAULT_CONVERGENCE","redTeam","blueTeam","import_node_path","path","import_promises","import_node_path","path","fs","import_promises","import_node_path","rows","import_node_crypto","import_promises","import_node_path","path","import_node_fs","import_promises","import_node_path","AgentRole","AgentState","MeetingPhase","parsed","_type","safeParsed","parsed","_type","safeParsed","parsed","_type","safeParsed","resolve","import_node_crypto","clampScore","noopLogger","createAgentId","createAgendaId","createSessionId","createOpinionId","DEFAULT_VERSIONING_CONFIG","VersionConflictError","path","VersionManager","delay","resolve","defaultVersionManager","deepClone","mapToObject","objectToMap","VALID_SECTIONS","DANGEROUS_KEYS","isValidSection","validatePathSegments","getByPath","path","setByPath","deepClone","deleteByPath","parsePath","normalizePath","isValidPath","createNodeId","StateSectionAccessor","PathNotFoundError","BlackboardError","KnowledgeSectionAccessor","BlackboardError","now","DecisionsSectionAccessor","BlackboardError","now","createAgendaId","createOpinionId","updatedAgenda","SNAPSHOT_FORMAT_VERSION","createDefaultId","createIdGenerator","import_pako","normalizeCompressionLevel","stringToUint8Array","uint8ArrayToString","uint8ArrayToBase64","base64ToUint8Array","inputToUint8Array","formatOutput","inputToUint8ArrayForDecompress","compress","inputToUint8Array","normalizeCompressionLevel","formatOutput","uint8ArrayToBase64","decompress","inputToUint8ArrayForDecompress","uint8ArrayToString","detectCompression","base64ToUint8Array","isSerializedState","sortedKeyReplacer","decompressSnapshotData","isSerializedState","detectCompression","decompress","validateFactArray","validateInferenceArray","validatePatternArray","validateResolutionArray","validateAgenda","StateSerializer","sortedKeyReplacer","calculateChecksumNodeJS","createHash","calculateChecksum","verifyChecksum","calculateChecksumSync","verifyChecksumSync","SnapshotCreator","StateSerializer","createIdGenerator","calculateChecksumSync","compress","SNAPSHOT_FORMAT_VERSION","SnapshotValidator","StateSerializer","verifyChecksum","detectCompression","decompressSnapshotData","verifyChecksumSync","SNAPSHOT_FORMAT_VERSION","decompress","isSerializedState","SnapshotRestoreError","SnapshotRestorer","StateSerializer","SnapshotValidator","createIdGenerator","decompressSnapshotData","SnapshotSerializer","SnapshotComparer","sortedKeyReplacer","decompressSnapshotData","SnapshotManager","SnapshotCreator","SnapshotValidator","SnapshotRestorer","SnapshotSerializer","SnapshotComparer","SimpleEventEmitter","PathNotFoundError","path","BlackboardError","Blackboard","SimpleEventEmitter","VersionManager","SnapshotManager","StateSectionAccessor","KnowledgeSectionAccessor","DecisionsSectionAccessor","createSessionId","now","deepClone","getByPath","isValidPath","setByPath","deleteByPath","mapToObject","objectToMap","EventTimeoutError","EventBus","resolve","TKGObserver","EventBus","createNodeId","createAgentId","TKGReflector"]}
|