@vauban-org/agent-sdk 1.0.0 → 1.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/CONTRACT.md +6401 -813
- package/dist/adapters/llm/anthropic-direct.d.ts +1 -0
- package/dist/adapters/llm/anthropic-direct.d.ts.map +1 -1
- package/dist/adapters/llm/anthropic-direct.js +43 -0
- package/dist/adapters/llm/anthropic-direct.js.map +1 -1
- package/dist/adapters/llm/cascade.d.ts.map +1 -1
- package/dist/adapters/llm/cascade.js +57 -14
- package/dist/adapters/llm/cascade.js.map +1 -1
- package/dist/adapters/llm/litellm.d.ts +2 -0
- package/dist/adapters/llm/litellm.d.ts.map +1 -1
- package/dist/adapters/llm/litellm.js +44 -0
- package/dist/adapters/llm/litellm.js.map +1 -1
- package/dist/compute/difficulty-estimator.d.ts +53 -0
- package/dist/compute/difficulty-estimator.d.ts.map +1 -0
- package/dist/compute/difficulty-estimator.js +82 -0
- package/dist/compute/difficulty-estimator.js.map +1 -0
- package/dist/compute/strategies/mixture-of-agents.d.ts +40 -0
- package/dist/compute/strategies/mixture-of-agents.d.ts.map +1 -0
- package/dist/compute/strategies/mixture-of-agents.js +110 -0
- package/dist/compute/strategies/mixture-of-agents.js.map +1 -0
- package/dist/compute/strategies/tree-of-thoughts.d.ts +48 -0
- package/dist/compute/strategies/tree-of-thoughts.d.ts.map +1 -0
- package/dist/compute/strategies/tree-of-thoughts.js +242 -0
- package/dist/compute/strategies/tree-of-thoughts.js.map +1 -0
- package/dist/compute/strategies/two-phase-orient.d.ts +72 -0
- package/dist/compute/strategies/two-phase-orient.d.ts.map +1 -0
- package/dist/compute/strategies/two-phase-orient.js +85 -0
- package/dist/compute/strategies/two-phase-orient.js.map +1 -0
- package/dist/constitution/types.d.ts +10 -10
- package/dist/container/protocol.d.ts +134 -0
- package/dist/container/protocol.d.ts.map +1 -0
- package/dist/container/protocol.js +157 -0
- package/dist/container/protocol.js.map +1 -0
- package/dist/container/runtime.d.ts +140 -0
- package/dist/container/runtime.d.ts.map +1 -0
- package/dist/container/runtime.js +256 -0
- package/dist/container/runtime.js.map +1 -0
- package/dist/events/catalogue.d.ts +46 -46
- package/dist/events/schemas/agent.completed.v1.d.ts +4 -4
- package/dist/events/schemas/agent.failed.v1.d.ts +2 -2
- package/dist/events/schemas/agent.hitl_resolved.v1.d.ts +2 -2
- package/dist/events/schemas/agent.started.v1.d.ts +2 -2
- package/dist/events/schemas/brain.skill.extracted.v1.d.ts +4 -4
- package/dist/events/schemas/cc.cost.anomaly_detected.v1.d.ts +2 -2
- package/dist/events/schemas/cc.cost.recorded.v1.d.ts +4 -4
- package/dist/events/schemas/citadel.sprint.analyzed.v1.d.ts +6 -6
- package/dist/events/schemas/citadel.sprint.closed.v1.d.ts +2 -2
- package/dist/events/schemas/forge.inbox.reply_classified.v1.d.ts +6 -6
- package/dist/events/schemas/forge.lead.qualified.v1.d.ts +2 -2
- package/dist/events/schemas/forge.outreach.sent.v1.d.ts +4 -4
- package/dist/events/schemas/incident.detected.v1.d.ts +2 -2
- package/dist/events/schemas/vauban.goal.checked.v1.d.ts +2 -2
- package/dist/events/schemas/vauban.rebalancing.checked.v1.d.ts +2 -2
- package/dist/events/schemas/vauban.tax.checked.v1.d.ts +2 -2
- package/dist/events/schemas/vauban.vault.analyzed.v1.d.ts +6 -6
- package/dist/identity/agent-persona.d.ts +73 -0
- package/dist/identity/agent-persona.d.ts.map +1 -0
- package/dist/identity/agent-persona.js +165 -0
- package/dist/identity/agent-persona.js.map +1 -0
- package/dist/identity/persona-prompt.d.ts +25 -0
- package/dist/identity/persona-prompt.d.ts.map +1 -0
- package/dist/identity/persona-prompt.js +71 -0
- package/dist/identity/persona-prompt.js.map +1 -0
- package/dist/identity/persona-schema.d.ts +120 -0
- package/dist/identity/persona-schema.d.ts.map +1 -0
- package/dist/identity/persona-schema.js +103 -0
- package/dist/identity/persona-schema.js.map +1 -0
- package/dist/index.d.ts +37 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/loop/minimal-loop.js +293 -287
- package/dist/memory/episodic-rrf.d.ts +114 -0
- package/dist/memory/episodic-rrf.d.ts.map +1 -0
- package/dist/memory/episodic-rrf.js +148 -0
- package/dist/memory/episodic-rrf.js.map +1 -0
- package/dist/mesh/attenuation.d.ts +78 -0
- package/dist/mesh/attenuation.d.ts.map +1 -0
- package/dist/mesh/attenuation.js +141 -0
- package/dist/mesh/attenuation.js.map +1 -0
- package/dist/mesh/delegate.d.ts +96 -0
- package/dist/mesh/delegate.d.ts.map +1 -0
- package/dist/mesh/delegate.js +172 -0
- package/dist/mesh/delegate.js.map +1 -0
- package/dist/mesh/dispatcher.d.ts +119 -0
- package/dist/mesh/dispatcher.d.ts.map +1 -0
- package/dist/mesh/dispatcher.js +207 -0
- package/dist/mesh/dispatcher.js.map +1 -0
- package/dist/mesh/index.d.ts +12 -0
- package/dist/mesh/index.d.ts.map +1 -0
- package/dist/mesh/index.js +11 -0
- package/dist/mesh/index.js.map +1 -0
- package/dist/mesh/types.d.ts +30 -0
- package/dist/mesh/types.d.ts.map +1 -0
- package/dist/mesh/types.js +11 -0
- package/dist/mesh/types.js.map +1 -0
- package/dist/orchestration/ooda/skills.d.ts +104 -0
- package/dist/orchestration/ooda/skills.d.ts.map +1 -1
- package/dist/orchestration/ooda/skills.js +106 -0
- package/dist/orchestration/ooda/skills.js.map +1 -1
- package/dist/ports/bastion-action.contract.test.d.ts +11 -0
- package/dist/ports/bastion-action.contract.test.d.ts.map +1 -0
- package/dist/ports/bastion-action.contract.test.js +238 -0
- package/dist/ports/bastion-action.contract.test.js.map +1 -0
- package/dist/ports/bastion-action.d.ts +133 -0
- package/dist/ports/bastion-action.d.ts.map +1 -0
- package/dist/ports/bastion-action.js +73 -0
- package/dist/ports/bastion-action.js.map +1 -0
- package/dist/ports/brain.d.ts +31 -0
- package/dist/ports/brain.d.ts.map +1 -1
- package/dist/ports/brain.js +115 -1
- package/dist/ports/brain.js.map +1 -1
- package/dist/ports/citadel-action.contract.test.d.ts +11 -0
- package/dist/ports/citadel-action.contract.test.d.ts.map +1 -0
- package/dist/ports/citadel-action.contract.test.js +317 -0
- package/dist/ports/citadel-action.contract.test.js.map +1 -0
- package/dist/ports/citadel-action.d.ts +111 -0
- package/dist/ports/citadel-action.d.ts.map +1 -0
- package/dist/ports/citadel-action.js +62 -0
- package/dist/ports/citadel-action.js.map +1 -0
- package/dist/ports/compliance-contract.d.ts +123 -0
- package/dist/ports/compliance-contract.d.ts.map +1 -0
- package/dist/ports/compliance-contract.js +35 -0
- package/dist/ports/compliance-contract.js.map +1 -0
- package/dist/ports/db.d.ts +38 -0
- package/dist/ports/db.d.ts.map +1 -1
- package/dist/ports/db.js +88 -1
- package/dist/ports/db.js.map +1 -1
- package/dist/ports/delegation.contract.test.d.ts +9 -0
- package/dist/ports/delegation.contract.test.d.ts.map +1 -0
- package/dist/ports/delegation.contract.test.js +337 -0
- package/dist/ports/delegation.contract.test.js.map +1 -0
- package/dist/ports/delegation.d.ts +134 -0
- package/dist/ports/delegation.d.ts.map +1 -0
- package/dist/ports/delegation.js +105 -0
- package/dist/ports/delegation.js.map +1 -0
- package/dist/ports/event-bus.d.ts +29 -0
- package/dist/ports/event-bus.d.ts.map +1 -1
- package/dist/ports/event-bus.js +106 -1
- package/dist/ports/event-bus.js.map +1 -1
- package/dist/ports/federation.contract.test.d.ts +9 -0
- package/dist/ports/federation.contract.test.d.ts.map +1 -0
- package/dist/ports/federation.contract.test.js +279 -0
- package/dist/ports/federation.contract.test.js.map +1 -0
- package/dist/ports/federation.d.ts +140 -0
- package/dist/ports/federation.d.ts.map +1 -0
- package/dist/ports/federation.js +57 -0
- package/dist/ports/federation.js.map +1 -0
- package/dist/ports/index.d.ts +28 -2
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +17 -2
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/llm-provider.d.ts +37 -0
- package/dist/ports/llm-provider.d.ts.map +1 -1
- package/dist/ports/llm-provider.js +99 -1
- package/dist/ports/llm-provider.js.map +1 -1
- package/dist/ports/logger.d.ts +27 -0
- package/dist/ports/logger.d.ts.map +1 -1
- package/dist/ports/logger.js +87 -0
- package/dist/ports/logger.js.map +1 -1
- package/dist/ports/manifest-registry.contract.test.d.ts +9 -0
- package/dist/ports/manifest-registry.contract.test.d.ts.map +1 -0
- package/dist/ports/manifest-registry.contract.test.js +246 -0
- package/dist/ports/manifest-registry.contract.test.js.map +1 -0
- package/dist/ports/manifest-registry.d.ts +116 -0
- package/dist/ports/manifest-registry.d.ts.map +1 -0
- package/dist/ports/manifest-registry.js +79 -0
- package/dist/ports/manifest-registry.js.map +1 -0
- package/dist/ports/observability.contract.test.d.ts +12 -0
- package/dist/ports/observability.contract.test.d.ts.map +1 -0
- package/dist/ports/observability.contract.test.js +260 -0
- package/dist/ports/observability.contract.test.js.map +1 -0
- package/dist/ports/observability.d.ts +98 -0
- package/dist/ports/observability.d.ts.map +1 -0
- package/dist/ports/observability.js +59 -0
- package/dist/ports/observability.js.map +1 -0
- package/dist/ports/outcome.d.ts +26 -0
- package/dist/ports/outcome.d.ts.map +1 -1
- package/dist/ports/outcome.js +62 -1
- package/dist/ports/outcome.js.map +1 -1
- package/dist/ports/privacy.contract.test.d.ts +12 -0
- package/dist/ports/privacy.contract.test.d.ts.map +1 -0
- package/dist/ports/privacy.contract.test.js +325 -0
- package/dist/ports/privacy.contract.test.js.map +1 -0
- package/dist/ports/privacy.d.ts +132 -0
- package/dist/ports/privacy.d.ts.map +1 -0
- package/dist/ports/privacy.js +83 -0
- package/dist/ports/privacy.js.map +1 -0
- package/dist/ports/tenant-context.contract.test.d.ts +14 -0
- package/dist/ports/tenant-context.contract.test.d.ts.map +1 -0
- package/dist/ports/tenant-context.contract.test.js +352 -0
- package/dist/ports/tenant-context.contract.test.js.map +1 -0
- package/dist/ports/tenant-context.d.ts +103 -0
- package/dist/ports/tenant-context.d.ts.map +1 -0
- package/dist/ports/tenant-context.js +48 -0
- package/dist/ports/tenant-context.js.map +1 -0
- package/dist/ports/vauban-finance-action.contract.test.d.ts +11 -0
- package/dist/ports/vauban-finance-action.contract.test.d.ts.map +1 -0
- package/dist/ports/vauban-finance-action.contract.test.js +260 -0
- package/dist/ports/vauban-finance-action.contract.test.js.map +1 -0
- package/dist/ports/vauban-finance-action.d.ts +106 -0
- package/dist/ports/vauban-finance-action.d.ts.map +1 -0
- package/dist/ports/vauban-finance-action.js +60 -0
- package/dist/ports/vauban-finance-action.js.map +1 -0
- package/dist/ports/workflow-runtime.d.ts +204 -0
- package/dist/ports/workflow-runtime.d.ts.map +1 -0
- package/dist/ports/workflow-runtime.js +72 -0
- package/dist/ports/workflow-runtime.js.map +1 -0
- package/dist/proof/cert-verify.d.ts +80 -0
- package/dist/proof/cert-verify.d.ts.map +1 -0
- package/dist/proof/cert-verify.js +178 -0
- package/dist/proof/cert-verify.js.map +1 -0
- package/dist/replay/replay.d.ts.map +1 -1
- package/dist/replay/replay.js +5 -1
- package/dist/replay/replay.js.map +1 -1
- package/dist/retry/index.d.ts +129 -0
- package/dist/retry/index.d.ts.map +1 -0
- package/dist/retry/index.js +156 -0
- package/dist/retry/index.js.map +1 -0
- package/dist/retry/presets.d.ts +39 -0
- package/dist/retry/presets.d.ts.map +1 -0
- package/dist/retry/presets.js +69 -0
- package/dist/retry/presets.js.map +1 -0
- package/dist/skill-loop/ab-runner.d.ts +67 -0
- package/dist/skill-loop/ab-runner.d.ts.map +1 -0
- package/dist/skill-loop/ab-runner.js +160 -0
- package/dist/skill-loop/ab-runner.js.map +1 -0
- package/dist/skill-loop/adoption.d.ts +67 -0
- package/dist/skill-loop/adoption.d.ts.map +1 -0
- package/dist/skill-loop/adoption.js +126 -0
- package/dist/skill-loop/adoption.js.map +1 -0
- package/dist/skill-loop/candidate.d.ts +45 -0
- package/dist/skill-loop/candidate.d.ts.map +1 -0
- package/dist/skill-loop/candidate.js +43 -0
- package/dist/skill-loop/candidate.js.map +1 -0
- package/dist/skill-loop/evaluator.d.ts +42 -0
- package/dist/skill-loop/evaluator.d.ts.map +1 -0
- package/dist/skill-loop/evaluator.js +184 -0
- package/dist/skill-loop/evaluator.js.map +1 -0
- package/dist/skill-loop/index.d.ts +27 -0
- package/dist/skill-loop/index.d.ts.map +1 -0
- package/dist/skill-loop/index.js +27 -0
- package/dist/skill-loop/index.js.map +1 -0
- package/dist/skill-loop/reflexion-replay.d.ts +87 -0
- package/dist/skill-loop/reflexion-replay.d.ts.map +1 -0
- package/dist/skill-loop/reflexion-replay.js +110 -0
- package/dist/skill-loop/reflexion-replay.js.map +1 -0
- package/dist/skill-loop/sign-off.d.ts +88 -0
- package/dist/skill-loop/sign-off.d.ts.map +1 -0
- package/dist/skill-loop/sign-off.js +146 -0
- package/dist/skill-loop/sign-off.js.map +1 -0
- package/dist/skill-loop/value-metric.d.ts +55 -0
- package/dist/skill-loop/value-metric.d.ts.map +1 -0
- package/dist/skill-loop/value-metric.js +69 -0
- package/dist/skill-loop/value-metric.js.map +1 -0
- package/dist/skill-loop/versioning.d.ts +36 -0
- package/dist/skill-loop/versioning.d.ts.map +1 -0
- package/dist/skill-loop/versioning.js +47 -0
- package/dist/skill-loop/versioning.js.map +1 -0
- package/dist/skill-manifest/anchor.d.ts +91 -0
- package/dist/skill-manifest/anchor.d.ts.map +1 -0
- package/dist/skill-manifest/anchor.js +331 -0
- package/dist/skill-manifest/anchor.js.map +1 -0
- package/dist/skill-manifest/builder.d.ts +47 -0
- package/dist/skill-manifest/builder.d.ts.map +1 -0
- package/dist/skill-manifest/builder.js +93 -0
- package/dist/skill-manifest/builder.js.map +1 -0
- package/dist/skill-manifest/index.d.ts +13 -0
- package/dist/skill-manifest/index.d.ts.map +1 -0
- package/dist/skill-manifest/index.js +9 -0
- package/dist/skill-manifest/index.js.map +1 -0
- package/dist/skill-manifest/types.d.ts +67 -0
- package/dist/skill-manifest/types.d.ts.map +1 -0
- package/dist/skill-manifest/types.js +16 -0
- package/dist/skill-manifest/types.js.map +1 -0
- package/dist/skill-manifest/verifier.d.ts +42 -0
- package/dist/skill-manifest/verifier.d.ts.map +1 -0
- package/dist/skill-manifest/verifier.js +136 -0
- package/dist/skill-manifest/verifier.js.map +1 -0
- package/dist/skills/brain-query.d.ts +4 -4
- package/dist/skills/brain-store.d.ts +6 -6
- package/dist/skills/errors.d.ts +15 -0
- package/dist/skills/errors.d.ts.map +1 -1
- package/dist/skills/errors.js +21 -0
- package/dist/skills/errors.js.map +1 -1
- package/dist/skills/hitl-request.d.ts +2 -2
- package/dist/skills/index.d.ts +3 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +4 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/markdown/loader.d.ts +52 -0
- package/dist/skills/markdown/loader.d.ts.map +1 -0
- package/dist/skills/markdown/loader.js +93 -0
- package/dist/skills/markdown/loader.js.map +1 -0
- package/dist/skills/markdown/schema.d.ts +432 -0
- package/dist/skills/markdown/schema.d.ts.map +1 -0
- package/dist/skills/markdown/schema.js +121 -0
- package/dist/skills/markdown/schema.js.map +1 -0
- package/dist/skills/poc-md-loader/markdown-loader.d.ts +77 -0
- package/dist/skills/poc-md-loader/markdown-loader.d.ts.map +1 -0
- package/dist/skills/poc-md-loader/markdown-loader.js +125 -0
- package/dist/skills/poc-md-loader/markdown-loader.js.map +1 -0
- package/dist/skills/poc-md-loader/runner.d.ts +24 -0
- package/dist/skills/poc-md-loader/runner.d.ts.map +1 -0
- package/dist/skills/poc-md-loader/runner.js +57 -0
- package/dist/skills/poc-md-loader/runner.js.map +1 -0
- package/dist/skills/poc-md-loader/vitest.poc.config.d.ts +3 -0
- package/dist/skills/poc-md-loader/vitest.poc.config.d.ts.map +1 -0
- package/dist/skills/poc-md-loader/vitest.poc.config.js +13 -0
- package/dist/skills/poc-md-loader/vitest.poc.config.js.map +1 -0
- package/dist/skills/poc-md-loader/web-search/script.d.ts +33 -0
- package/dist/skills/poc-md-loader/web-search/script.d.ts.map +1 -0
- package/dist/skills/poc-md-loader/web-search/script.js +75 -0
- package/dist/skills/poc-md-loader/web-search/script.js.map +1 -0
- package/dist/skills/record-outcome.d.ts +4 -4
- package/dist/skills/send-email.d.ts.map +1 -1
- package/dist/skills/send-email.js +15 -3
- package/dist/skills/send-email.js.map +1 -1
- package/dist/skills/slack-notify.d.ts +4 -4
- package/dist/skills/starknet-balance.d.ts +1 -1
- package/dist/skills/telegram-notify.d.ts +4 -4
- package/dist/skills/web-search.d.ts +1 -1
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/test-brain-port.d.ts +4 -0
- package/dist/testing/test-brain-port.d.ts.map +1 -1
- package/dist/testing/test-brain-port.js +75 -20
- package/dist/testing/test-brain-port.js.map +1 -1
- package/dist/testing/test-event-bus.d.ts.map +1 -1
- package/dist/testing/test-event-bus.js +89 -36
- package/dist/testing/test-event-bus.js.map +1 -1
- package/dist/trace/schema.d.ts +1 -1
- package/dist/trace/schema.d.ts.map +1 -1
- package/dist/trace/schema.js +1 -1
- package/dist/trace/schema.js.map +1 -1
- package/dist/verify/formal/index.d.ts +44 -0
- package/dist/verify/formal/index.d.ts.map +1 -0
- package/dist/verify/formal/index.js +98 -0
- package/dist/verify/formal/index.js.map +1 -0
- package/dist/verify/formal/policy.d.ts +105 -0
- package/dist/verify/formal/policy.d.ts.map +1 -0
- package/dist/verify/formal/policy.js +159 -0
- package/dist/verify/formal/policy.js.map +1 -0
- package/dist/verify/formal/result.d.ts +50 -0
- package/dist/verify/formal/result.d.ts.map +1 -0
- package/dist/verify/formal/result.js +21 -0
- package/dist/verify/formal/result.js.map +1 -0
- package/dist/verify/formal/solver.d.ts +67 -0
- package/dist/verify/formal/solver.d.ts.map +1 -0
- package/dist/verify/formal/solver.js +184 -0
- package/dist/verify/formal/solver.js.map +1 -0
- package/dist/verify/formal/spec-language.d.ts +80 -0
- package/dist/verify/formal/spec-language.d.ts.map +1 -0
- package/dist/verify/formal/spec-language.js +219 -0
- package/dist/verify/formal/spec-language.js.map +1 -0
- package/docs/attestation.md +199 -0
- package/docs/identity.md +193 -0
- package/package.json +34 -17
- package/src/adapters/llm/anthropic-direct.ts +51 -0
- package/src/adapters/llm/cascade.ts +64 -19
- package/src/adapters/llm/litellm.ts +49 -0
- package/src/compute/difficulty-estimator.ts +111 -0
- package/src/compute/strategies/mixture-of-agents.ts +150 -0
- package/src/compute/strategies/tree-of-thoughts.ts +293 -0
- package/src/compute/strategies/two-phase-orient.ts +147 -0
- package/src/container/protocol.ts +243 -0
- package/src/container/runtime.ts +424 -0
- package/src/db/migrations/026_formal_verify_results.sql +30 -0
- package/src/identity/agent-persona.ts +203 -0
- package/src/identity/persona-prompt.ts +84 -0
- package/src/identity/persona-schema.ts +127 -0
- package/src/index.ts +338 -1
- package/src/memory/episodic-rrf.ts +224 -0
- package/src/mesh/attenuation.ts +190 -0
- package/src/mesh/delegate.ts +254 -0
- package/src/mesh/dispatcher.ts +301 -0
- package/src/mesh/index.ts +39 -0
- package/src/mesh/types.ts +31 -0
- package/src/orchestration/ooda/skills.ts +177 -0
- package/src/ports/bastion-action.contract.test.ts +355 -0
- package/src/ports/bastion-action.ts +198 -0
- package/src/ports/brain.ts +177 -15
- package/src/ports/citadel-action.contract.test.ts +430 -0
- package/src/ports/citadel-action.ts +174 -0
- package/src/ports/compliance-contract.ts +191 -0
- package/src/ports/db.ts +98 -0
- package/src/ports/delegation.contract.test.ts +428 -0
- package/src/ports/delegation.ts +211 -0
- package/src/ports/event-bus.ts +133 -0
- package/src/ports/federation.contract.test.ts +355 -0
- package/src/ports/federation.ts +190 -0
- package/src/ports/index.ts +186 -1
- package/src/ports/llm-provider.ts +123 -0
- package/src/ports/logger.ts +104 -0
- package/src/ports/manifest-registry.contract.test.ts +324 -0
- package/src/ports/manifest-registry.ts +188 -0
- package/src/ports/observability.contract.test.ts +315 -0
- package/src/ports/observability.ts +150 -0
- package/src/ports/outcome.ts +69 -0
- package/src/ports/privacy.contract.test.ts +413 -0
- package/src/ports/privacy.ts +207 -0
- package/src/ports/tenant-context.contract.test.ts +454 -0
- package/src/ports/tenant-context.ts +150 -0
- package/src/ports/vauban-finance-action.contract.test.ts +335 -0
- package/src/ports/vauban-finance-action.ts +166 -0
- package/src/ports/workflow-runtime.ts +327 -0
- package/src/proof/cert-verify.ts +249 -0
- package/src/replay/replay.ts +11 -8
- package/src/retry/index.ts +227 -0
- package/src/retry/presets.ts +75 -0
- package/src/skill-loop/ab-runner.ts +196 -0
- package/src/skill-loop/adoption.ts +188 -0
- package/src/skill-loop/candidate.ts +75 -0
- package/src/skill-loop/evaluator.ts +238 -0
- package/src/skill-loop/index.ts +51 -0
- package/src/skill-loop/reflexion-replay.ts +173 -0
- package/src/skill-loop/sign-off.ts +247 -0
- package/src/skill-loop/value-metric.ts +120 -0
- package/src/skill-loop/versioning.ts +75 -0
- package/src/skill-manifest/anchor.ts +401 -0
- package/src/skill-manifest/builder.ts +129 -0
- package/src/skill-manifest/index.ts +18 -0
- package/src/skill-manifest/types.ts +72 -0
- package/src/skill-manifest/verifier.ts +198 -0
- package/src/skills/errors.ts +30 -2
- package/src/skills/index.ts +19 -0
- package/src/skills/markdown/loader.ts +129 -0
- package/src/skills/markdown/schema.ts +144 -0
- package/src/skills/poc-md-loader/e2e-parity.test.ts +237 -0
- package/src/skills/poc-md-loader/markdown-loader.ts +161 -0
- package/src/skills/poc-md-loader/runner.ts +82 -0
- package/src/skills/poc-md-loader/vitest.poc.config.ts +13 -0
- package/src/skills/poc-md-loader/web-search/SKILL.md +42 -0
- package/src/skills/poc-md-loader/web-search/script.ts +109 -0
- package/src/skills/send-email.ts +15 -3
- package/src/testing/test-brain-port.ts +98 -24
- package/src/testing/test-event-bus.ts +104 -43
- package/src/trace/schema.ts +1 -1
- package/src/verify/formal/index.ts +154 -0
- package/src/verify/formal/policy.ts +253 -0
- package/src/verify/formal/result.ts +52 -0
- package/src/verify/formal/solver.ts +235 -0
- package/src/verify/formal/spec-language.ts +274 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DelegationPort contract tests (S7 spec).
|
|
3
|
+
*
|
|
4
|
+
* Applied to any DelegationPort implementation.
|
|
5
|
+
* Verifies: narrowing R-1 invariant, chain verification, revocation cascade,
|
|
6
|
+
* depth limits, signature validation, cycle detection, temporal frame nesting.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { describe, expect, test } from "vitest";
|
|
10
|
+
import type {
|
|
11
|
+
DelegationClaim,
|
|
12
|
+
RootCapability,
|
|
13
|
+
CapabilityScope,
|
|
14
|
+
} from "./delegation.js";
|
|
15
|
+
import {
|
|
16
|
+
DelegationNotNarrowingError,
|
|
17
|
+
DelegationExpiredError,
|
|
18
|
+
DelegationRevokedError,
|
|
19
|
+
DelegationChainTooDeepError,
|
|
20
|
+
DelegationCycleDetectedError,
|
|
21
|
+
DelegationTemporalFrameError,
|
|
22
|
+
} from "./delegation.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Factory function to create a minimal valid DelegationClaim for testing.
|
|
26
|
+
*/
|
|
27
|
+
function makeDelegationClaim(
|
|
28
|
+
overrides: Partial<DelegationClaim> = {}
|
|
29
|
+
): DelegationClaim {
|
|
30
|
+
const now = new Date();
|
|
31
|
+
const expiresAt = new Date(now.getTime() + 86400000); // +24h
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
id: crypto.randomUUID(),
|
|
35
|
+
parent_id: undefined,
|
|
36
|
+
scope: {
|
|
37
|
+
capabilities: ["read", "write"],
|
|
38
|
+
constraints: [],
|
|
39
|
+
jurisdictions: ["EU.v1"],
|
|
40
|
+
expires_at: expiresAt.toISOString(),
|
|
41
|
+
},
|
|
42
|
+
ed25519_sig:
|
|
43
|
+
"ed25519_" + crypto.randomUUID().replace(/-/g, "").slice(0, 32),
|
|
44
|
+
ttl: 86400,
|
|
45
|
+
issuer: "issuer-agent",
|
|
46
|
+
holder: "holder-agent",
|
|
47
|
+
created_at: now.toISOString(),
|
|
48
|
+
revoked_at: null,
|
|
49
|
+
...overrides,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function makeRootCapability(
|
|
54
|
+
overrides: Partial<RootCapability> = {}
|
|
55
|
+
): RootCapability {
|
|
56
|
+
const expiresAt = new Date(Date.now() + 86400000).toISOString();
|
|
57
|
+
return {
|
|
58
|
+
capabilities: ["read", "write", "delegate"],
|
|
59
|
+
constraints: [],
|
|
60
|
+
jurisdictions: ["EU.v1"],
|
|
61
|
+
expires_at: expiresAt,
|
|
62
|
+
...overrides,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const delegationPortContract = (factory: () => any) => {
|
|
67
|
+
describe("DelegationPort contract", () => {
|
|
68
|
+
test("mintDelegation creates narrowed claim from parent", async () => {
|
|
69
|
+
const port = factory();
|
|
70
|
+
const parent = makeDelegationClaim({
|
|
71
|
+
scope: {
|
|
72
|
+
capabilities: ["read", "write", "delegate"],
|
|
73
|
+
constraints: [],
|
|
74
|
+
jurisdictions: ["EU.v1"],
|
|
75
|
+
expires_at: new Date(Date.now() + 86400000).toISOString(),
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const narrowed: CapabilityScope = {
|
|
80
|
+
capabilities: ["read"], // narrowed from 3 to 1
|
|
81
|
+
constraints: [],
|
|
82
|
+
jurisdictions: ["EU.v1"],
|
|
83
|
+
expires_at: parent.scope.expires_at,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const child = await port.mintDelegation(parent, narrowed, {
|
|
87
|
+
issuerId: parent.issuer,
|
|
88
|
+
holderId: "new-holder",
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
expect(child.parent_id).toBe(parent.id);
|
|
92
|
+
expect(child.scope.capabilities).toEqual(["read"]);
|
|
93
|
+
expect(child.holder).toBe("new-holder");
|
|
94
|
+
expect(child.ed25519_sig).toBeDefined();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("mintDelegation from RootCapability succeeds", async () => {
|
|
98
|
+
const port = factory();
|
|
99
|
+
const root = makeRootCapability();
|
|
100
|
+
|
|
101
|
+
const narrowed: CapabilityScope = {
|
|
102
|
+
capabilities: ["read"],
|
|
103
|
+
constraints: [],
|
|
104
|
+
jurisdictions: ["EU.v1"],
|
|
105
|
+
expires_at: root.expires_at,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const claim = await port.mintDelegation(root, narrowed, {
|
|
109
|
+
issuerId: "root-agent",
|
|
110
|
+
holderId: "delegatee-agent",
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
expect(claim.parent_id).toBeUndefined();
|
|
114
|
+
expect(claim.scope.capabilities).toEqual(["read"]);
|
|
115
|
+
expect(claim.issuer).toBe("root-agent");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("mintDelegation rejects R-1 violation (capability expansion)", async () => {
|
|
119
|
+
const port = factory();
|
|
120
|
+
const parent = makeDelegationClaim({
|
|
121
|
+
scope: {
|
|
122
|
+
capabilities: ["read"],
|
|
123
|
+
constraints: [],
|
|
124
|
+
jurisdictions: ["EU.v1"],
|
|
125
|
+
expires_at: new Date(Date.now() + 86400000).toISOString(),
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const expanded: CapabilityScope = {
|
|
130
|
+
capabilities: ["read", "write"], // expanded from 1 to 2 — R-1 violation
|
|
131
|
+
constraints: [],
|
|
132
|
+
jurisdictions: ["EU.v1"],
|
|
133
|
+
expires_at: parent.scope.expires_at,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
await expect(
|
|
137
|
+
port.mintDelegation(parent, expanded, { holderId: "attacker" })
|
|
138
|
+
).rejects.toThrow(DelegationNotNarrowingError);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("mintDelegation rejects jurisdiction expansion (R-1 violation)", async () => {
|
|
142
|
+
const port = factory();
|
|
143
|
+
const parent = makeDelegationClaim({
|
|
144
|
+
scope: {
|
|
145
|
+
capabilities: ["read"],
|
|
146
|
+
constraints: [],
|
|
147
|
+
jurisdictions: ["EU.v1"],
|
|
148
|
+
expires_at: new Date(Date.now() + 86400000).toISOString(),
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const expanded: CapabilityScope = {
|
|
153
|
+
capabilities: ["read"],
|
|
154
|
+
constraints: [],
|
|
155
|
+
jurisdictions: ["EU.v1", "UK.v1"], // expanded — R-1 violation
|
|
156
|
+
expires_at: parent.scope.expires_at,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
await expect(
|
|
160
|
+
port.mintDelegation(parent, expanded, { holderId: "attacker" })
|
|
161
|
+
).rejects.toThrow(DelegationNotNarrowingError);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test("verifyChain validates full chain from leaf to root", async () => {
|
|
165
|
+
const port = factory();
|
|
166
|
+
|
|
167
|
+
const grandparent = makeDelegationClaim({
|
|
168
|
+
id: "gp-1",
|
|
169
|
+
parent_id: undefined,
|
|
170
|
+
});
|
|
171
|
+
const parent = makeDelegationClaim({
|
|
172
|
+
id: "p-1",
|
|
173
|
+
parent_id: "gp-1",
|
|
174
|
+
issuer: "gp-agent",
|
|
175
|
+
});
|
|
176
|
+
const child = makeDelegationClaim({
|
|
177
|
+
id: "c-1",
|
|
178
|
+
parent_id: "p-1",
|
|
179
|
+
issuer: "p-agent",
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const result = await port.verifyChain(child);
|
|
183
|
+
expect(result.chain_depth).toBeGreaterThanOrEqual(1);
|
|
184
|
+
expect(grandparent.id).toBeDefined();
|
|
185
|
+
expect(parent.parent_id).toBe("gp-1");
|
|
186
|
+
if (result.valid) {
|
|
187
|
+
expect(result.errors.length).toBe(0);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("verifyChain rejects expired claim", async () => {
|
|
192
|
+
const port = factory();
|
|
193
|
+
const now = new Date();
|
|
194
|
+
const expired = new Date(now.getTime() - 3600000); // 1h ago
|
|
195
|
+
|
|
196
|
+
const claim = makeDelegationClaim({
|
|
197
|
+
scope: {
|
|
198
|
+
capabilities: ["read"],
|
|
199
|
+
constraints: [],
|
|
200
|
+
jurisdictions: ["EU.v1"],
|
|
201
|
+
expires_at: expired.toISOString(), // already expired
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
const result = await port.verifyChain(claim);
|
|
206
|
+
expect(result.valid).toBe(false);
|
|
207
|
+
expect(result.errors.some((e: string) => e.includes("expired"))).toBe(
|
|
208
|
+
true
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test("revoke cascades to all descendants", async () => {
|
|
213
|
+
const port = factory();
|
|
214
|
+
|
|
215
|
+
const parent = makeDelegationClaim({ id: "p-1" });
|
|
216
|
+
const child1 = makeDelegationClaim({
|
|
217
|
+
id: "c-1",
|
|
218
|
+
parent_id: "p-1",
|
|
219
|
+
});
|
|
220
|
+
const child2 = makeDelegationClaim({
|
|
221
|
+
id: "c-2",
|
|
222
|
+
parent_id: "p-1",
|
|
223
|
+
});
|
|
224
|
+
const grandchild = makeDelegationClaim({
|
|
225
|
+
id: "gc-1",
|
|
226
|
+
parent_id: "c-1",
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const revokedCount = await port.revoke("p-1", {
|
|
230
|
+
reason: "testing cascade",
|
|
231
|
+
cascade: true,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
expect(revokedCount).toBeGreaterThanOrEqual(1);
|
|
235
|
+
expect(parent.id).toBe("p-1");
|
|
236
|
+
expect(child1.parent_id).toBe("p-1");
|
|
237
|
+
expect(child2.parent_id).toBe("p-1");
|
|
238
|
+
expect(grandchild.parent_id).toBe("c-1");
|
|
239
|
+
|
|
240
|
+
const childRevoked = await port.isRevoked("c-1");
|
|
241
|
+
expect(childRevoked).toBe(true);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test("verifyChain rejects revoked ancestor", async () => {
|
|
245
|
+
const port = factory();
|
|
246
|
+
|
|
247
|
+
const parent = makeDelegationClaim({
|
|
248
|
+
id: "p-1",
|
|
249
|
+
revoked_at: new Date().toISOString(),
|
|
250
|
+
});
|
|
251
|
+
const child = makeDelegationClaim({
|
|
252
|
+
id: "c-1",
|
|
253
|
+
parent_id: "p-1",
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
expect(parent.revoked_at).toBeDefined();
|
|
257
|
+
expect(child.parent_id).toBe("p-1");
|
|
258
|
+
|
|
259
|
+
const result = await port.verifyChain(child);
|
|
260
|
+
expect(result.valid).toBe(false);
|
|
261
|
+
expect(result.errors.some((e: string) => e.includes("revoked"))).toBe(
|
|
262
|
+
true
|
|
263
|
+
);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test("verifyChain enforces max_depth limit (V0: max=5)", async () => {
|
|
267
|
+
const port = factory();
|
|
268
|
+
|
|
269
|
+
// Create a chain 6 levels deep (violates V0 max_depth=5)
|
|
270
|
+
let claim = makeDelegationClaim({ id: "level-0", parent_id: undefined });
|
|
271
|
+
for (let i = 1; i < 6; i++) {
|
|
272
|
+
claim = makeDelegationClaim({
|
|
273
|
+
id: `level-${i}`,
|
|
274
|
+
parent_id: `level-${i - 1}`,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const result = await port.verifyChain(claim);
|
|
279
|
+
// May fail or set chain_depth > max_depth depending on implementation
|
|
280
|
+
expect(result.chain_depth).toBeGreaterThan(0);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test("verifyChain detects cycle (I-S7-4 invariant)", async () => {
|
|
284
|
+
const port = factory();
|
|
285
|
+
|
|
286
|
+
// Claim that points back to itself (invalid cycle)
|
|
287
|
+
const cycleClaimId = "cycle-1";
|
|
288
|
+
const cycleClaim = makeDelegationClaim({
|
|
289
|
+
id: cycleClaimId,
|
|
290
|
+
parent_id: cycleClaimId, // points to itself — cycle
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const result = await port.verifyChain(cycleClaim);
|
|
294
|
+
expect(result.valid).toBe(false);
|
|
295
|
+
expect(result.errors.some((e: string) => e.includes("cycle"))).toBe(true);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test("isRevoked returns true for revoked claim (cache TTL 60s)", async () => {
|
|
299
|
+
const port = factory();
|
|
300
|
+
const claim = makeDelegationClaim({
|
|
301
|
+
id: "revoked-1",
|
|
302
|
+
revoked_at: new Date().toISOString(),
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
expect(claim.revoked_at).toBeDefined();
|
|
306
|
+
const revoked = await port.isRevoked("revoked-1");
|
|
307
|
+
expect(revoked).toBe(true);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test("getChain returns full path from leaf to root", async () => {
|
|
311
|
+
const port = factory();
|
|
312
|
+
|
|
313
|
+
const root = makeDelegationClaim({
|
|
314
|
+
id: "root",
|
|
315
|
+
parent_id: undefined,
|
|
316
|
+
});
|
|
317
|
+
const level1 = makeDelegationClaim({
|
|
318
|
+
id: "level1",
|
|
319
|
+
parent_id: "root",
|
|
320
|
+
});
|
|
321
|
+
const level2 = makeDelegationClaim({
|
|
322
|
+
id: "level2",
|
|
323
|
+
parent_id: "level1",
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
expect(root.parent_id).toBeUndefined();
|
|
327
|
+
expect(level1.parent_id).toBe("root");
|
|
328
|
+
expect(level2.parent_id).toBe("level1");
|
|
329
|
+
|
|
330
|
+
const chain = await port.getChain("level2");
|
|
331
|
+
// Should return at least the queried claim
|
|
332
|
+
expect(chain.length).toBeGreaterThanOrEqual(1);
|
|
333
|
+
expect(chain[0]?.id).toBe("level2");
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
test("getDescendants returns all transitive children", async () => {
|
|
337
|
+
const port = factory();
|
|
338
|
+
|
|
339
|
+
const parent = makeDelegationClaim({ id: "parent" });
|
|
340
|
+
const child1 = makeDelegationClaim({
|
|
341
|
+
id: "child1",
|
|
342
|
+
parent_id: "parent",
|
|
343
|
+
});
|
|
344
|
+
const child2 = makeDelegationClaim({
|
|
345
|
+
id: "child2",
|
|
346
|
+
parent_id: "parent",
|
|
347
|
+
});
|
|
348
|
+
const grandchild = makeDelegationClaim({
|
|
349
|
+
id: "grandchild",
|
|
350
|
+
parent_id: "child1",
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
expect(parent.id).toBe("parent");
|
|
354
|
+
expect(child1.parent_id).toBe("parent");
|
|
355
|
+
expect(child2.parent_id).toBe("parent");
|
|
356
|
+
expect(grandchild.parent_id).toBe("child1");
|
|
357
|
+
|
|
358
|
+
const descendants = await port.getDescendants("parent");
|
|
359
|
+
// Should include all descendants
|
|
360
|
+
const ids = descendants.map((c: DelegationClaim) => c.id);
|
|
361
|
+
expect(ids).toContain("child1");
|
|
362
|
+
expect(ids).toContain("child2");
|
|
363
|
+
expect(ids).toContain("grandchild");
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// ─── Error type tests ─────────────────────────────────────────────────────
|
|
369
|
+
|
|
370
|
+
describe("DelegationPort — error types", () => {
|
|
371
|
+
test("DelegationNotNarrowingError captures violation type", () => {
|
|
372
|
+
const err = new DelegationNotNarrowingError(
|
|
373
|
+
"parent-1",
|
|
374
|
+
"child-1",
|
|
375
|
+
"capability_expansion"
|
|
376
|
+
);
|
|
377
|
+
expect(err.parentId).toBe("parent-1");
|
|
378
|
+
expect(err.childId).toBe("child-1");
|
|
379
|
+
expect(err.violationType).toBe("capability_expansion");
|
|
380
|
+
expect(err.name).toBe("DelegationNotNarrowingError");
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
test("DelegationExpiredError captures expiry timestamp", () => {
|
|
384
|
+
const expiresAt = "2025-01-01T00:00:00Z";
|
|
385
|
+
const err = new DelegationExpiredError("claim-1", expiresAt);
|
|
386
|
+
expect(err.claimId).toBe("claim-1");
|
|
387
|
+
expect(err.expiresAt).toBe(expiresAt);
|
|
388
|
+
expect(err.name).toBe("DelegationExpiredError");
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
test("DelegationRevokedError captures revocation details", () => {
|
|
392
|
+
const revokedAt = new Date().toISOString();
|
|
393
|
+
const err = new DelegationRevokedError(
|
|
394
|
+
"claim-1",
|
|
395
|
+
revokedAt,
|
|
396
|
+
"security incident"
|
|
397
|
+
);
|
|
398
|
+
expect(err.claimId).toBe("claim-1");
|
|
399
|
+
expect(err.revokedAt).toBe(revokedAt);
|
|
400
|
+
expect(err.reason).toBe("security incident");
|
|
401
|
+
expect(err.name).toBe("DelegationRevokedError");
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
test("DelegationChainTooDeepError captures depth bounds", () => {
|
|
405
|
+
const err = new DelegationChainTooDeepError("claim-1", 7, 5);
|
|
406
|
+
expect(err.claimId).toBe("claim-1");
|
|
407
|
+
expect(err.depth).toBe(7);
|
|
408
|
+
expect(err.maxDepth).toBe(5);
|
|
409
|
+
expect(err.name).toBe("DelegationChainTooDeepError");
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
test("DelegationCycleDetectedError captures cycle subject", () => {
|
|
413
|
+
const err = new DelegationCycleDetectedError("claim-1", "cycle-subject-1");
|
|
414
|
+
expect(err.claimId).toBe("claim-1");
|
|
415
|
+
expect(err.cycleSubject).toBe("cycle-subject-1");
|
|
416
|
+
expect(err.name).toBe("DelegationCycleDetectedError");
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
test("DelegationTemporalFrameError captures temporal issue", () => {
|
|
420
|
+
const err = new DelegationTemporalFrameError(
|
|
421
|
+
"claim-1",
|
|
422
|
+
"temporal_nesting_violated"
|
|
423
|
+
);
|
|
424
|
+
expect(err.claimId).toBe("claim-1");
|
|
425
|
+
expect(err.reason).toBe("temporal_nesting_violated");
|
|
426
|
+
expect(err.name).toBe("DelegationTemporalFrameError");
|
|
427
|
+
});
|
|
428
|
+
});
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DelegationPort — delegation via → operator (Claim Algebra, S7 spec).
|
|
3
|
+
*
|
|
4
|
+
* Implements capability narrowing (R-1 invariant: child ⊆ parent),
|
|
5
|
+
* chain verification, revocation cascade, and depth limits.
|
|
6
|
+
* Ed25519 signatures, max_depth=5 V0 (configurable 1..10 Enterprise).
|
|
7
|
+
*
|
|
8
|
+
* Spec: docs/plans/PreCarre/canonical/specs/S7.md
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ─── Capability and constraint types ───────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
export interface Constraint {
|
|
14
|
+
readonly type: string; // e.g. "time_window", "rate_limit", "jurisdiction"
|
|
15
|
+
readonly value: string | number | boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CapabilityScope {
|
|
19
|
+
readonly capabilities: ReadonlyArray<string>; // e.g. ["read", "write", "delegate"]
|
|
20
|
+
readonly constraints: ReadonlyArray<Constraint>;
|
|
21
|
+
readonly jurisdictions: ReadonlyArray<string>; // e.g. ["EU.v1", "FR.v1"]
|
|
22
|
+
readonly expires_at: string; // ISO 8601
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ─── Delegation claim types ────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
export interface DelegationClaim {
|
|
28
|
+
readonly id: string; // UUID
|
|
29
|
+
readonly parent_id?: string; // parent claim UUID (undefined for root)
|
|
30
|
+
readonly scope: CapabilityScope;
|
|
31
|
+
readonly ed25519_sig: string; // hex-encoded Ed25519 signature
|
|
32
|
+
readonly ttl: number; // seconds
|
|
33
|
+
readonly issuer: string; // agent_id of delegator
|
|
34
|
+
readonly holder: string; // agent_id of delegatee
|
|
35
|
+
readonly created_at: string; // ISO 8601
|
|
36
|
+
readonly revoked_at?: string | null; // null = not revoked, string = revocation timestamp
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface RootCapability {
|
|
40
|
+
readonly capabilities: ReadonlyArray<string>;
|
|
41
|
+
readonly constraints: ReadonlyArray<Constraint>;
|
|
42
|
+
readonly jurisdictions: ReadonlyArray<string>;
|
|
43
|
+
readonly expires_at: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ─── Verification result ──────────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
export interface VerifyChainResult {
|
|
49
|
+
readonly valid: boolean;
|
|
50
|
+
readonly chain_depth: number;
|
|
51
|
+
readonly errors: string[]; // empty if valid
|
|
52
|
+
readonly chain: ReadonlyArray<DelegationClaim>; // path from leaf to root
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ─── Revocation options ───────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
export interface RevocationOpts {
|
|
58
|
+
readonly reason: string; // audit trail
|
|
59
|
+
readonly cascade?: boolean; // revoke descendants (default true)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ─── DelegationPort interface ─────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
export interface DelegationPort {
|
|
65
|
+
/**
|
|
66
|
+
* Mint a new delegation from a parent capability or root claim.
|
|
67
|
+
* Enforces R-1 narrowing: delegated scope must be ⊆ parent scope.
|
|
68
|
+
* Returns signed DelegationClaim or throws DelegationNotNarrowingError.
|
|
69
|
+
*/
|
|
70
|
+
mintDelegation(
|
|
71
|
+
parent: DelegationClaim | RootCapability,
|
|
72
|
+
narrowed: CapabilityScope,
|
|
73
|
+
opts?: { ttl?: number; issuerId?: string; holderId?: string }
|
|
74
|
+
): Promise<DelegationClaim>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Verify a delegation claim chain from leaf to root.
|
|
78
|
+
* Checks: Ed25519 signatures, R-1 narrowing at each step,
|
|
79
|
+
* temporal frame nesting, revocation status, cycle detection, max_depth.
|
|
80
|
+
* Returns VerifyChainResult with full chain or error list.
|
|
81
|
+
*/
|
|
82
|
+
verifyChain(claim: DelegationClaim): Promise<VerifyChainResult>;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Revoke a delegation claim.
|
|
86
|
+
* Propagates to all descendants (transitive revocation, ¬Revocation semantics).
|
|
87
|
+
* Returns count of claims revoked (including transitive descendants).
|
|
88
|
+
*/
|
|
89
|
+
revoke(claimId: string, opts?: RevocationOpts): Promise<number>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get a claim by id (from persistent storage).
|
|
93
|
+
* Returns null if not found.
|
|
94
|
+
*/
|
|
95
|
+
getClaim(claimId: string): Promise<DelegationClaim | null>;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get all claims in a delegation chain from leaf to root.
|
|
99
|
+
* Follows parent_id pointers to build full chain.
|
|
100
|
+
*/
|
|
101
|
+
getChain(claimId: string): Promise<DelegationClaim[]>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Check if a claim is revoked (checks cache + on-chain, TTL 60s).
|
|
105
|
+
* Returns true if revoked, false if valid.
|
|
106
|
+
*/
|
|
107
|
+
isRevoked(claimId: string): Promise<boolean>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get all descendant claims (transitive children).
|
|
111
|
+
* Used for revocation cascade validation.
|
|
112
|
+
*/
|
|
113
|
+
getDescendants(claimId: string): Promise<DelegationClaim[]>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ─── Typed errors ─────────────────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
export class DelegationNotNarrowingError extends Error {
|
|
119
|
+
constructor(
|
|
120
|
+
public readonly parentId: string,
|
|
121
|
+
public readonly childId: string,
|
|
122
|
+
public readonly violationType: string // "capability_expansion" | "constraint_removal" | "jurisdiction_expansion"
|
|
123
|
+
) {
|
|
124
|
+
super(
|
|
125
|
+
`Delegation R-1 narrowing violated (parent=${parentId}, child=${childId}): ${violationType}`
|
|
126
|
+
);
|
|
127
|
+
this.name = "DelegationNotNarrowingError";
|
|
128
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export class DelegationExpiredError extends Error {
|
|
133
|
+
constructor(
|
|
134
|
+
public readonly claimId: string,
|
|
135
|
+
public readonly expiresAt: string
|
|
136
|
+
) {
|
|
137
|
+
super(`Delegation claim expired (${claimId}): expires_at=${expiresAt}`);
|
|
138
|
+
this.name = "DelegationExpiredError";
|
|
139
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export class DelegationRevokedError extends Error {
|
|
144
|
+
constructor(
|
|
145
|
+
public readonly claimId: string,
|
|
146
|
+
public readonly revokedAt: string,
|
|
147
|
+
public readonly reason?: string
|
|
148
|
+
) {
|
|
149
|
+
super(
|
|
150
|
+
`Delegation claim revoked (${claimId}) at ${revokedAt}${
|
|
151
|
+
reason ? `: ${reason}` : ""
|
|
152
|
+
}`
|
|
153
|
+
);
|
|
154
|
+
this.name = "DelegationRevokedError";
|
|
155
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export class DelegationChainTooDeepError extends Error {
|
|
160
|
+
constructor(
|
|
161
|
+
public readonly claimId: string,
|
|
162
|
+
public readonly depth: number,
|
|
163
|
+
public readonly maxDepth: number
|
|
164
|
+
) {
|
|
165
|
+
super(
|
|
166
|
+
`Delegation chain exceeds max depth (${claimId}): depth=${depth}, max=${maxDepth}`
|
|
167
|
+
);
|
|
168
|
+
this.name = "DelegationChainTooDeepError";
|
|
169
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export class DelegationSignatureInvalidError extends Error {
|
|
174
|
+
constructor(public readonly claimId: string, public readonly reason: string) {
|
|
175
|
+
super(`Delegation signature invalid (${claimId}): ${reason}`);
|
|
176
|
+
this.name = "DelegationSignatureInvalidError";
|
|
177
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export class DelegationCycleDetectedError extends Error {
|
|
182
|
+
constructor(
|
|
183
|
+
public readonly claimId: string,
|
|
184
|
+
public readonly cycleSubject: string
|
|
185
|
+
) {
|
|
186
|
+
super(
|
|
187
|
+
`Delegation cycle detected (${claimId}): subject ${cycleSubject} appears in chain`
|
|
188
|
+
);
|
|
189
|
+
this.name = "DelegationCycleDetectedError";
|
|
190
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export class DelegationNotFoundError extends Error {
|
|
195
|
+
constructor(public readonly claimId: string) {
|
|
196
|
+
super(`Delegation claim not found: ${claimId}`);
|
|
197
|
+
this.name = "DelegationNotFoundError";
|
|
198
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export class DelegationTemporalFrameError extends Error {
|
|
203
|
+
constructor(
|
|
204
|
+
public readonly claimId: string,
|
|
205
|
+
public readonly reason: string // "not_yet_valid" | "temporal_nesting_violated"
|
|
206
|
+
) {
|
|
207
|
+
super(`Delegation temporal frame error (${claimId}): ${reason}`);
|
|
208
|
+
this.name = "DelegationTemporalFrameError";
|
|
209
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
210
|
+
}
|
|
211
|
+
}
|