@gate-forge/core 0.9.0 → 0.10.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.
@@ -72,6 +72,39 @@ export declare const LifecycleRulesSchema: z.ZodArray<z.ZodObject<{
72
72
  }, z.core.$strict>>;
73
73
  /** Deterministic rule ordering for authority minting and explanations. */
74
74
  export declare function sortLifecycleRules(rules: readonly LifecycleRule[]): LifecycleRule[];
75
+ /**
76
+ * How removal manifests for the resources an owner rule matches. Only
77
+ * these two exist: the engine never invents a third, and never picks
78
+ * between them on its own.
79
+ */
80
+ export declare const DeleteSemanticsSchema: z.ZodEnum<{
81
+ hard: "hard";
82
+ archive: "archive";
83
+ }>;
84
+ /** Inferred delete-semantics union. */
85
+ export type DeleteSemantics = z.infer<typeof DeleteSemanticsSchema>;
86
+ /** One owner-declared delete-semantics rule over a source glob. */
87
+ export declare const DeleteRuleSchema: z.ZodObject<{
88
+ match: z.ZodString;
89
+ semantics: z.ZodEnum<{
90
+ hard: "hard";
91
+ archive: "archive";
92
+ }>;
93
+ archiveFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
94
+ reason: z.ZodString;
95
+ }, z.core.$strict>;
96
+ /** Inferred delete-rule shape. */
97
+ export type DeleteRule = z.infer<typeof DeleteRuleSchema>;
98
+ /** Delete rules with duplicate match patterns rejected as ambiguous. */
99
+ export declare const DeleteRulesSchema: z.ZodArray<z.ZodObject<{
100
+ match: z.ZodString;
101
+ semantics: z.ZodEnum<{
102
+ hard: "hard";
103
+ archive: "archive";
104
+ }>;
105
+ archiveFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
106
+ reason: z.ZodString;
107
+ }, z.core.$strict>>;
75
108
  /**
76
109
  * One coverage requirement (red-team round 3): the named detector must
77
110
  * report examining every applicable file for a scan to count as COMPLETE.
@@ -122,6 +155,15 @@ export declare const ClassificationPolicySchema: z.ZodObject<{
122
155
  }>>;
123
156
  reason: z.ZodString;
124
157
  }, z.core.$strict>>>;
158
+ deleteRules: z.ZodOptional<z.ZodArray<z.ZodObject<{
159
+ match: z.ZodString;
160
+ semantics: z.ZodEnum<{
161
+ hard: "hard";
162
+ archive: "archive";
163
+ }>;
164
+ archiveFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
165
+ reason: z.ZodString;
166
+ }, z.core.$strict>>>;
125
167
  coverage: z.ZodOptional<z.ZodArray<z.ZodObject<{
126
168
  capability: z.ZodString;
127
169
  detector: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"classification-policy.d.ts","sourceRoot":"","sources":["../../src/schemas/classification-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,wEAAwE;AACxE,eAAO,MAAM,gCAAgC;;;;kBAmBlC,CAAC;AAEZ,oDAAoD;AACpD,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,oEAAoE;AACpE,eAAO,MAAM,uBAAuB;;;kBAUhC,CAAC;AAEL,0CAA0C;AAC1C,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,qFAAqF;AACrF,eAAO,MAAM,kBAAkB;;;;;;kBAOpB,CAAC;AAEZ,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,iDAAkD,CAAC;AAEpF,gDAAgD;AAChD,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAiBvE,wDAAwD;AACxD,eAAO,MAAM,wBAAwB;;kBAK1B,CAAC;AAEZ,2CAA2C;AAC3C,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,kFAAkF;AAClF,eAAO,MAAM,mBAAmB;;;;;;;;;;;kBAkCrB,CAAC;AAEZ,qCAAqC;AACrC,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB;;;;;;;;;;;mBAoB7B,CAAC;AAEL,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,EAAE,CAQnF;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB;;;;;kBAyBpB,CAAC;AAEZ,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqC5B,CAAC;AAEZ,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"classification-policy.d.ts","sourceRoot":"","sources":["../../src/schemas/classification-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,wEAAwE;AACxE,eAAO,MAAM,gCAAgC;;;;kBAmBlC,CAAC;AAEZ,oDAAoD;AACpD,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,oEAAoE;AACpE,eAAO,MAAM,uBAAuB;;;kBAUhC,CAAC;AAEL,0CAA0C;AAC1C,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,qFAAqF;AACrF,eAAO,MAAM,kBAAkB;;;;;;kBAOpB,CAAC;AAEZ,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,iDAAkD,CAAC;AAEpF,gDAAgD;AAChD,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAiBvE,wDAAwD;AACxD,eAAO,MAAM,wBAAwB;;kBAK1B,CAAC;AAEZ,2CAA2C;AAC3C,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,kFAAkF;AAClF,eAAO,MAAM,mBAAmB;;;;;;;;;;;kBAkCrB,CAAC;AAEZ,qCAAqC;AACrC,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB;;;;;;;;;;;mBAoB7B,CAAC;AAEL,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,EAAE,CAQnF;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;EAA8B,CAAC;AAEjE,uCAAuC;AACvC,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AA6BpE,mEAAmE;AACnE,eAAO,MAAM,gBAAgB;;;;;;;;kBA4CzB,CAAC;AAEL,kCAAkC;AAClC,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,wEAAwE;AACxE,eAAO,MAAM,iBAAiB;;;;;;;;mBAoB1B,CAAC;AAEL;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB;;;;;kBAyBpB,CAAC;AAEZ,oCAAoC;AACpC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4C5B,CAAC;AAEZ,4CAA4C;AAC5C,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -141,6 +141,104 @@ export function sortLifecycleRules(rules) {
141
141
  }))
142
142
  .sort((a, b) => compareStrings(a.match.resourceId, b.match.resourceId));
143
143
  }
144
+ /**
145
+ * How removal manifests for the resources an owner rule matches. Only
146
+ * these two exist: the engine never invents a third, and never picks
147
+ * between them on its own.
148
+ */
149
+ export const DeleteSemanticsSchema = z.enum(['hard', 'archive']);
150
+ /**
151
+ * A repo-root-relative glob over the SOURCE FILE of the resources the
152
+ * rule declares semantics for. A glob (not one exact id) is safe here
153
+ * because declaring semantics is an evidence CONTRACT, never a
154
+ * suppression: it can only resolve DELETE_SEMANTICS_UNRESOLVED, never
155
+ * remove an obligation on its own (contradicting detector evidence still
156
+ * blocks).
157
+ */
158
+ const DeleteRuleMatchSchema = z
159
+ .string()
160
+ .min(1, 'match must not be empty')
161
+ .refine((value) => value === value.trim(), {
162
+ message: 'match must not have leading or trailing whitespace',
163
+ })
164
+ .refine((value) => !value.includes('\\'), {
165
+ message: 'match must use posix "/" separators',
166
+ })
167
+ .refine((value) => !value.startsWith('/'), {
168
+ message: 'match must be repo-relative, never absolute',
169
+ })
170
+ .refine((value) => !value.split('/').includes('..'), {
171
+ message: 'match must not escape the repository',
172
+ });
173
+ /** The owner-owned archived field values an archive rule declares. */
174
+ const ArchiveFieldsSchema = z.record(z.string().min(1), z.union([z.string(), z.number(), z.boolean()]));
175
+ /** One owner-declared delete-semantics rule over a source glob. */
176
+ export const DeleteRuleSchema = z
177
+ .object({
178
+ /** Repo-root-relative glob over the matched resources' source file. */
179
+ match: DeleteRuleMatchSchema,
180
+ /** How removal manifests for every resource this rule matches. */
181
+ semantics: DeleteSemanticsSchema,
182
+ /**
183
+ * Required, and never empty, when `semantics` is `archive`: the
184
+ * owner-owned archived state (e.g. `{status: archived}`) the engine
185
+ * grades removal against. `hard` removal has no archived state and
186
+ * must not carry the key.
187
+ */
188
+ archiveFields: ArchiveFieldsSchema.optional(),
189
+ /** Owner explanation rendered in classifier traces and diagnostics. */
190
+ reason: z
191
+ .string()
192
+ .min(1, 'reason must not be empty')
193
+ .refine((value) => value === value.trim(), {
194
+ message: 'reason must not have leading or trailing whitespace',
195
+ })
196
+ .refine((value) => !/[\u0000-\u001f\u007f]/.test(value), {
197
+ message: 'reason must not contain control characters',
198
+ }),
199
+ })
200
+ .strict()
201
+ .superRefine((rule, ctx) => {
202
+ if (rule.semantics === 'archive' && Object.keys(rule.archiveFields ?? {}).length === 0) {
203
+ ctx.addIssue({
204
+ code: 'custom',
205
+ path: ['archiveFields'],
206
+ message: "delete rule semantics is 'archive': 'archiveFields' must declare the owner-owned " +
207
+ 'archived state (e.g. {status: archived}); removal is never guessed',
208
+ });
209
+ }
210
+ if (rule.semantics === 'hard' && rule.archiveFields !== undefined) {
211
+ ctx.addIssue({
212
+ code: 'custom',
213
+ path: ['archiveFields'],
214
+ message: "delete rule semantics is 'hard': a permanent removal has no archived state, so " +
215
+ "'archiveFields' must be absent",
216
+ });
217
+ }
218
+ });
219
+ /** Delete rules with duplicate match patterns rejected as ambiguous. */
220
+ export const DeleteRulesSchema = z
221
+ .array(DeleteRuleSchema)
222
+ .superRefine((rules, ctx) => {
223
+ const seen = new Map();
224
+ for (let index = 0; index < rules.length; index += 1) {
225
+ const match = rules[index]?.match;
226
+ if (match === undefined)
227
+ continue;
228
+ const first = seen.get(match);
229
+ if (first !== undefined) {
230
+ ctx.addIssue({
231
+ code: 'custom',
232
+ path: [index, 'match'],
233
+ message: `duplicate delete rule for '${match}' (already declared at index ${first}); ` +
234
+ 'one source pattern must have one unambiguous semantics',
235
+ });
236
+ }
237
+ else {
238
+ seen.set(match, index);
239
+ }
240
+ }
241
+ });
144
242
  /**
145
243
  * One coverage requirement (red-team round 3): the named detector must
146
244
  * report examining every applicable file for a scan to count as COMPLETE.
@@ -198,6 +296,13 @@ export const ClassificationPolicySchema = z
198
296
  internalRules: z.array(InternalRuleSchema),
199
297
  /** Exact owner lifecycle disables; suppressive effects require scan proof. */
