dsh-completion-guard 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -1
- package/CHANGELOG.zh-CN.md +24 -1
- package/README.md +45 -5
- package/README.zh-CN.md +45 -5
- package/bin/dsh-completion-guard-host-lock.mjs +52 -0
- package/dist/domain/index.d.ts +2 -2
- package/dist/domain/index.js +2 -2
- package/dist/domain-CBvBQHTL.js +5828 -0
- package/dist/index-GvKLkTqV.d.ts +957 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.js +2463 -119
- package/docs/ARCHITECTURE.md +11 -7
- package/docs/COMPATIBILITY.md +23 -3
- package/docs/LOCAL_ACCEPTANCE.md +192 -1
- package/docs/SEMANTIC_COMPATIBILITY.md +118 -0
- package/docs/distribution.md +45 -0
- package/docs/upstream-deltas.json +217 -0
- package/manifests/action-manifest.v1.json +33 -0
- package/manifests/git-command-manifest.v2.json +52 -0
- package/manifests/supported-host.v1.json +66 -0
- package/package.json +52 -14
- package/dist/domain-BN3_AuUr.js +0 -1997
- package/dist/index-Dk4SkQ8H.d.ts +0 -448
|
@@ -0,0 +1,957 @@
|
|
|
1
|
+
//#region src/domain/canonicalize.d.ts
|
|
2
|
+
declare function normalizeClause(text: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Canonicalize a filesystem path for subject matching. Windows-style paths are
|
|
5
|
+
* normalized (drive letter, both separator kinds, `.`/`..`, duplicate
|
|
6
|
+
* separators) and case-folded, because Windows paths compare case-insensitively
|
|
7
|
+
* and treat `/` and `\` as equivalent. POSIX-style paths are normalized but
|
|
8
|
+
* keep their case, so a case-sensitive filesystem is never made insensitive.
|
|
9
|
+
* Exactly one canonicalizer is shared by contract capture and evidence
|
|
10
|
+
* extraction so a Windows contract subject and a Windows evidence subject match.
|
|
11
|
+
*/
|
|
12
|
+
declare function canonicalizePath(value: string): string;
|
|
13
|
+
declare function sha256(text: string): string;
|
|
14
|
+
declare function digestStrings(values: readonly string[]): string;
|
|
15
|
+
declare function sanitizeClauseText(text: string): string;
|
|
16
|
+
declare function sanitizeUrl(value: string): string;
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/domain/protocol-manifest.d.ts
|
|
19
|
+
declare const STOP_PROTOCOL_VERSION = "2.0.0";
|
|
20
|
+
declare const CERTIFICATE_VERSION = "1";
|
|
21
|
+
declare const ACTION_MANIFEST_VERSION = 1;
|
|
22
|
+
declare const SUPPORTED_EVIDENCE_ADAPTERS: Readonly<Record<string, string>>;
|
|
23
|
+
declare const SEMANTIC_ACTIONS: readonly ["inspect_remote_updates", "install", "apply", "create", "modify", "test", "verify", "pull", "fetch", "commit", "push", "restart", "publish", "generic_run"];
|
|
24
|
+
type SemanticAction = (typeof SEMANTIC_ACTIONS)[number];
|
|
25
|
+
type StatefulAction = "install" | "apply" | "create" | "modify" | "restart" | "commit" | "push" | "publish" | "pull" | "fetch";
|
|
26
|
+
declare const STATEFUL_ACTIONS: readonly StatefulAction[];
|
|
27
|
+
interface ActionSpec {
|
|
28
|
+
stateful: boolean;
|
|
29
|
+
evidenceProducer: "supported" | "unavailable";
|
|
30
|
+
resolvedTargetKeys: string[];
|
|
31
|
+
observedStateKeys: string[];
|
|
32
|
+
predicateId: string;
|
|
33
|
+
commandManifestIds: string[];
|
|
34
|
+
}
|
|
35
|
+
interface ActionManifest {
|
|
36
|
+
version: number;
|
|
37
|
+
actions: Record<SemanticAction, ActionSpec>;
|
|
38
|
+
compatibility: Record<SemanticAction, SemanticAction[]>;
|
|
39
|
+
}
|
|
40
|
+
declare const ACTION_MANIFEST: ActionManifest;
|
|
41
|
+
declare function semanticActionFromText(text: string): SemanticAction;
|
|
42
|
+
declare function semanticActionFromCommand(command: string): SemanticAction;
|
|
43
|
+
declare function isStatefulAction(action: SemanticAction): action is StatefulAction;
|
|
44
|
+
declare function actionCompatible(required: SemanticAction, observed: SemanticAction): boolean;
|
|
45
|
+
declare function validateActionTarget(action: SemanticAction, resolved: TargetTuple | undefined, observed: TargetTuple | undefined): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Compare identities captured from the root instruction with a complete
|
|
48
|
+
* adapter-resolved target. Requested targets are partial by design: only
|
|
49
|
+
* explicitly named identities (plus the active repository scope) are frozen.
|
|
50
|
+
*/
|
|
51
|
+
declare function requestedTargetMatchesResolved(action: StatefulAction, requested: TargetTuple | undefined, resolved: TargetTuple | undefined): boolean;
|
|
52
|
+
/** A mutation requires every user-selectable identity field, not a partial match. */
|
|
53
|
+
declare function requestedTargetAuthorizesMutation(action: StatefulAction, requested: TargetTuple | undefined, resolved: TargetTuple | undefined): boolean;
|
|
54
|
+
declare function validateActionManifest(): string[];
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/domain/digest.d.ts
|
|
57
|
+
type TypedObject = {
|
|
58
|
+
k: "b" | "i" | "s" | "e" | "x";
|
|
59
|
+
v: unknown;
|
|
60
|
+
};
|
|
61
|
+
type Typed = boolean | number | string | TypedObject;
|
|
62
|
+
interface SessionHeader {
|
|
63
|
+
version: number;
|
|
64
|
+
id: string;
|
|
65
|
+
createdAt: number;
|
|
66
|
+
parentSession?: string;
|
|
67
|
+
seedLength?: number;
|
|
68
|
+
agentPreset?: string;
|
|
69
|
+
origin?: string;
|
|
70
|
+
delegationDepth?: number;
|
|
71
|
+
}
|
|
72
|
+
interface CapabilityRow {
|
|
73
|
+
name: string;
|
|
74
|
+
value: Typed;
|
|
75
|
+
}
|
|
76
|
+
interface PackageRow {
|
|
77
|
+
name: string;
|
|
78
|
+
version?: string;
|
|
79
|
+
integrity?: string;
|
|
80
|
+
}
|
|
81
|
+
interface HostLockManifest {
|
|
82
|
+
manifestVersion: number;
|
|
83
|
+
supportedGoalVersions: string[];
|
|
84
|
+
capabilities?: CapabilityRow[];
|
|
85
|
+
packages?: PackageRow[];
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/domain/types.d.ts
|
|
89
|
+
type GuardItemKind = "requirement" | "acceptance" | "prohibition";
|
|
90
|
+
type GuardItemStatus = "pending" | "passed" | "superseded";
|
|
91
|
+
type GuardIntegrity = "valid" | "unknown" | "corrupt";
|
|
92
|
+
type EvidenceOutcome = "success" | "failure" | "unknown" | "durability-unknown";
|
|
93
|
+
type GuardOperation = "create" | "write" | "modify" | "read" | "run" | "verify";
|
|
94
|
+
type TargetValue = boolean | number | string | {
|
|
95
|
+
k: "b" | "i" | "s" | "e" | "x";
|
|
96
|
+
v: unknown;
|
|
97
|
+
};
|
|
98
|
+
type TargetTuple = Record<string, TargetValue>;
|
|
99
|
+
type EvidenceRole = "resolution" | "effect" | "state";
|
|
100
|
+
type EvidenceParseStatus = "supported" | "unsupported_statement_operator" | "unsupported_command" | "malformed_quote" | "adapter_unavailable";
|
|
101
|
+
type HostStatus = "supported" | "unsupported" | "unavailable";
|
|
102
|
+
type TargetCaptureStatus = "resolved" | "clarification_required";
|
|
103
|
+
type TargetCaptureReasonCode = "requested_target_package_id_missing" | "requested_target_artifact_id_missing" | "requested_target_repository_missing" | "requested_target_service_id_missing" | "requested_target_registry_missing_or_invalid";
|
|
104
|
+
interface GoalRef {
|
|
105
|
+
id: string;
|
|
106
|
+
revision: number;
|
|
107
|
+
}
|
|
108
|
+
interface WaitAuthorization {
|
|
109
|
+
kind: "root_explicit_wait" | "user_decision_item";
|
|
110
|
+
id: string;
|
|
111
|
+
}
|
|
112
|
+
interface DeferAuthorization {
|
|
113
|
+
kind: "root_explicit_defer";
|
|
114
|
+
id: string;
|
|
115
|
+
}
|
|
116
|
+
interface PersistenceAuthorization {
|
|
117
|
+
kind: "root_explicit_persistence";
|
|
118
|
+
id: string;
|
|
119
|
+
}
|
|
120
|
+
interface VerificationContract {
|
|
121
|
+
subject?: string;
|
|
122
|
+
surface?: "artifact" | "ui" | "visual" | "scope";
|
|
123
|
+
enforced: boolean;
|
|
124
|
+
/** Explicitly-required tool/method (e.g. 'bash'); when set, a successful
|
|
125
|
+
* evidence from that tool must be present in addition to artifact/scope
|
|
126
|
+
* coverage before the item can close. */
|
|
127
|
+
method?: string;
|
|
128
|
+
/** Explicitly-required operation/effect (e.g. 'create', 'read'). When set
|
|
129
|
+
* alongside `method`, the method evidence must have performed that operation
|
|
130
|
+
* on the same canonical subject — mentioning the file is not enough. */
|
|
131
|
+
operation?: GuardOperation;
|
|
132
|
+
}
|
|
133
|
+
interface GuardItem {
|
|
134
|
+
id: string;
|
|
135
|
+
revision: number;
|
|
136
|
+
kind: GuardItemKind;
|
|
137
|
+
sourceMessageId: string;
|
|
138
|
+
normalizedText: string;
|
|
139
|
+
textSha256: string;
|
|
140
|
+
status: GuardItemStatus;
|
|
141
|
+
supersededBy?: string;
|
|
142
|
+
verification: VerificationContract;
|
|
143
|
+
semanticAction?: SemanticAction;
|
|
144
|
+
requestedTarget?: TargetTuple;
|
|
145
|
+
targetCaptureStatus?: TargetCaptureStatus;
|
|
146
|
+
targetCaptureReasonCode?: TargetCaptureReasonCode;
|
|
147
|
+
authority?: "root_instruction" | "root_adoption" | "legacy_authority_unclassified";
|
|
148
|
+
legacyFlags?: Array<"legacy_generic_run" | "legacy_authority_unclassified">;
|
|
149
|
+
waitAuthorization?: WaitAuthorization;
|
|
150
|
+
deferAuthorization?: DeferAuthorization;
|
|
151
|
+
persistenceAuthorization?: PersistenceAuthorization;
|
|
152
|
+
}
|
|
153
|
+
interface GuardEvidence {
|
|
154
|
+
id: string;
|
|
155
|
+
epoch: number;
|
|
156
|
+
callId: string;
|
|
157
|
+
rootCallId: string;
|
|
158
|
+
toolName: string;
|
|
159
|
+
toolResultSeq: number;
|
|
160
|
+
outcome: EvidenceOutcome;
|
|
161
|
+
capabilities: string[];
|
|
162
|
+
subjects: string[];
|
|
163
|
+
surfaces: Array<"artifact" | "ui" | "visual" | "scope">;
|
|
164
|
+
boundedSummarySha256: string;
|
|
165
|
+
/** Executables invoked by a shell-tool command (e.g. 'pnpm', 'git'); present
|
|
166
|
+
* only for command evidence, so an executable-method constraint ("使用 pnpm")
|
|
167
|
+
* can be verified against the command that actually ran. */
|
|
168
|
+
executables?: string[];
|
|
169
|
+
/** Operations with their paths, parsed from the evidence's command or tool
|
|
170
|
+
* payload (quote-aware). A subject mention alone proves nothing; the evidence
|
|
171
|
+
* must show the requested operation on the target. */
|
|
172
|
+
operations?: Array<{
|
|
173
|
+
op: GuardOperation;
|
|
174
|
+
path?: string;
|
|
175
|
+
}>;
|
|
176
|
+
semanticAction?: SemanticAction;
|
|
177
|
+
evidenceRole?: EvidenceRole;
|
|
178
|
+
resolvedTarget?: TargetTuple;
|
|
179
|
+
observedState?: TargetTuple;
|
|
180
|
+
/** Immutable predicate frozen by a trusted resolution producer before effect. */
|
|
181
|
+
expectedTransition?: ExpectedTransition;
|
|
182
|
+
/** Stable JSON sha256 of expectedTransition, minted by the same resolution producer. */
|
|
183
|
+
expectedTransitionDigest?: string;
|
|
184
|
+
parseStatus?: EvidenceParseStatus;
|
|
185
|
+
reasonCode?: string;
|
|
186
|
+
adapterId?: string;
|
|
187
|
+
adapterVersion?: string;
|
|
188
|
+
externalOperationRef?: ExternalOperation;
|
|
189
|
+
}
|
|
190
|
+
interface ExpectedTransition {
|
|
191
|
+
predicateId: string;
|
|
192
|
+
version: number;
|
|
193
|
+
predParamsKind: "inline";
|
|
194
|
+
parameters?: TargetTuple;
|
|
195
|
+
parametersDigest?: string;
|
|
196
|
+
}
|
|
197
|
+
interface EvidenceBinding {
|
|
198
|
+
itemId: string;
|
|
199
|
+
evidenceIds: string[];
|
|
200
|
+
semanticAction?: SemanticAction;
|
|
201
|
+
requestedTarget?: TargetTuple;
|
|
202
|
+
resolvedTarget?: TargetTuple;
|
|
203
|
+
observedState?: TargetTuple;
|
|
204
|
+
expectedTransition?: ExpectedTransition;
|
|
205
|
+
resolutionEvidenceId?: string;
|
|
206
|
+
effectEvidenceId?: string;
|
|
207
|
+
stateEvidenceIds?: string[];
|
|
208
|
+
}
|
|
209
|
+
interface GuardCheckpoint {
|
|
210
|
+
id: string;
|
|
211
|
+
stopProtocolVersion: string;
|
|
212
|
+
certificateVersion: string;
|
|
213
|
+
epoch: number;
|
|
214
|
+
sessionRefDigest: string;
|
|
215
|
+
hostLockDigest: string;
|
|
216
|
+
contractRevision: number;
|
|
217
|
+
contractSha256: string;
|
|
218
|
+
openDigest: string;
|
|
219
|
+
evidenceSha256: string;
|
|
220
|
+
bindingDigest: string;
|
|
221
|
+
bindings: EvidenceBinding[];
|
|
222
|
+
goalRef?: GoalRef;
|
|
223
|
+
certificationDigest: string;
|
|
224
|
+
result: "certified" | "incomplete" | "unknown";
|
|
225
|
+
}
|
|
226
|
+
type BoundaryDisposition = "user_wait" | "external_wait" | "deferred";
|
|
227
|
+
type BoundaryQualificationKind = "user_decision_item" | "root_explicit_wait" | "external_operation_pending" | "root_explicit_defer";
|
|
228
|
+
interface GuardBoundary {
|
|
229
|
+
protocolVersion: "1";
|
|
230
|
+
id: string;
|
|
231
|
+
disposition: BoundaryDisposition;
|
|
232
|
+
qualificationKind: BoundaryQualificationKind;
|
|
233
|
+
qualificationIds: string[];
|
|
234
|
+
epoch: number;
|
|
235
|
+
contractRevision: number;
|
|
236
|
+
contractSha256: string;
|
|
237
|
+
goalRef?: GoalRef;
|
|
238
|
+
candidateSha256: string;
|
|
239
|
+
callId?: string;
|
|
240
|
+
persistedResult: "accepted" | "rejected" | "unknown";
|
|
241
|
+
reasonCode: string;
|
|
242
|
+
}
|
|
243
|
+
interface ExternalOperation {
|
|
244
|
+
id: string;
|
|
245
|
+
epoch: number;
|
|
246
|
+
adapterId: string;
|
|
247
|
+
status: "running" | "pending" | "completed" | "failed" | "unknown";
|
|
248
|
+
}
|
|
249
|
+
interface GuardProjection {
|
|
250
|
+
enabled: boolean;
|
|
251
|
+
epoch: number;
|
|
252
|
+
contractRevision: number;
|
|
253
|
+
items: Map<string, GuardItem>;
|
|
254
|
+
evidence: Map<string, GuardEvidence>;
|
|
255
|
+
checkpoints: GuardCheckpoint[];
|
|
256
|
+
boundaries: GuardBoundary[];
|
|
257
|
+
externalOperations: Map<string, ExternalOperation>;
|
|
258
|
+
sessionRefDigest: string;
|
|
259
|
+
hostLockDigest: string;
|
|
260
|
+
hostStatus: HostStatus;
|
|
261
|
+
hostReasonCode?: string;
|
|
262
|
+
currentGoalRef?: GoalRef;
|
|
263
|
+
currentGoalPhase?: "active" | "paused" | "blocked" | "complete";
|
|
264
|
+
currentGoalActivation?: "armed" | "disarmed";
|
|
265
|
+
certificateStatusReason?: string;
|
|
266
|
+
integrityViolations: string[];
|
|
267
|
+
lastObservedSourceSeq: number;
|
|
268
|
+
lastGuardEventSeq: number;
|
|
269
|
+
lastRecoveryDigest?: string;
|
|
270
|
+
continuationAttempts: Map<number, number>;
|
|
271
|
+
/** Process-local one-shot fallback counters keyed by epoch + contract revision. */
|
|
272
|
+
persistenceCorrectionAttempts: Map<string, number>;
|
|
273
|
+
integrity: GuardIntegrity;
|
|
274
|
+
}
|
|
275
|
+
declare function createProjection(): GuardProjection;
|
|
276
|
+
interface DeriveScope {
|
|
277
|
+
/** Session working directory; used as the scope subject for captured clauses. */
|
|
278
|
+
cwd?: string;
|
|
279
|
+
sessionHeader?: SessionHeader;
|
|
280
|
+
}
|
|
281
|
+
interface DeriveConfig {
|
|
282
|
+
activation: "opt-in" | "always";
|
|
283
|
+
}
|
|
284
|
+
interface DeriveResult {
|
|
285
|
+
projection: GuardProjection;
|
|
286
|
+
/** True when the log contains a compaction summary the agent must recover from. */
|
|
287
|
+
compacted: boolean;
|
|
288
|
+
/** True when an off→on enablement transition was derived in this log. */
|
|
289
|
+
enablementTransitioned: boolean;
|
|
290
|
+
/** Sequence of the last compaction summary in the log, or -1 when none. */
|
|
291
|
+
lastCompactionSeq: number;
|
|
292
|
+
}
|
|
293
|
+
interface DerivedEnvelope {
|
|
294
|
+
seq: number;
|
|
295
|
+
type: string;
|
|
296
|
+
data?: unknown;
|
|
297
|
+
}
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/domain/boundary.d.ts
|
|
300
|
+
interface BoundaryRequest {
|
|
301
|
+
disposition: BoundaryDisposition;
|
|
302
|
+
qualificationKind: BoundaryQualificationKind;
|
|
303
|
+
qualificationIds: string[];
|
|
304
|
+
callId?: string;
|
|
305
|
+
}
|
|
306
|
+
interface BoundaryQualification {
|
|
307
|
+
id: string;
|
|
308
|
+
kind: BoundaryQualificationKind;
|
|
309
|
+
disposition: BoundaryDisposition;
|
|
310
|
+
source: "root_contract" | "trusted_adapter";
|
|
311
|
+
status: "pending" | "running";
|
|
312
|
+
}
|
|
313
|
+
/** Bounded, replay-derived qualifications that callers may cite verbatim. */
|
|
314
|
+
declare function availableBoundaryQualifications(projection: GuardProjection): BoundaryQualification[];
|
|
315
|
+
declare function qualifyBoundary(projection: GuardProjection, request: BoundaryRequest): GuardBoundary;
|
|
316
|
+
/**
|
|
317
|
+
* Reconstruct the immutable candidate against the latest replay projection.
|
|
318
|
+
* A persisted acceptance is not effectuation authority after any contract,
|
|
319
|
+
* Goal, epoch, or qualification change.
|
|
320
|
+
*/
|
|
321
|
+
declare function isCurrentAcceptedBoundary(projection: GuardProjection, boundary: GuardBoundary): boolean;
|
|
322
|
+
interface GoalActivationState extends GoalRef {
|
|
323
|
+
phase: "active" | "paused" | "blocked" | "complete";
|
|
324
|
+
activation: "armed" | "disarmed";
|
|
325
|
+
}
|
|
326
|
+
interface GoalBoundaryAccess {
|
|
327
|
+
get(): Promise<GoalActivationState | undefined>;
|
|
328
|
+
disarm(): Promise<GoalActivationState | undefined>;
|
|
329
|
+
/** Final live adapter readback immediately before any Goal mutation. */
|
|
330
|
+
requalify?: () => Promise<boolean>;
|
|
331
|
+
}
|
|
332
|
+
interface BoundaryEffectuation {
|
|
333
|
+
boundaryId: string;
|
|
334
|
+
goalRef?: GoalRef;
|
|
335
|
+
reasonCode: "boundary_effectuated" | "boundary_no_goal_safe_yield" | "boundary_already_disarmed" | "boundary_pre_effect_failure" | "boundary_readback_still_armed" | "boundary_post_effect_unknown" | "boundary_goal_ref_stale" | "boundary_not_accepted";
|
|
336
|
+
stopAllowed: boolean;
|
|
337
|
+
resumeRequired: boolean;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Effectuate only a replay-confirmed accepted boundary. The first disarm result
|
|
341
|
+
* and an independent get() must both read the same active Goal ref as disarmed.
|
|
342
|
+
* A failure after disarm may have taken effect is never auto-rearmed.
|
|
343
|
+
*/
|
|
344
|
+
declare function effectuateBoundary(boundary: GuardBoundary, access: GoalBoundaryAccess): Promise<BoundaryEffectuation>;
|
|
345
|
+
//#endregion
|
|
346
|
+
//#region src/domain/capture.d.ts
|
|
347
|
+
interface ClassifiedClause {
|
|
348
|
+
kind: GuardItemKind;
|
|
349
|
+
body: string;
|
|
350
|
+
}
|
|
351
|
+
declare function classifyClause(text: string): ClassifiedClause;
|
|
352
|
+
/**
|
|
353
|
+
* Detect an explicitly named tool/method in a clause ("使用 bash 创建",
|
|
354
|
+
* "via bash", "bash to create"). Returns the canonical tool id (e.g. 'bash')
|
|
355
|
+
* or undefined when no explicit method is named.
|
|
356
|
+
*/
|
|
357
|
+
declare function extractMethod(text: string): string | undefined;
|
|
358
|
+
/**
|
|
359
|
+
* Whether a whole user message reads as an informational report (acceptance
|
|
360
|
+
* receipt, progress summary, pasted log) rather than a task instruction.
|
|
361
|
+
* Evaluation is deliberately conservative: reports are detected only when the
|
|
362
|
+
* shape is clearly report-like (markdown headings, bold key/value lines, list
|
|
363
|
+
* or table rows, evidence terms) AND no sentence opens with an imperative, and
|
|
364
|
+
* any question mark keeps the message a task. False positives here would drop
|
|
365
|
+
* real instructions, so plain short sentences are never treated as reports.
|
|
366
|
+
*/
|
|
367
|
+
declare function isInformationalMessage(text: string): boolean;
|
|
368
|
+
/**
|
|
369
|
+
* Detect an explicit operation/effect in a clause ("创建" → create,
|
|
370
|
+
* "读取" → read, "运行" → run). Returns the first operation named, or undefined
|
|
371
|
+
* when the clause requests no specific effect.
|
|
372
|
+
*/
|
|
373
|
+
declare function extractOperation(text: string): GuardOperation | undefined;
|
|
374
|
+
interface CaptureScope {
|
|
375
|
+
/** Session working directory; used as the scope subject when no artifact path is named. */
|
|
376
|
+
cwd?: string;
|
|
377
|
+
}
|
|
378
|
+
declare function extractArtifactPaths(text: string): string[];
|
|
379
|
+
/**
|
|
380
|
+
* Split a single human message into independently tracked clauses. Sentence
|
|
381
|
+
* boundaries and embedded prohibition keywords delimit segments so a compound
|
|
382
|
+
* instruction such as "Modify src/a.ts and src/b.ts. Do not push." yields
|
|
383
|
+
* separate items instead of collapsing into one artifact.
|
|
384
|
+
*/
|
|
385
|
+
interface ClauseSegment {
|
|
386
|
+
kind: GuardItemKind;
|
|
387
|
+
body: string;
|
|
388
|
+
paths: string[];
|
|
389
|
+
}
|
|
390
|
+
declare function segmentClauses(text: string): ClauseSegment[];
|
|
391
|
+
/**
|
|
392
|
+
* Build a GuardItem from an already-classified clause body and a resolved
|
|
393
|
+
* verification subject/surface.
|
|
394
|
+
*/
|
|
395
|
+
declare function captureItem(kind: GuardItemKind, body: string, sourceMessageId: string, id: string, revision: number, subject: string, surface: "artifact" | "scope", method?: string, operation?: GuardOperation): GuardItem;
|
|
396
|
+
/**
|
|
397
|
+
* Capture one contract clause. Every captured item receives a concrete
|
|
398
|
+
* verification contract: a named artifact path (artifact surface) or the
|
|
399
|
+
* session scope (scope surface), so an unrelated file read can never close it.
|
|
400
|
+
*/
|
|
401
|
+
declare function captureClause(text: string, sourceMessageId: string, id: string, revision: number, scope?: CaptureScope): GuardItem;
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region src/domain/checkpoint.d.ts
|
|
404
|
+
interface RejectedBinding {
|
|
405
|
+
itemId: string;
|
|
406
|
+
reason: string;
|
|
407
|
+
reasonCode: string;
|
|
408
|
+
offendingEvidenceIds?: string[];
|
|
409
|
+
hint?: string;
|
|
410
|
+
}
|
|
411
|
+
interface CheckpointResult {
|
|
412
|
+
status: GuardCheckpoint["result"];
|
|
413
|
+
contractRevision: number;
|
|
414
|
+
openItems: string[];
|
|
415
|
+
rejectedBindings: RejectedBinding[];
|
|
416
|
+
checkpoint?: GuardCheckpoint;
|
|
417
|
+
}
|
|
418
|
+
declare function certifyCheckpoint(projection: GuardProjection, bindings: EvidenceBinding[], id: string, commit?: boolean): CheckpointResult;
|
|
419
|
+
//#endregion
|
|
420
|
+
//#region src/domain/conversation.d.ts
|
|
421
|
+
type UserInteractionKind = "instruction" | "conversational";
|
|
422
|
+
/**
|
|
423
|
+
* Classify a direct user message (or one clause of it) as an actionable
|
|
424
|
+
* `instruction` or a session-layer `conversational` utterance. Only
|
|
425
|
+
* conversational results drop capture, so the classifier fails closed:
|
|
426
|
+
* everything it cannot confidently recognize as session-layer talk stays an
|
|
427
|
+
* instruction and is captured exactly as before.
|
|
428
|
+
*
|
|
429
|
+
* Order matters: progression and prohibition leads first, then strong task
|
|
430
|
+
* features (artifact path, explicit method, or a non-negated operation verb
|
|
431
|
+
* outside progression/meta spans), then the meta-question and meta-comment
|
|
432
|
+
* forms, and finally a progression lead over a featureless remainder.
|
|
433
|
+
*/
|
|
434
|
+
declare function classifyUserInteraction(text: string): UserInteractionKind;
|
|
435
|
+
//#endregion
|
|
436
|
+
//#region src/domain/contract-segment.d.ts
|
|
437
|
+
type AuthorityBlockKind = "instruction" | "reference" | "quoted" | "code" | "uncertain";
|
|
438
|
+
type AuthorityKind = "root_instruction" | "root_adoption" | "none";
|
|
439
|
+
interface AuthorityBlock {
|
|
440
|
+
kind: AuthorityBlockKind;
|
|
441
|
+
authority: AuthorityKind;
|
|
442
|
+
text: string;
|
|
443
|
+
capture: boolean;
|
|
444
|
+
blockId: string;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Split a direct root-user message into authority blocks before clause capture.
|
|
448
|
+
* Framed reports, blockquotes and fenced code remain in the native DSH log but
|
|
449
|
+
* never become Guard items. Uncertain prose is captured fail-closed. Explicit
|
|
450
|
+
* adoption can promote only the referenced section, never the whole report by
|
|
451
|
+
* virtue of normative words inside the report itself.
|
|
452
|
+
*/
|
|
453
|
+
declare function segmentAuthorityBlocks(text: string, priorRootMessages?: readonly string[]): AuthorityBlock[];
|
|
454
|
+
declare function authorityCaptureCounts(blocks: readonly AuthorityBlock[]): Record<string, number>;
|
|
455
|
+
//#endregion
|
|
456
|
+
//#region src/domain/contract-digest.d.ts
|
|
457
|
+
/** One authoritative contract identity shared by checkpoints and boundaries. */
|
|
458
|
+
declare function currentContractDigest(projection: GuardProjection): string;
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region src/domain/host-lock.d.ts
|
|
461
|
+
type HostLockStatus = "supported" | "unsupported" | "unavailable";
|
|
462
|
+
type HostPlatform = "posix" | "windows";
|
|
463
|
+
type HostProfileKind = "headless" | "web";
|
|
464
|
+
declare const SUPPORTED_HOST_MANIFEST: HostLockManifest;
|
|
465
|
+
/**
|
|
466
|
+
* Audited package identities. This is a catalogue, not one indivisible lock:
|
|
467
|
+
* evaluateHostLock requires only BASE_HOST_PACKAGES globally and evaluates the
|
|
468
|
+
* remaining action/platform groups independently.
|
|
469
|
+
*/
|
|
470
|
+
declare const EXPECTED_HOST_PACKAGES: PackageRow[];
|
|
471
|
+
declare const BASE_HOST_PACKAGES: ReadonlySet<string>;
|
|
472
|
+
declare const GOAL_HOST_PACKAGES: ReadonlySet<string>;
|
|
473
|
+
type HostCapabilityId = "agent_loop" | "terminal_posix" | "terminal_windows" | "dsh_cli" | "plugin_inventory" | "web_control" | "jobs" | "filesystem";
|
|
474
|
+
declare const HOST_CAPABILITY_PACKAGE_GROUPS: Readonly<Record<HostCapabilityId, ReadonlySet<string>>>;
|
|
475
|
+
interface HostCapabilityEvaluation {
|
|
476
|
+
id: string;
|
|
477
|
+
status: HostLockStatus;
|
|
478
|
+
digest: string;
|
|
479
|
+
requiredPackages: string[];
|
|
480
|
+
missingPackages: string[];
|
|
481
|
+
reasonCode?: "host_capability_missing" | "host_capability_version_mismatch" | "host_capability_integrity_mismatch" | "host_capability_duplicate_package" | "host_capability_context_missing" | "host_capability_request_unsupported";
|
|
482
|
+
}
|
|
483
|
+
interface HostLockEvaluation {
|
|
484
|
+
status: HostLockStatus;
|
|
485
|
+
digest: string;
|
|
486
|
+
goalAvailable: boolean;
|
|
487
|
+
reasonCode?: "host_lock_missing" | "host_lock_version_mismatch" | "host_lock_integrity_mismatch" | "host_lock_unknown_package" | "host_lock_duplicate_package" | "host_lock_goal_graph_incomplete" | "host_lock_goal_capability_mismatch";
|
|
488
|
+
packages: PackageRow[];
|
|
489
|
+
capabilities: Record<HostCapabilityId, HostCapabilityEvaluation>;
|
|
490
|
+
platform?: HostPlatform;
|
|
491
|
+
profileKind?: HostProfileKind;
|
|
492
|
+
liveGoalAvailable?: boolean;
|
|
493
|
+
}
|
|
494
|
+
interface HostLockContext {
|
|
495
|
+
platform?: HostPlatform;
|
|
496
|
+
profileKind?: HostProfileKind;
|
|
497
|
+
capabilityId?: string;
|
|
498
|
+
}
|
|
499
|
+
declare function evaluateHostLock(rows: readonly PackageRow[], context?: HostLockContext): HostLockEvaluation;
|
|
500
|
+
interface HostCapabilityRequest {
|
|
501
|
+
action: SemanticAction;
|
|
502
|
+
platform?: HostPlatform;
|
|
503
|
+
profileKind?: HostProfileKind;
|
|
504
|
+
}
|
|
505
|
+
/** Evaluate only the packages needed for one effect/readback capability. */
|
|
506
|
+
declare function evaluateHostCapability(evaluation: HostLockEvaluation, request: HostCapabilityRequest): HostCapabilityEvaluation;
|
|
507
|
+
/**
|
|
508
|
+
* Bind external_wait qualification and pre-effect requalification to the
|
|
509
|
+
* exact jobs service definition, local provider, and live controller graph.
|
|
510
|
+
* This is deliberately independent of the global/base lock so profiles that
|
|
511
|
+
* do not support background jobs can still use unrelated Guard actions.
|
|
512
|
+
*/
|
|
513
|
+
declare function evaluateExternalWaitCapability(evaluation: HostLockEvaluation): HostCapabilityEvaluation;
|
|
514
|
+
type HostToolSurface = "bash" | "pwsh" | "filesystem";
|
|
515
|
+
/**
|
|
516
|
+
* Gate automatically replayed ordinary tool results by the exact host
|
|
517
|
+
* capability that owns their registration and outcome surface. Tool names are
|
|
518
|
+
* intentionally separate from semantic actions: a `bash` result on Windows,
|
|
519
|
+
* or a `pwsh` result on POSIX, is not evidence from the active host stack.
|
|
520
|
+
*/
|
|
521
|
+
declare function evaluateToolSurfaceCapability(evaluation: HostLockEvaluation, surface: HostToolSurface): HostCapabilityEvaluation;
|
|
522
|
+
/** Bind the injected Goal graph to the live Goal service for this agent. */
|
|
523
|
+
declare function bindLiveGoalCapability(evaluation: HostLockEvaluation, liveGoalAvailable: boolean): HostLockEvaluation;
|
|
524
|
+
type AuditedExecutable = "git" | "npm" | "pnpm" | "dsh";
|
|
525
|
+
interface ExecutableIdentity {
|
|
526
|
+
executable: AuditedExecutable;
|
|
527
|
+
realpath: string;
|
|
528
|
+
version: string;
|
|
529
|
+
interpreterRealpath?: string;
|
|
530
|
+
interpreterVersion?: string;
|
|
531
|
+
}
|
|
532
|
+
interface ExecutableIdentityBinding {
|
|
533
|
+
status: HostLockStatus;
|
|
534
|
+
digest: string;
|
|
535
|
+
identity?: ExecutableIdentity;
|
|
536
|
+
reasonCode?: "executable_identity_missing" | "executable_realpath_invalid" | "executable_identity_drift";
|
|
537
|
+
}
|
|
538
|
+
/** Bind resolution and effect to the exact same canonical executable tuple. */
|
|
539
|
+
declare function bindExecutableIdentity(resolution: ExecutableIdentity | undefined, effect: ExecutableIdentity | undefined): ExecutableIdentityBinding;
|
|
540
|
+
declare const DEFAULT_HOST_LOCK: HostLockEvaluation;
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region src/domain/derive.d.ts
|
|
543
|
+
declare const PROTOCOL_V3_NOTICE = "Context Guard protocol boundary: v3.0.0";
|
|
544
|
+
/**
|
|
545
|
+
* Pure, deterministic re-derivation of the guard projection from the DSH
|
|
546
|
+
* native event log. Context Guard never writes custom session events, so every
|
|
547
|
+
* piece of state is derived from `command/run`, `user/message`, `tool/call`,
|
|
548
|
+
* `tool/result`, `tool/code-dispatch-start`, `tool/code-dispatch`, and
|
|
549
|
+
* `compaction/summary`.
|
|
550
|
+
*/
|
|
551
|
+
declare function deriveProjection(sourceEvents: readonly DerivedEnvelope[], config: DeriveConfig, scope: DeriveScope, durableConfirmed: boolean, hostLock?: HostLockEvaluation): DeriveResult;
|
|
552
|
+
//#endregion
|
|
553
|
+
//#region src/domain/evidence.d.ts
|
|
554
|
+
interface ToolCallInput {
|
|
555
|
+
callId: string;
|
|
556
|
+
name: string;
|
|
557
|
+
arguments: string;
|
|
558
|
+
/** Code-mode dispatch root; falls back to `callId` when the harness does not carry one. */
|
|
559
|
+
rootCallId?: string;
|
|
560
|
+
}
|
|
561
|
+
interface ToolResultInput {
|
|
562
|
+
seq: number;
|
|
563
|
+
error?: unknown;
|
|
564
|
+
meta?: unknown;
|
|
565
|
+
textContent: string;
|
|
566
|
+
}
|
|
567
|
+
declare function extractTextContent(content: readonly unknown[]): string;
|
|
568
|
+
interface ToolOperation {
|
|
569
|
+
op: GuardOperation;
|
|
570
|
+
path?: string;
|
|
571
|
+
}
|
|
572
|
+
declare function isDeterministicCheck(command: string): boolean;
|
|
573
|
+
interface ToolSubject {
|
|
574
|
+
capabilities: string[];
|
|
575
|
+
subjects: string[];
|
|
576
|
+
surfaces: Array<"artifact" | "ui" | "visual" | "scope">;
|
|
577
|
+
outcome?: EvidenceOutcome;
|
|
578
|
+
executables?: string[];
|
|
579
|
+
operations?: ToolOperation[];
|
|
580
|
+
semanticAction?: SemanticAction;
|
|
581
|
+
evidenceRole?: EvidenceRole;
|
|
582
|
+
resolvedTarget?: TargetTuple;
|
|
583
|
+
observedState?: TargetTuple;
|
|
584
|
+
expectedTransition?: ExpectedTransition;
|
|
585
|
+
expectedTransitionDigest?: string;
|
|
586
|
+
parseStatus?: EvidenceParseStatus;
|
|
587
|
+
reasonCode?: string;
|
|
588
|
+
adapterId?: string;
|
|
589
|
+
adapterVersion?: string;
|
|
590
|
+
externalOperationRef?: ExternalOperation;
|
|
591
|
+
}
|
|
592
|
+
declare function extractToolSubject(call: ToolCallInput, result: ToolResultInput, defaultCwd?: string, hostLock?: HostLockEvaluation): ToolSubject;
|
|
593
|
+
declare function evidenceFromPersistedToolResult(call: ToolCallInput, result: ToolResultInput, epoch: number, evidenceId: string, defaultCwd?: string, hostLock?: HostLockEvaluation): GuardEvidence;
|
|
594
|
+
declare function withDurability(evidence: GuardEvidence, confirmed: boolean): GuardEvidence;
|
|
595
|
+
//#endregion
|
|
596
|
+
//#region src/domain/goal-gate.d.ts
|
|
597
|
+
declare function hasCurrentCertificate(projection: GuardProjection): boolean;
|
|
598
|
+
/**
|
|
599
|
+
* Denies `update_goal(action=complete)` while the guard is enabled and no
|
|
600
|
+
* current completion certificate exists. The gate itself has no bypass; a
|
|
601
|
+
* workflow that genuinely finished but cannot certify (for example a contract
|
|
602
|
+
* polluted by session-layer talk, or evidence that lives in another session)
|
|
603
|
+
* has three explicit remediation routes:
|
|
604
|
+
*
|
|
605
|
+
* 1. `/context-guard off` disables the guard, so completion is no longer
|
|
606
|
+
* gated. Use only after the user confirms the work is actually done.
|
|
607
|
+
* 2. `/context-guard clear` supersedes every pending requirement and
|
|
608
|
+
* acceptance under a `CLEAR:<revision>` sentinel (prohibitions are
|
|
609
|
+
* retained) and bumps the contract revision; an empty-binding checkpoint
|
|
610
|
+
* can then certify while the guard stays enabled.
|
|
611
|
+
* 3. `update_goal(action=blocked)` records the blocker truthfully, which is
|
|
612
|
+
* never denied by this gate.
|
|
613
|
+
*/
|
|
614
|
+
declare function goalCompletionDenial(projection: GuardProjection, toolName: string, argumentsValue: unknown, configuredToolName?: string): string | undefined;
|
|
615
|
+
//#endregion
|
|
616
|
+
//#region src/domain/shell-parse.d.ts
|
|
617
|
+
/**
|
|
618
|
+
* v0.1 certifiable command subset parser.
|
|
619
|
+
*
|
|
620
|
+
* This is NOT a general Bash or PowerShell static analyzer. Only a small,
|
|
621
|
+
* auditable grammar is supported: a single foreground simple command whose
|
|
622
|
+
* grammar parses fully. Anything else returns `status: 'unsupported'` (or
|
|
623
|
+
* `'malformed'` for unterminated quotes) with EMPTY executables and operations,
|
|
624
|
+
* so an unrecognized command can never certify an operation. False negatives
|
|
625
|
+
* are preferred over false positives: uncertain commands stay incomplete.
|
|
626
|
+
*/
|
|
627
|
+
type ShellParseStatus = "supported" | "unsupported" | "malformed";
|
|
628
|
+
interface ParsedShell {
|
|
629
|
+
status: ShellParseStatus;
|
|
630
|
+
/** Human-readable reason when the command is not supported (or malformed). */
|
|
631
|
+
reason?: string;
|
|
632
|
+
executables: string[];
|
|
633
|
+
operations: Array<{
|
|
634
|
+
op: GuardOperation;
|
|
635
|
+
path?: string;
|
|
636
|
+
}>;
|
|
637
|
+
malformed: boolean;
|
|
638
|
+
}
|
|
639
|
+
type CanonicalCommandSurface = "bash" | "pwsh";
|
|
640
|
+
interface CanonicalArgv {
|
|
641
|
+
status: ShellParseStatus;
|
|
642
|
+
reason?: string;
|
|
643
|
+
argv: string[];
|
|
644
|
+
malformed: boolean;
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Whether an executable carries run semantics (as opposed to the tiny
|
|
648
|
+
* file/read tool subset). Used for scope-subject attribution of a pathless
|
|
649
|
+
* run operation; `echo` or `cat` never becomes a subject-carrying run.
|
|
650
|
+
*/
|
|
651
|
+
declare function isRunExecutable(executable: string): boolean;
|
|
652
|
+
/**
|
|
653
|
+
* Parse one POSIX shell command against the v0.1 supported surface: a single
|
|
654
|
+
* foreground simple command made of an env-assignment prefix, one whitelisted
|
|
655
|
+
* executable and literal arguments, with at most one `>`/`>>` redirect to a
|
|
656
|
+
* literal path. Compound syntax (`;`, `&&`, `||`, pipes, background, subshells,
|
|
657
|
+
* command substitution, heredocs, unclosed quotes, dynamic eval/source,
|
|
658
|
+
* variable/glob paths) makes the WHOLE command unsupported with no partial
|
|
659
|
+
* results.
|
|
660
|
+
*/
|
|
661
|
+
declare function parseShellCommand(command: string): ParsedShell;
|
|
662
|
+
/**
|
|
663
|
+
* Parse one PowerShell command against the v0.2 subset: a single, directly
|
|
664
|
+
* invoked whitelisted cmdlet (Set-Content / Add-Content / New-Item /
|
|
665
|
+
* Out-File / Get-Content) whose path comes from an explicit named path
|
|
666
|
+
* parameter, or a whitelisted external executable (git, pnpm, node, …) with
|
|
667
|
+
* all-literal arguments. Unquoted `N>&M` diagnostic stream duplication is
|
|
668
|
+
* stripped. Multi-statements (`;`), pipelines (`|`), the call operator (`&`),
|
|
669
|
+
* script blocks, dot sourcing, .NET/dynamic invocation,
|
|
670
|
+
* variable/expression/subexpression paths, positional paths, and unknown
|
|
671
|
+
* parameters make the WHOLE command unsupported.
|
|
672
|
+
*/
|
|
673
|
+
declare function parsePwshCommand(command: string): ParsedShell;
|
|
674
|
+
/**
|
|
675
|
+
* Return canonical argv for the same literal, single-command grammar used by
|
|
676
|
+
* the production capture parser. This is intentionally stricter than the
|
|
677
|
+
* operation parser: environment prefixes and redirects are rejected because
|
|
678
|
+
* a stateful command manifest must bind the executable and every argument
|
|
679
|
+
* directly. Callers must still validate the executable-specific argv shape.
|
|
680
|
+
*/
|
|
681
|
+
declare function canonicalArgvFromCommand(command: string, surface: CanonicalCommandSurface): CanonicalArgv;
|
|
682
|
+
//#endregion
|
|
683
|
+
//#region src/domain/git-adapter.d.ts
|
|
684
|
+
type GitAdapterAction = "inspect_remote_updates" | "pull" | "fetch" | "commit" | "push";
|
|
685
|
+
declare const GIT_COMMAND_MANIFEST_IDS: {
|
|
686
|
+
readonly inspect_remote_updates: "git.ls_remote_exact.v2";
|
|
687
|
+
readonly pull: "git.pull_ff_only_explicit.v2";
|
|
688
|
+
readonly fetch: "git.fetch_tracking_explicit.v2";
|
|
689
|
+
readonly commit: "git.commit_index_tree.v2";
|
|
690
|
+
readonly push: "git.push_explicit_refs.v2";
|
|
691
|
+
};
|
|
692
|
+
interface GitCommandManifest {
|
|
693
|
+
manifestVersion: 2;
|
|
694
|
+
manifestId: (typeof GIT_COMMAND_MANIFEST_IDS)[GitAdapterAction];
|
|
695
|
+
action: GitAdapterAction;
|
|
696
|
+
surface: CanonicalCommandSurface;
|
|
697
|
+
argv: string[];
|
|
698
|
+
remote?: string;
|
|
699
|
+
sourceRef?: string;
|
|
700
|
+
destinationRef?: string;
|
|
701
|
+
trackingRef?: string;
|
|
702
|
+
}
|
|
703
|
+
interface GitCommandRejected {
|
|
704
|
+
status: "rejected";
|
|
705
|
+
reasonCode: "shell_command_unsupported" | "git_global_option_forbidden" | "git_alias_or_subcommand_forbidden" | "git_argv_shape_forbidden" | "git_remote_forbidden" | "git_ref_forbidden" | "git_tracking_ref_forbidden";
|
|
706
|
+
}
|
|
707
|
+
interface GitCommandAccepted {
|
|
708
|
+
status: "accepted";
|
|
709
|
+
manifest: GitCommandManifest;
|
|
710
|
+
}
|
|
711
|
+
type GitCommandParseResult = GitCommandAccepted | GitCommandRejected;
|
|
712
|
+
interface GitTargetIdentity {
|
|
713
|
+
repository: string;
|
|
714
|
+
remote?: string;
|
|
715
|
+
/** Canonical v3 target key; explicit identities remain separate in the command manifest. */
|
|
716
|
+
refspec?: string;
|
|
717
|
+
}
|
|
718
|
+
interface GitPrestateEnvelope {
|
|
719
|
+
envelopeVersion: "git.prestate.v1";
|
|
720
|
+
action: GitAdapterAction;
|
|
721
|
+
commandManifestId: string;
|
|
722
|
+
targetIdentityDigest: string;
|
|
723
|
+
stateTupleDigest: string;
|
|
724
|
+
}
|
|
725
|
+
interface GitPrestateCheck {
|
|
726
|
+
valid: boolean;
|
|
727
|
+
reasonCode?: "command_manifest_drift" | "target_identity_drift" | "prestate_drift";
|
|
728
|
+
}
|
|
729
|
+
interface GitEffectRunner {
|
|
730
|
+
(file: "git", argv: string[], repository: string): Promise<void>;
|
|
731
|
+
}
|
|
732
|
+
interface GitEffectExecution {
|
|
733
|
+
status: "executed" | "rejected";
|
|
734
|
+
reasonCode?: GitPrestateCheck["reasonCode"] | "repository_missing";
|
|
735
|
+
}
|
|
736
|
+
interface LinearCommitReadback {
|
|
737
|
+
/** Commit reached after the guarded effect. */
|
|
738
|
+
postHeadOid: string;
|
|
739
|
+
/** The sole parent parsed from the post-commit object. */
|
|
740
|
+
preHeadOid: string;
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Parse only the audited Git argv shapes. The shell words come from the
|
|
744
|
+
* production shell parser; this module does not maintain an independent split
|
|
745
|
+
* or quoting implementation. Global `git -C`/`git -c`, aliases, force/delete,
|
|
746
|
+
* wildcard refspecs, and implicit HEAD/ref destinations fail closed because
|
|
747
|
+
* none occur in an accepted exact shape.
|
|
748
|
+
*/
|
|
749
|
+
declare function parseGitCommandManifest(command: string, surface: CanonicalCommandSurface): GitCommandParseResult;
|
|
750
|
+
/** Bind the command's explicit remote/ref identities to the canonical target. */
|
|
751
|
+
declare function gitCommandMatchesTarget(manifest: GitCommandManifest, target: GitTargetIdentity): boolean;
|
|
752
|
+
/**
|
|
753
|
+
* Normalize the read-only `git ls-files --stage -z` surface. Only stage-zero
|
|
754
|
+
* entries are certifiable; the digest binds mode, blob OID, and raw path bytes
|
|
755
|
+
* without asking Git to create an object (in particular, never `write-tree`).
|
|
756
|
+
*/
|
|
757
|
+
declare function commitIndexSnapshotDigest(indexEntries: Uint8Array): string | undefined;
|
|
758
|
+
/** Normalize the committed `git ls-tree -r -z <oid>` surface to the same tuple. */
|
|
759
|
+
declare function commitTreeSnapshotDigest(treeEntries: Uint8Array): string | undefined;
|
|
760
|
+
/**
|
|
761
|
+
* Parse the raw `git rev-list --parents -n 1 HEAD` surface and accept only a
|
|
762
|
+
* linear commit whose sole parent is the exact resolved pre-effect HEAD.
|
|
763
|
+
* Root commits, merge commits, a substituted first parent, malformed output,
|
|
764
|
+
* and a no-op/self-parent tuple all fail closed.
|
|
765
|
+
*/
|
|
766
|
+
declare function verifiedLinearCommitReadback(rawParents: Uint8Array, expectedPreHeadOid: string): LinearCommitReadback | undefined;
|
|
767
|
+
declare function createGitPrestateEnvelope(manifest: GitCommandManifest, target: GitTargetIdentity, stateTuple: Readonly<Record<string, string | Uint8Array>>): GitPrestateEnvelope;
|
|
768
|
+
/**
|
|
769
|
+
* Mandatory resolution-to-effect gate. Call immediately before invoking Git;
|
|
770
|
+
* any command, target, ref/OID, remote, branch, or raw index tuple drift makes
|
|
771
|
+
* the previously resolved operation unusable.
|
|
772
|
+
*/
|
|
773
|
+
declare function revalidateGitPrestate(resolved: GitPrestateEnvelope, manifest: GitCommandManifest, target: GitTargetIdentity, currentStateTuple: Readonly<Record<string, string | Uint8Array>>): GitPrestateCheck;
|
|
774
|
+
/** Execute the exact resolved argv only after the mandatory live recheck. */
|
|
775
|
+
declare function executeRevalidatedGitEffect(resolved: GitPrestateEnvelope, manifest: GitCommandManifest, target: GitTargetIdentity, currentStateTuple: Readonly<Record<string, string | Uint8Array>>, runner: GitEffectRunner): Promise<GitEffectExecution>;
|
|
776
|
+
//#endregion
|
|
777
|
+
//#region src/domain/host-resolver.d.ts
|
|
778
|
+
declare class HostProfileError extends Error {
|
|
779
|
+
readonly code: string;
|
|
780
|
+
constructor(code: string, message: string);
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Read only the bounded package identities used by the host lock from a pnpm
|
|
784
|
+
* v9 lockfile. Multiple resolved versions are preserved as separate rows so
|
|
785
|
+
* callers cannot silently select a nearest instance.
|
|
786
|
+
*/
|
|
787
|
+
declare function packageRowsFromPnpmLock(text: string): PackageRow[];
|
|
788
|
+
declare function resolveInstalledHostLock(moduleUrl?: string): HostLockEvaluation;
|
|
789
|
+
/**
|
|
790
|
+
* Resolve only package identities reachable from the active pnpm importer.
|
|
791
|
+
* Historical snapshots elsewhere in the lockfile are deliberately ignored;
|
|
792
|
+
* two reachable peer variants of a critical package remain a duplicate and
|
|
793
|
+
* are returned twice so evaluateHostLock can fail closed with a bounded code.
|
|
794
|
+
*/
|
|
795
|
+
declare function packageRowsFromActiveGraph(packageMapText: string, lockText: string, nodeModulesRoot?: string): PackageRow[];
|
|
796
|
+
interface ActiveProfileHostLock {
|
|
797
|
+
evaluation: HostLockEvaluation;
|
|
798
|
+
runtimeRoot: string;
|
|
799
|
+
profileRoot: string;
|
|
800
|
+
pluginVersion: string;
|
|
801
|
+
platform: HostPlatform;
|
|
802
|
+
profileKind: HostProfileKind;
|
|
803
|
+
}
|
|
804
|
+
/** Read and validate the actual runtime graph plus the installed profile plugin. */
|
|
805
|
+
declare function resolveActiveProfileHostLock(runtimeRoot: string, profileRoot: string, expectedPluginVersion: string): ActiveProfileHostLock;
|
|
806
|
+
/** Atomically inject a repeatable managed patch into the selected profile only. */
|
|
807
|
+
declare function injectActiveProfileHostLock(input: ActiveProfileHostLock): string;
|
|
808
|
+
/** Extract the bounded host tuple from DSH's composed YAML dump. */
|
|
809
|
+
declare function hostLockRowsFromComposedDump(text: string): PackageRow[];
|
|
810
|
+
declare function hostLockContextFromComposedDump(text: string): {
|
|
811
|
+
platform?: HostPlatform;
|
|
812
|
+
profileKind?: HostProfileKind;
|
|
813
|
+
};
|
|
814
|
+
declare function verifyComposedHostLockDump(text: string, expected: HostLockEvaluation): HostLockEvaluation;
|
|
815
|
+
//#endregion
|
|
816
|
+
//#region src/domain/manifest.d.ts
|
|
817
|
+
/**
|
|
818
|
+
* The single source of truth for the certifiable command surface (v0.2).
|
|
819
|
+
*
|
|
820
|
+
* Every enumeration that decides which command shapes can produce evidence
|
|
821
|
+
* lives HERE, loaded by the parsers and by the contract capture. Adding a tool
|
|
822
|
+
* or a task verb is a data change, not a code change. The manifest is shipped
|
|
823
|
+
* with the package and is intentionally NOT runtime-writable: widening the
|
|
824
|
+
* surface lowers the evidence bar, so it must change only through a reviewed
|
|
825
|
+
* release, never through local configuration.
|
|
826
|
+
*/
|
|
827
|
+
interface OperationVerbEntry {
|
|
828
|
+
op: GuardOperation;
|
|
829
|
+
/** RegExp source, matched case-insensitively; array order = priority. */
|
|
830
|
+
pattern: string;
|
|
831
|
+
}
|
|
832
|
+
interface CommandSurfaceManifest {
|
|
833
|
+
/** POSIX file-effect tools (`printf`, `echo`, `touch`, `cat`). */
|
|
834
|
+
fileTools: string[];
|
|
835
|
+
/** POSIX read-only inspection tools; pathish args become read effects. */
|
|
836
|
+
readTools: string[];
|
|
837
|
+
/** POSIX run-executable whitelist (any supported simple command gets run semantics). */
|
|
838
|
+
runExecutables: string[];
|
|
839
|
+
/** PowerShell external-executable whitelist (mirrors runExecutables). */
|
|
840
|
+
pwshExternalExecutables: string[];
|
|
841
|
+
/**
|
|
842
|
+
* Clause verb → operation mapping. Order matters: the first matching group
|
|
843
|
+
* wins, and the group order is create → modify → read → verify → run.
|
|
844
|
+
*/
|
|
845
|
+
operationVerbs: OperationVerbEntry[];
|
|
846
|
+
}
|
|
847
|
+
declare const COMMAND_SURFACE_MANIFEST: CommandSurfaceManifest;
|
|
848
|
+
interface ManifestIssue {
|
|
849
|
+
path: string;
|
|
850
|
+
message: string;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Validate the manifest invariants the parsers and capture depend on:
|
|
854
|
+
* - every collection is non-empty, sorted-case-insensitively, and duplicate-free
|
|
855
|
+
* - external executables mirror the POSIX run set exactly
|
|
856
|
+
* - verb groups exist once, in the documented priority order, and compile
|
|
857
|
+
* (they compile by construction when validated, so a typo cannot silently
|
|
858
|
+
* widen or break the surface).
|
|
859
|
+
*/
|
|
860
|
+
declare function validateManifest(manifest?: CommandSurfaceManifest): ManifestIssue[];
|
|
861
|
+
//#endregion
|
|
862
|
+
//#region src/domain/matching.d.ts
|
|
863
|
+
declare function isVerifyingCapability(evidence: GuardEvidence): boolean;
|
|
864
|
+
/** The facets a single evidence contributes to for an item. */
|
|
865
|
+
interface EvidenceFacetCoverage {
|
|
866
|
+
artifact: boolean;
|
|
867
|
+
effect: boolean;
|
|
868
|
+
method: boolean;
|
|
869
|
+
verify: boolean;
|
|
870
|
+
run: boolean;
|
|
871
|
+
}
|
|
872
|
+
declare function evidenceCoverage(item: GuardItem, evidence: GuardEvidence): EvidenceFacetCoverage;
|
|
873
|
+
/**
|
|
874
|
+
* Whether a single evidence can close an enforced item on its own. This is the
|
|
875
|
+
* conservative per-evidence check; the certifier additionally verifies that the
|
|
876
|
+
* whole binding satisfies every required facet.
|
|
877
|
+
*/
|
|
878
|
+
declare function evidenceMatchesItem(item: GuardItem, evidence: GuardEvidence): boolean;
|
|
879
|
+
/**
|
|
880
|
+
* Whether a whole binding (a set of evidence ids) satisfies the fixed v0.1
|
|
881
|
+
* binding invariants:
|
|
882
|
+
*
|
|
883
|
+
* - run: the method (or run) evidence alone closes the contract — no extra
|
|
884
|
+
* read or unrelated deterministic-check is required.
|
|
885
|
+
* - create/write/modify: BOTH a method evidence (method + operation + subject)
|
|
886
|
+
* and a state-verification evidence on the same subject are required.
|
|
887
|
+
* - read: a successful read evidence matching method, read operation and
|
|
888
|
+
* subject satisfies the method side and the object side at once.
|
|
889
|
+
* - verify: only explicit read/verify/deterministic-check evidence on the
|
|
890
|
+
* subject closes; unrelated scope calls cannot be spliced in.
|
|
891
|
+
* - explicit method without a parsable operation fails closed.
|
|
892
|
+
* - a non-enforced item (prohibition) is acknowledged by any valid success
|
|
893
|
+
* evidence.
|
|
894
|
+
*/
|
|
895
|
+
declare function bindingSatisfies(projection: GuardProjection, item: GuardItem, evidenceIds: string[]): boolean;
|
|
896
|
+
//#endregion
|
|
897
|
+
//#region src/domain/recovery.d.ts
|
|
898
|
+
interface RecoveryOptions {
|
|
899
|
+
rejectedBindings?: Array<{
|
|
900
|
+
itemId: string;
|
|
901
|
+
reason: string;
|
|
902
|
+
reasonCode?: string;
|
|
903
|
+
offendingEvidenceIds?: string[];
|
|
904
|
+
}>;
|
|
905
|
+
charBudget?: number;
|
|
906
|
+
}
|
|
907
|
+
declare const DEFAULT_RECOVERY_CHAR_BUDGET = 4e3;
|
|
908
|
+
/**
|
|
909
|
+
* An actionable one-line hint for how an open item's verification contract can
|
|
910
|
+
* be closed. It never weakens the contract; it only names the missing facet so
|
|
911
|
+
* the agent can produce the right evidence shape instead of reverse-engineering
|
|
912
|
+
* the guard. When `evidenceIds` is given, the hint accounts for what those
|
|
913
|
+
* evidence already cover.
|
|
914
|
+
*/
|
|
915
|
+
declare function closingHint(projection: GuardProjection, item: GuardItem, evidenceIds?: string[]): string;
|
|
916
|
+
declare function openItems(projection: GuardProjection): GuardItem[];
|
|
917
|
+
/**
|
|
918
|
+
* Content identity of a rendered recovery packet, bound to the contract
|
|
919
|
+
* revision and epoch it was rendered from. The runtime compares digests before
|
|
920
|
+
* re-injecting, so a repeatedly re-armed recovery with unchanged content is
|
|
921
|
+
* injected once instead of looping (v0.2.1).
|
|
922
|
+
*/
|
|
923
|
+
declare function recoveryDigest(packet: string, projection: GuardProjection): string;
|
|
924
|
+
declare function renderRecoveryPacket(projection: GuardProjection, options?: RecoveryOptions): string;
|
|
925
|
+
//#endregion
|
|
926
|
+
//#region src/domain/stop-policy.d.ts
|
|
927
|
+
type CompletionDisposition = "complete" | "user_wait" | "external_wait" | "report";
|
|
928
|
+
declare function isWholeTaskCompletionClaim(text: string): boolean;
|
|
929
|
+
declare function classifyCompletionClaim(text: string): CompletionDisposition;
|
|
930
|
+
interface TurnStoppingDecision {
|
|
931
|
+
action: "continue" | "stop";
|
|
932
|
+
reason?: string;
|
|
933
|
+
}
|
|
934
|
+
interface AssistantOutcomeObservation {
|
|
935
|
+
kind: "completion_claim" | "user_wait_claim" | "external_wait_claim" | "report";
|
|
936
|
+
reasonCode: string;
|
|
937
|
+
}
|
|
938
|
+
/** Assistant prose is retained only as a bounded diagnostic observation. */
|
|
939
|
+
declare function observeAssistantOutcome(text: string): AssistantOutcomeObservation;
|
|
940
|
+
/**
|
|
941
|
+
* Stop Protocol 2.0 decision. This function deliberately has no assistant-text
|
|
942
|
+
* parameter: completion wording, quotation, negation and translation cannot
|
|
943
|
+
* steer the protocol. A structured root persistence authorization may request
|
|
944
|
+
* one fallback correction; subsequent attempts safe-yield. An active, armed
|
|
945
|
+
* Goal remains exclusively owned by the host Goal Round Driver.
|
|
946
|
+
*/
|
|
947
|
+
declare function decideTurnBoundary(projection: GuardProjection): TurnStoppingDecision;
|
|
948
|
+
declare function decideTurnStopping(projection: GuardProjection, _assistantText: string, _turn: number, _maxAttempts: number): TurnStoppingDecision;
|
|
949
|
+
declare function latestAssistantText(events: readonly {
|
|
950
|
+
type: string;
|
|
951
|
+
data: unknown;
|
|
952
|
+
}[]): string;
|
|
953
|
+
//#endregion
|
|
954
|
+
//#region src/domain/supersession.d.ts
|
|
955
|
+
declare function supersedeItem(items: Map<string, GuardItem>, oldId: string, replacement: GuardItem): boolean;
|
|
956
|
+
//#endregion
|
|
957
|
+
export { gitCommandMatchesTarget as $, VerificationContract as $n, UserInteractionKind as $t, hostLockRowsFromComposedDump as A, DerivedEnvelope as An, HOST_CAPABILITY_PACKAGE_GROUPS as At, GitCommandManifest as B, GuardEvidence as Bn, SUPPORTED_HOST_MANIFEST as Bt, CommandSurfaceManifest as C, qualifyBoundary as Cn, digestStrings as Cr, AuditedExecutable as Ct, ActiveProfileHostLock as D, DeriveConfig as Dn, sha256 as Dr, ExecutableIdentity as Dt, validateManifest as E, DeferAuthorization as En, sanitizeUrl as Er, EXPECTED_HOST_PACKAGES as Et, resolveInstalledHostLock as F, ExpectedTransition as Fn, HostLockEvaluation as Ft, GitPrestateCheck as G, GuardOperation as Gn, evaluateHostLock as Gt, GitCommandRejected as H, GuardItem as Hn, bindLiveGoalCapability as Ht, verifyComposedHostLockDump as I, ExternalOperation as In, HostLockStatus as It, LinearCommitReadback as J, PersistenceAuthorization as Jn, AuthorityBlock as Jt, GitPrestateEnvelope as K, GuardProjection as Kn, evaluateToolSurfaceCapability as Kt, GIT_COMMAND_MANIFEST_IDS as L, GoalRef as Ln, HostPlatform as Lt, packageRowsFromActiveGraph as M, EvidenceOutcome as Mn, HostCapabilityId as Mt, packageRowsFromPnpmLock as N, EvidenceParseStatus as Nn, HostCapabilityRequest as Nt, HostProfileError as O, DeriveResult as On, ExecutableIdentityBinding as Ot, resolveActiveProfileHostLock as P, EvidenceRole as Pn, HostLockContext as Pt, executeRevalidatedGitEffect as Q, TargetValue as Qn, segmentAuthorityBlocks as Qt, GitAdapterAction as R, GuardBoundary as Rn, HostProfileKind as Rt, COMMAND_SURFACE_MANIFEST as S, isCurrentAcceptedBoundary as Sn, canonicalizePath as Sr, deriveProjection as St, OperationVerbEntry as T, BoundaryQualificationKind as Tn, sanitizeClauseText as Tr, DEFAULT_HOST_LOCK as Tt, GitEffectExecution as U, GuardItemKind as Un, evaluateExternalWaitCapability as Ut, GitCommandParseResult as V, GuardIntegrity as Vn, bindExecutableIdentity as Vt, GitEffectRunner as W, GuardItemStatus as Wn, evaluateHostCapability as Wt, commitTreeSnapshotDigest as X, TargetCaptureStatus as Xn, AuthorityKind as Xt, commitIndexSnapshotDigest as Y, TargetCaptureReasonCode as Yn, AuthorityBlockKind as Yt, createGitPrestateEnvelope as Z, TargetTuple as Zn, authorityCaptureCounts as Zt, EvidenceFacetCoverage as _, BoundaryRequest as _n, requestedTargetMatchesResolved as _r, extractTextContent as _t, classifyCompletionClaim as a, ClassifiedClause as an, ActionManifest as ar, ParsedShell as at, evidenceMatchesItem as b, availableBoundaryQualifications as bn, validateActionManifest as br, withDurability as bt, isWholeTaskCompletionClaim as c, captureItem as cn, SEMANTIC_ACTIONS as cr, isRunExecutable as ct, DEFAULT_RECOVERY_CHAR_BUDGET as d, extractMethod as dn, SUPPORTED_EVIDENCE_ADAPTERS as dr, goalCompletionDenial as dt, classifyUserInteraction as en, WaitAuthorization as er, parseGitCommandManifest as et, RecoveryOptions as f, extractOperation as fn, SemanticAction as fr, hasCurrentCertificate as ft, renderRecoveryPacket as g, BoundaryQualification as gn, requestedTargetAuthorizesMutation as gr, evidenceFromPersistedToolResult as gt, recoveryDigest as h, BoundaryEffectuation as hn, isStatefulAction as hr, ToolSubject as ht, TurnStoppingDecision as i, CaptureScope as in, ACTION_MANIFEST_VERSION as ir, CanonicalCommandSurface as it, injectActiveProfileHostLock as j, EvidenceBinding as jn, HostCapabilityEvaluation as jt, hostLockContextFromComposedDump as k, DeriveScope as kn, GOAL_HOST_PACKAGES as kt, latestAssistantText as l, classifyClause as ln, STATEFUL_ACTIONS as lr, parsePwshCommand as lt, openItems as m, segmentClauses as mn, actionCompatible as mr, ToolResultInput as mt, AssistantOutcomeObservation as n, RejectedBinding as nn, PackageRow as nr, verifiedLinearCommitReadback as nt, decideTurnBoundary as o, ClauseSegment as on, ActionSpec as or, ShellParseStatus as ot, closingHint as p, isInformationalMessage as pn, StatefulAction as pr, ToolCallInput as pt, GitTargetIdentity as q, HostStatus as qn, currentContractDigest as qt, CompletionDisposition as r, certifyCheckpoint as rn, ACTION_MANIFEST as rr, CanonicalArgv as rt, decideTurnStopping as s, captureClause as sn, CERTIFICATE_VERSION as sr, canonicalArgvFromCommand as st, supersedeItem as t, CheckpointResult as tn, createProjection as tr, revalidateGitPrestate as tt, observeAssistantOutcome as u, extractArtifactPaths as un, STOP_PROTOCOL_VERSION as ur, parseShellCommand as ut, bindingSatisfies as v, GoalActivationState as vn, semanticActionFromCommand as vr, extractToolSubject as vt, ManifestIssue as w, BoundaryDisposition as wn, normalizeClause as wr, BASE_HOST_PACKAGES as wt, isVerifyingCapability as x, effectuateBoundary as xn, validateActionTarget as xr, PROTOCOL_V3_NOTICE as xt, evidenceCoverage as y, GoalBoundaryAccess as yn, semanticActionFromText as yr, isDeterministicCheck as yt, GitCommandAccepted as z, GuardCheckpoint as zn, HostToolSurface as zt };
|