@principles/core 1.296.0 → 1.296.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime-v2/adapter/artificer-l2-adapter.d.ts.map +1 -1
- package/dist/runtime-v2/adapter/artificer-l2-adapter.js +18 -0
- package/dist/runtime-v2/adapter/artificer-l2-adapter.js.map +1 -1
- package/dist/runtime-v2/internalization/artificer-intent-preflight.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-intent-preflight.js +10 -0
- package/dist/runtime-v2/internalization/artificer-intent-preflight.js.map +1 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.js +3 -1
- package/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
- package/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-runner.js +8 -1
- package/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.d.ts +2 -0
- package/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.js +3 -0
- package/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +2 -2
- package/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-prompt-builder.js +90 -38
- package/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.js +115 -39
- package/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/rulecode-verification-obligations.d.ts +66 -0
- package/dist/runtime-v2/internalization/rulecode-verification-obligations.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/rulecode-verification-obligations.js +150 -0
- package/dist/runtime-v2/internalization/rulecode-verification-obligations.js.map +1 -0
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.d.ts +10 -0
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.d.ts.map +1 -1
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.js +55 -5
- package/dist/runtime-v2/tools/artificer-l2-tool-contract.js.map +1 -1
- package/package.json +1 -1
|
@@ -21,6 +21,7 @@ import { buildGoldenTraceFromArtificer } from '../golden-trace.js';
|
|
|
21
21
|
// PRI-485 Phase 6: auto-generate 5 v2 adversarial cases (unavailable/truncation/
|
|
22
22
|
// alias/path/combination) to defend against false-positive blocks.
|
|
23
23
|
import { generateV2ContextAdversarialCases } from './v2-adversarial-cases.js';
|
|
24
|
+
import { deriveRuleCodeVerification } from './rulecode-verification-obligations.js';
|
|
24
25
|
import { canonicalizeToolKind } from './rule-context-v2.js';
|
|
25
26
|
/** PRI-741: length of the shared case-insensitive prefix of two tool names. */
|
|
26
27
|
function commonPrefixLength(a, b) {
|
|
@@ -381,6 +382,21 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
381
382
|
throw new PDRuntimeError('input_invalid', 'Artificer dependency artifact not found');
|
|
382
383
|
}
|
|
383
384
|
async invokeRuntime(taskId, context) {
|
|
385
|
+
if (context.scribeArtifact !== null) {
|
|
386
|
+
let scribe;
|
|
387
|
+
try {
|
|
388
|
+
scribe = JSON.parse(context.scribeArtifact);
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
throw new PDRuntimeError('input_invalid', 'scribe_artifact_unparseable');
|
|
392
|
+
}
|
|
393
|
+
const material = deriveRuleCodeVerification(scribe, [], this.hostSemanticContext?.tools ?? []);
|
|
394
|
+
if (material.unavailable.length > 0) {
|
|
395
|
+
this.emitEvent('adversarial_replay_skipped', taskId, { reason: 'required_fact_verification_unavailable', required: material.required,
|
|
396
|
+
executed: 0, passed: 0, failed: 0, unavailable: material.unavailable, nextAction: 'restore_supported_valid_fact_contract_before_model_request' });
|
|
397
|
+
throw new PDRuntimeError('input_invalid', `required_fact_verification_unavailable:${material.unavailable.join(',')}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
384
400
|
// Single-stage evaluation is the only path — the two-stage
|
|
385
401
|
// progressive_evaluator branch was retired with PRI-819 R-06.
|
|
386
402
|
const { message, systemPrompt } = await this.buildEvaluatorPrompt(taskId, context);
|
|
@@ -2086,13 +2102,17 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2086
2102
|
// PRI-705 / PRI-703 Phase 2: 混合场景 (非纯 out-of-scope) 下,归因与
|
|
2087
2103
|
// out-of-scope case 清单随载荷流动 — 修复 LLM 明确知道哪些失败属于
|
|
2088
2104
|
// 通道设计限制(不得尝试满足),哪些是真实 Rule 缺陷(必须修复)。
|
|
2105
|
+
const systemReplayChanges = ctx.diagnosticReplayEvidence?.passed === false
|
|
2106
|
+
&& output.evaluation.requiredChanges.length === 0 && isEvaluatorOutputV2(output)
|
|
2107
|
+
? [`[system deterministic replay] Repair the RuleCode against the executed failure evidence without inventing Owner facts: ${(output.adversarialResult?.failedCases ?? []).slice(0, 8).map((failure) => `${failure.caseId}: expected=${failure.expectedDecision}, actual=${failure.actualDecision ?? 'no decision'}, error=${failure.errorType ?? 'unknown'}; ${(failure.message ?? failure.rationale).slice(0, 160)}`).join(' | ') || 'deterministic replay failed; inspect the referenced evaluator artifact for the execution failure and restore the supported contract.'}`]
|
|
2108
|
+
: [];
|
|
2089
2109
|
const repairPayload = {
|
|
2090
2110
|
requiredChanges: completionIntent?.transitionOverrideReason === 'owner_golden_trace_provenance_missing'
|
|
2091
2111
|
? [
|
|
2092
2112
|
...output.evaluation.requiredChanges,
|
|
2093
2113
|
'Regenerate this RuleCode from the current validated Owner BehaviorExamplePack so the persisted artifact carries the system-owned ownerGoldenTraceCases; preserve the approved principle semantics.',
|
|
2094
2114
|
]
|
|
2095
|
-
: [...output.evaluation.requiredChanges],
|
|
2115
|
+
: [...output.evaluation.requiredChanges, ...systemReplayChanges],
|
|
2096
2116
|
concerns: [...output.evaluation.concerns],
|
|
2097
2117
|
previousScore: output.evaluation.score,
|
|
2098
2118
|
repairIteration: priorRepairIteration + 1,
|
|
@@ -2353,6 +2373,30 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2353
2373
|
// examples as its independent Owner acceptance baseline.
|
|
2354
2374
|
positiveCases = this.extractPositiveCases(goldenTraceCases);
|
|
2355
2375
|
}
|
|
2376
|
+
let scribe = null;
|
|
2377
|
+
try {
|
|
2378
|
+
scribe = context.scribeArtifact === null ? null : JSON.parse(context.scribeArtifact);
|
|
2379
|
+
}
|
|
2380
|
+
catch { /* the declaration extraction below fails closed on malformed content */ }
|
|
2381
|
+
const verification = deriveRuleCodeVerification(scribe, [...positiveCases, ...ownerNegativeCases], this.hostSemanticContext?.tools ?? []);
|
|
2382
|
+
if (context.scribeArtifact !== null && scribe === null)
|
|
2383
|
+
verification.unavailable.push('scribe_artifact_unparseable');
|
|
2384
|
+
if (verification.unavailable.length > 0) {
|
|
2385
|
+
this.emitEvent('adversarial_replay_skipped', taskId, { runId, reason: 'required_fact_verification_unavailable',
|
|
2386
|
+
required: verification.required, unavailable: verification.unavailable, historical: verification.historical,
|
|
2387
|
+
nextAction: 'restore_valid_declared_fact_contract_and_supported_host_projection_before_replay' });
|
|
2388
|
+
return { updatedOutput: null, skipReason: `required_fact_verification_unavailable:${verification.unavailable.join(',')}` };
|
|
2389
|
+
}
|
|
2390
|
+
positiveCases = verification.replayCases.filter((entry) => entry.kind === 'positive');
|
|
2391
|
+
ownerNegativeCases = verification.replayCases.filter((entry) => entry.kind === 'negative');
|
|
2392
|
+
// Explicit system contract positives can establish replay eligibility;
|
|
2393
|
+
// historical evidence-only labels are preserved but never counted as pass.
|
|
2394
|
+
if (positiveCases.length === 0 && verification.counterfactuals.length > 0) {
|
|
2395
|
+
positiveCases = verification.counterfactuals.filter((entry) => entry.expectedDecision === 'allow').map((entry) => ({
|
|
2396
|
+
caseId: entry.caseId, kind: 'positive', toolName: entry.toolName, params: entry.params,
|
|
2397
|
+
expectedDecision: 'allow', ruleContext: entry.ruleContext,
|
|
2398
|
+
}));
|
|
2399
|
+
}
|
|
2356
2400
|
if (positiveCases.length === 0) {
|
|
2357
2401
|
this.emitEvent('adversarial_replay_skipped', taskId, {
|
|
2358
2402
|
runId,
|
|
@@ -2368,7 +2412,7 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2368
2412
|
// PRI-634 R1: V1-shaped outputs carry no adversarialCases — the merged
|
|
2369
2413
|
// set below then relies entirely on the auto-generated v2 cases.
|
|
2370
2414
|
const llmCases = isEvaluatorOutputV2(output) ? (output.adversarialCases ?? []) : [];
|
|
2371
|
-
const v2Cases = this.generateV2CasesFromArtificer(affectedTools, positiveCases, taskId, runId);
|
|
2415
|
+
const v2Cases = verification.required.length > 0 ? [] : this.generateV2CasesFromArtificer(affectedTools, positiveCases, taskId, runId);
|
|
2372
2416
|
if (!Array.isArray(v2Cases)) {
|
|
2373
2417
|
this.emitEvent('v2_adversarial_cases_skipped', taskId, { runId, ...v2Cases });
|
|
2374
2418
|
this.emitEvent('adversarial_replay_skipped', taskId, { runId, ...v2Cases });
|
|
@@ -2376,7 +2420,7 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2376
2420
|
}
|
|
2377
2421
|
// PRI-741: host-name parity case — the rule must reach the same decision
|
|
2378
2422
|
// under the REAL host tool name as under the author's vocabulary.
|
|
2379
|
-
const hostAliasCase = this.generateHostAliasCase(requiresContextVersion === 2 ? ownerGoldenTraceCases : goldenTraceCases, taskId, runId);
|
|
2423
|
+
const hostAliasCase = this.generateHostAliasCase(verification.required.length > 0 ? verification.replayCases : requiresContextVersion === 2 ? ownerGoldenTraceCases : goldenTraceCases, taskId, runId);
|
|
2380
2424
|
const ownerNegativeAdversarial = ownerNegativeCases.map((ownerCase) => ({
|
|
2381
2425
|
caseId: `owner:${ownerCase.caseId}`,
|
|
2382
2426
|
attackType: 'boundary',
|
|
@@ -2386,39 +2430,12 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2386
2430
|
rationale: 'System-restored Owner-labelled negative behavior example; expected decision comes from the validated BehaviorExamplePack.',
|
|
2387
2431
|
...(ownerCase.ruleContext !== undefined ? { ruleContext: ownerCase.ruleContext } : {}),
|
|
2388
2432
|
}));
|
|
2389
|
-
// A trusted design fact scopes the invocation already. Changing its command
|
|
2390
|
-
// spelling must not bypass the same denied scope (counterfactual, not history).
|
|
2391
|
-
const designScopeCases = [];
|
|
2392
|
-
if (context.scribeArtifact !== null) {
|
|
2393
|
-
let scribe;
|
|
2394
|
-
try {
|
|
2395
|
-
scribe = JSON.parse(context.scribeArtifact);
|
|
2396
|
-
}
|
|
2397
|
-
catch {
|
|
2398
|
-
scribe = null;
|
|
2399
|
-
}
|
|
2400
|
-
const conditions = extractExecutionConditions(scribe);
|
|
2401
|
-
if (!conditions.corrupted && conditions.conditions?.requiredFacts.some((fact) => fact.required && fact.factKind === 'design_approval')) {
|
|
2402
|
-
for (const ownerCase of ownerNegativeCases) {
|
|
2403
|
-
const fact = ownerCase.ruleContext?.facts.designGate;
|
|
2404
|
-
const semantic = this.hostSemanticContext?.tools.find((tool) => tool.rawToolName === ownerCase.toolName);
|
|
2405
|
-
if (semantic?.canonicalKind !== 'execute' || fact?.resolution !== 'not_approved' || !fact.requiresApproval)
|
|
2406
|
-
continue;
|
|
2407
|
-
designScopeCases.push({
|
|
2408
|
-
caseId: `design-scope:${ownerCase.caseId}`, attackType: 'omission', toolName: ownerCase.toolName,
|
|
2409
|
-
params: { command: 'node -e "process.stdout.write(123)"' }, expectedDecision: 'block',
|
|
2410
|
-
rationale: 'System-derived counterfactual: the same trusted denied invocation scope cannot depend on command spelling; not a claim about historical behavior.',
|
|
2411
|
-
ruleContext: ownerCase.ruleContext,
|
|
2412
|
-
});
|
|
2413
|
-
}
|
|
2414
|
-
}
|
|
2415
|
-
}
|
|
2416
2433
|
const mergedAdversarialCases = [
|
|
2417
2434
|
...ownerNegativeAdversarial,
|
|
2418
|
-
...
|
|
2435
|
+
...verification.counterfactuals.filter((entry) => !positiveCases.some((positive) => positive.caseId === entry.caseId)),
|
|
2419
2436
|
...v2Cases,
|
|
2420
2437
|
...(hostAliasCase !== null ? [hostAliasCase] : []),
|
|
2421
|
-
...llmCases,
|
|
2438
|
+
...llmCases.filter((entry) => verification.required.length === 0 || entry.ruleContext?.facts.designGate !== undefined),
|
|
2422
2439
|
];
|
|
2423
2440
|
// (4) No adversarial cases (neither v2-generated nor LLM-supplied) →
|
|
2424
2441
|
// nothing to replay. codeReview may still be present (passive review only).
|
|
@@ -2552,11 +2569,33 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2552
2569
|
const accepted = gateResult.decision === 'accepted_shadow';
|
|
2553
2570
|
const failedCases = accepted
|
|
2554
2571
|
? []
|
|
2555
|
-
: this.mapFailedCases(gateResult, mergedAdversarialCases);
|
|
2572
|
+
: this.mapFailedCases(gateResult, mergedAdversarialCases, mergedTrace.cases);
|
|
2573
|
+
const failedIds = new Set(gateResult.sandboxResult.failedCases.map((entry) => entry.caseId));
|
|
2574
|
+
const runtimeUnavailable = gateResult.sandboxResult.forbiddenPatternViolations.length > 0
|
|
2575
|
+
|| (!gateResult.sandboxResult.success && gateResult.sandboxResult.failedCases.length === 0)
|
|
2576
|
+
|| gateResult.sandboxResult.failedCases.some((entry) => RESERVED_SYSTEM_CASE_ID.test(entry.caseId));
|
|
2577
|
+
const historyExecuted = runtimeUnavailable ? 0 : verification.replayCases.length;
|
|
2578
|
+
const historyFailed = verification.replayCases.filter((entry) => failedIds.has(entry.caseId) || failedIds.has(`owner:${entry.caseId}`)).length;
|
|
2579
|
+
const contractExecuted = runtimeUnavailable ? 0 : verification.counterfactuals.length;
|
|
2580
|
+
const contractFailed = verification.counterfactuals.filter((entry) => failedIds.has(entry.caseId)).length;
|
|
2556
2581
|
const adversarialResult = {
|
|
2557
2582
|
passed: accepted,
|
|
2558
2583
|
failedCases,
|
|
2559
2584
|
...(gateResult.failure ? { failure: { layer: gateResult.failure.layer, reasonCode: gateResult.failure.reasonCode } } : {}),
|
|
2585
|
+
verificationCoverage: {
|
|
2586
|
+
required: verification.required,
|
|
2587
|
+
executed: runtimeUnavailable ? 0 : mergedTrace.cases.length,
|
|
2588
|
+
passed: runtimeUnavailable ? 0 : mergedTrace.cases.length - gateResult.sandboxResult.failedCases.length,
|
|
2589
|
+
failed: runtimeUnavailable ? 0 : gateResult.sandboxResult.failedCases.length,
|
|
2590
|
+
unavailable: runtimeUnavailable ? [...verification.unavailable, 'sandbox_execution_unavailable'] : verification.unavailable,
|
|
2591
|
+
historicalCoverage: { executed: historyExecuted, passed: Math.max(0, historyExecuted - historyFailed), failed: historyFailed,
|
|
2592
|
+
unavailable: verification.historical.length - historyExecuted },
|
|
2593
|
+
contractCoverage: { required: verification.counterfactuals.length, executed: contractExecuted,
|
|
2594
|
+
passed: Math.max(0, contractExecuted - contractFailed), failed: contractFailed,
|
|
2595
|
+
unavailable: verification.counterfactuals.length - contractExecuted },
|
|
2596
|
+
historical: verification.historical,
|
|
2597
|
+
counterfactuals: verification.counterfactuals.map((entry) => ({ caseId: entry.caseId, source: 'system_counterfactual', contract: 'DesignGateFact/v1' })),
|
|
2598
|
+
},
|
|
2560
2599
|
};
|
|
2561
2600
|
return {
|
|
2562
2601
|
updatedOutput: { ...output, adversarialResult },
|
|
@@ -2801,8 +2840,14 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2801
2840
|
* (Runtime Contract Rule 9: graceful degradation includes a reason).
|
|
2802
2841
|
*/
|
|
2803
2842
|
// eslint-disable-next-line @typescript-eslint/class-methods-use-this
|
|
2804
|
-
mapFailedCases(gateResult, adversarialCases) {
|
|
2843
|
+
mapFailedCases(gateResult, adversarialCases, executedCases = []) {
|
|
2805
2844
|
const advById = new Map(adversarialCases.map((c) => [c.caseId, c]));
|
|
2845
|
+
for (const entry of executedCases) {
|
|
2846
|
+
if (!advById.has(entry.caseId))
|
|
2847
|
+
advById.set(entry.caseId, { caseId: entry.caseId, attackType: 'boundary',
|
|
2848
|
+
toolName: entry.toolName, params: entry.params, expectedDecision: entry.expectedDecision,
|
|
2849
|
+
rationale: 'System-executed replay case; this input is execution evidence, not a reconstructed historical fact.', ruleContext: entry.ruleContext });
|
|
2850
|
+
}
|
|
2806
2851
|
// PRI-634 PR-A (SPEC §14): the sandbox failedCase is the authority for
|
|
2807
2852
|
// expected/actual/errorType — it sees merged positive-case failures the
|
|
2808
2853
|
// adversarial-case list cannot. actualDecision is copied ONLY when the
|
|
@@ -2871,7 +2916,11 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
2871
2916
|
const contextState = adv.ruleContext
|
|
2872
2917
|
? `history ${history?.status ?? 'unknown'}${history?.truncated ? ' (truncated)' : ''}`
|
|
2873
2918
|
: 'none';
|
|
2874
|
-
const
|
|
2919
|
+
const gate = facts?.designGate;
|
|
2920
|
+
const designContext = gate !== undefined
|
|
2921
|
+
? `designGate=${gate.resolution}, requiresApproval=${gate.requiresApproval}, binding=${gate.taskRef === gate.decisionTaskRef && gate.specDigest === gate.decisionSpecDigest && gate.scopeRef === gate.decisionScopeRef ? 'matched' : 'mismatched'}, revoked=${gate.revoked}; `
|
|
2922
|
+
: adv.caseId.startsWith('system-contract:design_approval:') ? 'designGate=missing; ' : '';
|
|
2923
|
+
const identityAndContext = `tool=${adv.toolName} | context: ${designContext}${contextState}, priorReadOfTarget=${facts?.priorReadOfTarget ?? 'unknown'}, readCount=${facts?.readCount ?? 'unknown'}`;
|
|
2875
2924
|
let paramsDigest;
|
|
2876
2925
|
try {
|
|
2877
2926
|
paramsDigest = EvaluatorRunner.digestParams(adv.params);
|
|
@@ -3178,6 +3227,7 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
3178
3227
|
&& hostContext.tools.every((tool) => typeof tool.rawToolName === 'string' && tool.rawToolName.trim() !== ''
|
|
3179
3228
|
&& typeof tool.canonicalKind === 'string' && tool.canonicalKind.trim() !== '');
|
|
3180
3229
|
let requiredFactKinds;
|
|
3230
|
+
let executableTrace = traceBuild.trace;
|
|
3181
3231
|
if (typeof bearerPrincipleContentJson === 'string') {
|
|
3182
3232
|
let scribeArtifact;
|
|
3183
3233
|
try {
|
|
@@ -3201,9 +3251,34 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
3201
3251
|
return null;
|
|
3202
3252
|
}
|
|
3203
3253
|
if (executionConditions.conditions !== null) {
|
|
3204
|
-
|
|
3205
|
-
if (
|
|
3206
|
-
|
|
3254
|
+
requiredFactKinds = [...new Set(executionConditions.conditions.requiredFacts.filter((fact) => fact.required).map((fact) => fact.factKind))];
|
|
3255
|
+
if (requiredFactKinds.some((kind) => kind !== 'design_approval')) {
|
|
3256
|
+
this.emitEvent('rule_assembly_failed', taskId, { runId, reason: 'required_fact_contract_unsupported', requiredFactKinds,
|
|
3257
|
+
nextAction: 'provide_a_supported_runtime_fact_contract_before_assembly' });
|
|
3258
|
+
return null;
|
|
3259
|
+
}
|
|
3260
|
+
if (requiredFactKinds.length > 0) {
|
|
3261
|
+
const ownerBuild = Array.isArray(artificerParsed.ownerGoldenTraceCases)
|
|
3262
|
+
? buildGoldenTraceFromArtificer({ cases: artificerParsed.ownerGoldenTraceCases })
|
|
3263
|
+
: null;
|
|
3264
|
+
if (ownerBuild === null || !ownerBuild.ok) {
|
|
3265
|
+
this.emitEvent('rule_assembly_failed', taskId, { runId, reason: 'owner_verification_cases_unavailable',
|
|
3266
|
+
nextAction: 'restore_the_system_owned_owner_cases_before_assembly' });
|
|
3267
|
+
return null;
|
|
3268
|
+
}
|
|
3269
|
+
const material = deriveRuleCodeVerification(scribeArtifact, ownerBuild.trace.cases, hostContext?.tools ?? []);
|
|
3270
|
+
if (material.unavailable.length > 0) {
|
|
3271
|
+
this.emitEvent('rule_assembly_failed', taskId, { runId, reason: 'required_fact_verification_unavailable', unavailable: material.unavailable,
|
|
3272
|
+
nextAction: 'restore_valid_supported_fact_material_before_assembly' });
|
|
3273
|
+
return null;
|
|
3274
|
+
}
|
|
3275
|
+
// The activation consumer replays this trace. Evidence-only Owner
|
|
3276
|
+
// labels remain verbatim alongside it, never synthetic history.
|
|
3277
|
+
executableTrace = { ...traceBuild.trace, cases: [...material.replayCases, ...material.counterfactuals.map((entry) => ({
|
|
3278
|
+
caseId: entry.caseId, kind: entry.expectedDecision === 'allow' ? 'positive' : 'negative', toolName: entry.toolName,
|
|
3279
|
+
params: entry.params, expectedDecision: entry.expectedDecision, ruleContext: entry.ruleContext,
|
|
3280
|
+
}))] };
|
|
3281
|
+
}
|
|
3207
3282
|
}
|
|
3208
3283
|
}
|
|
3209
3284
|
if (requiresContextVersion === 2 && !hasHostInputContract) {
|
|
@@ -3215,8 +3290,9 @@ export class EvaluatorRunner extends BasePeerRunner {
|
|
|
3215
3290
|
}
|
|
3216
3291
|
const ruleContent = {
|
|
3217
3292
|
implementationCode,
|
|
3218
|
-
goldenTrace:
|
|
3293
|
+
goldenTrace: executableTrace,
|
|
3219
3294
|
goldenTraceCases,
|
|
3295
|
+
...(artificerParsed.ownerGoldenTraceCases !== undefined ? { ownerGoldenTraceCases: artificerParsed.ownerGoldenTraceCases } : {}),
|
|
3220
3296
|
affectedTools: validatedAffectedTools,
|
|
3221
3297
|
// adversarialResult.passed === true is the precondition for this method;
|
|
3222
3298
|
// the gate decision is therefore accepted_shadow.
|