200
298
  lifecycleRules: LifecycleRulesSchema.optional(),
299
+ /**
300
+ * Owner-declared delete semantics (hard|archive) per source glob.
301
+ * Declaring semantics ADDS an evidence contract — it can resolve
302
+ * DELETE_SEMANTICS_UNRESOLVED, never remove an obligation: detector
303
+ * evidence that disagrees still blocks as a contradiction.
304
+ */
305
+ deleteRules: DeleteRulesSchema.optional(),
201
306
  /**
202
307
  * Coverage requirements for COMPLETE-scan proofs (ADR 0003 D4). A
203
308
  * closed-world attestation holds only when every rule's detector is
@@ -1 +1 @@
1
- {"version":3,"file":"classification-policy.js","sourceRoot":"","sources":["../../src/schemas/classification-policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classification-policy.js","sourceRoot":"","sources":["../../src/schemas/classification-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,wEAAwE;AACxE,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC;KAC9C,MAAM,CAAC;IACN,0DAA0D;IAC1D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B;;;OAGG;IACH,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC/C;;;;;;;OAOG;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ,oEAAoE;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC;KACrC,MAAM,CAAC;IACN,yFAAyF;IACzF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC1C,yEAAyE;IACzE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC3C,CAAC;KACD,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE;IACvF,OAAO,EAAE,yEAAyE;CACnF,CAAC,CAAC;AAKL,qFAAqF;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN,6BAA6B;IAC7B,KAAK,EAAE,uBAAuB;IAC9B,qFAAqF;IACrF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1B,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ,6EAA6E;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAKpF,8EAA8E;AAC9E,MAAM,qBAAqB,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,8BAA8B,CAAC;KACtC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE;IACzC,OAAO,EAAE,yDAAyD;CACnE,CAAC;KACD,KAAK,CACJ,yCAAyC,EACzC,mGAAmG,CACpG;KACA,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;IAC5C,OAAO,EAAE,4DAA4D;CACtE,CAAC,CAAC;AAEL,wDAAwD;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC;KACtC,MAAM,CAAC;IACN,yEAAyE;IACzE,UAAU,EAAE,qBAAqB;CAClC,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ,kFAAkF;AAClF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KACjC,MAAM,CAAC;IACN,oDAAoD;IACpD,KAAK,EAAE,wBAAwB;IAC/B,6EAA6E;IAC7E,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;SACnC,GAAG,CAAC,CAAC,EAAE,oDAAoD,CAAC;SAC5D,WAAW,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YAC1D,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,SAAS,KAAK,SAAS;gBAAE,SAAS;YACtC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxB,GAAG,CAAC,QAAQ,CAAC;oBACX,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,KAAK,CAAC;oBACb,OAAO,EAAE,2CAA2C,SAAS,GAAG;iBACjE,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;IACJ,uEAAuE;IACvE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,0BAA0B,CAAC;SAClC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE;QACzC,OAAO,EAAE,qDAAqD;KAC/D,CAAC;SACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACvD,OAAO,EAAE,4CAA4C;KACtD,CAAC;CACL,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ,6EAA6E;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC;KAClC,KAAK,CAAC,mBAAmB,CAAC;KAC1B,WAAW,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC;QAClD,IAAI,UAAU,KAAK,SAAS;YAAE,SAAS;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,QAAQ,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC;gBACpC,OAAO,EACL,iCAAiC,UAAU,gCAAgC,KAAK,KAAK;oBACrF,mDAAmD;aACtD,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAAC,KAA+B;IAChE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAiB,oBAAoB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1G,OAAO,CAAC,GAAG,KAAK,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,GAAG,IAAI;QACP,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;KACrF,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAKjE;;;;;;;GAOG;AACH,MAAM,qBAAqB,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,yBAAyB,CAAC;KACjC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE;IACzC,OAAO,EAAE,oDAAoD;CAC9D,CAAC;KACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;IACxC,OAAO,EAAE,qCAAqC;CAC/C,CAAC;KACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;IACzC,OAAO,EAAE,6CAA6C;CACvD,CAAC;KACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;IACnD,OAAO,EAAE,sCAAsC;CAChD,CAAC,CAAC;AAEL,sEAAsE;AACtE,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;AAExG,mEAAmE;AACnE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN,uEAAuE;IACvE,KAAK,EAAE,qBAAqB;IAC5B,kEAAkE;IAClE,SAAS,EAAE,qBAAqB;IAChC;;;;;OAKG;IACH,aAAa,EAAE,mBAAmB,CAAC,QAAQ,EAAE;IAC7C,uEAAuE;IACvE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,0BAA0B,CAAC;SAClC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE;QACzC,OAAO,EAAE,qDAAqD;KAC/D,CAAC;SACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;QACvD,OAAO,EAAE,4CAA4C;KACtD,CAAC;CACL,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IACzB,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvF,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,eAAe,CAAC;YACvB,OAAO,EACL,mFAAmF;gBACnF,oEAAoE;SACvE,CAAC,CAAC;IACL,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QAClE,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,eAAe,CAAC;YACvB,OAAO,EACL,iFAAiF;gBACjF,gCAAgC;SACnC,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAKL,wEAAwE;AACxE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC;KAC/B,KAAK,CAAC,gBAAgB,CAAC;KACvB,WAAW,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,QAAQ,CAAC;gBACX,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;gBACtB,OAAO,EACL,8BAA8B,KAAK,gCAAgC,KAAK,KAAK;oBAC7E,wDAAwD;aAC3D,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEL;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,MAAM,CAAC;IACN;;;;;;;OAOG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,sEAAsE;IACtE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C;;;;;;;OAOG;IACH,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC;KACD,MAAM,EAAE,CAAC;AAKZ;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC;KACxC,MAAM,CAAC;IACN,aAAa,EAAE,kBAAkB;IACjC;;;;;OAKG;IACH,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,uEAAuE;IACvE,0BAA0B,EAAE,CAAC,CAAC,KAAK,CAAC,gCAAgC,CAAC;IACrE,yEAAyE;IACzE,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;IAC1C,8EAA8E;IAC9E,cAAc,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IAC/C;;;;;OAKG;IACH,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC;;;;;;OAMG;IACH,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;IAChD;;;;;OAKG;IACH,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrD;;;OAGG;IACH,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC3C,CAAC;KACD,MAAM,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pack-verifiers.d.ts","sourceRoot":"","sources":["../../src/verdict/pack-verifiers.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAQxE,OAAO,EASL,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AAiKvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,GACd;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAqB5D;AA+CD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,SAAS,kBAAkB,EAAE,EACzC,oBAAoB,EAAE,MAAM,GAE1B;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoD3C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAgCrF;AAsfD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAKxF;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,IAAI,IAAI,CAS5C"}
1
+ {"version":3,"file":"pack-verifiers.d.ts","sourceRoot":"","sources":["../../src/verdict/pack-verifiers.ts"],"names":[],"mappings":"AAwDA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAQxE,OAAO,EASL,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AAiLvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,GACd;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAqB5D;AA+CD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,SAAS,kBAAkB,EAAE,EACzC,oBAAoB,EAAE,MAAM,GAE1B;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAA;CAAE,GACnD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoD3C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAgCrF;AAksBD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAKxF;AAED,uEAAuE;AACvE,wBAAgB,qBAAqB,IAAI,IAAI,CAS5C"}
@@ -28,6 +28,20 @@
28
28
  * exchange proves only that the witness observed an HTTP exchange —
29
29
  * test attribution is suite-claimed, never independently verified.
30
30
  *
31
+ * Both transport contracts accept a SECOND channel (plan 0.9.2 item D):
32
+ * the OBSERVE channel. ONLY when the engine-browser anchor path comes
33
+ * back `missing` is a witnessed `http.observed` record stamped
34
+ * `channel: 'observe'` consulted — carrying the exchanges the witness
35
+ * proxied for THIS session, minted only for claims the supervisor
36
+ * registered `observed-e2e`. It grades through the SAME
37
+ * {@link gradeObservedExchange} matcher, so a normal suite-driven test
38
+ * mapped `observed-e2e` can discharge the obligation without any second
39
+ * endpoint resolver. An anchor-path `invalid` is final (I6): an
40
+ * engine-found error is never masked by a second channel's match.
41
+ * Admission is trust- AND channel-gated exactly as for persistence
42
+ * (I3), and `http:frontend-request-observed` still grades blocking
43
+ * before any of this runs (I1).
44
+ *
31
45
  * Domain namespaces (`auth:*`, `task:*`, `validation:*`, `webhook:*`,
32
46
  * `workflow:*`): their approved contract vocabularies are available only
33
47
  * through the required-case aggregation. A genuine engine-issued,
@@ -50,6 +64,20 @@ import { registerContractCapabilities, setContractAvailability, registerContract
50
64
  /** Record kinds the witness and suites exchange. */
