project-tiny-context-harness 0.8.12 → 0.8.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -19
- package/assets/README.md +81 -40
- package/assets/README.zh-CN.md +44 -22
- package/assets/agents/AGENTS_CORE.md +8 -4
- package/assets/skills/context_development_engineer/SKILL.md +9 -1
- package/assets/skills/design-resource-authoring/SKILL.md +7 -5
- package/assets/skills/design-resource-authoring/references/downstream-handoff.md +2 -2
- package/assets/skills/design-resource-authoring/references/open-design-provider.md +22 -2
- package/assets/skills/design-resource-authoring/references/recovery-and-writeback.md +199 -0
- package/assets/skills/design-resource-authoring/references/resource-selection.md +2 -2
- package/assets/skills/long-task-workflow/SKILL.md +6 -6
- package/assets/skills/long-task-workflow/references/contract-authoring.md +27 -22
- package/assets/skills/long-task-workflow/references/evidence-design.md +49 -32
- package/assets/skills/long-task-workflow/references/source-authoring.md +2 -2
- package/dist/commands/design-resource-recovery.d.ts +1 -0
- package/dist/commands/design-resource-recovery.js +152 -0
- package/dist/commands/design-resource.js +20 -1
- package/dist/commands/index.js +1 -1
- package/dist/lib/design-resource-reconciliation-codec.d.ts +2 -0
- package/dist/lib/design-resource-reconciliation-codec.js +174 -0
- package/dist/lib/design-resource-reconciliation-types.d.ts +62 -0
- package/dist/lib/design-resource-reconciliation-types.js +1 -0
- package/dist/lib/design-resource-reconciliation.d.ts +3 -0
- package/dist/lib/design-resource-reconciliation.js +224 -0
- package/dist/lib/design-resource-recovery-authority-policy.d.ts +8 -0
- package/dist/lib/design-resource-recovery-authority-policy.js +123 -0
- package/dist/lib/design-resource-recovery-catalog-resources.d.ts +6 -0
- package/dist/lib/design-resource-recovery-catalog-resources.js +121 -0
- package/dist/lib/design-resource-recovery-catalog-shape.d.ts +3 -0
- package/dist/lib/design-resource-recovery-catalog-shape.js +104 -0
- package/dist/lib/design-resource-recovery-catalog.d.ts +9 -0
- package/dist/lib/design-resource-recovery-catalog.js +103 -0
- package/dist/lib/design-resource-recovery-cleanup.d.ts +2 -0
- package/dist/lib/design-resource-recovery-cleanup.js +11 -0
- package/dist/lib/design-resource-recovery-codec-primitives.d.ts +19 -0
- package/dist/lib/design-resource-recovery-codec-primitives.js +92 -0
- package/dist/lib/design-resource-recovery-codec.d.ts +4 -0
- package/dist/lib/design-resource-recovery-codec.js +93 -0
- package/dist/lib/design-resource-recovery-current.d.ts +9 -0
- package/dist/lib/design-resource-recovery-current.js +41 -0
- package/dist/lib/design-resource-recovery-delta-policy.d.ts +5 -0
- package/dist/lib/design-resource-recovery-delta-policy.js +108 -0
- package/dist/lib/design-resource-recovery-files.d.ts +37 -0
- package/dist/lib/design-resource-recovery-files.js +204 -0
- package/dist/lib/design-resource-recovery-final-disposition-shape.d.ts +2 -0
- package/dist/lib/design-resource-recovery-final-disposition-shape.js +47 -0
- package/dist/lib/design-resource-recovery-patch-types.d.ts +54 -0
- package/dist/lib/design-resource-recovery-patch-types.js +1 -0
- package/dist/lib/design-resource-recovery-replay.d.ts +7 -0
- package/dist/lib/design-resource-recovery-replay.js +112 -0
- package/dist/lib/design-resource-recovery-repository-bindings.d.ts +9 -0
- package/dist/lib/design-resource-recovery-repository-bindings.js +49 -0
- package/dist/lib/design-resource-recovery-schema.d.ts +5 -0
- package/dist/lib/design-resource-recovery-schema.js +5 -0
- package/dist/lib/design-resource-recovery-shape.d.ts +10 -0
- package/dist/lib/design-resource-recovery-shape.js +184 -0
- package/dist/lib/design-resource-recovery-source-authority.d.ts +5 -0
- package/dist/lib/design-resource-recovery-source-authority.js +219 -0
- package/dist/lib/design-resource-recovery-text.d.ts +17 -0
- package/dist/lib/design-resource-recovery-text.js +186 -0
- package/dist/lib/design-resource-recovery-types.d.ts +197 -0
- package/dist/lib/design-resource-recovery-types.js +1 -0
- package/dist/lib/design-resource-recovery-writeback-policy.d.ts +5 -0
- package/dist/lib/design-resource-recovery-writeback-policy.js +326 -0
- package/dist/lib/design-resource-recovery-writeback-shape.d.ts +6 -0
- package/dist/lib/design-resource-recovery-writeback-shape.js +155 -0
- package/dist/lib/design-resource-recovery.d.ts +44 -0
- package/dist/lib/design-resource-recovery.js +216 -0
- package/dist/lib/long-task-acceptance-shape.js +8 -2
- package/dist/lib/long-task-activation-validation.js +13 -3
- package/dist/lib/long-task-admitted-observation-records.d.ts +25 -0
- package/dist/lib/long-task-admitted-observation-records.js +40 -0
- package/dist/lib/long-task-admitted-observation.d.ts +93 -0
- package/dist/lib/long-task-admitted-observation.js +201 -0
- package/dist/lib/long-task-artifacts.d.ts +1 -0
- package/dist/lib/long-task-artifacts.js +1 -0
- package/dist/lib/long-task-authority-material-diff.js +1 -0
- package/dist/lib/long-task-authority-policy.d.ts +2 -0
- package/dist/lib/long-task-authority-policy.js +2 -0
- package/dist/lib/long-task-authority-revision-details.js +3 -1
- package/dist/lib/long-task-authority.js +2 -1
- package/dist/lib/long-task-check-execution-policy.js +5 -0
- package/dist/lib/long-task-check-runner.d.ts +2 -2
- package/dist/lib/long-task-check-runner.js +440 -23
- package/dist/lib/long-task-claims.d.ts +18 -0
- package/dist/lib/long-task-claims.js +35 -0
- package/dist/lib/long-task-compact-structure-targets.js +1 -0
- package/dist/lib/long-task-conformance-policy.js +3 -1
- package/dist/lib/long-task-counterfactual-claim-policy.d.ts +3 -4
- package/dist/lib/long-task-counterfactual-claim-policy.js +11 -3
- package/dist/lib/long-task-counterfactual-sandbox.js +1 -0
- package/dist/lib/long-task-counterfactual-types.d.ts +2 -0
- package/dist/lib/long-task-delivery-compiler.js +2 -0
- package/dist/lib/long-task-evidence-capability-policy.d.ts +3 -2
- package/dist/lib/long-task-evidence-capability-policy.js +114 -8
- package/dist/lib/long-task-evidence-capability-runtime.d.ts +5 -2
- package/dist/lib/long-task-evidence-capability-runtime.js +149 -5
- package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +9 -0
- package/dist/lib/long-task-evidence-sensitivity-policy.js +31 -1
- package/dist/lib/long-task-evidence-v2.d.ts +4 -4
- package/dist/lib/long-task-evidence-v2.js +321 -43
- package/dist/lib/long-task-exact-comparison.d.ts +16 -0
- package/dist/lib/long-task-exact-comparison.js +28 -0
- package/dist/lib/long-task-execution-observation.d.ts +24 -0
- package/dist/lib/long-task-execution-observation.js +332 -0
- package/dist/lib/long-task-explain-acceptance-link.d.ts +4 -0
- package/dist/lib/long-task-explain-acceptance-link.js +4 -0
- package/dist/lib/long-task-explain-claim-links.d.ts +2 -0
- package/dist/lib/long-task-explain-claim-links.js +2 -0
- package/dist/lib/long-task-explain-source-links.d.ts +6 -0
- package/dist/lib/long-task-final-v2.js +7 -4
- package/dist/lib/long-task-json-pointer-observation.d.ts +59 -0
- package/dist/lib/long-task-json-pointer-observation.js +184 -0
- package/dist/lib/long-task-observation-artifact.d.ts +8 -0
- package/dist/lib/long-task-observation-artifact.js +58 -0
- package/dist/lib/long-task-observation-authority.d.ts +17 -0
- package/dist/lib/long-task-observation-authority.js +348 -0
- package/dist/lib/long-task-paths.js +1 -1
- package/dist/lib/long-task-process-observation.d.ts +6 -0
- package/dist/lib/long-task-process-observation.js +117 -0
- package/dist/lib/long-task-process-runtime-closure.d.ts +13 -0
- package/dist/lib/long-task-process-runtime-closure.js +175 -0
- package/dist/lib/long-task-progress.js +2 -0
- package/dist/lib/long-task-protected-files.d.ts +1 -1
- package/dist/lib/long-task-protected-files.js +1 -30
- package/dist/lib/long-task-risk.js +8 -3
- package/dist/lib/long-task-root-shape.js +10 -1
- package/dist/lib/long-task-runner-environment.d.ts +1 -1
- package/dist/lib/long-task-runner-environment.js +4 -4
- package/dist/lib/long-task-runner-freeze.d.ts +4 -2
- package/dist/lib/long-task-runner-freeze.js +128 -28
- package/dist/lib/long-task-runtime-types.d.ts +111 -0
- package/dist/lib/long-task-scoped-binding.d.ts +13 -0
- package/dist/lib/long-task-scoped-binding.js +11 -0
- package/dist/lib/long-task-semantic-contract-types.d.ts +1 -0
- package/dist/lib/long-task-semantic-fact-contract-closure.js +3 -3
- package/dist/lib/long-task-semantic-fact-evidence.d.ts +3 -3
- package/dist/lib/long-task-semantic-fact-evidence.js +75 -58
- package/dist/lib/long-task-source-claim-validation.js +4 -1
- package/dist/lib/long-task-source-target-continuity.d.ts +2 -2
- package/dist/lib/long-task-source-target-continuity.js +35 -2
- package/dist/lib/long-task-source-target-index.d.ts +3 -0
- package/dist/lib/long-task-source-target-index.js +19 -0
- package/dist/lib/long-task-stage-policy.js +10 -4
- package/dist/lib/long-task-static-observation-freeze.d.ts +83 -0
- package/dist/lib/long-task-static-observation-freeze.js +428 -0
- package/dist/lib/long-task-status-projection.js +5 -1
- package/dist/lib/long-task-target-policy.d.ts +1 -1
- package/dist/lib/long-task-target-policy.js +3 -0
- package/dist/lib/long-task-verifier-dependency-closure.js +7 -3
- package/dist/lib/long-task-verifier-v2.js +70 -9
- package/dist/lib/long-task-workspace.d.ts +1 -1
- package/dist/lib/long-task-workspace.js +1 -12
- package/dist/lib/repository-path-safety.d.ts +14 -0
- package/dist/lib/repository-path-safety.js +126 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +53 -8
- package/migrations/README.md +77 -0
- package/package.json +1 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { DESIGN_RESOURCE_AUTHORITY_PROJECTION_SCHEMA, DESIGN_RESOURCE_RECOVERY_INPUT_SCHEMA, DESIGN_RESOURCE_RECOVERY_SCHEMA } from "./design-resource-recovery-schema.js";
|
|
2
|
+
import type { DesignResourceRecoveryWriteback, DesignResourceWritebackInput } from "./design-resource-recovery-patch-types.js";
|
|
3
|
+
import type { SourceItemKind } from "./long-task-source-authority-types.js";
|
|
4
|
+
export type DesignResourceDecisionOrigin = "user-direct" | "necessary-derived" | "repository-evidence-backed" | "provider-suggested";
|
|
5
|
+
export type DesignResourceDecisionStatus = "accepted" | "rejected" | "unresolved";
|
|
6
|
+
export type DesignResourceDecisionAuthority = "explicit-user" | "none" | `delegated:${string}`;
|
|
7
|
+
export type DesignResourceSemanticKind = "exact-visual" | "product" | "business" | "permission" | "data" | "algorithm" | "commercial" | "safety-security" | "technical";
|
|
8
|
+
export type DesignResourceTextEncoding = "utf8" | "utf8-bom" | "utf16le" | "utf16be";
|
|
9
|
+
export type DesignResourceEolPolicy = "none" | "lf" | "crlf" | "cr" | "mixed";
|
|
10
|
+
export interface DesignResourceRecoveryBaseInput {
|
|
11
|
+
locator: string;
|
|
12
|
+
raw_byte_digest: string;
|
|
13
|
+
materialization: {
|
|
14
|
+
kind: "repository-source";
|
|
15
|
+
} | {
|
|
16
|
+
kind: "authorized-recovery-snapshot";
|
|
17
|
+
authorization_ref: string;
|
|
18
|
+
};
|
|
19
|
+
scope_ceiling: string;
|
|
20
|
+
in_scope_keys: string[];
|
|
21
|
+
explicitly_excluded_keys: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface DesignResourceRecoveryBase extends DesignResourceRecoveryBaseInput {
|
|
24
|
+
encoding: DesignResourceTextEncoding;
|
|
25
|
+
eol_policy: DesignResourceEolPolicy;
|
|
26
|
+
}
|
|
27
|
+
export interface DesignResourceDelegation {
|
|
28
|
+
key: string;
|
|
29
|
+
source_ref: string;
|
|
30
|
+
allowed_origins: DesignResourceDecisionOrigin[];
|
|
31
|
+
allowed_target_keys: string[];
|
|
32
|
+
allowed_semantic_kinds: DesignResourceSemanticKind[];
|
|
33
|
+
}
|
|
34
|
+
export type DesignResourceAuthorityProjection = {
|
|
35
|
+
schema_version: typeof DESIGN_RESOURCE_AUTHORITY_PROJECTION_SCHEMA;
|
|
36
|
+
mode: "explicit-user";
|
|
37
|
+
target_keys: string[];
|
|
38
|
+
semantic_kinds: DesignResourceSemanticKind[];
|
|
39
|
+
allowed_origins: DesignResourceDecisionOrigin[];
|
|
40
|
+
meaning_sha256: string;
|
|
41
|
+
} | {
|
|
42
|
+
schema_version: typeof DESIGN_RESOURCE_AUTHORITY_PROJECTION_SCHEMA;
|
|
43
|
+
mode: "delegation";
|
|
44
|
+
delegation_key: string;
|
|
45
|
+
allowed_target_keys: string[];
|
|
46
|
+
allowed_semantic_kinds: DesignResourceSemanticKind[];
|
|
47
|
+
allowed_origins: DesignResourceDecisionOrigin[];
|
|
48
|
+
};
|
|
49
|
+
export interface DesignResourceAuthoritySourceItem {
|
|
50
|
+
source_ref: string;
|
|
51
|
+
locator: string;
|
|
52
|
+
raw_byte_digest: string;
|
|
53
|
+
source_item_key: string;
|
|
54
|
+
source_item_kind: SourceItemKind;
|
|
55
|
+
source_item_text_sha256: string;
|
|
56
|
+
}
|
|
57
|
+
export interface DesignResourceDelta {
|
|
58
|
+
delta_id: string;
|
|
59
|
+
sequence: number;
|
|
60
|
+
supersedes: string[];
|
|
61
|
+
proposes_replacement_of: string[];
|
|
62
|
+
operation: "add" | "replace" | "remove" | "preserve";
|
|
63
|
+
semantic_kind: DesignResourceSemanticKind;
|
|
64
|
+
target_keys: string[];
|
|
65
|
+
before_semantics: unknown;
|
|
66
|
+
after_semantics: unknown;
|
|
67
|
+
origin: DesignResourceDecisionOrigin;
|
|
68
|
+
decision_authority: DesignResourceDecisionAuthority;
|
|
69
|
+
evidence_refs: string[];
|
|
70
|
+
source_refs: string[];
|
|
71
|
+
explicitly_unchanged_keys: string[];
|
|
72
|
+
status: DesignResourceDecisionStatus;
|
|
73
|
+
}
|
|
74
|
+
export type DesignResourceAuthorityIdentity = {
|
|
75
|
+
kind: "repository-file" | "external-immutable";
|
|
76
|
+
locator: string;
|
|
77
|
+
raw_byte_digest: string;
|
|
78
|
+
} | {
|
|
79
|
+
kind: "not-applicable";
|
|
80
|
+
rationale: string;
|
|
81
|
+
};
|
|
82
|
+
export interface DesignResourceProviderIdentity {
|
|
83
|
+
key: string;
|
|
84
|
+
locator: string;
|
|
85
|
+
immutable_identity: string;
|
|
86
|
+
}
|
|
87
|
+
export interface DesignResourceProviderResourceIdentity extends DesignResourceProviderIdentity {
|
|
88
|
+
raw_byte_digest: string;
|
|
89
|
+
}
|
|
90
|
+
export interface DesignResourceProviderReferences {
|
|
91
|
+
project: DesignResourceProviderIdentity;
|
|
92
|
+
run: DesignResourceProviderIdentity;
|
|
93
|
+
resources: DesignResourceProviderResourceIdentity[];
|
|
94
|
+
}
|
|
95
|
+
export interface DesignResourceSelectedResourceBinding {
|
|
96
|
+
key: string;
|
|
97
|
+
identity_kind: "repository-snapshot" | "external-immutable";
|
|
98
|
+
locator: string;
|
|
99
|
+
raw_byte_digest: string;
|
|
100
|
+
condition_refs: string[];
|
|
101
|
+
}
|
|
102
|
+
export type DesignResourceDownstreamOwner = {
|
|
103
|
+
kind: "selected-source-record";
|
|
104
|
+
locator: string;
|
|
105
|
+
raw_byte_digest: string;
|
|
106
|
+
resource_key: string;
|
|
107
|
+
} | {
|
|
108
|
+
kind: "external-immutable";
|
|
109
|
+
locator: string;
|
|
110
|
+
raw_byte_digest: string;
|
|
111
|
+
resource_key: string;
|
|
112
|
+
};
|
|
113
|
+
export type DesignResourceFinalDisposition = {
|
|
114
|
+
kind: "proposal-written";
|
|
115
|
+
operation_id: string;
|
|
116
|
+
} | {
|
|
117
|
+
kind: "resource-owned-exact-visual";
|
|
118
|
+
resource_ref: string;
|
|
119
|
+
condition_refs: string[];
|
|
120
|
+
downstream_owner: DesignResourceDownstreamOwner;
|
|
121
|
+
} | {
|
|
122
|
+
kind: "not-adopted";
|
|
123
|
+
} | {
|
|
124
|
+
kind: "unresolved";
|
|
125
|
+
};
|
|
126
|
+
export interface DesignResourceAuditExpectations {
|
|
127
|
+
changed: Array<{
|
|
128
|
+
key: string;
|
|
129
|
+
delta_ids: string[];
|
|
130
|
+
resource_refs: string[];
|
|
131
|
+
condition_refs: string[];
|
|
132
|
+
}>;
|
|
133
|
+
unchanged: Array<{
|
|
134
|
+
key: string;
|
|
135
|
+
resource_refs: string[];
|
|
136
|
+
condition_refs: string[];
|
|
137
|
+
basis_source_refs: string[];
|
|
138
|
+
}>;
|
|
139
|
+
resource_decisions: Array<{
|
|
140
|
+
key: string;
|
|
141
|
+
resource_ref: string;
|
|
142
|
+
semantic_kind: DesignResourceSemanticKind;
|
|
143
|
+
bindings: Array<{
|
|
144
|
+
binding_id: string;
|
|
145
|
+
delta_id: string;
|
|
146
|
+
target_key: string;
|
|
147
|
+
final_disposition: DesignResourceFinalDisposition;
|
|
148
|
+
}>;
|
|
149
|
+
condition_refs: string[];
|
|
150
|
+
}>;
|
|
151
|
+
blast_radius: Array<{
|
|
152
|
+
key: string;
|
|
153
|
+
}>;
|
|
154
|
+
inactive_delta_leakage: Array<{
|
|
155
|
+
delta_id: string;
|
|
156
|
+
reason: "rejected" | "unresolved" | "superseded";
|
|
157
|
+
}>;
|
|
158
|
+
}
|
|
159
|
+
export interface DesignResourceRecoveryCreateInput {
|
|
160
|
+
schema_version: typeof DESIGN_RESOURCE_RECOVERY_INPUT_SCHEMA;
|
|
161
|
+
session_id: string;
|
|
162
|
+
disclosure_review: {
|
|
163
|
+
reviewed: true;
|
|
164
|
+
contains_sensitive_raw_values: false;
|
|
165
|
+
};
|
|
166
|
+
base: DesignResourceRecoveryBaseInput;
|
|
167
|
+
authority_sources: DesignResourceAuthoritySourceItem[];
|
|
168
|
+
delegations: DesignResourceDelegation[];
|
|
169
|
+
deltas: DesignResourceDelta[];
|
|
170
|
+
decision_sets: {
|
|
171
|
+
accepted_delta_ids: string[];
|
|
172
|
+
rejected_delta_ids: string[];
|
|
173
|
+
unresolved_delta_ids: string[];
|
|
174
|
+
};
|
|
175
|
+
audit_expectations: DesignResourceAuditExpectations;
|
|
176
|
+
design_authority: DesignResourceAuthorityIdentity;
|
|
177
|
+
provider: DesignResourceProviderReferences;
|
|
178
|
+
selected_resource_bindings: DesignResourceSelectedResourceBinding[];
|
|
179
|
+
writeback?: DesignResourceWritebackInput;
|
|
180
|
+
}
|
|
181
|
+
export interface DesignResourceRecoveryCheckpoint extends Omit<DesignResourceRecoveryCreateInput, "schema_version" | "base" | "writeback"> {
|
|
182
|
+
schema_version: typeof DESIGN_RESOURCE_RECOVERY_SCHEMA;
|
|
183
|
+
owner: "ty-context-design-resource-recovery";
|
|
184
|
+
base: DesignResourceRecoveryBase;
|
|
185
|
+
writeback?: DesignResourceRecoveryWriteback;
|
|
186
|
+
}
|
|
187
|
+
export interface DesignResourceReplayProjection {
|
|
188
|
+
status: "replayable";
|
|
189
|
+
base: DesignResourceRecoveryBase;
|
|
190
|
+
ordered_active_accepted_deltas: DesignResourceDelta[];
|
|
191
|
+
rejected_deltas: DesignResourceDelta[];
|
|
192
|
+
unresolved_deltas: DesignResourceDelta[];
|
|
193
|
+
superseded_delta_ids: string[];
|
|
194
|
+
explicitly_unchanged_keys: string[];
|
|
195
|
+
design_authority: DesignResourceAuthorityIdentity;
|
|
196
|
+
external_revalidation_required: string[];
|
|
197
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DesignResourceDelta, DesignResourceRecoveryCheckpoint, DesignResourceRecoveryCreateInput } from "./design-resource-recovery-types.js";
|
|
2
|
+
type RecoveryState = DesignResourceRecoveryCreateInput | DesignResourceRecoveryCheckpoint;
|
|
3
|
+
export declare function validateRecoveryProviderAndWriteback(state: RecoveryState, activeAccepted: DesignResourceDelta[]): void;
|
|
4
|
+
export declare function renderDesignResourceProposalScalarCarrier(targetKey: string, semanticPath: string[], value: string | number | boolean | null, operationId?: string): string;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
|
|
2
|
+
export function validateRecoveryProviderAndWriteback(state, activeAccepted) {
|
|
3
|
+
const resourceKeys = uniqueValues(state.provider.resources.map((resource) => resource.key), "provider_resource_key_duplicate");
|
|
4
|
+
uniqueValues(state.provider.resources.map((resource) => resource.locator), "provider_resource_locator_duplicate");
|
|
5
|
+
const selectedKeys = uniqueValues(state.selected_resource_bindings.map((resource) => resource.key), "selected_resource_key_duplicate");
|
|
6
|
+
assertSubset(selectedKeys, resourceKeys, "selected_resource_not_declared");
|
|
7
|
+
const proposalBindings = frozenProposalBindings(state, activeAccepted);
|
|
8
|
+
if (!proposalBindings.size) {
|
|
9
|
+
if (state.writeback)
|
|
10
|
+
invalid("writeback_without_proposal_owner");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (!state.writeback)
|
|
14
|
+
invalid("proposal_owner_writeback_required");
|
|
15
|
+
const writeback = state.writeback;
|
|
16
|
+
if (writeback.target_locator === state.base.locator)
|
|
17
|
+
invalid("writeback_target_must_not_replace_immutable_base");
|
|
18
|
+
assertExactSet(writeback.proposal_written_delta_ids, [...new Set([...proposalBindings.values()].map((row) => row.deltaId))], "writeback_proposal_delta_set_mismatch");
|
|
19
|
+
validatePatch(writeback.patch.operations, activeAccepted, proposalBindings);
|
|
20
|
+
const patchIdentity = sha256Hex(canonicalValueJson(writeback.patch));
|
|
21
|
+
if (patchIdentity !== writeback.patch_identity)
|
|
22
|
+
invalid(`patch_identity_mismatch:${writeback.patch_identity}:${patchIdentity}`);
|
|
23
|
+
uniqueValues(writeback.resource_identities.map((resource) => resource.key), "writeback_resource_identity_duplicate");
|
|
24
|
+
const resources = new Map(state.provider.resources.map((resource) => [resource.key, resource]));
|
|
25
|
+
assertExactSet(writeback.resource_identities.map((row) => row.key), [...selectedKeys], "writeback_resource_set_mismatch");
|
|
26
|
+
for (const identity of writeback.resource_identities) {
|
|
27
|
+
const provider = resources.get(identity.key);
|
|
28
|
+
if (!provider || provider.raw_byte_digest !== identity.raw_byte_digest)
|
|
29
|
+
invalid(`writeback_resource_identity_mismatch:${identity.key}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function frozenProposalBindings(state, activeAccepted) {
|
|
33
|
+
const active = new Set(activeAccepted
|
|
34
|
+
.filter((delta) => delta.operation !== "preserve")
|
|
35
|
+
.flatMap((delta) => delta.target_keys.map((target) => deltaTarget(delta.delta_id, target))));
|
|
36
|
+
const result = new Map();
|
|
37
|
+
const operationIds = [];
|
|
38
|
+
for (const row of state.audit_expectations.resource_decisions)
|
|
39
|
+
for (const binding of row.bindings) {
|
|
40
|
+
if (binding.final_disposition.kind !== "proposal-written")
|
|
41
|
+
continue;
|
|
42
|
+
const identity = deltaTarget(binding.delta_id, binding.target_key);
|
|
43
|
+
if (!active.has(identity))
|
|
44
|
+
invalid(`proposal_owner_inactive:${binding.binding_id}`);
|
|
45
|
+
if (result.has(identity))
|
|
46
|
+
invalid(`proposal_owner_duplicate:${binding.binding_id}`);
|
|
47
|
+
const item = {
|
|
48
|
+
deltaId: binding.delta_id,
|
|
49
|
+
targetKey: binding.target_key,
|
|
50
|
+
operationId: binding.final_disposition.operation_id,
|
|
51
|
+
};
|
|
52
|
+
result.set(identity, item);
|
|
53
|
+
operationIds.push(item.operationId);
|
|
54
|
+
}
|
|
55
|
+
uniqueValues(operationIds, "proposal_owner_operation_duplicate");
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
function validatePatch(operations, activeAccepted, expectedBindings) {
|
|
59
|
+
uniqueValues(operations.map((operation) => operation.operation_id), "patch_operation_id_duplicate");
|
|
60
|
+
const activeById = new Map(activeAccepted.map((delta) => [delta.delta_id, delta]));
|
|
61
|
+
const bindingIdentities = [];
|
|
62
|
+
for (const operation of operations) {
|
|
63
|
+
if (operation.before_text === operation.after_text)
|
|
64
|
+
invalid(`patch_operation_no_change:${operation.operation_id}`);
|
|
65
|
+
assertDigest(operation.before_text_sha256, sha256Hex(operation.before_text), `patch_before_text_digest:${operation.operation_id}`);
|
|
66
|
+
assertDigest(operation.after_text_sha256, sha256Hex(operation.after_text), `patch_after_text_digest:${operation.operation_id}`);
|
|
67
|
+
validateSourceSpanMetadata(operation);
|
|
68
|
+
const operationBinding = validateSemanticBinding(operation, operation.semantic_binding, activeById);
|
|
69
|
+
const frozen = expectedBindings.get(operationBinding.identity);
|
|
70
|
+
if (!frozen)
|
|
71
|
+
invalid(`patch_binding_not_proposal_owned:${operation.operation_id}:${operationBinding.identity}`);
|
|
72
|
+
if (frozen.operationId !== operation.operation_id)
|
|
73
|
+
invalid(`patch_operation_owner_mismatch:${operation.operation_id}`);
|
|
74
|
+
bindingIdentities.push(operationBinding.identity);
|
|
75
|
+
}
|
|
76
|
+
validateSourceSpanLayout(operations);
|
|
77
|
+
uniqueValues(bindingIdentities, "patch_binding_duplicate_global");
|
|
78
|
+
assertExactSet(bindingIdentities, [...expectedBindings.keys()], "writeback_patch_binding_universe_mismatch");
|
|
79
|
+
}
|
|
80
|
+
function validateSourceSpanLayout(operations) {
|
|
81
|
+
const ordered = [...operations].sort((left, right) => left.source_span.start_offset - right.source_span.start_offset ||
|
|
82
|
+
left.source_span.end_offset - right.source_span.end_offset ||
|
|
83
|
+
left.operation_id.localeCompare(right.operation_id));
|
|
84
|
+
for (let index = 1; index < ordered.length; index += 1) {
|
|
85
|
+
const previous = ordered[index - 1];
|
|
86
|
+
const current = ordered[index];
|
|
87
|
+
if (current.source_span.start_offset < previous.source_span.end_offset)
|
|
88
|
+
invalid(`patch_source_span_overlap:${previous.operation_id}:${current.operation_id}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function validateSourceSpanMetadata(operation) {
|
|
92
|
+
const span = operation.source_span;
|
|
93
|
+
if (span.start_offset < 0 ||
|
|
94
|
+
span.end_offset <= span.start_offset ||
|
|
95
|
+
span.end_offset - span.start_offset !== operation.before_text.length)
|
|
96
|
+
invalid(`patch_source_span_range:${operation.operation_id}`);
|
|
97
|
+
if (span.before_text_sha256 !== operation.before_text_sha256)
|
|
98
|
+
invalid(`patch_source_span_digest:${operation.operation_id}`);
|
|
99
|
+
}
|
|
100
|
+
function validateSemanticBinding(operation, binding, activeById) {
|
|
101
|
+
const operationId = operation.operation_id;
|
|
102
|
+
const delta = activeById.get(binding.delta_id);
|
|
103
|
+
if (!delta)
|
|
104
|
+
invalid(`patch_binding_inactive_or_unknown:${operationId}:${binding.delta_id}`);
|
|
105
|
+
if (delta.operation === "preserve")
|
|
106
|
+
invalid(`patch_binding_preserve_delta:${operationId}:${binding.delta_id}`);
|
|
107
|
+
if (operation.delta_id !== binding.delta_id ||
|
|
108
|
+
operation.target_key !== binding.target_key)
|
|
109
|
+
invalid(`patch_operation_binding_identity:${operationId}`);
|
|
110
|
+
if (!delta.target_keys.includes(binding.target_key))
|
|
111
|
+
invalid(`patch_binding_target_mismatch:${operationId}:${binding.delta_id}:${binding.target_key}`);
|
|
112
|
+
if (operation.operation !== delta.operation)
|
|
113
|
+
invalid(`patch_operation_semantic_operation:${operationId}`);
|
|
114
|
+
assertDigest(binding.before_semantics_sha256, sha256Hex(canonicalValueJson(delta.before_semantics)), `patch_before_semantics:${operationId}:${binding.delta_id}:${binding.target_key}`);
|
|
115
|
+
assertDigest(binding.after_semantics_sha256, sha256Hex(canonicalValueJson(delta.after_semantics)), `patch_after_semantics:${operationId}:${binding.delta_id}:${binding.target_key}`);
|
|
116
|
+
validateOperationProjection(operation, delta, binding);
|
|
117
|
+
return { identity: deltaTarget(binding.delta_id, binding.target_key) };
|
|
118
|
+
}
|
|
119
|
+
function validateOperationProjection(operation, delta, binding) {
|
|
120
|
+
const operationId = operation.operation_id;
|
|
121
|
+
if (operation.operation === "add") {
|
|
122
|
+
if (delta.before_semantics !== null ||
|
|
123
|
+
delta.after_semantics === null ||
|
|
124
|
+
binding.before_text_projection !== null ||
|
|
125
|
+
!operation.after_text.length)
|
|
126
|
+
invalid(`patch_add_shape:${operationId}`);
|
|
127
|
+
validateCanonicalCarrierAdd(operation, delta, binding);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (operation.operation === "remove") {
|
|
131
|
+
if (delta.before_semantics === null ||
|
|
132
|
+
delta.after_semantics !== null ||
|
|
133
|
+
binding.after_text_projection !== null ||
|
|
134
|
+
operation.after_text !== "")
|
|
135
|
+
invalid(`patch_remove_shape:${operationId}`);
|
|
136
|
+
validateCanonicalCarrierRemove(operation, delta, binding);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (delta.before_semantics === null ||
|
|
140
|
+
delta.after_semantics === null ||
|
|
141
|
+
!operation.after_text.length)
|
|
142
|
+
invalid(`patch_replace_shape:${operationId}`);
|
|
143
|
+
validateTextProjection(operationId, "before", operation.before_text, delta.before_semantics, binding.before_text_projection);
|
|
144
|
+
validateTextProjection(operationId, "after", operation.after_text, delta.after_semantics, binding.after_text_projection);
|
|
145
|
+
const beforeProjection = binding.before_text_projection;
|
|
146
|
+
const afterProjection = binding.after_text_projection;
|
|
147
|
+
if (!beforeProjection || !afterProjection)
|
|
148
|
+
invalid(`patch_replace_projection_required:${operationId}`);
|
|
149
|
+
if (operation.before_text.slice(0, beforeProjection.start_offset) !==
|
|
150
|
+
operation.after_text.slice(0, afterProjection.start_offset))
|
|
151
|
+
invalid(`patch_replace_scaffold_prefix:${operationId}`);
|
|
152
|
+
if (operation.before_text.slice(beforeProjection.end_offset) !==
|
|
153
|
+
operation.after_text.slice(afterProjection.end_offset))
|
|
154
|
+
invalid(`patch_replace_scaffold_suffix:${operationId}`);
|
|
155
|
+
}
|
|
156
|
+
function validateCanonicalCarrierAdd(operation, delta, binding) {
|
|
157
|
+
const operationId = operation.operation_id;
|
|
158
|
+
const leaf = uniqueScalarLeaf(delta.after_semantics, operationId, "after");
|
|
159
|
+
const carrier = renderDesignResourceProposalScalarCarrier(operation.target_key, leaf.path, leaf.value, operationId);
|
|
160
|
+
if (countLiteral(operation.before_text, carrier) !== 0 ||
|
|
161
|
+
countLiteral(operation.after_text, carrier) !== 1)
|
|
162
|
+
invalid(`patch_add_carrier_count:${operationId}`);
|
|
163
|
+
const carrierLine = carrierLineFragment(operation.after_text, carrier);
|
|
164
|
+
const anchorFirst = operation.after_text === operation.before_text + carrierLine;
|
|
165
|
+
const anchorLast = operation.after_text === carrierLine + operation.before_text;
|
|
166
|
+
if (!anchorFirst && !anchorLast)
|
|
167
|
+
invalid(`patch_add_anchor_or_carrier:${operationId}`);
|
|
168
|
+
if (anchorFirst && !/(?:\r\n|\n|\r)$/u.test(operation.before_text))
|
|
169
|
+
invalid(`patch_add_carrier_line_boundary:${operationId}`);
|
|
170
|
+
validateCarrierProjection(operationId, "after", operation.after_text, leaf, binding.after_text_projection, anchorFirst ? operation.before_text.length : 0, carrier);
|
|
171
|
+
}
|
|
172
|
+
function countLiteral(text, value) {
|
|
173
|
+
let count = 0;
|
|
174
|
+
let offset = 0;
|
|
175
|
+
while (true) {
|
|
176
|
+
const found = text.indexOf(value, offset);
|
|
177
|
+
if (found < 0)
|
|
178
|
+
return count;
|
|
179
|
+
count += 1;
|
|
180
|
+
offset = found + value.length;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function validateCanonicalCarrierRemove(operation, delta, binding) {
|
|
184
|
+
const operationId = operation.operation_id;
|
|
185
|
+
const leaf = uniqueScalarLeaf(delta.before_semantics, operationId, "before");
|
|
186
|
+
const carrier = renderDesignResourceProposalScalarCarrier(operation.target_key, leaf.path, leaf.value, operationId);
|
|
187
|
+
if (operation.before_text !==
|
|
188
|
+
carrierLineFragment(operation.before_text, carrier))
|
|
189
|
+
invalid(`patch_remove_carrier:${operationId}`);
|
|
190
|
+
validateCarrierProjection(operationId, "before", operation.before_text, leaf, binding.before_text_projection, 0, carrier);
|
|
191
|
+
}
|
|
192
|
+
function carrierLineFragment(text, carrier) {
|
|
193
|
+
for (const eol of ["\r\n", "\n", "\r"])
|
|
194
|
+
if (text.includes(`${carrier}${eol}`))
|
|
195
|
+
return `${carrier}${eol}`;
|
|
196
|
+
return "";
|
|
197
|
+
}
|
|
198
|
+
function validateCarrierProjection(operationId, side, text, leaf, projection, carrierOffset, carrier) {
|
|
199
|
+
if (!projection)
|
|
200
|
+
invalid(`patch_${side}_semantic_projection_required:${operationId}`);
|
|
201
|
+
if (!samePath(projection.semantic_path, leaf.path))
|
|
202
|
+
invalid(`patch_${side}_semantic_path:${operationId}`);
|
|
203
|
+
const scalar = canonicalCarrierScalar(leaf.value, operationId, side);
|
|
204
|
+
const marker = `\"value\":${scalar}`;
|
|
205
|
+
const relative = carrier.indexOf(marker);
|
|
206
|
+
if (relative < 0)
|
|
207
|
+
invalid(`patch_${side}_carrier_scalar:${operationId}`);
|
|
208
|
+
const expectedStart = carrierOffset + relative + `\"value\":`.length;
|
|
209
|
+
const expectedEnd = expectedStart + scalar.length;
|
|
210
|
+
if (projection.start_offset !== expectedStart ||
|
|
211
|
+
projection.end_offset !== expectedEnd ||
|
|
212
|
+
text.slice(expectedStart, expectedEnd) !== scalar)
|
|
213
|
+
invalid(`patch_${side}_carrier_projection:${operationId}`);
|
|
214
|
+
}
|
|
215
|
+
function validateTextProjection(operationId, side, text, semantics, projection) {
|
|
216
|
+
if (!projection)
|
|
217
|
+
invalid(`patch_${side}_semantic_projection_required:${operationId}`);
|
|
218
|
+
const leaf = uniqueScalarLeaf(semantics, operationId, side);
|
|
219
|
+
if (!samePath(projection.semantic_path, leaf.path))
|
|
220
|
+
invalid(`patch_${side}_semantic_path:${operationId}`);
|
|
221
|
+
if (projection.start_offset < 0 ||
|
|
222
|
+
projection.end_offset <= projection.start_offset ||
|
|
223
|
+
projection.end_offset > text.length)
|
|
224
|
+
invalid(`patch_${side}_projection_range:${operationId}`);
|
|
225
|
+
const actual = text.slice(projection.start_offset, projection.end_offset);
|
|
226
|
+
if (actual !== renderSemanticScalar(leaf.value, operationId, side))
|
|
227
|
+
invalid(`patch_${side}_semantic_text_mismatch:${operationId}`);
|
|
228
|
+
}
|
|
229
|
+
function uniqueScalarLeaf(semantics, operationId, side) {
|
|
230
|
+
const leaves = [];
|
|
231
|
+
collectScalarLeaves(semantics, [], leaves, operationId, side);
|
|
232
|
+
if (leaves.length !== 1)
|
|
233
|
+
invalid(`patch_${side}_semantic_leaf_count:${operationId}:${leaves.length}`);
|
|
234
|
+
return leaves[0];
|
|
235
|
+
}
|
|
236
|
+
function collectScalarLeaves(value, path, leaves, operationId, side) {
|
|
237
|
+
if (value === null ||
|
|
238
|
+
typeof value === "string" ||
|
|
239
|
+
typeof value === "boolean" ||
|
|
240
|
+
(typeof value === "number" && Number.isFinite(value))) {
|
|
241
|
+
leaves.push({ path, value });
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (typeof value !== "object" || Array.isArray(value))
|
|
245
|
+
invalid(`patch_${side}_semantic_scalar_tree:${operationId}`);
|
|
246
|
+
for (const key of Object.keys(value).sort())
|
|
247
|
+
collectScalarLeaves(value[key], [...path, key], leaves, operationId, side);
|
|
248
|
+
}
|
|
249
|
+
function samePath(left, right) {
|
|
250
|
+
return (left.length === right.length &&
|
|
251
|
+
left.every((value, index) => value === right[index]));
|
|
252
|
+
}
|
|
253
|
+
function renderSemanticScalar(value, operationId, side) {
|
|
254
|
+
if (typeof value === "string") {
|
|
255
|
+
assertSafeStringScalar(value, operationId, side);
|
|
256
|
+
return value;
|
|
257
|
+
}
|
|
258
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
259
|
+
return String(value);
|
|
260
|
+
if (typeof value === "boolean")
|
|
261
|
+
return String(value);
|
|
262
|
+
if (value === null)
|
|
263
|
+
return "null";
|
|
264
|
+
invalid(`patch_${side}_semantic_scalar_required:${operationId}`);
|
|
265
|
+
}
|
|
266
|
+
export function renderDesignResourceProposalScalarCarrier(targetKey, semanticPath, value, operationId = "carrier") {
|
|
267
|
+
assertSafeCarrierCommentComponent(targetKey, operationId, "target_key");
|
|
268
|
+
for (const segment of semanticPath)
|
|
269
|
+
assertSafeCarrierCommentComponent(segment, operationId, "semantic_path");
|
|
270
|
+
if (typeof value === "string") {
|
|
271
|
+
assertSafeStringScalar(value, operationId, "carrier");
|
|
272
|
+
assertSafeCarrierCommentComponent(value, operationId, "value");
|
|
273
|
+
}
|
|
274
|
+
if (!targetKey.length ||
|
|
275
|
+
semanticPath.some((segment) => !segment.length) ||
|
|
276
|
+
(typeof value === "number" && !Number.isFinite(value)))
|
|
277
|
+
invalid(`patch_carrier_value:${operationId}`);
|
|
278
|
+
return `<!-- ty-dra-proposal-scalar-v1 ${canonicalValueJson({
|
|
279
|
+
semantic_path: semanticPath,
|
|
280
|
+
target_key: targetKey,
|
|
281
|
+
value,
|
|
282
|
+
})} -->`;
|
|
283
|
+
}
|
|
284
|
+
function assertSafeCarrierCommentComponent(value, operationId, field) {
|
|
285
|
+
if (/--/u.test(value))
|
|
286
|
+
invalid(`patch_carrier_comment_escape:${operationId}:${field}`);
|
|
287
|
+
}
|
|
288
|
+
function canonicalCarrierScalar(value, operationId, side) {
|
|
289
|
+
if (typeof value === "string")
|
|
290
|
+
assertSafeStringScalar(value, operationId, side);
|
|
291
|
+
return canonicalValueJson(value);
|
|
292
|
+
}
|
|
293
|
+
function assertSafeStringScalar(value, operationId, side) {
|
|
294
|
+
if (!value.length || /[\p{Cc}\p{Cs}]/u.test(value))
|
|
295
|
+
invalid(`patch_${side}_semantic_scalar_control:${operationId}`);
|
|
296
|
+
}
|
|
297
|
+
function deltaTarget(deltaId, target) {
|
|
298
|
+
return `${deltaId}\u0000${target}`;
|
|
299
|
+
}
|
|
300
|
+
function assertDigest(actual, expected, code) {
|
|
301
|
+
if (actual !== expected)
|
|
302
|
+
invalid(`${code}:${actual}:${expected}`);
|
|
303
|
+
}
|
|
304
|
+
function uniqueValues(values, code) {
|
|
305
|
+
const result = new Set(values);
|
|
306
|
+
if (result.size !== values.length)
|
|
307
|
+
invalid(code);
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
function assertSubset(candidate, owner, code) {
|
|
311
|
+
const outside = [...candidate].filter((value) => !owner.has(value));
|
|
312
|
+
if (outside.length)
|
|
313
|
+
invalid(`${code}:${outside.sort().join(",")}`);
|
|
314
|
+
}
|
|
315
|
+
function assertExactSet(actual, expected, code) {
|
|
316
|
+
uniqueValues(actual, `${code}:actual_duplicate`);
|
|
317
|
+
uniqueValues(expected, `${code}:expected_duplicate`);
|
|
318
|
+
const left = [...actual].sort();
|
|
319
|
+
const right = [...expected].sort();
|
|
320
|
+
if (left.length !== right.length ||
|
|
321
|
+
left.some((value, index) => value !== right[index]))
|
|
322
|
+
invalid(code);
|
|
323
|
+
}
|
|
324
|
+
function invalid(code) {
|
|
325
|
+
throw new Error(`design_resource_recovery_invalid:${code}`);
|
|
326
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type DesignResourceExactPatch, type DesignResourceRecoveryWriteback, type DesignResourceWritebackInput } from "./design-resource-recovery-patch-types.js";
|
|
2
|
+
import { type DesignResourceProviderReferences } from "./design-resource-recovery-types.js";
|
|
3
|
+
export declare function parseProviderReferences(value: unknown, label: string): DesignResourceProviderReferences;
|
|
4
|
+
export declare function parsePatch(value: unknown, label: string): DesignResourceExactPatch;
|
|
5
|
+
export declare function parseWritebackInput(value: unknown, label: string, complete: false): DesignResourceWritebackInput;
|
|
6
|
+
export declare function parseWritebackInput(value: unknown, label: string, complete: true): DesignResourceRecoveryWriteback;
|