@namzu/sdk 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -5
- package/README.md +14 -9
- package/dist/agents/ReactiveAgent.d.ts.map +1 -1
- package/dist/agents/ReactiveAgent.js +5 -3
- package/dist/agents/ReactiveAgent.js.map +1 -1
- package/dist/agents/RouterAgent.d.ts.map +1 -1
- package/dist/agents/RouterAgent.js +3 -0
- package/dist/agents/RouterAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js +18 -5
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +6 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/a2a/task.d.ts +2 -2
- package/dist/bridge/a2a/task.d.ts.map +1 -1
- package/dist/bridge/a2a/task.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +6 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/constants/a2a/index.d.ts +2 -2
- package/dist/constants/a2a/index.d.ts.map +1 -1
- package/dist/constants/a2a/index.js.map +1 -1
- package/dist/contracts/api.d.ts +22 -3
- package/dist/contracts/api.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +3 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js.map +1 -1
- package/dist/gateway/local.d.ts.map +1 -1
- package/dist/gateway/local.js +6 -0
- package/dist/gateway/local.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/manager/agent/__tests__/lifecycle.test.d.ts +2 -0
- package/dist/manager/agent/__tests__/lifecycle.test.d.ts.map +1 -0
- package/dist/manager/agent/__tests__/lifecycle.test.js +302 -0
- package/dist/manager/agent/__tests__/lifecycle.test.js.map +1 -0
- package/dist/manager/agent/lifecycle.d.ts +58 -3
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +311 -12
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/run/persistence.d.ts +8 -1
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +15 -0
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/run/reporter.d.ts.map +1 -1
- package/dist/run/reporter.js +25 -0
- package/dist/run/reporter.js.map +1 -1
- package/dist/runtime/query/__tests__/context.test.d.ts +2 -0
- package/dist/runtime/query/__tests__/context.test.d.ts.map +1 -0
- package/dist/runtime/query/__tests__/context.test.js +84 -0
- package/dist/runtime/query/__tests__/context.test.js.map +1 -0
- package/dist/runtime/query/context.d.ts +55 -2
- package/dist/runtime/query/context.d.ts.map +1 -1
- package/dist/runtime/query/context.js +48 -8
- package/dist/runtime/query/context.js.map +1 -1
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +8 -0
- package/dist/runtime/query/events.js.map +1 -1
- package/dist/runtime/query/index.d.ts +25 -2
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +11 -1
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/session/__tests__/integration/_fixtures.d.ts +115 -0
- package/dist/session/__tests__/integration/_fixtures.d.ts.map +1 -0
- package/dist/session/__tests__/integration/_fixtures.js +198 -0
- package/dist/session/__tests__/integration/_fixtures.js.map +1 -0
- package/dist/session/__tests__/integration/capacity-caps.test.d.ts +13 -0
- package/dist/session/__tests__/integration/capacity-caps.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/capacity-caps.test.js +116 -0
- package/dist/session/__tests__/integration/capacity-caps.test.js.map +1 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.d.ts +18 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.js +226 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.js.map +1 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts +15 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.js +323 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts +12 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js +170 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts +18 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.js +146 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts +15 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js +163 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts +12 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js +157 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js.map +1 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.d.ts +11 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.js +140 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.js.map +1 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts +13 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.js +84 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.js.map +1 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts +14 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.js +241 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.js.map +1 -0
- package/dist/session/__tests__/integration/retention-archive.test.d.ts +12 -0
- package/dist/session/__tests__/integration/retention-archive.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/retention-archive.test.js +186 -0
- package/dist/session/__tests__/integration/retention-archive.test.js.map +1 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts +18 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.js +200 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.d.ts +14 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.js +180 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.js.map +1 -0
- package/dist/session/errors.d.ts +60 -0
- package/dist/session/errors.d.ts.map +1 -0
- package/dist/session/errors.js +50 -0
- package/dist/session/errors.js.map +1 -0
- package/dist/session/events/index.d.ts +4 -0
- package/dist/session/events/index.d.ts.map +1 -0
- package/dist/session/events/index.js +8 -0
- package/dist/session/events/index.js.map +1 -0
- package/dist/session/events/schema-version.d.ts +13 -0
- package/dist/session/events/schema-version.d.ts.map +1 -0
- package/dist/session/events/schema-version.js +12 -0
- package/dist/session/events/schema-version.js.map +1 -0
- package/dist/session/events/types.d.ts +64 -0
- package/dist/session/events/types.d.ts.map +1 -0
- package/dist/session/events/types.js +2 -0
- package/dist/session/events/types.js.map +1 -0
- package/dist/session/handoff/__tests__/broadcast.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/broadcast.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/broadcast.test.js +243 -0
- package/dist/session/handoff/__tests__/broadcast.test.js.map +1 -0
- package/dist/session/handoff/__tests__/capacity.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/capacity.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/capacity.test.js +100 -0
- package/dist/session/handoff/__tests__/capacity.test.js.map +1 -0
- package/dist/session/handoff/__tests__/single.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/single.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/single.test.js +230 -0
- package/dist/session/handoff/__tests__/single.test.js.map +1 -0
- package/dist/session/handoff/assignment.d.ts +59 -0
- package/dist/session/handoff/assignment.d.ts.map +1 -0
- package/dist/session/handoff/assignment.js +11 -0
- package/dist/session/handoff/assignment.js.map +1 -0
- package/dist/session/handoff/broadcast.d.ts +47 -0
- package/dist/session/handoff/broadcast.d.ts.map +1 -0
- package/dist/session/handoff/broadcast.js +296 -0
- package/dist/session/handoff/broadcast.js.map +1 -0
- package/dist/session/handoff/capacity.d.ts +66 -0
- package/dist/session/handoff/capacity.d.ts.map +1 -0
- package/dist/session/handoff/capacity.js +60 -0
- package/dist/session/handoff/capacity.js.map +1 -0
- package/dist/session/handoff/events.d.ts +66 -0
- package/dist/session/handoff/events.d.ts.map +1 -0
- package/dist/session/handoff/events.js +13 -0
- package/dist/session/handoff/events.js.map +1 -0
- package/dist/session/handoff/index.d.ts +12 -0
- package/dist/session/handoff/index.d.ts.map +1 -0
- package/dist/session/handoff/index.js +9 -0
- package/dist/session/handoff/index.js.map +1 -0
- package/dist/session/handoff/single.d.ts +62 -0
- package/dist/session/handoff/single.d.ts.map +1 -0
- package/dist/session/handoff/single.js +217 -0
- package/dist/session/handoff/single.js.map +1 -0
- package/dist/session/handoff/version.d.ts +52 -0
- package/dist/session/handoff/version.d.ts.map +1 -0
- package/dist/session/handoff/version.js +36 -0
- package/dist/session/handoff/version.js.map +1 -0
- package/dist/session/hierarchy/__tests__/session.test.d.ts +2 -0
- package/dist/session/hierarchy/__tests__/session.test.d.ts.map +1 -0
- package/dist/session/hierarchy/__tests__/session.test.js +67 -0
- package/dist/session/hierarchy/__tests__/session.test.js.map +1 -0
- package/dist/session/hierarchy/actor.d.ts +26 -0
- package/dist/session/hierarchy/actor.d.ts.map +1 -0
- package/dist/session/hierarchy/actor.js +2 -0
- package/dist/session/hierarchy/actor.js.map +1 -0
- package/dist/session/hierarchy/index.d.ts +8 -0
- package/dist/session/hierarchy/index.d.ts.map +1 -0
- package/dist/session/hierarchy/index.js +4 -0
- package/dist/session/hierarchy/index.js.map +1 -0
- package/dist/session/hierarchy/lineage.d.ts +15 -0
- package/dist/session/hierarchy/lineage.d.ts.map +1 -0
- package/dist/session/hierarchy/lineage.js +2 -0
- package/dist/session/hierarchy/lineage.js.map +1 -0
- package/dist/session/hierarchy/project.d.ts +40 -0
- package/dist/session/hierarchy/project.d.ts.map +1 -0
- package/dist/session/hierarchy/project.js +2 -0
- package/dist/session/hierarchy/project.js.map +1 -0
- package/dist/session/hierarchy/session.d.ts +59 -0
- package/dist/session/hierarchy/session.d.ts.map +1 -0
- package/dist/session/hierarchy/session.js +51 -0
- package/dist/session/hierarchy/session.js.map +1 -0
- package/dist/session/hierarchy/sub-session.d.ts +76 -0
- package/dist/session/hierarchy/sub-session.d.ts.map +1 -0
- package/dist/session/hierarchy/sub-session.js +2 -0
- package/dist/session/hierarchy/sub-session.js.map +1 -0
- package/dist/session/hierarchy/tenant.d.ts +13 -0
- package/dist/session/hierarchy/tenant.d.ts.map +1 -0
- package/dist/session/hierarchy/tenant.js +2 -0
- package/dist/session/hierarchy/tenant.js.map +1 -0
- package/dist/session/index.d.ts +10 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +15 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.d.ts +2 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.d.ts.map +1 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.js +179 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.js.map +1 -0
- package/dist/session/intervention/index.d.ts +3 -0
- package/dist/session/intervention/index.d.ts.map +1 -0
- package/dist/session/intervention/index.js +8 -0
- package/dist/session/intervention/index.js.map +1 -0
- package/dist/session/intervention/prev-artifact.d.ts +103 -0
- package/dist/session/intervention/prev-artifact.d.ts.map +1 -0
- package/dist/session/intervention/prev-artifact.js +112 -0
- package/dist/session/intervention/prev-artifact.js.map +1 -0
- package/dist/session/migration/__tests__/filesystem.test.d.ts +2 -0
- package/dist/session/migration/__tests__/filesystem.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/filesystem.test.js +188 -0
- package/dist/session/migration/__tests__/filesystem.test.js.map +1 -0
- package/dist/session/migration/__tests__/id-prefix.test.d.ts +2 -0
- package/dist/session/migration/__tests__/id-prefix.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/id-prefix.test.js +83 -0
- package/dist/session/migration/__tests__/id-prefix.test.js.map +1 -0
- package/dist/session/migration/__tests__/marker.test.d.ts +2 -0
- package/dist/session/migration/__tests__/marker.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/marker.test.js +75 -0
- package/dist/session/migration/__tests__/marker.test.js.map +1 -0
- package/dist/session/migration/errors.d.ts +26 -0
- package/dist/session/migration/errors.d.ts.map +1 -0
- package/dist/session/migration/errors.js +22 -0
- package/dist/session/migration/errors.js.map +1 -0
- package/dist/session/migration/filesystem.d.ts +94 -0
- package/dist/session/migration/filesystem.d.ts.map +1 -0
- package/dist/session/migration/filesystem.js +319 -0
- package/dist/session/migration/filesystem.js.map +1 -0
- package/dist/session/migration/id-prefix.d.ts +98 -0
- package/dist/session/migration/id-prefix.d.ts.map +1 -0
- package/dist/session/migration/id-prefix.js +116 -0
- package/dist/session/migration/id-prefix.js.map +1 -0
- package/dist/session/migration/index.d.ts +8 -0
- package/dist/session/migration/index.d.ts.map +1 -0
- package/dist/session/migration/index.js +8 -0
- package/dist/session/migration/index.js.map +1 -0
- package/dist/session/migration/marker.d.ts +57 -0
- package/dist/session/migration/marker.d.ts.map +1 -0
- package/dist/session/migration/marker.js +111 -0
- package/dist/session/migration/marker.js.map +1 -0
- package/dist/session/retention/__tests__/archive.test.d.ts +2 -0
- package/dist/session/retention/__tests__/archive.test.d.ts.map +1 -0
- package/dist/session/retention/__tests__/archive.test.js +252 -0
- package/dist/session/retention/__tests__/archive.test.js.map +1 -0
- package/dist/session/retention/__tests__/disk-backend.test.d.ts +2 -0
- package/dist/session/retention/__tests__/disk-backend.test.d.ts.map +1 -0
- package/dist/session/retention/__tests__/disk-backend.test.js +154 -0
- package/dist/session/retention/__tests__/disk-backend.test.js.map +1 -0
- package/dist/session/retention/archive-backend-ref.d.ts +18 -0
- package/dist/session/retention/archive-backend-ref.d.ts.map +1 -0
- package/dist/session/retention/archive-backend-ref.js +2 -0
- package/dist/session/retention/archive-backend-ref.js.map +1 -0
- package/dist/session/retention/archive.d.ts +130 -0
- package/dist/session/retention/archive.d.ts.map +1 -0
- package/dist/session/retention/archive.js +203 -0
- package/dist/session/retention/archive.js.map +1 -0
- package/dist/session/retention/backend.d.ts +101 -0
- package/dist/session/retention/backend.d.ts.map +1 -0
- package/dist/session/retention/backend.js +15 -0
- package/dist/session/retention/backend.js.map +1 -0
- package/dist/session/retention/disk-backend.d.ts +59 -0
- package/dist/session/retention/disk-backend.d.ts.map +1 -0
- package/dist/session/retention/disk-backend.js +236 -0
- package/dist/session/retention/disk-backend.js.map +1 -0
- package/dist/session/retention/index.d.ts +9 -0
- package/dist/session/retention/index.d.ts.map +1 -0
- package/dist/session/retention/index.js +6 -0
- package/dist/session/retention/index.js.map +1 -0
- package/dist/session/retention/policy.d.ts +49 -0
- package/dist/session/retention/policy.d.ts.map +1 -0
- package/dist/session/retention/policy.js +21 -0
- package/dist/session/retention/policy.js.map +1 -0
- package/dist/session/summary/__tests__/materialize.test.d.ts +2 -0
- package/dist/session/summary/__tests__/materialize.test.d.ts.map +1 -0
- package/dist/session/summary/__tests__/materialize.test.js +269 -0
- package/dist/session/summary/__tests__/materialize.test.js.map +1 -0
- package/dist/session/summary/deliverable.d.ts +74 -0
- package/dist/session/summary/deliverable.d.ts.map +1 -0
- package/dist/session/summary/deliverable.js +20 -0
- package/dist/session/summary/deliverable.js.map +1 -0
- package/dist/session/summary/index.d.ts +6 -0
- package/dist/session/summary/index.d.ts.map +1 -0
- package/dist/session/summary/index.js +9 -0
- package/dist/session/summary/index.js.map +1 -0
- package/dist/session/summary/materialize.d.ts +82 -0
- package/dist/session/summary/materialize.d.ts.map +1 -0
- package/dist/session/summary/materialize.js +117 -0
- package/dist/session/summary/materialize.js.map +1 -0
- package/dist/session/summary/ref.d.ts +91 -0
- package/dist/session/summary/ref.d.ts.map +1 -0
- package/dist/session/summary/ref.js +51 -0
- package/dist/session/summary/ref.js.map +1 -0
- package/dist/session/workspace/__tests__/git-worktree.test.d.ts +2 -0
- package/dist/session/workspace/__tests__/git-worktree.test.d.ts.map +1 -0
- package/dist/session/workspace/__tests__/git-worktree.test.js +244 -0
- package/dist/session/workspace/__tests__/git-worktree.test.js.map +1 -0
- package/dist/session/workspace/__tests__/path-builder.test.d.ts +2 -0
- package/dist/session/workspace/__tests__/path-builder.test.d.ts.map +1 -0
- package/dist/session/workspace/__tests__/path-builder.test.js +37 -0
- package/dist/session/workspace/__tests__/path-builder.test.js.map +1 -0
- package/dist/session/workspace/driver.d.ts +55 -0
- package/dist/session/workspace/driver.d.ts.map +1 -0
- package/dist/session/workspace/driver.js +12 -0
- package/dist/session/workspace/driver.js.map +1 -0
- package/dist/session/workspace/git-worktree.d.ts +65 -0
- package/dist/session/workspace/git-worktree.d.ts.map +1 -0
- package/dist/session/workspace/git-worktree.js +156 -0
- package/dist/session/workspace/git-worktree.js.map +1 -0
- package/dist/session/workspace/index.d.ts +8 -0
- package/dist/session/workspace/index.d.ts.map +1 -0
- package/dist/session/workspace/index.js +7 -0
- package/dist/session/workspace/index.js.map +1 -0
- package/dist/session/workspace/path-builder.d.ts +50 -0
- package/dist/session/workspace/path-builder.d.ts.map +1 -0
- package/dist/session/workspace/path-builder.js +50 -0
- package/dist/session/workspace/path-builder.js.map +1 -0
- package/dist/session/workspace/ref.d.ts +46 -0
- package/dist/session/workspace/ref.d.ts.map +1 -0
- package/dist/session/workspace/ref.js +11 -0
- package/dist/session/workspace/ref.js.map +1 -0
- package/dist/session/workspace/registry.d.ts +26 -0
- package/dist/session/workspace/registry.d.ts.map +1 -0
- package/dist/session/workspace/registry.js +35 -0
- package/dist/session/workspace/registry.js.map +1 -0
- package/dist/store/conversation/memory.d.ts +22 -0
- package/dist/store/conversation/memory.d.ts.map +1 -1
- package/dist/store/conversation/memory.js +22 -0
- package/dist/store/conversation/memory.js.map +1 -1
- package/dist/store/session/__tests__/disk.test.d.ts +2 -0
- package/dist/store/session/__tests__/disk.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/disk.test.js +240 -0
- package/dist/store/session/__tests__/disk.test.js.map +1 -0
- package/dist/store/session/__tests__/memory.test.d.ts +2 -0
- package/dist/store/session/__tests__/memory.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/memory.test.js +217 -0
- package/dist/store/session/__tests__/memory.test.js.map +1 -0
- package/dist/store/session/disk.d.ts +85 -0
- package/dist/store/session/disk.d.ts.map +1 -0
- package/dist/store/session/disk.js +757 -0
- package/dist/store/session/disk.js.map +1 -0
- package/dist/store/session/index.d.ts +7 -0
- package/dist/store/session/index.d.ts.map +1 -0
- package/dist/store/session/index.js +11 -0
- package/dist/store/session/index.js.map +1 -0
- package/dist/store/session/linkage.d.ts +38 -0
- package/dist/store/session/linkage.d.ts.map +1 -0
- package/dist/store/session/linkage.js +64 -0
- package/dist/store/session/linkage.js.map +1 -0
- package/dist/store/session/memory.d.ts +48 -0
- package/dist/store/session/memory.d.ts.map +1 -0
- package/dist/store/session/memory.js +322 -0
- package/dist/store/session/memory.js.map +1 -0
- package/dist/store/session/messages.d.ts +20 -0
- package/dist/store/session/messages.d.ts.map +1 -0
- package/dist/store/session/messages.js +12 -0
- package/dist/store/session/messages.js.map +1 -0
- package/dist/tools/builtins/__tests__/structuredOutput.example.d.ts +1 -1
- package/dist/types/agent/base.d.ts +28 -1
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +50 -2
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/agent/task.js.map +1 -1
- package/dist/types/conversation/index.d.ts +7 -0
- package/dist/types/conversation/index.d.ts.map +1 -1
- package/dist/types/ids/index.d.ts +26 -3
- package/dist/types/ids/index.d.ts.map +1 -1
- package/dist/types/ids/index.js +8 -1
- package/dist/types/ids/index.js.map +1 -1
- package/dist/types/invocation/__tests__/state.test.js +36 -29
- package/dist/types/invocation/__tests__/state.test.js.map +1 -1
- package/dist/types/invocation/index.d.ts +20 -4
- package/dist/types/invocation/index.d.ts.map +1 -1
- package/dist/types/invocation/index.js +10 -7
- package/dist/types/invocation/index.js.map +1 -1
- package/dist/types/run/config.d.ts +11 -1
- package/dist/types/run/config.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +26 -1
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/index.d.ts.map +1 -1
- package/dist/types/run/index.js +8 -0
- package/dist/types/run/index.js.map +1 -1
- package/dist/types/run/metadata.d.ts +24 -1
- package/dist/types/run/metadata.d.ts.map +1 -1
- package/dist/types/run/status.d.ts +26 -0
- package/dist/types/run/status.d.ts.map +1 -0
- package/dist/types/run/status.js +2 -0
- package/dist/types/run/status.js.map +1 -0
- package/dist/types/session/ids.d.ts +18 -0
- package/dist/types/session/ids.d.ts.map +1 -0
- package/dist/types/session/ids.js +12 -0
- package/dist/types/session/ids.js.map +1 -0
- package/dist/types/session/index.d.ts +3 -0
- package/dist/types/session/index.d.ts.map +1 -0
- package/dist/types/session/index.js +5 -0
- package/dist/types/session/index.js.map +1 -0
- package/dist/types/session/store.d.ts +188 -0
- package/dist/types/session/store.d.ts.map +1 -0
- package/dist/types/session/store.js +14 -0
- package/dist/types/session/store.js.map +1 -0
- package/dist/utils/id.d.ts +18 -1
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +42 -4
- package/dist/utils/id.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/ReactiveAgent.ts +7 -3
- package/src/agents/RouterAgent.ts +5 -0
- package/src/agents/SupervisorAgent.ts +26 -6
- package/src/bridge/a2a/mapper.ts +7 -0
- package/src/bridge/a2a/task.ts +2 -2
- package/src/bridge/sse/mapper.ts +8 -1
- package/src/constants/a2a/index.ts +2 -2
- package/src/contracts/api.ts +23 -3
- package/src/contracts/index.ts +2 -0
- package/src/gateway/local.ts +6 -0
- package/src/index.ts +14 -0
- package/src/manager/agent/__tests__/lifecycle.test.ts +452 -0
- package/src/manager/agent/lifecycle.ts +434 -19
- package/src/manager/run/persistence.ts +20 -1
- package/src/run/reporter.ts +28 -0
- package/src/runtime/query/__tests__/context.test.ts +101 -0
- package/src/runtime/query/context.ts +106 -10
- package/src/runtime/query/events.ts +8 -0
- package/src/runtime/query/index.ts +41 -3
- package/src/session/__tests__/integration/_fixtures.ts +282 -0
- package/src/session/__tests__/integration/capacity-caps.test.ts +164 -0
- package/src/session/__tests__/integration/e2e-spawn.test.ts +278 -0
- package/src/session/__tests__/integration/event-stream-ordering.test.ts +403 -0
- package/src/session/__tests__/integration/handoff-broadcast-e2e.test.ts +245 -0
- package/src/session/__tests__/integration/handoff-illegal-transition.test.ts +179 -0
- package/src/session/__tests__/integration/handoff-single-e2e.test.ts +220 -0
- package/src/session/__tests__/integration/hierarchy-lifecycle.test.ts +237 -0
- package/src/session/__tests__/integration/migration-filesystem.test.ts +209 -0
- package/src/session/__tests__/integration/migration-id-prefix.test.ts +101 -0
- package/src/session/__tests__/integration/prev-artifact-dag.test.ts +318 -0
- package/src/session/__tests__/integration/retention-archive.test.ts +231 -0
- package/src/session/__tests__/integration/summary-materialization-e2e.test.ts +237 -0
- package/src/session/__tests__/integration/tenant-isolation.test.ts +282 -0
- package/src/session/errors.ts +70 -0
- package/src/session/events/index.ts +16 -0
- package/src/session/events/schema-version.ts +13 -0
- package/src/session/events/types.ts +71 -0
- package/src/session/handoff/__tests__/broadcast.test.ts +350 -0
- package/src/session/handoff/__tests__/capacity.test.ts +123 -0
- package/src/session/handoff/__tests__/single.test.ts +316 -0
- package/src/session/handoff/assignment.ts +62 -0
- package/src/session/handoff/broadcast.ts +381 -0
- package/src/session/handoff/capacity.ts +121 -0
- package/src/session/handoff/events.ts +72 -0
- package/src/session/handoff/index.ts +29 -0
- package/src/session/handoff/single.ts +288 -0
- package/src/session/handoff/version.ts +59 -0
- package/src/session/hierarchy/__tests__/session.test.ts +92 -0
- package/src/session/hierarchy/actor.ts +17 -0
- package/src/session/hierarchy/index.ts +17 -0
- package/src/session/hierarchy/lineage.ts +15 -0
- package/src/session/hierarchy/project.ts +41 -0
- package/src/session/hierarchy/session.ts +97 -0
- package/src/session/hierarchy/sub-session.ts +92 -0
- package/src/session/hierarchy/tenant.ts +13 -0
- package/src/session/index.ts +15 -0
- package/src/session/intervention/__tests__/prev-artifact.test.ts +234 -0
- package/src/session/intervention/index.ts +16 -0
- package/src/session/intervention/prev-artifact.ts +180 -0
- package/src/session/migration/__tests__/filesystem.test.ts +263 -0
- package/src/session/migration/__tests__/id-prefix.test.ts +101 -0
- package/src/session/migration/__tests__/marker.test.ts +84 -0
- package/src/session/migration/errors.ts +23 -0
- package/src/session/migration/filesystem.ts +401 -0
- package/src/session/migration/id-prefix.ts +146 -0
- package/src/session/migration/index.ts +38 -0
- package/src/session/migration/marker.ts +131 -0
- package/src/session/retention/__tests__/archive.test.ts +316 -0
- package/src/session/retention/__tests__/disk-backend.test.ts +180 -0
- package/src/session/retention/archive-backend-ref.ts +17 -0
- package/src/session/retention/archive.ts +281 -0
- package/src/session/retention/backend.ts +107 -0
- package/src/session/retention/disk-backend.ts +304 -0
- package/src/session/retention/index.ts +16 -0
- package/src/session/retention/policy.ts +53 -0
- package/src/session/summary/__tests__/materialize.test.ts +341 -0
- package/src/session/summary/deliverable.ts +84 -0
- package/src/session/summary/index.ts +31 -0
- package/src/session/summary/materialize.ts +169 -0
- package/src/session/summary/ref.ts +104 -0
- package/src/session/workspace/__tests__/git-worktree.test.ts +258 -0
- package/src/session/workspace/__tests__/path-builder.test.ts +51 -0
- package/src/session/workspace/driver.ts +60 -0
- package/src/session/workspace/git-worktree.ts +209 -0
- package/src/session/workspace/index.ts +25 -0
- package/src/session/workspace/path-builder.ts +71 -0
- package/src/session/workspace/ref.ts +50 -0
- package/src/session/workspace/registry.ts +42 -0
- package/src/store/conversation/memory.ts +23 -0
- package/src/store/session/__tests__/disk.test.ts +346 -0
- package/src/store/session/__tests__/memory.test.ts +327 -0
- package/src/store/session/disk.ts +920 -0
- package/src/store/session/index.ts +14 -0
- package/src/store/session/linkage.ts +80 -0
- package/src/store/session/memory.ts +400 -0
- package/src/store/session/messages.ts +21 -0
- package/src/types/agent/base.ts +31 -1
- package/src/types/agent/task.ts +58 -2
- package/src/types/conversation/index.ts +7 -0
- package/src/types/ids/index.ts +41 -3
- package/src/types/invocation/__tests__/state.test.ts +37 -29
- package/src/types/invocation/index.ts +26 -10
- package/src/types/run/config.ts +12 -1
- package/src/types/run/events.ts +36 -1
- package/src/types/run/index.ts +8 -0
- package/src/types/run/metadata.ts +24 -1
- package/src/types/run/status.ts +33 -0
- package/src/types/session/ids.ts +34 -0
- package/src/types/session/index.ts +28 -0
- package/src/types/session/store.ts +229 -0
- package/src/utils/id.ts +55 -4
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration — multi-tenant isolation enforcement at every store accessor
|
|
3
|
+
* and cross-store boundary.
|
|
4
|
+
*
|
|
5
|
+
* Covers roadmap §5 invariants: §12 `tenantId` denormalized on every
|
|
6
|
+
* persisted entity, §12.2 cross-tenant rejection (TenantIsolationError at
|
|
7
|
+
* every accessor), broadcast handoff rejecting when recipient tenant
|
|
8
|
+
* differs.
|
|
9
|
+
*
|
|
10
|
+
* Every assertion here crosses a kernel boundary with a mismatched tenantId
|
|
11
|
+
* and checks that the SDK rejects rather than silently re-scoping.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { describe, expect, it } from 'vitest'
|
|
15
|
+
import { InMemorySessionStore } from '../../../store/session/memory.js'
|
|
16
|
+
import { createUserMessage } from '../../../types/message/index.js'
|
|
17
|
+
import type { ProjectId, SubSessionId, SummaryId } from '../../../types/session/ids.js'
|
|
18
|
+
import { TenantIsolationError } from '../../errors.js'
|
|
19
|
+
import { DEFAULT_TENANT, OTHER_TENANT, agentActor, userActor } from './_fixtures.js'
|
|
20
|
+
|
|
21
|
+
async function seedTenantAResources() {
|
|
22
|
+
const store = new InMemorySessionStore()
|
|
23
|
+
const project = await store.createProject(
|
|
24
|
+
{ tenantId: DEFAULT_TENANT, name: 'tenA' },
|
|
25
|
+
DEFAULT_TENANT,
|
|
26
|
+
)
|
|
27
|
+
const parent = await store.createSession(
|
|
28
|
+
{ projectId: project.id, currentActor: userActor('usr_a') },
|
|
29
|
+
DEFAULT_TENANT,
|
|
30
|
+
)
|
|
31
|
+
const child = await store.createSession(
|
|
32
|
+
{ projectId: project.id, currentActor: agentActor('agt_a') },
|
|
33
|
+
DEFAULT_TENANT,
|
|
34
|
+
)
|
|
35
|
+
const sub = await store.createSubSession(
|
|
36
|
+
{
|
|
37
|
+
parentSessionId: parent.id,
|
|
38
|
+
childSessionId: child.id,
|
|
39
|
+
kind: 'agent_spawn',
|
|
40
|
+
spawnedBy: userActor('usr_a'),
|
|
41
|
+
},
|
|
42
|
+
DEFAULT_TENANT,
|
|
43
|
+
)
|
|
44
|
+
return { store, project, parent, child, sub }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
describe('Integration — tenant isolation', () => {
|
|
48
|
+
it('getProject with wrong tenantId → TenantIsolationError', async () => {
|
|
49
|
+
const { store, project } = await seedTenantAResources()
|
|
50
|
+
await expect(store.getProject(project.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
51
|
+
TenantIsolationError,
|
|
52
|
+
)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('getSession with wrong tenantId → TenantIsolationError', async () => {
|
|
56
|
+
const { store, parent } = await seedTenantAResources()
|
|
57
|
+
await expect(store.getSession(parent.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
58
|
+
TenantIsolationError,
|
|
59
|
+
)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('getSubSession with wrong tenantId → TenantIsolationError', async () => {
|
|
63
|
+
const { store, sub } = await seedTenantAResources()
|
|
64
|
+
await expect(store.getSubSession(sub.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
65
|
+
TenantIsolationError,
|
|
66
|
+
)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('updateSession with wrong tenantId → TenantIsolationError', async () => {
|
|
70
|
+
const { store, parent } = await seedTenantAResources()
|
|
71
|
+
await expect(
|
|
72
|
+
store.updateSession({ ...parent, status: 'active' }, OTHER_TENANT),
|
|
73
|
+
).rejects.toBeInstanceOf(TenantIsolationError)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('createSubSession from a session owned by another tenant → TenantIsolationError', async () => {
|
|
77
|
+
const { store, parent, child } = await seedTenantAResources()
|
|
78
|
+
await expect(
|
|
79
|
+
store.createSubSession(
|
|
80
|
+
{
|
|
81
|
+
parentSessionId: parent.id,
|
|
82
|
+
childSessionId: child.id,
|
|
83
|
+
kind: 'agent_spawn',
|
|
84
|
+
spawnedBy: userActor('usr_intruder', OTHER_TENANT),
|
|
85
|
+
},
|
|
86
|
+
OTHER_TENANT,
|
|
87
|
+
),
|
|
88
|
+
).rejects.toBeInstanceOf(TenantIsolationError)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('appendMessage with wrong tenantId → TenantIsolationError', async () => {
|
|
92
|
+
const { store, child } = await seedTenantAResources()
|
|
93
|
+
await expect(
|
|
94
|
+
store.appendMessage(child.id, createUserMessage('intruder'), OTHER_TENANT),
|
|
95
|
+
).rejects.toBeInstanceOf(TenantIsolationError)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('loadSessionMessages cross-tenant → TenantIsolationError', async () => {
|
|
99
|
+
const { store, child } = await seedTenantAResources()
|
|
100
|
+
await store.appendMessage(child.id, createUserMessage('legit'), DEFAULT_TENANT)
|
|
101
|
+
await expect(store.loadSessionMessages(child.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
102
|
+
TenantIsolationError,
|
|
103
|
+
)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('loadMessages cross-tenant → TenantIsolationError', async () => {
|
|
107
|
+
const { store, child } = await seedTenantAResources()
|
|
108
|
+
await store.appendMessage(child.id, createUserMessage('legit'), DEFAULT_TENANT)
|
|
109
|
+
await expect(store.loadMessages(child.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
110
|
+
TenantIsolationError,
|
|
111
|
+
)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('drill(sessionId, OTHER_TENANT) on an existing session → TenantIsolationError (pattern doc §12.2 hard reject)', async () => {
|
|
115
|
+
const { store, parent } = await seedTenantAResources()
|
|
116
|
+
// Existing session owned by DEFAULT_TENANT, caller supplies OTHER_TENANT.
|
|
117
|
+
// Pattern doc §12 specifies hard reject — no silent null masking.
|
|
118
|
+
await expect(store.drill(parent.id, OTHER_TENANT)).rejects.toBeInstanceOf(TenantIsolationError)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('drill on a missing session returns null (deny-by-default surface without leaking tenant info)', async () => {
|
|
122
|
+
const { store } = await seedTenantAResources()
|
|
123
|
+
const view = await store.drill(
|
|
124
|
+
'ses_never_existed' as Parameters<typeof store.drill>[0],
|
|
125
|
+
OTHER_TENANT,
|
|
126
|
+
)
|
|
127
|
+
// Missing session for the queried tenant returns null (Convention #5).
|
|
128
|
+
// The tenant check is conditional on the resource existing; absent
|
|
129
|
+
// resources don't leak tenant info via a thrown isolation error.
|
|
130
|
+
expect(view).toBeNull()
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('getChildren cross-tenant → TenantIsolationError', async () => {
|
|
134
|
+
const { store, parent } = await seedTenantAResources()
|
|
135
|
+
await expect(store.getChildren(parent.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
136
|
+
TenantIsolationError,
|
|
137
|
+
)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('getAncestry cross-tenant → TenantIsolationError', async () => {
|
|
141
|
+
const { store, parent } = await seedTenantAResources()
|
|
142
|
+
await expect(store.getAncestry(parent.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
143
|
+
TenantIsolationError,
|
|
144
|
+
)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('recordSummary with mismatched payload tenantId → TenantIsolationError', async () => {
|
|
148
|
+
const { store, parent } = await seedTenantAResources()
|
|
149
|
+
// Attempt to record a summary whose payload tenantId differs from the
|
|
150
|
+
// caller tenantId — runtime guard rejects.
|
|
151
|
+
await expect(
|
|
152
|
+
store.recordSummary(
|
|
153
|
+
{
|
|
154
|
+
id: 'sum_intruder' as SummaryId,
|
|
155
|
+
sessionRef: parent.id,
|
|
156
|
+
tenantId: OTHER_TENANT,
|
|
157
|
+
outcome: { status: 'succeeded' },
|
|
158
|
+
deliverables: [],
|
|
159
|
+
agentSummary: '',
|
|
160
|
+
keyDecisions: [],
|
|
161
|
+
at: new Date(),
|
|
162
|
+
materializedBy: 'kernel',
|
|
163
|
+
},
|
|
164
|
+
DEFAULT_TENANT,
|
|
165
|
+
),
|
|
166
|
+
).rejects.toBeInstanceOf(TenantIsolationError)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('getSummary cross-tenant → TenantIsolationError when a summary exists', async () => {
|
|
170
|
+
const { store, parent } = await seedTenantAResources()
|
|
171
|
+
await store.updateSession({ ...parent, status: 'active' }, DEFAULT_TENANT)
|
|
172
|
+
await store.recordSummary(
|
|
173
|
+
{
|
|
174
|
+
id: 'sum_ok' as SummaryId,
|
|
175
|
+
sessionRef: parent.id,
|
|
176
|
+
tenantId: DEFAULT_TENANT,
|
|
177
|
+
outcome: { status: 'succeeded' },
|
|
178
|
+
deliverables: [],
|
|
179
|
+
agentSummary: '',
|
|
180
|
+
keyDecisions: [],
|
|
181
|
+
at: new Date(),
|
|
182
|
+
materializedBy: 'kernel',
|
|
183
|
+
},
|
|
184
|
+
DEFAULT_TENANT,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
await expect(store.getSummary(parent.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
188
|
+
TenantIsolationError,
|
|
189
|
+
)
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('createProject with params.tenantId ≠ caller tenantId → TenantIsolationError (deep check)', async () => {
|
|
193
|
+
const store = new InMemorySessionStore()
|
|
194
|
+
await expect(
|
|
195
|
+
store.createProject({ tenantId: OTHER_TENANT, name: 'mismatch' }, DEFAULT_TENANT),
|
|
196
|
+
).rejects.toBeInstanceOf(TenantIsolationError)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
it('createSession with project owned by another tenant → TenantIsolationError', async () => {
|
|
200
|
+
const { store, project } = await seedTenantAResources()
|
|
201
|
+
await expect(
|
|
202
|
+
store.createSession(
|
|
203
|
+
{ projectId: project.id, currentActor: userActor('usr_intruder', OTHER_TENANT) },
|
|
204
|
+
OTHER_TENANT,
|
|
205
|
+
),
|
|
206
|
+
).rejects.toBeInstanceOf(TenantIsolationError)
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
it('tenant denormalization: Session, SubSession records carry tenantId explicitly', async () => {
|
|
210
|
+
const { store, parent, sub } = await seedTenantAResources()
|
|
211
|
+
const parentReloaded = await store.getSession(parent.id, DEFAULT_TENANT)
|
|
212
|
+
expect(parentReloaded?.tenantId).toBe(DEFAULT_TENANT)
|
|
213
|
+
|
|
214
|
+
// SubSession record itself does not carry tenantId in its shape — the
|
|
215
|
+
// isolation is stored via the parent record tuple (subSessions map:
|
|
216
|
+
// { tenantId, subSession }). Getting it via the correct tenant succeeds;
|
|
217
|
+
// via the wrong tenant rejects — already covered above. This test just
|
|
218
|
+
// confirms the successful access path.
|
|
219
|
+
const reloaded = await store.getSubSession(sub.id, DEFAULT_TENANT)
|
|
220
|
+
expect(reloaded?.id).toBe(sub.id)
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it('broadcast-style cross-tenant attempt: cannot createSubSession linking parents owned by another tenant', async () => {
|
|
224
|
+
// Pattern doc §12 requires recipient & source to share tenant. The
|
|
225
|
+
// store-level guard here catches the shape violation — createSubSession
|
|
226
|
+
// refuses to link parent/child across tenants.
|
|
227
|
+
const { store, parent } = await seedTenantAResources()
|
|
228
|
+
|
|
229
|
+
// Create a session in OTHER_TENANT with its own project.
|
|
230
|
+
const otherProject = await store.createProject(
|
|
231
|
+
{ tenantId: OTHER_TENANT, name: 'other' },
|
|
232
|
+
OTHER_TENANT,
|
|
233
|
+
)
|
|
234
|
+
const otherChild = await store.createSession(
|
|
235
|
+
{ projectId: otherProject.id, currentActor: userActor('usr_other', OTHER_TENANT) },
|
|
236
|
+
OTHER_TENANT,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
await expect(
|
|
240
|
+
store.createSubSession(
|
|
241
|
+
{
|
|
242
|
+
parentSessionId: parent.id, // DEFAULT_TENANT
|
|
243
|
+
childSessionId: otherChild.id, // OTHER_TENANT
|
|
244
|
+
kind: 'agent_spawn',
|
|
245
|
+
spawnedBy: userActor('usr_a'),
|
|
246
|
+
},
|
|
247
|
+
DEFAULT_TENANT,
|
|
248
|
+
),
|
|
249
|
+
).rejects.toBeInstanceOf(TenantIsolationError)
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('deleteSubSession cross-tenant → TenantIsolationError', async () => {
|
|
253
|
+
const { store, sub } = await seedTenantAResources()
|
|
254
|
+
await expect(store.deleteSubSession(sub.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
255
|
+
TenantIsolationError,
|
|
256
|
+
)
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
it('deleteSession cross-tenant → TenantIsolationError', async () => {
|
|
260
|
+
const { store } = await seedTenantAResources()
|
|
261
|
+
// Parent has a sub-session attached → deleteSession would fail anyway,
|
|
262
|
+
// but the tenant guard fires first. Use a standalone session.
|
|
263
|
+
const project: ProjectId = (
|
|
264
|
+
await store.createProject({ tenantId: DEFAULT_TENANT, name: 'del' }, DEFAULT_TENANT)
|
|
265
|
+
).id
|
|
266
|
+
const lonely = await store.createSession(
|
|
267
|
+
{ projectId: project, currentActor: userActor('usr_lonely') },
|
|
268
|
+
DEFAULT_TENANT,
|
|
269
|
+
)
|
|
270
|
+
await expect(store.deleteSession(lonely.id, OTHER_TENANT)).rejects.toBeInstanceOf(
|
|
271
|
+
TenantIsolationError,
|
|
272
|
+
)
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
it('missing sub-session returns null for correct tenant (not a leak channel)', async () => {
|
|
276
|
+
const { store } = await seedTenantAResources()
|
|
277
|
+
// Missing id via correct tenant → null, not thrown. Confirms the
|
|
278
|
+
// missing-resource fast-path doesn't pre-empt the tenant check.
|
|
279
|
+
const missing = await store.getSubSession('sub_never_existed' as SubSessionId, DEFAULT_TENANT)
|
|
280
|
+
expect(missing).toBeNull()
|
|
281
|
+
})
|
|
282
|
+
})
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors for the session hierarchy module.
|
|
3
|
+
*
|
|
4
|
+
* See session-hierarchy.md §12.2 (cross-tenant rejection), §6.2 (workspace
|
|
5
|
+
* backend operation failures), §4.5 (intervention DAG). Each error carries a
|
|
6
|
+
* structured `details` payload so consumers can route without string parsing
|
|
7
|
+
* (Convention #5: deny-by-default, fail fast).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { SessionId, TenantId } from '../types/ids/index.js'
|
|
11
|
+
import type { WorkspaceBackendKind } from './workspace/driver.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Raised by {@link SessionStore} accessors when the supplied {@link TenantId}
|
|
15
|
+
* does not match the tenant owning the target resource. Convention #17:
|
|
16
|
+
* cross-tenant access is a hard error at the kernel boundary — there is no
|
|
17
|
+
* escape hatch. See session-hierarchy.md §12.2.
|
|
18
|
+
*/
|
|
19
|
+
export class TenantIsolationError extends Error {
|
|
20
|
+
readonly details: {
|
|
21
|
+
requested: TenantId
|
|
22
|
+
resource: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor(details: { requested: TenantId; resource: string }) {
|
|
26
|
+
super(`Tenant isolation violation: ${details.requested} accessed ${details.resource}`)
|
|
27
|
+
this.name = 'TenantIsolationError'
|
|
28
|
+
this.details = details
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Raised by {@link SessionStore.getAncestry} / {@link SessionStore.drill}
|
|
34
|
+
* when walking parent sub-session links encounters a revisit. Indicates store
|
|
35
|
+
* corruption — the write path enforces acyclicity (session-hierarchy.md §4.5).
|
|
36
|
+
*/
|
|
37
|
+
export class AncestryCycleError extends Error {
|
|
38
|
+
readonly details: {
|
|
39
|
+
sessionId: SessionId
|
|
40
|
+
cyclePath: readonly SessionId[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
constructor(details: { sessionId: SessionId; cyclePath: readonly SessionId[] }) {
|
|
44
|
+
super(
|
|
45
|
+
`Ancestry cycle detected starting at ${details.sessionId}: ${details.cyclePath.join(' -> ')}`,
|
|
46
|
+
)
|
|
47
|
+
this.name = 'AncestryCycleError'
|
|
48
|
+
this.details = details
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Raised by {@link WorkspaceBackendDriver} implementations on any I/O or
|
|
54
|
+
* invariant failure. Wraps the underlying cause; callers can match on
|
|
55
|
+
* `details.op` + `details.kind` for routing (Convention #0: no silent
|
|
56
|
+
* fallbacks — surface the failure). See session-hierarchy.md §6.2 / §7.
|
|
57
|
+
*/
|
|
58
|
+
export class WorkspaceBackendError extends Error {
|
|
59
|
+
readonly details: {
|
|
60
|
+
op: string
|
|
61
|
+
kind: WorkspaceBackendKind
|
|
62
|
+
cause?: unknown
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
constructor(details: { op: string; kind: WorkspaceBackendKind; cause?: unknown }) {
|
|
66
|
+
super(`Workspace backend ${details.kind} failed on ${details.op}`)
|
|
67
|
+
this.name = 'WorkspaceBackendError'
|
|
68
|
+
this.details = details
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Sub-barrel for session-hierarchy run-event surface.
|
|
2
|
+
// Convention #4: concrete types live in sibling files; re-export them here.
|
|
3
|
+
//
|
|
4
|
+
// Phase 2 scope is limited to the sub-session lifecycle variants that are
|
|
5
|
+
// spliced into `RunEvent`. A dedicated `SessionHierarchyEvent` top-level
|
|
6
|
+
// union lands in a later phase (see session-hierarchy.md §10.2).
|
|
7
|
+
|
|
8
|
+
export { RUN_EVENT_SCHEMA_VERSION } from './schema-version.js'
|
|
9
|
+
export type { RunEventSchemaVersion } from './schema-version.js'
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
SubsessionSpawnedEvent,
|
|
13
|
+
SubsessionMessagedEvent,
|
|
14
|
+
SubsessionIdledEvent,
|
|
15
|
+
SubsessionLifecycleEvent,
|
|
16
|
+
} from './types.js'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RunEvent envelope schema version. Bumped on breaking envelope change.
|
|
3
|
+
*
|
|
4
|
+
* - v1: pre-0.2.0 (implicit; untagged events are treated as v1 by consumers).
|
|
5
|
+
* - v2: 0.2.0+ — adds `schemaVersion`, `lineage`, and sub-session lifecycle
|
|
6
|
+
* events.
|
|
7
|
+
*
|
|
8
|
+
* See session-hierarchy.md §10.1 (Event-schema evolution contract) and
|
|
9
|
+
* §13.3.2 (`schemaVersion` back-compat).
|
|
10
|
+
*/
|
|
11
|
+
export const RUN_EVENT_SCHEMA_VERSION = 2 as const
|
|
12
|
+
|
|
13
|
+
export type RunEventSchemaVersion = typeof RUN_EVENT_SCHEMA_VERSION
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { MessageId, RunId, SessionId } from '../../types/ids/index.js'
|
|
2
|
+
import type { SubSessionId } from '../../types/session/ids.js'
|
|
3
|
+
import type { ActorRef } from '../hierarchy/actor.js'
|
|
4
|
+
import type { Lineage } from '../hierarchy/lineage.js'
|
|
5
|
+
import type { RunEventSchemaVersion } from './schema-version.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Sub-session lifecycle events that splice into {@link RunEvent}.
|
|
9
|
+
*
|
|
10
|
+
* See session-hierarchy.md §10.4 (Parent-Child Linkage). These cover the
|
|
11
|
+
* in-flight visibility gap that the terminal-only `SessionSummaryRef` does
|
|
12
|
+
* not address. Every sub-session emission carries the full {@link Lineage}
|
|
13
|
+
* chain — consumers can reconstruct the delegation tree without walking the
|
|
14
|
+
* store (§10.4 invariant).
|
|
15
|
+
*
|
|
16
|
+
* Note: these events are spliced into the `RunEvent` union in
|
|
17
|
+
* `types/run/events.ts` rather than kept as a separate top-level union.
|
|
18
|
+
* A dedicated `SessionHierarchyEvent` top-level type lands in Phase 3+.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Emitted when the kernel creates a new sub-session. Precedes the child
|
|
23
|
+
* session's `run_started`. See §10.4 / §10.5 example stream.
|
|
24
|
+
*/
|
|
25
|
+
export interface SubsessionSpawnedEvent {
|
|
26
|
+
type: 'subsession_spawned'
|
|
27
|
+
runId: RunId
|
|
28
|
+
subSessionId: SubSessionId
|
|
29
|
+
parentSessionId: SessionId
|
|
30
|
+
spawnedBy: ActorRef
|
|
31
|
+
lineage: Lineage
|
|
32
|
+
schemaVersion: RunEventSchemaVersion
|
|
33
|
+
at: Date
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Emitted each time the child session's Run appends a message. Gives parents
|
|
38
|
+
* and platform consumers in-flight visibility without requiring a drill into
|
|
39
|
+
* the child transcript. See §10.4.
|
|
40
|
+
*/
|
|
41
|
+
export interface SubsessionMessagedEvent {
|
|
42
|
+
type: 'subsession_messaged'
|
|
43
|
+
runId: RunId
|
|
44
|
+
subSessionId: SubSessionId
|
|
45
|
+
parentSessionId: SessionId
|
|
46
|
+
messageId: MessageId
|
|
47
|
+
lineage: Lineage
|
|
48
|
+
schemaVersion: RunEventSchemaVersion
|
|
49
|
+
at: Date
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Emitted when the child session transitions to `idle` (terminal persistent
|
|
54
|
+
* state per §5.3 — sub-sessions never close). A separate
|
|
55
|
+
* `sub_session.summarized` event carries the `SessionSummaryRef` (§8); this
|
|
56
|
+
* event only reports the lifecycle transition.
|
|
57
|
+
*/
|
|
58
|
+
export interface SubsessionIdledEvent {
|
|
59
|
+
type: 'subsession_idled'
|
|
60
|
+
runId: RunId
|
|
61
|
+
subSessionId: SubSessionId
|
|
62
|
+
parentSessionId: SessionId
|
|
63
|
+
lineage: Lineage
|
|
64
|
+
schemaVersion: RunEventSchemaVersion
|
|
65
|
+
at: Date
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type SubsessionLifecycleEvent =
|
|
69
|
+
| SubsessionSpawnedEvent
|
|
70
|
+
| SubsessionMessagedEvent
|
|
71
|
+
| SubsessionIdledEvent
|