51
65
  const UI_ACTION_KIND = 'ui.action';
52
66
  const HTTP_REQUEST_KIND = 'http.request';
67
+ /**
68
+ * Observe-channel transport kind: issued ONLY by the witness's
69
+ * observe finalize (the declaring session's own proxied exchanges).
70
+ * Mirrors `HTTP_OBSERVED_KIND` in `@gate-forge/pack-playwright`'s
71
+ * constants.ts — keep the two in lockstep, exactly as
72
+ * `OBSERVED_RECORD_KIND` mirrors the witness's `OBSERVED_KIND`.
73
+ */
74
+ const HTTP_OBSERVED_KIND = 'http.observed';
75
+ /**
76
+ * Payload discriminant the witness stamps on every observe-finalized
77
+ * record. Mirrors `OBSERVE_CHANNEL` in `@gate-forge/pack-playwright`
78
+ * (and `evaluate.ts`'s local constant) — keep the three in lockstep.
79
+ */
80
+ const OBSERVE_CHANNEL = 'observe';
53
81
  /**
54
82
  * The only HTTP contracts the verifier knows (plan §7): a namespace
55
83
  * registration never implies every operation in it. Any other `http:*`
@@ -470,59 +498,46 @@ function transportInventoryBlock(input) {
470
498
  return null;
471
499
  }
472
500
  /**
473
- * Grades ONE `http.request` record independently for origin, trust,
474
- * provenance, payload, route identity, and required status (plan §10
475
- * step 3). Never returns from the outer verifier; the caller
476
- * aggregates every grade. All reason wordings are verbatim from the
477
- * single-record grader.
501
+ * Grades ONE observed HTTP exchange against the obligation's endpoint
502
+ * (plan §9/§10): the observed path must be interpretable, the COMPLETE
503
+ * route inventory must attribute it to EXACTLY the obligation's own
504
+ * endpoint, and `http:response-status-ok` additionally requires a 2xx.
505
+ * The single matcher for both the engine-browser (`http.request`) and
506
+ * the Observe channel (`http.observed`).
478
507
  *
479
508
  * Args:
480
- * record: the lenient record view to grade.
481
- * trust: the engine-derived trust tier for the record.
509
+ * facts: the exchange's method, url and observed status.
482
510
  * input: the claim plus its obligation (for ids/contract/status rule).
511
+ * subject: how the exchange's source is named in reasons — e.g.
512
+ * ``witnessed 'http.request' record 'r-1'`` on the anchor path, and
513
+ * ``observe-channel exchange in witnessed 'http.observed' record
514
+ * 'r-1'`` on the Observe path.
483
515
  * inventoryBlock: the precomputed inventory reason, or null when usable.
484
516
  * candidates: the usable route inventory (ignored when inventoryBlock
485
517
  * is set).
486
518
  *
487
519
  * Returns:
488
- * TransportRecordGrade: the independent grade for this record.
520
+ * ExchangeGrade: ok only for a uniquely attributed exchange (plus a
521
+ * 2xx for the status contract).
489
522
  */
