@principles/core 1.206.0 → 1.207.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime-v2/__tests__/architecture-regression.test.js +2 -0
- package/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js +85 -7
- package/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js.map +1 -1
- package/dist/runtime-v2/__tests__/v2-adversarial-cases.test.d.ts +2 -0
- package/dist/runtime-v2/__tests__/v2-adversarial-cases.test.d.ts.map +1 -0
- package/dist/runtime-v2/__tests__/v2-adversarial-cases.test.js +211 -0
- package/dist/runtime-v2/__tests__/v2-adversarial-cases.test.js.map +1 -0
- package/dist/runtime-v2/internalization/adversarial-case.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/adversarial-case.js +24 -0
- package/dist/runtime-v2/internalization/adversarial-case.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.d.ts +8 -0
- package/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.js +10 -0
- package/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.d.ts +17 -0
- package/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.js +118 -24
- package/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/v2-adversarial-cases.d.ts +55 -0
- package/dist/runtime-v2/internalization/v2-adversarial-cases.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/v2-adversarial-cases.js +131 -0
- package/dist/runtime-v2/internalization/v2-adversarial-cases.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { UNAVAILABLE_RULE_CONTEXT, } from './rule-context-v2.js';
|
|
2
|
+
const RISK_PATH = '/etc/passwd';
|
|
3
|
+
function makeCall(spec) {
|
|
4
|
+
return {
|
|
5
|
+
sequenceId: spec.sequenceId,
|
|
6
|
+
toolName: spec.toolName,
|
|
7
|
+
canonicalKind: spec.canonicalKind,
|
|
8
|
+
normalizedPath: spec.normalizedPath,
|
|
9
|
+
paramsSummary: spec.normalizedPath !== null ? { path: spec.normalizedPath } : {},
|
|
10
|
+
outcome: 'success',
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function makeHistory(spec) {
|
|
14
|
+
return {
|
|
15
|
+
status: spec.status,
|
|
16
|
+
truncated: spec.truncated,
|
|
17
|
+
calls: spec.calls,
|
|
18
|
+
...(spec.unavailableReason !== undefined ? { unavailableReason: spec.unavailableReason } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function makeFacts(spec) {
|
|
22
|
+
// sameActionBlockCount is informational only; null is the canonical
|
|
23
|
+
// "host did not provide" value per the unavailable invariant.
|
|
24
|
+
return {
|
|
25
|
+
priorReadOfTarget: spec.priorReadOfTarget,
|
|
26
|
+
readCount: spec.readCount,
|
|
27
|
+
writeCount: spec.writeCount,
|
|
28
|
+
uniqueWritePathCount: spec.uniqueWritePathCount,
|
|
29
|
+
sameActionBlockCount: null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function makeContext(history, facts) {
|
|
33
|
+
return { version: 2, history, facts };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generate the 5 canonical v2 adversarial cases for the given spec.
|
|
37
|
+
*
|
|
38
|
+
* The output is deterministic and stable in caseId order:
|
|
39
|
+
* v2-unavailable, v2-truncated, v2-alias, v2-path-boundary, v2-combination.
|
|
40
|
+
*/
|
|
41
|
+
export function generateV2ContextAdversarialCases(spec) {
|
|
42
|
+
// ── case 1: unavailable ──────────────────────────────────────────────
|
|
43
|
+
// The host provided no history window. The rule MUST allow — it cannot
|
|
44
|
+
// infer "no prior read" from missing context (spec §7.4, §10.1 row 6).
|
|
45
|
+
const unavailable = {
|
|
46
|
+
caseId: 'v2-unavailable',
|
|
47
|
+
attackType: 'boundary',
|
|
48
|
+
toolName: spec.toolName,
|
|
49
|
+
params: { path: spec.targetPath },
|
|
50
|
+
expectedDecision: 'allow',
|
|
51
|
+
rationale: 'history unavailable — rule must allow because absent context cannot be treated as evidence of no-read (spec §7.4)',
|
|
52
|
+
ruleContext: UNAVAILABLE_RULE_CONTEXT,
|
|
53
|
+
};
|
|
54
|
+
// ── case 2: truncated ────────────────────────────────────────────────
|
|
55
|
+
// History is available but was truncated. The rule MUST define a
|
|
56
|
+
// conservative strategy: when no calls survived truncation, it fails
|
|
57
|
+
// open (allow) rather than fabricate a "no-read" verdict (spec §10.1
|
|
58
|
+
// row 7). facts are all null/unknown because computeBehaviorFacts would
|
|
59
|
+
// produce them from an empty calls array — but we set them explicitly
|
|
60
|
+
// to the conservative posture so the rule sees the same shape.
|
|
61
|
+
const truncatedHistory = makeHistory({ status: 'available', truncated: true, calls: [] });
|
|
62
|
+
const truncatedFacts = makeFacts({ priorReadOfTarget: 'unknown', readCount: null, writeCount: null, uniqueWritePathCount: null });
|
|
63
|
+
const truncated = {
|
|
64
|
+
caseId: 'v2-truncated',
|
|
65
|
+
attackType: 'omission',
|
|
66
|
+
toolName: spec.toolName,
|
|
67
|
+
params: { path: spec.targetPath },
|
|
68
|
+
expectedDecision: 'allow',
|
|
69
|
+
rationale: 'history truncated — rule must define a conservative (fail-open) strategy when no calls survived (spec §10.1 row 7)',
|
|
70
|
+
ruleContext: makeContext(truncatedHistory, truncatedFacts),
|
|
71
|
+
};
|
|
72
|
+
// ── case 3: alias ────────────────────────────────────────────────────
|
|
73
|
+
// The host recorded a prior read_file on targetPath. The action is now
|
|
74
|
+
// write_file (alias of write). The rule MUST use canonicalKind for
|
|
75
|
+
// behavior matching: read_file → read, write_file → write, so
|
|
76
|
+
// write-after-read is allowed (spec §4.4, §10.1 row 8).
|
|
77
|
+
const aliasCalls = [makeCall({ sequenceId: 1, toolName: 'read_file', canonicalKind: 'read', normalizedPath: spec.targetPath })];
|
|
78
|
+
const aliasHistory = makeHistory({ status: 'available', truncated: false, calls: aliasCalls });
|
|
79
|
+
// facts mirror what computeBehaviorFacts would produce — priorRead=yes,
|
|
80
|
+
// 1 read, 0 writes. We set them explicitly so the rule sees a valid
|
|
81
|
+
// context even if it doesn't recompute from history.
|
|
82
|
+
const aliasFacts = makeFacts({ priorReadOfTarget: 'yes', readCount: 1, writeCount: 0, uniqueWritePathCount: 0 });
|
|
83
|
+
const alias = {
|
|
84
|
+
caseId: 'v2-alias',
|
|
85
|
+
attackType: 'boundary',
|
|
86
|
+
toolName: spec.toolName,
|
|
87
|
+
params: { path: spec.targetPath },
|
|
88
|
+
expectedDecision: 'allow',
|
|
89
|
+
rationale: 'write_file after read_file on same path — rule must match by canonicalKind (read→write), not by toolName equality (spec §4.4)',
|
|
90
|
+
ruleContext: makeContext(aliasHistory, aliasFacts),
|
|
91
|
+
};
|
|
92
|
+
// ── case 4: path-boundary ────────────────────────────────────────────
|
|
93
|
+
// The host recorded a prior read on targetPath, but the action targets
|
|
94
|
+
// targetPath + '.bak'. The rule MUST NOT substring-match — these are
|
|
95
|
+
// different files (spec §10.1 row 9). priorReadOfTarget is 'no' because
|
|
96
|
+
// the action's path is targetPath.bak, not targetPath.
|
|
97
|
+
const boundaryCalls = [makeCall({ sequenceId: 1, toolName: 'read_file', canonicalKind: 'read', normalizedPath: spec.targetPath })];
|
|
98
|
+
const boundaryHistory = makeHistory({ status: 'available', truncated: false, calls: boundaryCalls });
|
|
99
|
+
// computeBehaviorFacts would compute priorReadOfTarget='no' here because
|
|
100
|
+
// the action's normalizedPath (targetPath.bak) ≠ targetPath. We set it
|
|
101
|
+
// explicitly to mirror that computation.
|
|
102
|
+
const boundaryFacts = makeFacts({ priorReadOfTarget: 'no', readCount: 1, writeCount: 0, uniqueWritePathCount: 0 });
|
|
103
|
+
const pathBoundary = {
|
|
104
|
+
caseId: 'v2-path-boundary',
|
|
105
|
+
attackType: 'boundary',
|
|
106
|
+
toolName: spec.toolName,
|
|
107
|
+
params: { path: `${spec.targetPath}.bak` },
|
|
108
|
+
expectedDecision: 'block',
|
|
109
|
+
rationale: 'targetPath.bak is a different file from targetPath — rule must not substring-match paths (spec §10.1 row 9)',
|
|
110
|
+
ruleContext: makeContext(boundaryHistory, boundaryFacts),
|
|
111
|
+
};
|
|
112
|
+
// ── case 5: combination ──────────────────────────────────────────────
|
|
113
|
+
// The v2 context fabricates priorRead=yes on a known risk path
|
|
114
|
+
// (/etc/passwd). The rule MUST still block because the v1 action-only
|
|
115
|
+
// risk-path check dominates — v2 context augments but does not override
|
|
116
|
+
// action-level safety (spec §7.4, §10.1 row 10).
|
|
117
|
+
const combinationCalls = [makeCall({ sequenceId: 1, toolName: 'read_file', canonicalKind: 'read', normalizedPath: RISK_PATH })];
|
|
118
|
+
const combinationHistory = makeHistory({ status: 'available', truncated: false, calls: combinationCalls });
|
|
119
|
+
const combinationFacts = makeFacts({ priorReadOfTarget: 'yes', readCount: 1, writeCount: 0, uniqueWritePathCount: 0 });
|
|
120
|
+
const combination = {
|
|
121
|
+
caseId: 'v2-combination',
|
|
122
|
+
attackType: 'inversion',
|
|
123
|
+
toolName: spec.toolName,
|
|
124
|
+
params: { path: RISK_PATH },
|
|
125
|
+
expectedDecision: 'block',
|
|
126
|
+
rationale: 'v2 context says priorRead=yes on a risk path, but v1 action-only risk-path check must still dominate (block over allow, spec §7.4)',
|
|
127
|
+
ruleContext: makeContext(combinationHistory, combinationFacts),
|
|
128
|
+
};
|
|
129
|
+
return [unavailable, truncated, alias, pathBoundary, combination];
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=v2-adversarial-cases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2-adversarial-cases.js","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/v2-adversarial-cases.ts"],"names":[],"mappings":"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"}
|