@oscharko-dev/keiko-contracts 0.2.8 → 0.2.9
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/.tsbuildinfo +1 -1
- package/dist/bff-wire.d.ts +33 -0
- package/dist/bff-wire.d.ts.map +1 -1
- package/dist/command-runner.d.ts +81 -0
- package/dist/command-runner.d.ts.map +1 -0
- package/dist/command-runner.js +209 -0
- package/dist/container-runtime.d.ts +125 -0
- package/dist/container-runtime.d.ts.map +1 -0
- package/dist/container-runtime.js +287 -0
- package/dist/context-engineering.js +2 -2
- package/dist/discussion-intelligence.d.ts +70 -0
- package/dist/discussion-intelligence.d.ts.map +1 -0
- package/dist/discussion-intelligence.js +440 -0
- package/dist/editor-agent-governance.d.ts +65 -0
- package/dist/editor-agent-governance.d.ts.map +1 -0
- package/dist/editor-agent-governance.js +180 -0
- package/dist/editor-agent.d.ts +29 -1
- package/dist/editor-agent.d.ts.map +1 -1
- package/dist/editor-agent.js +183 -6
- package/dist/editor-builtin-capabilities.d.ts +13 -0
- package/dist/editor-builtin-capabilities.d.ts.map +1 -0
- package/dist/editor-builtin-capabilities.js +135 -0
- package/dist/editor-language-mode-map.d.ts +11 -0
- package/dist/editor-language-mode-map.d.ts.map +1 -0
- package/dist/editor-language-mode-map.js +89 -0
- package/dist/editor-layout.d.ts +37 -0
- package/dist/editor-layout.d.ts.map +1 -1
- package/dist/editor-layout.js +125 -8
- package/dist/editor-workspace-path.d.ts +20 -0
- package/dist/editor-workspace-path.d.ts.map +1 -0
- package/dist/editor-workspace-path.js +133 -0
- package/dist/evidence.d.ts +3 -1
- package/dist/evidence.d.ts.map +1 -1
- package/dist/gateway.d.ts +72 -3
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +73 -3
- package/dist/git-commit-intent.d.ts +28 -0
- package/dist/git-commit-intent.d.ts.map +1 -0
- package/dist/git-commit-intent.js +155 -0
- package/dist/git-commit-policy.d.ts +29 -0
- package/dist/git-commit-policy.d.ts.map +1 -0
- package/dist/git-commit-policy.js +173 -0
- package/dist/git-delivery-action-sheet.d.ts +157 -0
- package/dist/git-delivery-action-sheet.d.ts.map +1 -0
- package/dist/git-delivery-action-sheet.js +430 -0
- package/dist/git-delivery-evidence.d.ts +92 -0
- package/dist/git-delivery-evidence.d.ts.map +1 -0
- package/dist/git-delivery-evidence.js +272 -0
- package/dist/git-delivery-policy.d.ts +40 -0
- package/dist/git-delivery-policy.d.ts.map +1 -0
- package/dist/git-delivery-policy.js +183 -0
- package/dist/git-delivery-provider.d.ts +53 -0
- package/dist/git-delivery-provider.d.ts.map +1 -0
- package/dist/git-delivery-provider.js +96 -0
- package/dist/git-delivery.d.ts +202 -0
- package/dist/git-delivery.d.ts.map +1 -0
- package/dist/git-delivery.js +410 -0
- package/dist/git-history.d.ts +27 -0
- package/dist/git-history.d.ts.map +1 -0
- package/dist/git-history.js +73 -0
- package/dist/git-merge.d.ts +67 -0
- package/dist/git-merge.d.ts.map +1 -0
- package/dist/git-merge.js +323 -0
- package/dist/git-pull-request.d.ts +112 -0
- package/dist/git-pull-request.d.ts.map +1 -0
- package/dist/git-pull-request.js +351 -0
- package/dist/git-repository-agent.d.ts +46 -0
- package/dist/git-repository-agent.d.ts.map +1 -0
- package/dist/git-repository-agent.js +198 -0
- package/dist/git-repository-summary.d.ts +54 -0
- package/dist/git-repository-summary.d.ts.map +1 -0
- package/dist/git-repository-summary.js +105 -0
- package/dist/git-repository.d.ts +60 -0
- package/dist/git-repository.d.ts.map +1 -0
- package/dist/git-repository.js +106 -0
- package/dist/git-sync.d.ts +49 -0
- package/dist/git-sync.d.ts.map +1 -0
- package/dist/git-sync.js +110 -0
- package/dist/index.d.ts +63 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -6
- package/dist/lsp-process.d.ts +38 -0
- package/dist/lsp-process.d.ts.map +1 -0
- package/dist/lsp-process.js +103 -0
- package/dist/runtime-capabilities.d.ts +44 -0
- package/dist/runtime-capabilities.d.ts.map +1 -0
- package/dist/runtime-capabilities.js +141 -0
- package/dist/task-workspace.d.ts +302 -0
- package/dist/task-workspace.d.ts.map +1 -0
- package/dist/task-workspace.js +1236 -0
- package/dist/voice-action-intent.d.ts +86 -0
- package/dist/voice-action-intent.d.ts.map +1 -0
- package/dist/voice-action-intent.js +387 -0
- package/dist/voice-playback.d.ts +50 -0
- package/dist/voice-playback.d.ts.map +1 -0
- package/dist/voice-playback.js +240 -0
- package/dist/voice-protocol.d.ts +165 -0
- package/dist/voice-protocol.d.ts.map +1 -0
- package/dist/voice-protocol.js +312 -0
- package/dist/voice-transcript.d.ts +57 -0
- package/dist/voice-transcript.d.ts.map +1 -0
- package/dist/voice-transcript.js +221 -0
- package/package.json +5 -1
- package/dist/conversation-budget.d.ts +0 -37
- package/dist/conversation-budget.d.ts.map +0 -1
- package/dist/conversation-budget.js +0 -97
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { VoiceProfile } from "./gateway.js";
|
|
2
|
+
import type { CommittedVoiceTranscriptProjection, VoiceTranscriptSource } from "./voice-transcript.js";
|
|
3
|
+
export declare const VOICE_ACTION_INTENT_SCHEMA_VERSION: "1";
|
|
4
|
+
export declare function isVoiceActionIntentSchemaVersionSupported(version: unknown): boolean;
|
|
5
|
+
export type SpokenActionEffectClass = "read-only" | "mutating" | "destructive" | "external-effect" | "unknown";
|
|
6
|
+
export declare const SPOKEN_ACTION_EFFECT_CLASSES: readonly SpokenActionEffectClass[];
|
|
7
|
+
export declare function isSpokenActionEffectClass(value: unknown): value is SpokenActionEffectClass;
|
|
8
|
+
export declare function assertNeverSpokenActionEffectClass(value: never): never;
|
|
9
|
+
export declare const SPOKEN_ACTION_EFFECT_REQUIRES_CONFIRMATION: Readonly<Record<SpokenActionEffectClass, boolean>>;
|
|
10
|
+
export declare function spokenActionRequiresConfirmation(effectClass: SpokenActionEffectClass): boolean;
|
|
11
|
+
export interface SpokenActionEffectMarkers {
|
|
12
|
+
readonly destructive: readonly string[];
|
|
13
|
+
readonly externalEffect: readonly string[];
|
|
14
|
+
readonly mutating: readonly string[];
|
|
15
|
+
readonly readOnly: readonly string[];
|
|
16
|
+
}
|
|
17
|
+
export declare const SPOKEN_ACTION_EFFECT_MARKERS: SpokenActionEffectMarkers;
|
|
18
|
+
export declare function classifySpokenActionEffect(committedText: string): SpokenActionEffectClass;
|
|
19
|
+
export type SpokenActionState = "proposed" | "awaiting-confirmation" | "confirmed" | "routed" | "completed" | "cancelled" | "superseded" | "interrupted" | "expired";
|
|
20
|
+
export declare const SPOKEN_ACTION_STATES: readonly SpokenActionState[];
|
|
21
|
+
export declare const SPOKEN_ACTION_TERMINAL_STATES: readonly SpokenActionState[];
|
|
22
|
+
export declare const SPOKEN_ACTION_STATE_TRANSITIONS: Readonly<Record<SpokenActionState, readonly SpokenActionState[]>>;
|
|
23
|
+
export declare function isSpokenActionState(value: unknown): value is SpokenActionState;
|
|
24
|
+
export declare function canTransitionSpokenAction(from: SpokenActionState, to: SpokenActionState): boolean;
|
|
25
|
+
export declare function isTerminalSpokenActionState(state: SpokenActionState): boolean;
|
|
26
|
+
export declare function assertNeverSpokenActionState(value: never): never;
|
|
27
|
+
export declare function voiceCanProposeAction(profile: VoiceProfile): boolean;
|
|
28
|
+
export type SpokenActionOutcome = "routed" | "denied" | "cancelled" | "superseded" | "not-applicable";
|
|
29
|
+
export declare const SPOKEN_ACTION_OUTCOMES: readonly SpokenActionOutcome[];
|
|
30
|
+
export declare function isSpokenActionOutcome(value: unknown): value is SpokenActionOutcome;
|
|
31
|
+
export interface SpokenActionConfirmationInput {
|
|
32
|
+
readonly schemaVersion: typeof VOICE_ACTION_INTENT_SCHEMA_VERSION;
|
|
33
|
+
readonly committedText: string;
|
|
34
|
+
readonly turnIndex: number;
|
|
35
|
+
readonly effectClass: SpokenActionEffectClass;
|
|
36
|
+
readonly source: VoiceTranscriptSource;
|
|
37
|
+
readonly committedSegmentCount: number;
|
|
38
|
+
}
|
|
39
|
+
export declare function canonicalizeSpokenActionConfirmation(input: SpokenActionConfirmationInput): string;
|
|
40
|
+
export interface SpokenActionProposal {
|
|
41
|
+
readonly schemaVersion: typeof VOICE_ACTION_INTENT_SCHEMA_VERSION;
|
|
42
|
+
readonly effectClass: SpokenActionEffectClass;
|
|
43
|
+
readonly requiresConfirmation: boolean;
|
|
44
|
+
readonly state: SpokenActionState;
|
|
45
|
+
readonly source: VoiceTranscriptSource;
|
|
46
|
+
readonly turnIndex: number;
|
|
47
|
+
readonly committedSegmentCount: number;
|
|
48
|
+
readonly committedChars: number;
|
|
49
|
+
readonly confirmationInput: SpokenActionConfirmationInput;
|
|
50
|
+
}
|
|
51
|
+
export declare function normalizeSpokenActionProposal(projection: CommittedVoiceTranscriptProjection, profile: VoiceProfile, turnIndex: number, source: VoiceTranscriptSource): SpokenActionProposal | undefined;
|
|
52
|
+
export interface SpokenActionAuditRecord {
|
|
53
|
+
readonly schemaVersion: typeof VOICE_ACTION_INTENT_SCHEMA_VERSION;
|
|
54
|
+
readonly effectClass: SpokenActionEffectClass;
|
|
55
|
+
readonly state: SpokenActionState;
|
|
56
|
+
readonly confirmationRequired: boolean;
|
|
57
|
+
readonly confirmed: boolean;
|
|
58
|
+
readonly outcome: SpokenActionOutcome;
|
|
59
|
+
readonly source: VoiceTranscriptSource;
|
|
60
|
+
readonly turnIndex: number;
|
|
61
|
+
readonly committedSegmentCount: number;
|
|
62
|
+
readonly committedChars: number;
|
|
63
|
+
readonly bindingDigest: string;
|
|
64
|
+
}
|
|
65
|
+
export interface SpokenActionAuditInput {
|
|
66
|
+
readonly effectClass: SpokenActionEffectClass;
|
|
67
|
+
readonly state: SpokenActionState;
|
|
68
|
+
readonly confirmationRequired: boolean;
|
|
69
|
+
readonly confirmed: boolean;
|
|
70
|
+
readonly outcome: SpokenActionOutcome;
|
|
71
|
+
readonly source: VoiceTranscriptSource;
|
|
72
|
+
readonly turnIndex: number;
|
|
73
|
+
readonly committedSegmentCount: number;
|
|
74
|
+
readonly committedChars: number;
|
|
75
|
+
readonly bindingDigest: string;
|
|
76
|
+
}
|
|
77
|
+
export declare function buildSpokenActionAuditRecord(input: SpokenActionAuditInput): SpokenActionAuditRecord;
|
|
78
|
+
export type SpokenActionValidationResult = {
|
|
79
|
+
readonly ok: true;
|
|
80
|
+
} | {
|
|
81
|
+
readonly ok: false;
|
|
82
|
+
readonly reasons: readonly string[];
|
|
83
|
+
};
|
|
84
|
+
export declare function validateSpokenActionProposal(value: unknown): SpokenActionValidationResult;
|
|
85
|
+
export declare function validateSpokenActionAuditRecord(value: unknown): SpokenActionValidationResult;
|
|
86
|
+
//# sourceMappingURL=voice-action-intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-action-intent.d.ts","sourceRoot":"","sources":["../src/voice-action-intent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
// Spoken Action Intent governance contract (Epic #491, Issue #503, ADR-0066). Voice is an UNTRUSTED
|
|
2
|
+
// input source: a committed spoken transcript may PROPOSE an action but can never EXECUTE one or bypass
|
|
3
|
+
// any existing gate. This leaf module DEFINES the deterministic, fail-closed normalization +
|
|
4
|
+
// confirmation layer that sits IN FRONT OF the existing governance (the workflow-handoff request, its
|
|
5
|
+
// user approval gate, `validateWorkflowHandoffRequest`, and `checkPatchAgainstScope`). It ADDS
|
|
6
|
+
// preconditions; it removes none.
|
|
7
|
+
//
|
|
8
|
+
// It is pure data + pure functions only — nothing performs IO, crypto, clock reads, randomness, or audio
|
|
9
|
+
// processing. The audit record (`SpokenActionAuditRecord`) has NO raw text and NO audio field: it carries
|
|
10
|
+
// only closed enums, bools, ints, and a content-free one-way digest computed downstream. The proposal
|
|
11
|
+
// (`SpokenActionProposal`) carries `committedText` ONLY transiently inside `confirmationInput` for the
|
|
12
|
+
// downstream digest derivation (Artifact 2); that seed is never persisted into evidence.
|
|
13
|
+
//
|
|
14
|
+
// Classification is a GUARDRAIL, not a semantic engine. `classifySpokenActionEffect` is deterministic,
|
|
15
|
+
// local (no NLU, no model call), and fail-closed: text it does not recognize as read-only-only resolves
|
|
16
|
+
// to `unknown`, which requires confirmation. Its accuracy is NOT load-bearing for safety, because (a) the
|
|
17
|
+
// default is fail-closed and (b) a proposal never authorizes anything — the existing approval gate and
|
|
18
|
+
// handoff gates still independently apply downstream. Keeping classification on-host and content-free is
|
|
19
|
+
// the strongest posture for the banking / insurer audience.
|
|
20
|
+
//
|
|
21
|
+
// `VOICE_ACTION_INTENT_SCHEMA_VERSION` follows the sibling evolution rule (ADR-0010 D2): a breaking
|
|
22
|
+
// change introduces a NEW literal rather than mutating "1", and it is INDEPENDENT of every other schema
|
|
23
|
+
// version. Leaf-package rule (ADR-0019 direction 1): no cross-package workspace import may appear here;
|
|
24
|
+
// siblings are reached by relative path only.
|
|
25
|
+
import { isVoiceTranscriptSource, voiceTranscriptCaptureAllowed } from "./voice-transcript.js";
|
|
26
|
+
// ─── Schema version ───────────────────────────────────────────────────────────
|
|
27
|
+
export const VOICE_ACTION_INTENT_SCHEMA_VERSION = "1";
|
|
28
|
+
export function isVoiceActionIntentSchemaVersionSupported(version) {
|
|
29
|
+
return version === VOICE_ACTION_INTENT_SCHEMA_VERSION;
|
|
30
|
+
}
|
|
31
|
+
export const SPOKEN_ACTION_EFFECT_CLASSES = [
|
|
32
|
+
"read-only",
|
|
33
|
+
"mutating",
|
|
34
|
+
"destructive",
|
|
35
|
+
"external-effect",
|
|
36
|
+
"unknown",
|
|
37
|
+
];
|
|
38
|
+
export function isSpokenActionEffectClass(value) {
|
|
39
|
+
return (typeof value === "string" && SPOKEN_ACTION_EFFECT_CLASSES.includes(value));
|
|
40
|
+
}
|
|
41
|
+
export function assertNeverSpokenActionEffectClass(value) {
|
|
42
|
+
throw new TypeError(`Unhandled SpokenActionEffectClass: ${JSON.stringify(value)}`);
|
|
43
|
+
}
|
|
44
|
+
// Fail-closed confirmation table: every class except `read-only` requires explicit confirmation. Keyed
|
|
45
|
+
// by class for totality (a new class without an entry is a compile error).
|
|
46
|
+
export const SPOKEN_ACTION_EFFECT_REQUIRES_CONFIRMATION = {
|
|
47
|
+
"read-only": false,
|
|
48
|
+
mutating: true,
|
|
49
|
+
destructive: true,
|
|
50
|
+
"external-effect": true,
|
|
51
|
+
unknown: true,
|
|
52
|
+
};
|
|
53
|
+
export function spokenActionRequiresConfirmation(effectClass) {
|
|
54
|
+
return SPOKEN_ACTION_EFFECT_REQUIRES_CONFIRMATION[effectClass];
|
|
55
|
+
}
|
|
56
|
+
export const SPOKEN_ACTION_EFFECT_MARKERS = {
|
|
57
|
+
destructive: ["delete", "remove", "drop", "purge", "erase", "destroy", "wipe", "truncate"],
|
|
58
|
+
externalEffect: [
|
|
59
|
+
"send",
|
|
60
|
+
"deploy",
|
|
61
|
+
"publish",
|
|
62
|
+
"email",
|
|
63
|
+
"pay",
|
|
64
|
+
"transfer",
|
|
65
|
+
"call",
|
|
66
|
+
"post",
|
|
67
|
+
"merge",
|
|
68
|
+
],
|
|
69
|
+
mutating: [
|
|
70
|
+
"create",
|
|
71
|
+
"add",
|
|
72
|
+
"update",
|
|
73
|
+
"edit",
|
|
74
|
+
"rename",
|
|
75
|
+
"move",
|
|
76
|
+
"write",
|
|
77
|
+
"set",
|
|
78
|
+
"change",
|
|
79
|
+
"modify",
|
|
80
|
+
],
|
|
81
|
+
readOnly: [
|
|
82
|
+
"show",
|
|
83
|
+
"list",
|
|
84
|
+
"read",
|
|
85
|
+
"view",
|
|
86
|
+
"display",
|
|
87
|
+
"find",
|
|
88
|
+
"search",
|
|
89
|
+
"open",
|
|
90
|
+
"get",
|
|
91
|
+
"describe",
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
// Strip characters that could smuggle an invisible or compatibility-form verb past the ASCII
|
|
95
|
+
// lexicon: C0/C1 controls (\u0000-\u0008, \u000E-\u001F, \u007F-\u009F),
|
|
96
|
+
// zero-width chars (\u200B-\u200D, \uFEFF), and bidi-override controls
|
|
97
|
+
// (\u202A-\u202E, \u2066-\u2069). The standard whitespace controls (\u0009-\u000D:
|
|
98
|
+
// tab/LF/VT/FF/CR) are deliberately EXCLUDED so the later \s+ collapse turns them into a single
|
|
99
|
+
// space and word boundaries survive; stripping them would join adjacent words and silently lose the
|
|
100
|
+
// marker. Without this strip, a destructive verb interrupted by a zero-width char would dodge the
|
|
101
|
+
// marker, misclassify as read-only, and skip confirmation.
|
|
102
|
+
/* eslint-disable no-control-regex -- C0/C1 control ranges are intentional here */
|
|
103
|
+
const UNSAFE_FORMAT_CHARS = /[\u0000-\u0008\u000E-\u001F\u007F-\u009F\u200B-\u200D\uFEFF\u202A-\u202E\u2066-\u2069]/g;
|
|
104
|
+
/* eslint-enable no-control-regex */
|
|
105
|
+
// Inline minimal normalization — leaf cannot import keiko-security. Apply Unicode NFKC FIRST so
|
|
106
|
+
// compatibility forms fold to ASCII (a fullwidth destructive verb folds to its ASCII spelling);
|
|
107
|
+
// otherwise such forms evade the ASCII marker lexicon and a destructive request would misclassify
|
|
108
|
+
// as read-only and skip confirmation. Then strip zero-width / bidi / control chars, lowercase, trim,
|
|
109
|
+
// and collapse internal whitespace runs to single spaces so word-boundary matching is stable. On
|
|
110
|
+
// plain ASCII input NFKC and the strip are the identity, so existing ASCII classification is unchanged.
|
|
111
|
+
function normalizeForClassification(text) {
|
|
112
|
+
return text
|
|
113
|
+
.normalize("NFKC")
|
|
114
|
+
.replace(UNSAFE_FORMAT_CHARS, "")
|
|
115
|
+
.trim()
|
|
116
|
+
.toLowerCase()
|
|
117
|
+
.replace(/\s+/g, " ");
|
|
118
|
+
}
|
|
119
|
+
// Whole-word membership test: wraps both sides in spaces so `set` does not match inside `settlement`.
|
|
120
|
+
function containsMarker(paddedText, markers) {
|
|
121
|
+
return markers.some((marker) => paddedText.includes(` ${marker} `));
|
|
122
|
+
}
|
|
123
|
+
// Conservative, ordered precedence: destructive > external-effect > mutating > read-only. Empty /
|
|
124
|
+
// whitespace-only text → `unknown`. Text that matches no recognized marker → `unknown` (fail-closed).
|
|
125
|
+
export function classifySpokenActionEffect(committedText) {
|
|
126
|
+
const normalized = normalizeForClassification(committedText);
|
|
127
|
+
if (normalized.length === 0) {
|
|
128
|
+
return "unknown";
|
|
129
|
+
}
|
|
130
|
+
const padded = ` ${normalized} `;
|
|
131
|
+
if (containsMarker(padded, SPOKEN_ACTION_EFFECT_MARKERS.destructive)) {
|
|
132
|
+
return "destructive";
|
|
133
|
+
}
|
|
134
|
+
if (containsMarker(padded, SPOKEN_ACTION_EFFECT_MARKERS.externalEffect)) {
|
|
135
|
+
return "external-effect";
|
|
136
|
+
}
|
|
137
|
+
if (containsMarker(padded, SPOKEN_ACTION_EFFECT_MARKERS.mutating)) {
|
|
138
|
+
return "mutating";
|
|
139
|
+
}
|
|
140
|
+
if (containsMarker(padded, SPOKEN_ACTION_EFFECT_MARKERS.readOnly)) {
|
|
141
|
+
return "read-only";
|
|
142
|
+
}
|
|
143
|
+
return "unknown";
|
|
144
|
+
}
|
|
145
|
+
export const SPOKEN_ACTION_STATES = [
|
|
146
|
+
"proposed",
|
|
147
|
+
"awaiting-confirmation",
|
|
148
|
+
"confirmed",
|
|
149
|
+
"routed",
|
|
150
|
+
"completed",
|
|
151
|
+
"cancelled",
|
|
152
|
+
"superseded",
|
|
153
|
+
"interrupted",
|
|
154
|
+
"expired",
|
|
155
|
+
];
|
|
156
|
+
export const SPOKEN_ACTION_TERMINAL_STATES = [
|
|
157
|
+
"completed",
|
|
158
|
+
"cancelled",
|
|
159
|
+
"superseded",
|
|
160
|
+
"interrupted",
|
|
161
|
+
"expired",
|
|
162
|
+
];
|
|
163
|
+
// The non-terminal invalidation targets every non-terminal state can reach (cancel / supersede /
|
|
164
|
+
// interrupt / expire). Shared so the transition table stays consistent.
|
|
165
|
+
const SPOKEN_ACTION_INVALIDATION_STATES = [
|
|
166
|
+
"cancelled",
|
|
167
|
+
"superseded",
|
|
168
|
+
"interrupted",
|
|
169
|
+
"expired",
|
|
170
|
+
];
|
|
171
|
+
// Legal state-changing transitions, keyed by state for totality.
|
|
172
|
+
// read-only path: proposed → routed → completed
|
|
173
|
+
// confirm path: proposed → awaiting-confirmation → confirmed → routed → completed
|
|
174
|
+
// any non-terminal: → cancelled | superseded | interrupted | expired
|
|
175
|
+
export const SPOKEN_ACTION_STATE_TRANSITIONS = {
|
|
176
|
+
proposed: ["awaiting-confirmation", "routed", ...SPOKEN_ACTION_INVALIDATION_STATES],
|
|
177
|
+
"awaiting-confirmation": ["confirmed", ...SPOKEN_ACTION_INVALIDATION_STATES],
|
|
178
|
+
confirmed: ["routed", ...SPOKEN_ACTION_INVALIDATION_STATES],
|
|
179
|
+
routed: ["completed", ...SPOKEN_ACTION_INVALIDATION_STATES],
|
|
180
|
+
completed: [],
|
|
181
|
+
cancelled: [],
|
|
182
|
+
superseded: [],
|
|
183
|
+
interrupted: [],
|
|
184
|
+
expired: [],
|
|
185
|
+
};
|
|
186
|
+
export function isSpokenActionState(value) {
|
|
187
|
+
return typeof value === "string" && SPOKEN_ACTION_STATES.includes(value);
|
|
188
|
+
}
|
|
189
|
+
export function canTransitionSpokenAction(from, to) {
|
|
190
|
+
return SPOKEN_ACTION_STATE_TRANSITIONS[from].includes(to);
|
|
191
|
+
}
|
|
192
|
+
export function isTerminalSpokenActionState(state) {
|
|
193
|
+
return SPOKEN_ACTION_TERMINAL_STATES.includes(state);
|
|
194
|
+
}
|
|
195
|
+
export function assertNeverSpokenActionState(value) {
|
|
196
|
+
throw new TypeError(`Unhandled SpokenActionState: ${JSON.stringify(value)}`);
|
|
197
|
+
}
|
|
198
|
+
// ─── Capability gating (AC1 / AC2) ───────────────────────────────────────────────
|
|
199
|
+
// Derived from the voice transcript capability so it cannot drift: a spoken action can be proposed only
|
|
200
|
+
// where committed transcript capture is allowed (`speech-to-text` / `full-realtime`). `none` and
|
|
201
|
+
// `speech-output` (playback-only) make the whole layer dormant (AC1). The text path never calls this.
|
|
202
|
+
export function voiceCanProposeAction(profile) {
|
|
203
|
+
return voiceTranscriptCaptureAllowed(profile);
|
|
204
|
+
}
|
|
205
|
+
export const SPOKEN_ACTION_OUTCOMES = [
|
|
206
|
+
"routed",
|
|
207
|
+
"denied",
|
|
208
|
+
"cancelled",
|
|
209
|
+
"superseded",
|
|
210
|
+
"not-applicable",
|
|
211
|
+
];
|
|
212
|
+
export function isSpokenActionOutcome(value) {
|
|
213
|
+
return typeof value === "string" && SPOKEN_ACTION_OUTCOMES.includes(value);
|
|
214
|
+
}
|
|
215
|
+
// Deterministic, stable field ordering with length-prefixed segments so no field's content can be
|
|
216
|
+
// confused with another's (a classic canonicalization ambiguity). Pure string; no crypto here.
|
|
217
|
+
export function canonicalizeSpokenActionConfirmation(input) {
|
|
218
|
+
const fields = [
|
|
219
|
+
`v=${input.schemaVersion}`,
|
|
220
|
+
`turn=${String(input.turnIndex)}`,
|
|
221
|
+
`effect=${input.effectClass}`,
|
|
222
|
+
`source=${input.source}`,
|
|
223
|
+
`segments=${String(input.committedSegmentCount)}`,
|
|
224
|
+
`textlen=${String(input.committedText.length)}`,
|
|
225
|
+
`text=${input.committedText}`,
|
|
226
|
+
];
|
|
227
|
+
return fields.join("\n");
|
|
228
|
+
}
|
|
229
|
+
// AC1/AC2 entry gate: returns `undefined` when the profile cannot propose actions (AC1) or the committed
|
|
230
|
+
// projection carries no text (AC2). Partial / stable / discarded / redacted / superseded segments can
|
|
231
|
+
// never appear in `projection.text` by construction (`selectCommittedVoiceTranscript`), so a non-empty
|
|
232
|
+
// projection text already means committed content only.
|
|
233
|
+
export function normalizeSpokenActionProposal(projection, profile, turnIndex, source) {
|
|
234
|
+
if (!voiceCanProposeAction(profile)) {
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
const committedText = projection.text;
|
|
238
|
+
if (committedText.trim().length === 0) {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
const effectClass = classifySpokenActionEffect(committedText);
|
|
242
|
+
const requiresConfirmation = spokenActionRequiresConfirmation(effectClass);
|
|
243
|
+
const confirmationInput = {
|
|
244
|
+
schemaVersion: VOICE_ACTION_INTENT_SCHEMA_VERSION,
|
|
245
|
+
committedText,
|
|
246
|
+
turnIndex,
|
|
247
|
+
effectClass,
|
|
248
|
+
source,
|
|
249
|
+
committedSegmentCount: projection.segmentCount,
|
|
250
|
+
};
|
|
251
|
+
return {
|
|
252
|
+
schemaVersion: VOICE_ACTION_INTENT_SCHEMA_VERSION,
|
|
253
|
+
effectClass,
|
|
254
|
+
requiresConfirmation,
|
|
255
|
+
state: requiresConfirmation ? "awaiting-confirmation" : "proposed",
|
|
256
|
+
source,
|
|
257
|
+
turnIndex,
|
|
258
|
+
committedSegmentCount: projection.segmentCount,
|
|
259
|
+
committedChars: committedText.length,
|
|
260
|
+
confirmationInput,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
// Pure builder. Copies only the content-free fields; structurally cannot carry committed text because no
|
|
264
|
+
// text field exists on either the input or the record.
|
|
265
|
+
export function buildSpokenActionAuditRecord(input) {
|
|
266
|
+
return {
|
|
267
|
+
schemaVersion: VOICE_ACTION_INTENT_SCHEMA_VERSION,
|
|
268
|
+
effectClass: input.effectClass,
|
|
269
|
+
state: input.state,
|
|
270
|
+
confirmationRequired: input.confirmationRequired,
|
|
271
|
+
confirmed: input.confirmed,
|
|
272
|
+
outcome: input.outcome,
|
|
273
|
+
source: input.source,
|
|
274
|
+
turnIndex: input.turnIndex,
|
|
275
|
+
committedSegmentCount: input.committedSegmentCount,
|
|
276
|
+
committedChars: input.committedChars,
|
|
277
|
+
bindingDigest: input.bindingDigest,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function buildSpokenActionResult(reasons) {
|
|
281
|
+
return reasons.length === 0 ? { ok: true } : { ok: false, reasons };
|
|
282
|
+
}
|
|
283
|
+
function isRecord(value) {
|
|
284
|
+
return typeof value === "object" && value !== null;
|
|
285
|
+
}
|
|
286
|
+
function isNonNegativeInteger(value) {
|
|
287
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
288
|
+
}
|
|
289
|
+
// A binding digest is either the empty string (no confirmation bound) or a 64-char lowercase sha256 hex.
|
|
290
|
+
const BINDING_DIGEST_PATTERN = /^[0-9a-f]{64}$/;
|
|
291
|
+
function isValidBindingDigest(value) {
|
|
292
|
+
return value === "" || (typeof value === "string" && BINDING_DIGEST_PATTERN.test(value));
|
|
293
|
+
}
|
|
294
|
+
// Shared count-field check used by both record validators: turnIndex / committedSegmentCount /
|
|
295
|
+
// committedChars must each be non-negative integers. Extracting it keeps both validators under the
|
|
296
|
+
// complexity cap and keeps the reason strings identical across record shapes.
|
|
297
|
+
function validateCommittedCounts(value, reasons) {
|
|
298
|
+
if (!isNonNegativeInteger(value.turnIndex)) {
|
|
299
|
+
reasons.push("turnIndex: must be a non-negative integer");
|
|
300
|
+
}
|
|
301
|
+
if (!isNonNegativeInteger(value.committedSegmentCount)) {
|
|
302
|
+
reasons.push("committedSegmentCount: must be a non-negative integer");
|
|
303
|
+
}
|
|
304
|
+
if (!isNonNegativeInteger(value.committedChars)) {
|
|
305
|
+
reasons.push("committedChars: must be a non-negative integer");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function validateConfirmationInput(value, reasons) {
|
|
309
|
+
if (!isRecord(value)) {
|
|
310
|
+
reasons.push("confirmationInput: must be an object");
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (!isVoiceActionIntentSchemaVersionSupported(value.schemaVersion)) {
|
|
314
|
+
reasons.push("confirmationInput.schemaVersion: unsupported");
|
|
315
|
+
}
|
|
316
|
+
if (typeof value.committedText !== "string") {
|
|
317
|
+
reasons.push("confirmationInput.committedText: must be a string");
|
|
318
|
+
}
|
|
319
|
+
if (!isNonNegativeInteger(value.turnIndex)) {
|
|
320
|
+
reasons.push("confirmationInput.turnIndex: must be a non-negative integer");
|
|
321
|
+
}
|
|
322
|
+
if (!isSpokenActionEffectClass(value.effectClass)) {
|
|
323
|
+
reasons.push("confirmationInput.effectClass: unknown effect class");
|
|
324
|
+
}
|
|
325
|
+
if (!isVoiceTranscriptSource(value.source)) {
|
|
326
|
+
reasons.push("confirmationInput.source: unknown transcript source");
|
|
327
|
+
}
|
|
328
|
+
if (!isNonNegativeInteger(value.committedSegmentCount)) {
|
|
329
|
+
reasons.push("confirmationInput.committedSegmentCount: must be a non-negative integer");
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
export function validateSpokenActionProposal(value) {
|
|
333
|
+
if (!isRecord(value)) {
|
|
334
|
+
return { ok: false, reasons: ["proposal: must be an object"] };
|
|
335
|
+
}
|
|
336
|
+
const reasons = [];
|
|
337
|
+
if (!isVoiceActionIntentSchemaVersionSupported(value.schemaVersion)) {
|
|
338
|
+
reasons.push("schemaVersion: unsupported");
|
|
339
|
+
}
|
|
340
|
+
if (!isSpokenActionEffectClass(value.effectClass)) {
|
|
341
|
+
reasons.push("effectClass: unknown effect class");
|
|
342
|
+
}
|
|
343
|
+
if (typeof value.requiresConfirmation !== "boolean") {
|
|
344
|
+
reasons.push("requiresConfirmation: must be a boolean");
|
|
345
|
+
}
|
|
346
|
+
if (!isSpokenActionState(value.state)) {
|
|
347
|
+
reasons.push("state: unknown spoken action state");
|
|
348
|
+
}
|
|
349
|
+
if (!isVoiceTranscriptSource(value.source)) {
|
|
350
|
+
reasons.push("source: unknown transcript source");
|
|
351
|
+
}
|
|
352
|
+
validateCommittedCounts(value, reasons);
|
|
353
|
+
validateConfirmationInput(value.confirmationInput, reasons);
|
|
354
|
+
return buildSpokenActionResult(reasons);
|
|
355
|
+
}
|
|
356
|
+
export function validateSpokenActionAuditRecord(value) {
|
|
357
|
+
if (!isRecord(value)) {
|
|
358
|
+
return { ok: false, reasons: ["audit: must be an object"] };
|
|
359
|
+
}
|
|
360
|
+
const reasons = [];
|
|
361
|
+
if (!isVoiceActionIntentSchemaVersionSupported(value.schemaVersion)) {
|
|
362
|
+
reasons.push("schemaVersion: unsupported");
|
|
363
|
+
}
|
|
364
|
+
if (!isSpokenActionEffectClass(value.effectClass)) {
|
|
365
|
+
reasons.push("effectClass: unknown effect class");
|
|
366
|
+
}
|
|
367
|
+
if (!isSpokenActionState(value.state)) {
|
|
368
|
+
reasons.push("state: unknown spoken action state");
|
|
369
|
+
}
|
|
370
|
+
if (typeof value.confirmationRequired !== "boolean") {
|
|
371
|
+
reasons.push("confirmationRequired: must be a boolean");
|
|
372
|
+
}
|
|
373
|
+
if (typeof value.confirmed !== "boolean") {
|
|
374
|
+
reasons.push("confirmed: must be a boolean");
|
|
375
|
+
}
|
|
376
|
+
if (!isSpokenActionOutcome(value.outcome)) {
|
|
377
|
+
reasons.push("outcome: unknown outcome");
|
|
378
|
+
}
|
|
379
|
+
if (!isVoiceTranscriptSource(value.source)) {
|
|
380
|
+
reasons.push("source: unknown transcript source");
|
|
381
|
+
}
|
|
382
|
+
validateCommittedCounts(value, reasons);
|
|
383
|
+
if (!isValidBindingDigest(value.bindingDigest)) {
|
|
384
|
+
reasons.push("bindingDigest: must be empty or a 64-char lowercase sha256 hex");
|
|
385
|
+
}
|
|
386
|
+
return buildSpokenActionResult(reasons);
|
|
387
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { VoiceProfile } from "./gateway.js";
|
|
2
|
+
import type { VoicePlaybackState, VoiceReplayClass, VoiceRedactionClass } from "./voice-protocol.js";
|
|
3
|
+
export declare const VOICE_PLAYBACK_SCHEMA_VERSION: "1";
|
|
4
|
+
export declare function isVoicePlaybackSchemaVersionSupported(version: unknown): boolean;
|
|
5
|
+
export type VoicePlaybackPhase = "unavailable" | "preparing" | "speaking" | "paused" | "interrupted" | "canceled" | "failed" | "complete";
|
|
6
|
+
export declare const VOICE_PLAYBACK_PHASES: readonly VoicePlaybackPhase[];
|
|
7
|
+
export declare const VOICE_PLAYBACK_ACTIVE_PHASES: readonly VoicePlaybackPhase[];
|
|
8
|
+
export declare const VOICE_PLAYBACK_SETTLED_PHASES: readonly VoicePlaybackPhase[];
|
|
9
|
+
export type VoicePlaybackFailureKind = "rate-limited" | "timeout" | "provider-error" | "unavailable" | "internal";
|
|
10
|
+
export declare const VOICE_PLAYBACK_FAILURE_KINDS: readonly VoicePlaybackFailureKind[];
|
|
11
|
+
export declare const VOICE_PLAYBACK_PHASE_REPLAY: Record<VoicePlaybackPhase, VoiceReplayClass>;
|
|
12
|
+
export declare const VOICE_PLAYBACK_PHASE_REDACTION: Record<VoicePlaybackPhase, VoiceRedactionClass>;
|
|
13
|
+
export declare const VOICE_PLAYBACK_AUDIO_PLANE: import("./voice-protocol.js").VoiceMediaPlaneDescriptor;
|
|
14
|
+
export declare const VOICE_PLAYBACK_TRANSITIONS: Record<VoicePlaybackPhase, readonly VoicePlaybackPhase[]>;
|
|
15
|
+
export declare function isVoicePlaybackPhase(value: unknown): value is VoicePlaybackPhase;
|
|
16
|
+
export declare function isVoicePlaybackFailureKind(value: unknown): value is VoicePlaybackFailureKind;
|
|
17
|
+
export declare function voicePlaybackPhaseReplayClass(phase: VoicePlaybackPhase): VoiceReplayClass;
|
|
18
|
+
export declare function voicePlaybackPhaseRedactionClass(phase: VoicePlaybackPhase): VoiceRedactionClass;
|
|
19
|
+
export declare function isActiveVoicePlaybackPhase(phase: VoicePlaybackPhase): boolean;
|
|
20
|
+
export declare function isSettledVoicePlaybackPhase(phase: VoicePlaybackPhase): boolean;
|
|
21
|
+
export declare function canTransitionVoicePlayback(from: VoicePlaybackPhase, to: VoicePlaybackPhase): boolean;
|
|
22
|
+
export declare function assertNeverVoicePlaybackPhase(phase: never): never;
|
|
23
|
+
export declare function mapVoicePlaybackPhaseToWireState(phase: VoicePlaybackPhase): VoicePlaybackState | undefined;
|
|
24
|
+
export type VoicePlaybackEffect = "request-synthesis" | "start-output" | "pause-output" | "resume-output" | "stop-output" | "mute-output" | "unmute-output" | "notify-turn-speech-start" | "notify-turn-speech-completed" | "notify-turn-speech-stopped" | "notify-turn-interrupt";
|
|
25
|
+
export declare const VOICE_PLAYBACK_EFFECTS: readonly VoicePlaybackEffect[];
|
|
26
|
+
export declare function isVoicePlaybackEffect(value: unknown): value is VoicePlaybackEffect;
|
|
27
|
+
export declare function voicePlaybackAllowedForProfile(profile: VoiceProfile): boolean;
|
|
28
|
+
export declare function voicePlaybackInterruptAllowedForProfile(profile: VoiceProfile): boolean;
|
|
29
|
+
export declare function initialVoicePlaybackPhase(_profile: VoiceProfile): VoicePlaybackPhase;
|
|
30
|
+
export interface VoicePlaybackTurnSummary {
|
|
31
|
+
readonly schemaVersion: typeof VOICE_PLAYBACK_SCHEMA_VERSION;
|
|
32
|
+
readonly phase: VoicePlaybackPhase;
|
|
33
|
+
readonly available: boolean;
|
|
34
|
+
readonly spoke: boolean;
|
|
35
|
+
readonly completed: boolean;
|
|
36
|
+
readonly interrupted: boolean;
|
|
37
|
+
readonly failed: boolean;
|
|
38
|
+
readonly interruptions: number;
|
|
39
|
+
readonly replays: number;
|
|
40
|
+
readonly failureKind?: VoicePlaybackFailureKind | undefined;
|
|
41
|
+
}
|
|
42
|
+
export declare function summarizeVoicePlaybackTurn(input: {
|
|
43
|
+
readonly phase: VoicePlaybackPhase;
|
|
44
|
+
readonly available: boolean;
|
|
45
|
+
readonly spoke: boolean;
|
|
46
|
+
readonly interruptions: number;
|
|
47
|
+
readonly replays: number;
|
|
48
|
+
readonly failureKind?: VoicePlaybackFailureKind | undefined;
|
|
49
|
+
}): VoicePlaybackTurnSummary;
|
|
50
|
+
//# sourceMappingURL=voice-playback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-playback.d.ts","sourceRoot":"","sources":["../src/voice-playback.ts"],"names":[],"mappings":"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"}
|