490
- function gradeTransportRecord(record, trust, input, inventoryBlock, candidates) {
491
- const label = String(record.recordId);
492
- if (record.origin !== 'engine-observed') {
493
- return {
494
- status: 'invalid',
495
- reason: `'${input.obligation.id}': suite-submitted network record ` +
496
- `'${label}' cannot satisfy an HTTP runtime contract ` +
497
- `(${HTTP_OBSERVATION_UNTRUSTED}); only a witness-observed HTTP exchange proves ` +
498
- 'transport, and test attribution is suite-claimed',
499
- };
500
- }
501
- if (trust !== 'witnessed' || !isProvenancedRecord(record)) {
502
- return {
503
- status: 'missing',
504
- reason: `'${input.obligation.id}': observed requests exist but none carries witnessed ` +
505
- 'provenance bound to this run',
506
- };
507
- }
508
- const payload = payloadOf(record);
509
- if (payload === null || typeof payload['method'] !== 'string' || typeof payload['url'] !== 'string') {
523
+ function gradeObservedExchange(facts, input, subject, inventoryBlock, candidates) {
524
+ if (typeof facts.method !== 'string' || typeof facts.url !== 'string') {
510
525
  return {
526
+ ok: false,
511
527
  status: 'invalid',
512
- reason: `'${input.obligation.id}': witnessed '${HTTP_REQUEST_KIND}' record ` +
513
- `'${label}' carries no method/url pair`,
528
+ reason: `'${input.obligation.id}': ${subject} carries no method/url pair`,
514
529
  };
515
530
  }
516
531
  if (inventoryBlock !== null) {
517
- return { status: 'missing', reason: inventoryBlock };
532
+ return { ok: false, status: 'missing', reason: inventoryBlock };
518
533
  }
519
- const observedMethod = payload['method'];
520
- const interpreted = interpretObservedPath(payload['url']);
534
+ const observedMethod = facts.method;
535
+ const interpreted = interpretObservedPath(facts.url);
521
536
  if (interpreted.ok === false) {
522
537
  return {
538
+ ok: false,
523
539
  status: 'invalid',
524
- reason: `'${input.obligation.id}': witnessed '${HTTP_REQUEST_KIND}' record ` +
525
- `'${label}' carries a noncanonical observed path: ` +
540
+ reason: `'${input.obligation.id}': ${subject} carries a noncanonical observed path: ` +
526
541
  `${interpreted.reason}`,
527
542
  };
528
543
  }
@@ -535,19 +550,21 @@ function gradeTransportRecord(record, trust, input, inventoryBlock, candidates)
535
550
  const resolution = resolveHttpRoute(observedMethod, interpreted.path, candidates, input.obligation.resourceId);
536
551
  if (resolution.status === 'incomplete') {
537
552
  return {
553
+ ok: false,
538
554
  status: 'missing',
539
555
  reason: `'${input.obligation.id}': ${resolution.reason}`,
540
556
  };
541
557
  }
542
558
  if (resolution.status === 'nomatch') {
543
559
  return {
560
+ ok: false,
544
561
  status: 'invalid',
545
- reason: `'${input.obligation.id}': witnessed '${HTTP_REQUEST_KIND}' record ` +
546
- `'${label}' ${resolution.reason}`,
562
+ reason: `'${input.obligation.id}': ${subject} ${resolution.reason}`,
547
563
  };
548
564
  }
549
565
  if (resolution.status === 'ambiguous') {
550
566
  return {
567
+ ok: false,
551
568
  status: 'invalid',
552
569
  reason: `'${input.obligation.id}': ambiguous route attribution: observed ` +
553
570
  `${observedMethod.toUpperCase()} ${interpreted.path} matches ${resolution.candidates.length} ` +
@@ -558,42 +575,87 @@ function gradeTransportRecord(record, trust, input, inventoryBlock, candidates)
558
575
  }
559
576
  if (resolution.status === 'mismatch') {
560
577
  return {
578
+ ok: false,
561
579
  status: 'invalid',
562
- reason: `'${input.obligation.id}': witnessed '${HTTP_REQUEST_KIND}' record ` +
563
- `'${label}' observed ${observedMethod.toUpperCase()} ` +
580
+ reason: `'${input.obligation.id}': ${subject} observed ${observedMethod.toUpperCase()} ` +
564
581
  `${interpreted.path} uniquely matches route ${candidateIdentityText(resolution.matched)} ` +
565
582
  `but the obligation requires endpoint '${input.obligation.resourceId}'; evidence from ` +
566
583
  'a different endpoint can never satisfy it',
567
584
  };
568
585
  }
569
586
  if (input.obligation.contract === 'http:response-status-ok') {
570
- const status = payload['status'];
587
+ const status = facts.status;
571
588
  if (typeof status !== 'number' || !Number.isInteger(status) || status < 200 || status > 299) {
572
589
  return {
590
+ ok: false,
573
591
  status: 'invalid',
574
592
  reason: `'${input.obligation.id}': observed status ` +
575
593
  `'${String(status)}' is not a 2xx response`,
576
594
  };
577
595
  }
578
596
  }
579
- return { status: 'satisfied', recordId: label };
597
+ return { ok: true };
580
598
  }
581
599
  /**
582
- * Grades the explicit transport contracts (`http:request-observed`,
583
- * `http:response-status-ok`): one shared path, no divergent verifier.
584
- * Proves only that the witness observed an HTTP exchange in the bound
585
- * run; test attribution is suite-claimed.
600
+ * Grades ONE `http.request` record independently for origin, trust,
601
+ * provenance and payload (plan §10 step 3), then hands its
602
+ * method/url/status to the shared {@link gradeObservedExchange}. Never
603
+ * returns from the outer verifier; the caller aggregates every grade.
604
+ * All reason wordings are verbatim from the single-exchange grader.
586
605
  *
587
- * Deterministic aggregation (plan §10 steps 1-8): the exact contract
588
- * and the suite anchor are validated once (codepoint-smallest anchor
589
- * when several qualify); the route inventory is scanned once; then
590
- * EVERY `http.request` record is graded independently with NO early
591
- * return on the first bad record. `satisfied > invalid > missing`
592
- * decides; ≥1 satisfying record selects the codepoint-smallest
593
- * record id joined with the anchor — identical for every input
594
- * permutation. Otherwise the codepoint-smallest invalid reason wins,
595
- * else the smallest missing reason. Untrusted records never satisfy;
596
- * status-ok still means ≥1 eligible 2xx (no new success rule).
606
+ * Args:
607
+ * record: the lenient record view to grade.
608
+ * trust: the engine-derived trust tier for the record.
609
+ * input: the claim plus its obligation (for ids/contract/status rule).
610
+ * inventoryBlock: the precomputed inventory reason, or null when usable.
611
+ * candidates: the usable route inventory (ignored when inventoryBlock
612
+ * is set).
613
+ *
614
+ * Returns:
615
+ * TransportRecordGrade: the independent grade for this record.
616
+ */
617
+ function gradeTransportRecord(record, trust, input, inventoryBlock, candidates) {
618
+ const label = String(record.recordId);
619
+ if (record.origin !== 'engine-observed') {
620
+ return {
621
+ status: 'invalid',
622
+ reason: `'${input.obligation.id}': suite-submitted network record ` +
623
+ `'${label}' cannot satisfy an HTTP runtime contract ` +
624
+ `(${HTTP_OBSERVATION_UNTRUSTED}); only a witness-observed HTTP exchange proves ` +
625
+ 'transport, and test attribution is suite-claimed',
626
+ };
627
+ }
628
+ if (trust !== 'witnessed' || !isProvenancedRecord(record)) {
629
+ return {
630
+ status: 'missing',
631
+ reason: `'${input.obligation.id}': observed requests exist but none carries witnessed ` +
632
+ 'provenance bound to this run',
633
+ };
634
+ }
635
+ const payload = payloadOf(record);
636
+ const subject = `witnessed '${HTTP_REQUEST_KIND}' record '${label}'`;
637
+ if (payload === null) {
638
+ return {
639
+ status: 'invalid',
640
+ reason: `'${input.obligation.id}': ${subject} carries no method/url pair`,
641
+ };
642
+ }
643
+ const exchange = gradeObservedExchange({ method: payload['method'], url: payload['url'], status: payload['status'] }, input, subject, inventoryBlock, candidates);
644
+ if (exchange.ok)
645
+ return { status: 'satisfied', recordId: label };
646
+ return exchange;
647
+ }
648
+ /**
649
+ * The ANCHOR channel of the transport grader: the historical rule,
650
+ * byte-identical. The suite anchor is validated once (codepoint-smallest
651
+ * anchor when several qualify); the route inventory is scanned once;
652
+ * then EVERY `http.request` record is graded independently with NO
653
+ * early return on the first bad record. `satisfied > invalid > missing`
654
+ * decides; ≥1 satisfying record selects the codepoint-smallest record
655
+ * id joined with the anchor — identical for every input permutation.
656
+ * Otherwise the codepoint-smallest invalid reason wins, else the
657
+ * smallest missing reason. Untrusted records never satisfy; status-ok
658
+ * still means ≥1 eligible 2xx (no new success rule).
597
659
  *
598
660
  * Args:
599
661
  * input: the claim plus its attributed evidence and obligation.
@@ -602,7 +664,7 @@ function gradeTransportRecord(record, trust, input, inventoryBlock, candidates)
602
664
  * ClaimOutcome: satisfied only for a witnessed engine-observed
603
665
  * exchange matching the endpoint shape (plus 2xx for status-ok).
604
666
  */
605
- function gradeTransportObservation(input) {
667
+ function gradeAnchoredTransport(input) {
606
668
  const anchor = selectTransportAnchor(input);
607
669
  if (anchor.ok === false)
608
670
  return anchor.outcome;
@@ -643,6 +705,145 @@ function gradeTransportObservation(input) {
643
705
  const reason = missingReasons.sort(compareStrings)[0];
644
706
  return { status: 'missing', reason };
645
707
  }
708
+ /**
709
+ * The OBSERVE channel of the transport grader: the exchanges the
710
+ * witness proxied for THIS test session, stamped into one witnessed
711
+ * `http.observed` record by the observe finalize. Admission mirrors the
712
+ * persistence Observe channel exactly: `trust === 'witnessed'` AND the
713
+ * `channel: 'observe'` stamp (both witness-issued, both covered by the
714
+ * ledger MAC) — a suite-asserted or untrusted `http.observed` record is
715
+ * admissible NOWHERE. Only obligations the supervisor registered
716
+ * `observed-e2e` ever carry such a record, so the gate lives in the
717
+ * witness's declarations, not here.
718
+ *
719
+ * Returns null — the channel says NOTHING, so the anchor outcome stands
720
+ * verbatim — when no record qualifies (the persistence channel's
721
+ * `observeFailure === null` rule: an absent channel never rewords an
722
+ * absent anchor).
723
+ *
724
+ * Args:
725
+ * input: the claim plus its attributed evidence and obligation.
726
+ *
727
+ * Returns:
728
+ * ClaimOutcome | null: satisfied with the record id carrying a
729
+ * matching exchange, the sharpest typed reason otherwise, or null
730
+ * when no witnessed Observe-channel record is present at all.
731
+ */
732
+ function gradeObservedTransport(input) {
733
+ const records = input.evidence.filter((entry) => entry.trust === 'witnessed' &&
734
+ typeof entry.record.kind === 'string' &&
735
+ entry.record.kind === HTTP_OBSERVED_KIND &&
736
+ payloadOf(entry.record)?.['channel'] === OBSERVE_CHANNEL);
737
+ if (records.length === 0)
738
+ return null;
739
+ const inventoryBlock = transportInventoryBlock(input);
740
+ const candidates = (input.httpRoutes ?? []);
741
+ const satisfied = [];
742
+ const invalidReasons = [];
743
+ const missingReasons = [];
744
+ for (const entry of records) {
745
+ const label = String(entry.record.recordId);
746
+ const subject = `observe-channel exchange in witnessed '${HTTP_OBSERVED_KIND}' record '${label}'`;
747
+ const payload = payloadOf(entry.record);
748
+ const exchanges = payload?.['exchanges'];
749
+ if (!Array.isArray(exchanges)) {
750
+ invalidReasons.push(`'${input.obligation.id}': ${subject} carries no exchanges list — the witness records ` +
751
+ "only the session's own proxied exchanges, and this one names none");
752
+ continue;
753
+ }
754
+ if (exchanges.length === 0) {
755
+ invalidReasons.push(`'${input.obligation.id}': ${subject} carries an EMPTY exchanges list; a session that ` +
756
+ 'proxied no HTTP exchange gets a typed missing-traffic note instead of a record');
757
+ continue;
758
+ }
759
+ let invalid = null;
760
+ let missing = null;
761
+ let matchedHere = false;
762
+ for (const raw of exchanges) {
763
+ const facts = typeof raw === 'object' && raw !== null && !Array.isArray(raw)
764
+ ? { method: raw['method'], url: raw['url'], status: raw['status'] }
765
+ : { method: undefined, url: undefined, status: undefined };
766
+ const grade = gradeObservedExchange(facts, input, subject, inventoryBlock, candidates);
767
+ if (grade.ok) {
768
+ matchedHere = true;
769
+ break;
770
+ }
771
+ if (grade.status === 'invalid') {
772
+ if (invalid === null)
773
+ invalid = grade.reason;
774
+ }
775
+ else if (missing === null) {
776
+ missing = grade.reason;
777
+ }
778
+ }
779
+ if (matchedHere)
780
+ satisfied.push(label);
781
+ else if (invalid !== null)
782
+ invalidReasons.push(invalid);
783
+ else if (missing !== null)
784
+ missingReasons.push(missing);
785
+ }
786
+ if (satisfied.length > 0) {
787
+ // ONE selected id, codepoint-smallest exactly as the anchor path
788
+ // does: the result never depends on the input order.
789
+ return {
790
+ status: 'satisfied',
791
+ recordIds: [sortedUniqueIds(satisfied)[0]],
792
+ };
793
+ }
794
+ if (invalidReasons.length > 0) {
795
+ return { status: 'invalid', reason: invalidReasons.sort(compareStrings)[0] };
796
+ }
797
+ return { status: 'missing', reason: missingReasons.sort(compareStrings)[0] };
798
+ }
799
+ /**
800
+ * Grades the explicit transport contracts (`http:request-observed`,
801
+ * `http:response-status-ok`): ONE matcher, two evidence channels, no
802
+ * divergent verifier. Proves only that the witness observed an HTTP
803
+ * exchange in the bound run; test attribution is suite-claimed on both.
804
+ *
805
+ * Channel order (plan 0.9.2 item D, invariants I4/I6): the engine
806
+ * browser anchor path grades FIRST and decides everything:
807
+ * - satisfied → returned verbatim, with the same record ids;
808
+ * - invalid → returned verbatim too. An engine-found ERROR (a
809
+ * witnessed exchange of a different endpoint, a non-2xx response) is
810
+ * FINAL: a second channel's match never masks it. When the engine
811
+ * observed the traffic and it was wrong, no other evidence may make
812
+ * the claim pass.
813
+ * - missing → and only then is the Observe channel consulted, which is
814
+ * what lets a normal suite-driven test mapped `observed-e2e` discharge
815
+ * the same obligation without weakening what the engine path proves.
816
+ *
817
+ * When the anchor path is missing and the Observe channel does not
818
+ * satisfy either, the sharpest reason wins — `invalid > missing`, then
819
+ * codepoint-smallest — so a witnessed exchange of the wrong endpoint is
820
+ * never reported as an absent anchor. With no admissible Observe
821
+ * record the anchor outcome is returned BYTE-IDENTICAL: the channel
822
+ * that said nothing cannot reword the channel that did.
823
+ *
824
+ * Args:
825
+ * input: the claim plus its attributed evidence and obligation.
826
+ *
827
+ * Returns:
828
+ * ClaimOutcome: satisfied only for a witnessed exchange matching the
829
+ * endpoint shape (plus 2xx for status-ok), on either channel.
830
+ */
831
+ function gradeTransportObservation(input) {
832
+ const anchored = gradeAnchoredTransport(input);
833
+ if (anchored.status !== 'missing')
834
+ return anchored;
835
+ const observed = gradeObservedTransport(input);
836
+ if (observed === null)
837
+ return anchored;
838
+ if (observed.status === 'satisfied')
839
+ return observed;
840
+ if (observed.status === 'invalid')
841
+ return observed;
842
+ return {
843
+ status: 'missing',
844
+ reason: [anchored.reason, observed.reason].sort(compareStrings)[0],
845
+ };
846
+ }
646
847
  /** Grades the HTTP namespace: exact dispatch, frontend fail-closed, shared transport path. */
647
848
  function httpVerifier(input) {
648
849
  // Exact contract dispatch first (plan §7): an unknown `http:*` name is