@sanctuary-framework/mcp-server 1.2.11 → 1.2.13
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/dist/cli.cjs +2375 -201
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2375 -201
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1238 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +388 -0
- package/dist/index.d.ts +388 -0
- package/dist/index.js +1238 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -3522,6 +3522,44 @@ interface ExitBundleArtifactEntry {
|
|
|
3522
3522
|
*/
|
|
3523
3523
|
subkind?: string;
|
|
3524
3524
|
}
|
|
3525
|
+
/**
|
|
3526
|
+
* did:web pointer embedded in the identity binding when the operator
|
|
3527
|
+
* has issued a did:web identifier for the source fortress and asked
|
|
3528
|
+
* the exit-bundle exporter to publish that pointer alongside the
|
|
3529
|
+
* manifest (Recognition-Layer Path C primary build 2).
|
|
3530
|
+
*
|
|
3531
|
+
* The bundle does NOT carry the did:web DID Document itself; the
|
|
3532
|
+
* receiving regime resolves the DID Document via standard DNS + TLS
|
|
3533
|
+
* against `authority_host`. That dependency is intentional: it is
|
|
3534
|
+
* the operator's HTTPS infrastructure that publishes the document,
|
|
3535
|
+
* not Sanctuary's, and it is the receiving regime's resolver that
|
|
3536
|
+
* verifies the document, not Sanctuary's. Recognition flows along
|
|
3537
|
+
* the web's existing trust chain without trusting Sanctuary as a
|
|
3538
|
+
* middleman.
|
|
3539
|
+
*
|
|
3540
|
+
* The signature scheme over the manifest body covers this field by
|
|
3541
|
+
* construction (it lives inside `ExitBundleManifestBody`), so an
|
|
3542
|
+
* attacker who substituted the did:web pointer without re-signing
|
|
3543
|
+
* the body would be rejected at the existing manifest-signature
|
|
3544
|
+
* gate.
|
|
3545
|
+
*/
|
|
3546
|
+
interface ExitBundleDidWebBinding {
|
|
3547
|
+
/**
|
|
3548
|
+
* The did:web URI string the operator published, e.g.,
|
|
3549
|
+
* `did:web:alice.example.com:fortress:abc123`. The receiving
|
|
3550
|
+
* regime resolves this to fetch the DID Document.
|
|
3551
|
+
*/
|
|
3552
|
+
identifier: string;
|
|
3553
|
+
/** Authority host the operator's DID Document is published on. */
|
|
3554
|
+
authority_host: string;
|
|
3555
|
+
/**
|
|
3556
|
+
* Optional ISO 8601 timestamp at which the operator confirmed
|
|
3557
|
+
* HTTPS publication. Surfaces to the verifier as evidence that
|
|
3558
|
+
* the operator believes the document is reachable; the verifier
|
|
3559
|
+
* still re-resolves to confirm.
|
|
3560
|
+
*/
|
|
3561
|
+
published_at?: string;
|
|
3562
|
+
}
|
|
3525
3563
|
/**
|
|
3526
3564
|
* Identity binding embedded in the manifest. Carries only public material.
|
|
3527
3565
|
*/
|
|
@@ -3534,6 +3572,17 @@ interface ExitBundleIdentityBinding {
|
|
|
3534
3572
|
fortress_master_pubkey: string;
|
|
3535
3573
|
/** Optional DID, when one is bound to this identity. */
|
|
3536
3574
|
did?: string;
|
|
3575
|
+
/**
|
|
3576
|
+
* Optional did:web pointer (Recognition-Layer Path C primary build 2).
|
|
3577
|
+
* Present only when the operator has issued a did:web identifier
|
|
3578
|
+
* for the source fortress AND has not explicitly opted out at
|
|
3579
|
+
* export time via `--include-did-web=false`. The receiving regime
|
|
3580
|
+
* resolves the pointer via DNS + TLS to verify the bundle's origin
|
|
3581
|
+
* without trusting Sanctuary as intermediary. Absent on bundles
|
|
3582
|
+
* exported before the recognition-layer integration shipped
|
|
3583
|
+
* (backward-compatible).
|
|
3584
|
+
*/
|
|
3585
|
+
did_web?: ExitBundleDidWebBinding;
|
|
3537
3586
|
}
|
|
3538
3587
|
/**
|
|
3539
3588
|
* v1 manifest body — what the operator's fortress-master signs.
|
|
@@ -3925,6 +3974,37 @@ declare class FilesystemStorage implements StorageBackend {
|
|
|
3925
3974
|
totalSize(): Promise<number>;
|
|
3926
3975
|
}
|
|
3927
3976
|
|
|
3977
|
+
interface ResolveDidWebOpts {
|
|
3978
|
+
/**
|
|
3979
|
+
* Hosts the operator has explicitly allowed for outbound did:web
|
|
3980
|
+
* resolution. Empty array means resolution is disabled and the
|
|
3981
|
+
* call returns synchronously with `host_not_allowed`. This is
|
|
3982
|
+
* the load-bearing opt-in surface for the no-outbound-by-default
|
|
3983
|
+
* rule; the kernel-level Castle Wall egress filter enforces the
|
|
3984
|
+
* same allowlist independently.
|
|
3985
|
+
*/
|
|
3986
|
+
allowed_hosts: string[];
|
|
3987
|
+
/** Resolution timeout. Defaults to 5000ms. */
|
|
3988
|
+
timeout_ms?: number;
|
|
3989
|
+
/**
|
|
3990
|
+
* Optional fetcher override for tests. Defaults to globalThis.fetch.
|
|
3991
|
+
* Production callers should leave this undefined.
|
|
3992
|
+
*/
|
|
3993
|
+
fetcher?: (url: string, init?: {
|
|
3994
|
+
signal?: AbortSignal;
|
|
3995
|
+
}) => Promise<{
|
|
3996
|
+
ok: boolean;
|
|
3997
|
+
status: number;
|
|
3998
|
+
json: () => Promise<unknown>;
|
|
3999
|
+
}>;
|
|
4000
|
+
/**
|
|
4001
|
+
* Optional expected Ed25519 public key. When set, the resolved
|
|
4002
|
+
* document's verificationMethod[0].publicKeyJwk.x must match
|
|
4003
|
+
* (base64url-encoded). Mismatch returns `signature_mismatch`.
|
|
4004
|
+
*/
|
|
4005
|
+
expected_public_key?: Uint8Array;
|
|
4006
|
+
}
|
|
4007
|
+
|
|
3928
4008
|
/**
|
|
3929
4009
|
* Sanctuary MCP Server — Key Derivation
|
|
3930
4010
|
*
|
|
@@ -4052,6 +4132,21 @@ interface ExportExitBundleOptions {
|
|
|
4052
4132
|
* When omitted, the export self-generates an id.
|
|
4053
4133
|
*/
|
|
4054
4134
|
exportApprovalAuditId?: string;
|
|
4135
|
+
/**
|
|
4136
|
+
* Recognition-Layer Path C primary build 2: optional did:web binding
|
|
4137
|
+
* to embed in the manifest's identity_binding. When provided, the
|
|
4138
|
+
* export validates that the binding's identifier resolves (per the
|
|
4139
|
+
* did:web spec) to a pointer over the same authority host as
|
|
4140
|
+
* `binding.authority_host`, and that the operator's fortress public
|
|
4141
|
+
* key matches the key the did:web identifier was issued against
|
|
4142
|
+
* (the export does NOT re-fetch the published DID Document; that
|
|
4143
|
+
* check is the receiving regime's job at import time).
|
|
4144
|
+
*
|
|
4145
|
+
* Omit to skip did:web embedding entirely. Receiving regimes that
|
|
4146
|
+
* import the bundle treat absence as backward-compatible (no
|
|
4147
|
+
* recognition-layer verification step).
|
|
4148
|
+
*/
|
|
4149
|
+
didWeb?: ExitBundleDidWebBinding;
|
|
4055
4150
|
}
|
|
4056
4151
|
interface ExportExitBundleResult {
|
|
4057
4152
|
bundle_dir: string;
|
|
@@ -4090,6 +4185,40 @@ interface ImportExitBundleOptions {
|
|
|
4090
4185
|
* operator in to an explicit relaxed verdict (Tier 1 confirmation in CLI).
|
|
4091
4186
|
*/
|
|
4092
4187
|
acceptUnverifiableAttestations?: boolean;
|
|
4188
|
+
/**
|
|
4189
|
+
* Recognition-Layer Path C primary build 2: hosts the importing
|
|
4190
|
+
* operator has explicitly allowed for outbound did:web resolution.
|
|
4191
|
+
* Empty array means resolution refuses to leave the fortress
|
|
4192
|
+
* (preserves no-outbound-by-default). The same allowlist is also
|
|
4193
|
+
* enforced at the kernel level by the operator's Castle Wall egress
|
|
4194
|
+
* filter; this option is the application-level coordinator.
|
|
4195
|
+
*
|
|
4196
|
+
* Absent + did_web present in manifest = the importer surfaces a
|
|
4197
|
+
* warning and proceeds with the manifest-signature check alone
|
|
4198
|
+
* (degraded confidence). The operator can re-run with the
|
|
4199
|
+
* allowlist set or with `skipDidWebVerify: true`.
|
|
4200
|
+
*/
|
|
4201
|
+
didWebAllowedHosts?: string[];
|
|
4202
|
+
/**
|
|
4203
|
+
* Recognition-Layer Path C primary build 2: when true, the importer
|
|
4204
|
+
* skips did:web resolution entirely even if the manifest carries a
|
|
4205
|
+
* did_web binding. Operator surface: CLI flag
|
|
4206
|
+
* `--skip-did-web-verify`. Tradeoff is operator-visible: skipping
|
|
4207
|
+
* loses the recognition-layer cross-check that the bundle's claimed
|
|
4208
|
+
* origin matches the published DID Document.
|
|
4209
|
+
*/
|
|
4210
|
+
skipDidWebVerify?: boolean;
|
|
4211
|
+
/**
|
|
4212
|
+
* Recognition-Layer Path C primary build 2: optional fetcher
|
|
4213
|
+
* override for tests. Defaults to globalThis.fetch via the did:web
|
|
4214
|
+
* foundation's resolver. Production callers leave undefined.
|
|
4215
|
+
*/
|
|
4216
|
+
didWebFetcher?: ResolveDidWebOpts["fetcher"];
|
|
4217
|
+
/**
|
|
4218
|
+
* Recognition-Layer Path C primary build 2: resolution timeout.
|
|
4219
|
+
* Defaults to the did:web foundation's 5000ms default.
|
|
4220
|
+
*/
|
|
4221
|
+
didWebTimeoutMs?: number;
|
|
4093
4222
|
}
|
|
4094
4223
|
/**
|
|
4095
4224
|
* Structured error raised by `importExitBundle` for codes the CLI / hub want
|
|
@@ -7626,6 +7755,250 @@ declare class HandoffLog {
|
|
|
7626
7755
|
private normalize;
|
|
7627
7756
|
}
|
|
7628
7757
|
|
|
7758
|
+
/**
|
|
7759
|
+
* Sanctuary v1.3 WP-V1.3-3 Omega-2 Context-Transfer Extractor.
|
|
7760
|
+
*
|
|
7761
|
+
* Decomposes a handoff into the structured TRANSFERRED-vs-WITHHELD
|
|
7762
|
+
* breakdown the operator's Coordination view renders. Operates on a
|
|
7763
|
+
* `HandoffEntryDetail` (Omega-1 surface) and returns a
|
|
7764
|
+
* `ContextTransferBreakdown`.
|
|
7765
|
+
*
|
|
7766
|
+
* Why this matters: the operator needs to know not just THAT a
|
|
7767
|
+
* handoff happened, but WHAT crossed the boundary. Per-handoff
|
|
7768
|
+
* context-transfer breakdown makes Castle Layer 3 cooperative-MCP
|
|
7769
|
+
* integrity legible at the operator UX layer.
|
|
7770
|
+
*
|
|
7771
|
+
* Three resolution paths in fixed order; first one that produces
|
|
7772
|
+
* usable output wins. Higher paths produce higher confidence.
|
|
7773
|
+
*
|
|
7774
|
+
* Path A: structured-source events. Triggered when the source audit
|
|
7775
|
+
* details payload carries explicit `transferred` and / or `withheld`
|
|
7776
|
+
* arrays / objects. Future Tau-X work will wire the coordinator to
|
|
7777
|
+
* emit these explicitly; the extractor handles them today so when
|
|
7778
|
+
* those emissions arrive, no further code change is needed. Ships
|
|
7779
|
+
* with confidence 1.0.
|
|
7780
|
+
*
|
|
7781
|
+
* Path B: composition events. Triggered when the source audit
|
|
7782
|
+
* operation matches `composition_completed` (Concordia bridge).
|
|
7783
|
+
* Decomposes via the receipt-references graph: items in the receipt
|
|
7784
|
+
* are transferred; items in the source-state-snapshot but not in the
|
|
7785
|
+
* receipt are withheld. Composition events do not flow through the
|
|
7786
|
+
* audit log today (mesh-only signed envelopes; same finding as Phi-3
|
|
7787
|
+
* cross-agent-chatter watcher and Omega-1's HandoffLog union scope);
|
|
7788
|
+
* Path B is scaffolded so when composition wires audit emissions,
|
|
7789
|
+
* extraction extends. Ships with confidence 0.9 when present.
|
|
7790
|
+
*
|
|
7791
|
+
* Path C: heuristic fallback. Triggered when neither A nor B fires
|
|
7792
|
+
* (the common case at v1.3 Omega-2 since current Tau-3 audit
|
|
7793
|
+
* emissions are minimal and composition is mesh-only). Derives
|
|
7794
|
+
* transferred from the policy_rule_id (cross_harness_approval) or
|
|
7795
|
+
* task-scope category (v1.1_local_handoff via the source audit
|
|
7796
|
+
* payload's reason_class + status). Ships with confidence 0.5.
|
|
7797
|
+
*
|
|
7798
|
+
* LLM-assist fallback. Optional. Triggered when Path C returns a
|
|
7799
|
+
* low-confidence result (no clear category match) AND a substrate
|
|
7800
|
+
* selector is supplied. Routes through `selector.invokeClassify` on
|
|
7801
|
+
* the coordination surface. Failure is silent (degrade-not-destroy);
|
|
7802
|
+
* the caller still gets the heuristic Path C result with confidence
|
|
7803
|
+
* 0.3. Ships with confidence 0.6 on success.
|
|
7804
|
+
*
|
|
7805
|
+
* Castle-walking discipline:
|
|
7806
|
+
* - No new outbound surface. The substrate selector is the only
|
|
7807
|
+
* LLM-capable channel and is opt-in via dependency injection.
|
|
7808
|
+
* - Reads server-local audit log + Concordia receipts only.
|
|
7809
|
+
* - Encryption boundary holds.
|
|
7810
|
+
* - Multi-fortress isolation preserved by the caller-supplied
|
|
7811
|
+
* HandoffEntryDetail (which is fortress-scoped via Omega-1).
|
|
7812
|
+
*/
|
|
7813
|
+
|
|
7814
|
+
/** Extractor dependency contract. */
|
|
7815
|
+
interface ContextTransferExtractorDeps {
|
|
7816
|
+
/** Optional LLM-assist substrate selector. Off by default. */
|
|
7817
|
+
substrateSelector?: SubstrateSelector;
|
|
7818
|
+
}
|
|
7819
|
+
|
|
7820
|
+
/**
|
|
7821
|
+
* Sanctuary v1.3 WP-V1.3-3 Omega-3 Workflow Grouper.
|
|
7822
|
+
*
|
|
7823
|
+
* CLOSES WP-V1.3-3 Coordination Handoff Visualization. Omega-1 (#191)
|
|
7824
|
+
* shipped the chronological handoff log; Omega-2 (#196) shipped the
|
|
7825
|
+
* per-handoff context-transfer breakdown; Omega-3 lifts isolated
|
|
7826
|
+
* handoff events into multi-handoff WORKFLOWS so the operator finally
|
|
7827
|
+
* sees the shape of a multi-agent collaboration as a single object:
|
|
7828
|
+
* who started it, who participated, how recently it was active, and
|
|
7829
|
+
* whether it is still in progress, stalled, or done.
|
|
7830
|
+
*
|
|
7831
|
+
* Pure functions. No I/O, no clock side effects beyond the optional
|
|
7832
|
+
* `now` argument for deterministic state determination. Tests inject
|
|
7833
|
+
* synthetic `HandoffEntry[]` and assert the grouping + state
|
|
7834
|
+
* decisions directly.
|
|
7835
|
+
*
|
|
7836
|
+
* Grouping algorithm:
|
|
7837
|
+
*
|
|
7838
|
+
* 1. Explicit link path: handoffs whose `workflow_link` field is
|
|
7839
|
+
* non-null group by that key. (At v1.3 Omega-1, Omega-1's
|
|
7840
|
+
* `normalize()` always sets the field to null. Omega-3 still
|
|
7841
|
+
* reads it because future Tau-X work will populate the field
|
|
7842
|
+
* from coordinator-emitted audit payloads, at which point
|
|
7843
|
+
* explicit grouping is the high-confidence path and the heuristic
|
|
7844
|
+
* becomes the fallback.)
|
|
7845
|
+
*
|
|
7846
|
+
* 2. Heuristic chain path: among handoffs without an explicit link,
|
|
7847
|
+
* sort by `observed_at` ascending and walk. A handoff joins an
|
|
7848
|
+
* existing workflow when (a) it shares at least one agent
|
|
7849
|
+
* (sender or recipient) with the most recent member of that
|
|
7850
|
+
* workflow AND (b) the time gap is at most HEURISTIC_WINDOW_MS
|
|
7851
|
+
* (5 minutes). Otherwise it starts a new workflow.
|
|
7852
|
+
*
|
|
7853
|
+
* This relaxes the literal "same source-target pair within 5
|
|
7854
|
+
* minutes" reading of the WP-V1.3-3 scope-lock to also handle
|
|
7855
|
+
* multi-hop chains like Cline -> OpenClaw -> Cursor, which is
|
|
7856
|
+
* what the operator-facing example in the scope-lock describes.
|
|
7857
|
+
* Without this relaxation, every hop in a chain becomes its own
|
|
7858
|
+
* "workflow" of one, and the dashboard surface loses the
|
|
7859
|
+
* legibility the WP-V1.3-3 acceptance gate promises. Documented
|
|
7860
|
+
* as a deviation in the PR body; consistent with how Phi-3
|
|
7861
|
+
* cross-agent-chatter shipped its connectivity heuristic.
|
|
7862
|
+
*
|
|
7863
|
+
* Root handoff: the oldest handoff in a workflow group. (At v1.3 there
|
|
7864
|
+
* is no audit-log surface for "this handoff was caused by handoff X",
|
|
7865
|
+
* so the chronological-oldest is the load-bearing root signal; when
|
|
7866
|
+
* Tau-X wires causal-link payloads, this rule extends without API
|
|
7867
|
+
* change.)
|
|
7868
|
+
*
|
|
7869
|
+
* State determination (in priority order):
|
|
7870
|
+
*
|
|
7871
|
+
* - `completed`: the last member's recipient is OPERATOR_PSEUDO_AGENT
|
|
7872
|
+
* (the workflow returned to the operator for approval / done),
|
|
7873
|
+
* OR the workflow has crossed >=2 hops and the last member returns
|
|
7874
|
+
* to the workflow's root agent (cycle closure).
|
|
7875
|
+
* - `stalled`: no member observed within STALL_THRESHOLD_MS (2h) of
|
|
7876
|
+
* `now`.
|
|
7877
|
+
* - `in_progress`: recent member within STALL_THRESHOLD_MS, no
|
|
7878
|
+
* completion signal.
|
|
7879
|
+
* - `unknown`: insufficient evidence (e.g., an empty member list,
|
|
7880
|
+
* which the grouper never emits but which we accept defensively
|
|
7881
|
+
* for downstream callers that synthesize Workflow objects).
|
|
7882
|
+
*
|
|
7883
|
+
* Castle-walking discipline:
|
|
7884
|
+
*
|
|
7885
|
+
* - No outbound surface. Pure computation over already-server-local
|
|
7886
|
+
* `HandoffEntry` records.
|
|
7887
|
+
* - No LLM call. The heuristic is rule-based.
|
|
7888
|
+
* - Multi-fortress isolation: the grouper takes whatever input it
|
|
7889
|
+
* receives; the caller (a `HandoffLog` instance scoped to ONE
|
|
7890
|
+
* fortress) is responsible for not mixing fortress data. The
|
|
7891
|
+
* route layer reads through `HandoffLog.query()` which already
|
|
7892
|
+
* enforces fortress boundary at the encryption layer.
|
|
7893
|
+
*
|
|
7894
|
+
* Out of scope for Omega-3 (deferred to v1.4+ federation): cross-
|
|
7895
|
+
* fortress workflow tracking. Workflow templating + operator-action
|
|
7896
|
+
* UI on stalled workflows ("auto-restart") are v1.5+ scope.
|
|
7897
|
+
*/
|
|
7898
|
+
|
|
7899
|
+
/** Stable lifecycle-state enum surfaced into the operator UI. */
|
|
7900
|
+
type WorkflowState = "in_progress" | "completed" | "stalled" | "unknown";
|
|
7901
|
+
/**
|
|
7902
|
+
* One multi-handoff workflow grouped from the underlying handoff log.
|
|
7903
|
+
*
|
|
7904
|
+
* `workflow_id` is deterministic (SHA-256 of the root handoff's
|
|
7905
|
+
* `entry_id` truncated to 32 hex chars) so the same workflow re-
|
|
7906
|
+
* derives identical ids across server restarts. Tests and the SSE
|
|
7907
|
+
* stream rely on this stability for diff-based state-change
|
|
7908
|
+
* emission.
|
|
7909
|
+
*
|
|
7910
|
+
* `member_handoffs` is sorted oldest-first and INCLUDES the root.
|
|
7911
|
+
* `involved_agents` is deduplicated, alphabetically ordered. Empty
|
|
7912
|
+
* pseudo-agent strings are dropped; the OPERATOR_PSEUDO_AGENT is
|
|
7913
|
+
* preserved as a member because it signals completion.
|
|
7914
|
+
*/
|
|
7915
|
+
interface Workflow {
|
|
7916
|
+
workflow_id: string;
|
|
7917
|
+
root_handoff: HandoffEntry;
|
|
7918
|
+
member_handoffs: HandoffEntry[];
|
|
7919
|
+
state: WorkflowState;
|
|
7920
|
+
started_at: string;
|
|
7921
|
+
last_activity_at: string;
|
|
7922
|
+
involved_agents: string[];
|
|
7923
|
+
}
|
|
7924
|
+
|
|
7925
|
+
/**
|
|
7926
|
+
* Sanctuary v1.3 WP-V1.3-3 Omega-3 Workflow State Tracker.
|
|
7927
|
+
*
|
|
7928
|
+
* Tracks the most-recently-observed `state` for each workflow_id so
|
|
7929
|
+
* the list-route handler can emit a `coordination_workflow_state_changed`
|
|
7930
|
+
* audit event when a workflow transitions (e.g., from `in_progress`
|
|
7931
|
+
* to `stalled`). Coordination state changes are operator-relevant
|
|
7932
|
+
* signals; the tracker makes them legible without coupling the pure
|
|
7933
|
+
* grouper to side effects.
|
|
7934
|
+
*
|
|
7935
|
+
* The tracker is fortress-scoped: callers construct one instance per
|
|
7936
|
+
* `HandoffLog` (which is itself per-fortress). Different fortresses
|
|
7937
|
+
* cannot leak state transitions into each other's audit logs because
|
|
7938
|
+
* each fortress has its own tracker holding its own snapshot map.
|
|
7939
|
+
*
|
|
7940
|
+
* Sovereignty invariants:
|
|
7941
|
+
*
|
|
7942
|
+
* - No outbound surface. The tracker is a stateful diff observer
|
|
7943
|
+
* over input from `groupHandoffsIntoWorkflows()`; it never reaches
|
|
7944
|
+
* the network and never reads storage on its own.
|
|
7945
|
+
* - No LLM call.
|
|
7946
|
+
* - Pure modulo the in-memory snapshot map. `observe()` is the only
|
|
7947
|
+
* mutating call.
|
|
7948
|
+
*
|
|
7949
|
+
* Threading: callers MUST NOT share a single tracker between
|
|
7950
|
+
* concurrent observers; the route handler in `handoff-routes.ts`
|
|
7951
|
+
* already holds the dispatch-side lock via the request lifecycle.
|
|
7952
|
+
*/
|
|
7953
|
+
|
|
7954
|
+
/**
|
|
7955
|
+
* One emitted state-change event. The route handler audit-emits this
|
|
7956
|
+
* as `coordination_workflow_state_changed` and (optionally) pushes it
|
|
7957
|
+
* to SSE subscribers so the dashboard tab updates without a poll.
|
|
7958
|
+
*/
|
|
7959
|
+
interface WorkflowStateChange {
|
|
7960
|
+
workflow_id: string;
|
|
7961
|
+
previous_state: WorkflowState | "unobserved";
|
|
7962
|
+
new_state: WorkflowState;
|
|
7963
|
+
observed_at: string;
|
|
7964
|
+
}
|
|
7965
|
+
interface WorkflowStateTrackerOptions {
|
|
7966
|
+
/**
|
|
7967
|
+
* Wall-clock provider for the emitted `observed_at` timestamp.
|
|
7968
|
+
* Defaults to a fresh `Date.now()` on each emit. Tests inject a
|
|
7969
|
+
* fixed clock so audit emissions stay deterministic.
|
|
7970
|
+
*/
|
|
7971
|
+
now?: () => Date;
|
|
7972
|
+
}
|
|
7973
|
+
declare class WorkflowStateTracker {
|
|
7974
|
+
private readonly states;
|
|
7975
|
+
private readonly now;
|
|
7976
|
+
constructor(opts?: WorkflowStateTrackerOptions);
|
|
7977
|
+
/**
|
|
7978
|
+
* Diff the supplied workflow list against the last-observed states.
|
|
7979
|
+
* Returns the set of transitions detected this call; the tracker
|
|
7980
|
+
* mutates its internal map to reflect the new states.
|
|
7981
|
+
*
|
|
7982
|
+
* Transitions emitted:
|
|
7983
|
+
* - First observation of a workflow (`previous_state` is the
|
|
7984
|
+
* sentinel `unobserved`). Lets the route handler audit-emit
|
|
7985
|
+
* the initial state so the operator sees workflows as they
|
|
7986
|
+
* surface, not only when they change.
|
|
7987
|
+
* - Subsequent observation where `previous_state !== new_state`.
|
|
7988
|
+
*/
|
|
7989
|
+
observe(workflows: ReadonlyArray<Workflow>): WorkflowStateChange[];
|
|
7990
|
+
/**
|
|
7991
|
+
* Drop a workflow's recorded state. Surfaced for tests + future
|
|
7992
|
+
* "operator dismissed this workflow" affordance; not currently
|
|
7993
|
+
* called by the production wiring.
|
|
7994
|
+
*/
|
|
7995
|
+
forget(workflowId: string): void;
|
|
7996
|
+
/** Reset the tracker. Tests use this between runs. */
|
|
7997
|
+
reset(): void;
|
|
7998
|
+
/** Read-only view of the current snapshot. Useful for diagnostics. */
|
|
7999
|
+
snapshot(): ReadonlyMap<string, WorkflowState>;
|
|
8000
|
+
}
|
|
8001
|
+
|
|
7629
8002
|
/**
|
|
7630
8003
|
* Sanctuary v1.3 WP-V1.3-3 Omega-1 Coordination handoff HTTP routes.
|
|
7631
8004
|
*
|
|
@@ -7754,6 +8127,8 @@ declare class DashboardApprovalChannel implements ApprovalChannel {
|
|
|
7754
8127
|
*/
|
|
7755
8128
|
private handoffLog;
|
|
7756
8129
|
private handoffEventBridge;
|
|
8130
|
+
private handoffContextTransfer;
|
|
8131
|
+
private workflowStateTracker;
|
|
7757
8132
|
private handoffAuditLog;
|
|
7758
8133
|
private handoffOperatorId;
|
|
7759
8134
|
constructor(config: DashboardConfig);
|
|
@@ -7810,6 +8185,19 @@ declare class DashboardApprovalChannel implements ApprovalChannel {
|
|
|
7810
8185
|
eventBridge?: HandoffEventBridge | null;
|
|
7811
8186
|
auditLog?: AuditLog | null;
|
|
7812
8187
|
operatorId?: string | null;
|
|
8188
|
+
/**
|
|
8189
|
+
* v1.3 WP-V1.3-3 Omega-2: context-transfer extractor deps. When
|
|
8190
|
+
* provided, the handoff detail route enriches its response with a
|
|
8191
|
+
* `context_transfer_breakdown` field.
|
|
8192
|
+
*/
|
|
8193
|
+
contextTransfer?: ContextTransferExtractorDeps | null;
|
|
8194
|
+
/**
|
|
8195
|
+
* v1.3 WP-V1.3-3 Omega-3: workflow state tracker. When provided,
|
|
8196
|
+
* the workflow routes emit `coordination_workflow_state_changed`
|
|
8197
|
+
* audit events as the tracker observes transitions and push them
|
|
8198
|
+
* to SSE subscribers.
|
|
8199
|
+
*/
|
|
8200
|
+
workflowStateTracker?: WorkflowStateTracker | null;
|
|
7813
8201
|
}): void;
|
|
7814
8202
|
/**
|
|
7815
8203
|
* v1.3 WP-V1.3-10 dispatch entry point. Called from `handleRequest`
|