@sema-agent/core 7.51.1 → 7.51.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/dist/agents/subagent.d.ts +5 -0
- package/dist/agents/subagent.js +1 -0
- package/dist/core/allow-entry.d.ts +4 -2
- package/dist/core/allow-entry.js +1 -1
- package/dist/core/locked-config.d.ts +26 -5
- package/dist/core/locked-config.js +31 -6
- package/dist/core/mcp-server-spec.d.ts +37 -7
- package/dist/core/mcp-server-spec.js +84 -1
- package/dist/core/mcp.js +16 -4
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +4 -2
- package/dist/core/runner/session-rule-policy.d.ts +3 -1
- package/dist/core/runner/session-rule-policy.js +11 -9
- package/dist/core/secret-env.d.ts +5 -0
- package/dist/core/session-policy-store.d.ts +54 -14
- package/dist/core/session-policy-store.js +82 -19
- package/dist/core/types.d.ts +2 -1
- package/dist/core/types.js +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -2
- package/dist/stores/file/session-policy-store.d.ts +3 -3
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +15 -1
- package/wire-changes/core@7.51.1.json +5 -5
- package/wire-changes/core@7.51.2.json +293 -0
|
@@ -18,10 +18,13 @@
|
|
|
18
18
|
* (`readRuleEntry`, allow-entry.ts): a tool name, a protocol namespace, a shell command rule (`Bash(git push:*)`), a
|
|
19
19
|
* path rule, a name or host rule. Entries are stored as written; every station that validates, compares, matches or
|
|
20
20
|
* names one reads that reader's answer ({@link judgeSessionRulesWrite}, {@link loosenReasons}, the run-time layer).
|
|
21
|
+
* - **a row keeps its grammar**: the write judge stamps the grammar it read the entries in ({@link SESSION_RULES_GRAMMAR}), and
|
|
22
|
+
* every station reads a row's entries in the grammar the row carries ({@link readSessionRulesShape}) — a row stored before
|
|
23
|
+
* the stamp keeps the reading it was written under, so an upgrade never turns a stored entry into a grant.
|
|
21
24
|
* - **NOT A SANDBOX**: a shell command rule reads the command line the call carries (every program run in its connector
|
|
22
25
|
* chain); the real isolation boundary is the executionEnv, never these rules.
|
|
23
26
|
*/
|
|
24
|
-
import { type AllowEntryInertDetail, type AllowEntryInertReason } from "./allow-entry.js";
|
|
27
|
+
import { compileAllowList, type AllowEntryInertDetail, type AllowEntryInertReason } from "./allow-entry.js";
|
|
25
28
|
/** The per-session rules. All optional; an absent bucket imposes no constraint of that kind. */
|
|
26
29
|
export interface SessionPermissionRules {
|
|
27
30
|
/** If set, ONLY the calls these entries admit are allowed — a narrowing allowlist: a call no entry admits is refused.
|
|
@@ -45,6 +48,14 @@ declare const SESSION_RULE_BUCKETS: {
|
|
|
45
48
|
export type SessionRuleEntryField = {
|
|
46
49
|
[K in keyof typeof SESSION_RULE_BUCKETS]: (typeof SESSION_RULE_BUCKETS)[K] extends "dirs" ? never : K;
|
|
47
50
|
}[keyof typeof SESSION_RULE_BUCKETS];
|
|
51
|
+
/**
|
|
52
|
+
* The rule grammar this engine reads a session's rule entries in: the `grammar` the write judge stamps on every rules value it
|
|
53
|
+
* judges ({@link judgeSessionRulesWrite}), so every store that writes through it keeps the stamp on the row. It counts
|
|
54
|
+
* revisions of what an entry MEANS and moves only when that changes. Grammar 0 is the reading before the one entry reader:
|
|
55
|
+
* a bucket's entries were tool names compared as written, so an allow entry the reader now reads as speaking for another name
|
|
56
|
+
* (`Bash(rm:*)`, `Bash(*)`) named no tool and admitted nothing.
|
|
57
|
+
*/
|
|
58
|
+
export declare const SESSION_RULES_GRAMMAR = 1;
|
|
48
59
|
/** {@link SessionPermissionRules} plus the monotonic `rev` the store stamps (the OCC key). */
|
|
49
60
|
export interface StoredSessionRules extends SessionPermissionRules {
|
|
50
61
|
rev: number;
|
|
@@ -53,7 +64,15 @@ export interface StoredSessionRules extends SessionPermissionRules {
|
|
|
53
64
|
* can tell a recreated row from a continuation of the one it enforces whatever `rev` the new row wears.
|
|
54
65
|
* Absent = generation 0 (a backend that predates the mark, or a row written before it). */
|
|
55
66
|
gen?: number;
|
|
67
|
+
/** The rule grammar the row's entries are read in ({@link SESSION_RULES_GRAMMAR}), stamped by the write judge. Absent =
|
|
68
|
+
* a row stored before the stamp: grammar 0. */
|
|
69
|
+
grammar?: number;
|
|
56
70
|
}
|
|
71
|
+
/** A rules value as the shape reading hands it on ({@link readSessionRulesShape}): its buckets, and the grammar its entries
|
|
72
|
+
* are read in — resolved, so a store that serves it on beside its own counters serves the row's grammar with it. */
|
|
73
|
+
export type SessionRulesInGrammar = SessionPermissionRules & {
|
|
74
|
+
grammar: number;
|
|
75
|
+
};
|
|
57
76
|
/** Options for {@link SessionPolicyStore.putRules}. */
|
|
58
77
|
export interface PutRulesOptions {
|
|
59
78
|
/** CAS: reject the write if the stored `rev` is not this (optimistic concurrency). Omit to skip the check. */
|
|
@@ -169,13 +188,14 @@ declare function lexWithin(root: string, p: string): boolean;
|
|
|
169
188
|
* THE ONE SHAPE READING of a rules value — what every station that takes one reads it through: the write (incoming rules),
|
|
170
189
|
* a store's read-back of its own rows, the tighten comparison's prior, the run-time layer's served row. A rules value is an
|
|
171
190
|
* object whose keys are buckets ({@link SessionPermissionRules}); each bucket present is a list of strings (`allowDirs`: of
|
|
172
|
-
* non-blank strings — a directory is no blank). A bucket's TYPE is all this reads: what an entry means is the entry reader's
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* `["r","m"]`), and a key outside the buckets is
|
|
191
|
+
* non-blank strings — a directory is no blank). A bucket's TYPE is all this reads: what an entry means is the entry reader's,
|
|
192
|
+
* in the grammar the value is written in ({@link grammarOf}), handed on as `grammar`. The store's counters (`rev`, `gen`) are
|
|
193
|
+
* passed over, and a key holding `undefined` holds nothing. Anything else is a fault, named by key and by TYPE, never by value —
|
|
194
|
+
* a bare string is never one rule and never its characters (`"rm"` spread into `["r","m"]`), and a key outside the buckets is
|
|
195
|
+
* never dropped (a dropped deny is a deny nobody enforces).
|
|
176
196
|
*/
|
|
177
197
|
export declare function readSessionRulesShape(value: unknown): {
|
|
178
|
-
rules:
|
|
198
|
+
rules: SessionRulesInGrammar;
|
|
179
199
|
} | {
|
|
180
200
|
fault: SessionRuleShapeRefusal;
|
|
181
201
|
sentence: string;
|
|
@@ -185,15 +205,33 @@ export declare function readSessionRulesShape(value: unknown): {
|
|
|
185
205
|
* stored form is `..`-free and the tighten diff compares the form the runtime resolves. Both bundled stores and a durable twin
|
|
186
206
|
* stamp exactly this, so a structuredClone and a JSON round-trip of it are byte-identical. */
|
|
187
207
|
export declare function normalizeRules(rules: unknown): SessionPermissionRules;
|
|
208
|
+
/**
|
|
209
|
+
* THE LIST READING of one rule bucket of a rules value the shape reading read — what the run-time layer enforces, the tighten
|
|
210
|
+
* comparison compares and the write judge refuses on: `compileAllowList` over the one entry reader, in the bucket's direction,
|
|
211
|
+
* against `roster` when given, in the grammar the value is written in. An entry its grammar reads as nothing that the reader
|
|
212
|
+
* reads as a row ({@link readsAsNothingIn}) is moved to the entries that read as nothing, reason `earlier_grammar`.
|
|
213
|
+
*/
|
|
214
|
+
export declare function compileSessionRuleBucket(rules: SessionRulesInGrammar, field: SessionRuleEntryField, roster?: ReadonlySet<string>): ReturnType<typeof compileAllowList>;
|
|
215
|
+
/** The advisory for allow entries a stored row's earlier grammar reads as nothing ({@link compileSessionRuleBucket}): the session,
|
|
216
|
+
* the entries as written, what they do and the way to make them the rules they now spell. */
|
|
217
|
+
export declare function earlierGrammarAdvisory(sessionId: string, entries: readonly string[]): string;
|
|
218
|
+
/** A layer's delivery of the entries its snapshots' earlier grammar reads as nothing ({@link compileSessionRuleBucket},
|
|
219
|
+
* `earlier_grammar`) to `sink`: once per distinct set per layer (the ledger is this closure's), an empty set is no news, and a
|
|
220
|
+
* throwing sink never changes what the snapshot enforces. */
|
|
221
|
+
export declare function earlierGrammarAnnouncer(sink: ((entries: readonly string[]) => void) | undefined): (entries: readonly string[]) => void;
|
|
188
222
|
/**
|
|
189
223
|
* THE ONE WRITE JUDGE every store applies before it stamps a row (both bundled stores, and a durable backend at the same point):
|
|
190
224
|
* the rules to stamp, or a {@link SessionPolicyError}, in this order — `conflict` (a stale `expectedRev` against `prior`'s rev),
|
|
191
|
-
* `invalid_shape` ({@link normalizeRules}), `inert_entry` (an entry
|
|
192
|
-
* rule that names nothing guards nothing whoever writes it), then, for a non-operator write
|
|
193
|
-
* `loosen_forbidden` ({@link loosenReasons}) — or `corrupt` when that prior cannot be read as rules,
|
|
194
|
-
* reads as fewer. `
|
|
225
|
+
* `invalid_shape` ({@link normalizeRules}), `inert_entry` (an entry that reads as nothing in the grammar the rules are written
|
|
226
|
+
* in; operator writes included — a rule that names nothing guards nothing whoever writes it), then, for a non-operator write
|
|
227
|
+
* over an existing row, `loosen_forbidden` ({@link loosenReasons}) — or `corrupt` when that prior cannot be read as rules,
|
|
228
|
+
* which the comparison never reads as fewer. The rules to stamp carry `grammar` = {@link SESSION_RULES_GRAMMAR}: what passed
|
|
229
|
+
* the judge means the same in this engine's grammar, and THIS is the one place the stamp is minted, so every store that
|
|
230
|
+
* stores what the judge returns keeps it. `mountedToolNames` = the store's declaration ({@link SessionPolicyStoreOptions.mountedToolNames}).
|
|
195
231
|
*/
|
|
196
|
-
export declare function judgeSessionRulesWrite(prior: StoredSessionRules | null, rules: unknown, opts: PutRulesOptions | undefined, mountedToolNames?: ReadonlySet<string>): SessionPermissionRules
|
|
232
|
+
export declare function judgeSessionRulesWrite(prior: StoredSessionRules | null, rules: unknown, opts: PutRulesOptions | undefined, mountedToolNames?: ReadonlySet<string>): SessionPermissionRules & {
|
|
233
|
+
grammar: number;
|
|
234
|
+
};
|
|
197
235
|
/**
|
|
198
236
|
* Pure tighten-only diff: the reasons `next` LOOSENS `prior` (empty ⇒ `next` is a pure tightening or no-op), over the EFFECTIVE
|
|
199
237
|
* entries of each rule bucket — the list as the run-time layer enforces it ({@link effectiveEntries}). An entry that reads as
|
|
@@ -201,9 +239,11 @@ export declare function judgeSessionRulesWrite(prior: StoredSessionRules | null,
|
|
|
201
239
|
* takes out an entry that names nothing); an allowlist a `*` voids admits nothing, so dropping the `*` widens. toolDeny: removing an effective entry loosens. toolAllow: removing the list
|
|
202
240
|
* (→ everything allowed) or adding an effective entry outside the prior set loosens; prior-undefined → any defined next only
|
|
203
241
|
* narrows. allowDirs: removing confinement, or adding a dir not within some prior dir, loosens (coarse raw containment).
|
|
204
|
-
* Entries compare as written
|
|
205
|
-
* is no
|
|
206
|
-
*
|
|
242
|
+
* Entries compare as written, each side's in the grammar that side is written in (a stored row's entry that its grammar reads as
|
|
243
|
+
* nothing is in no effect, so writing it in this engine's grammar widens). Both sides are read through
|
|
244
|
+
* {@link readSessionRulesShape} first: a side it cannot read (a key that is no bucket — a retired one included) throws
|
|
245
|
+
* `invalid_shape` rather than compare without it. `mountedToolNames` = the store's declaration
|
|
246
|
+
* ({@link SessionPolicyStoreOptions.mountedToolNames}; empty when it has none) — the write judge's too.
|
|
207
247
|
*/
|
|
208
248
|
export declare function loosenReasons(priorValue: SessionPermissionRules, nextValue: SessionPermissionRules, mountedToolNames?: ReadonlySet<string>): string[];
|
|
209
249
|
/**
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { posix } from "node:path";
|
|
2
2
|
import { isWinFormPath } from "../tools/fs/safety.js";
|
|
3
3
|
import { NAMESPACED_NAME_SHAPES, carriesNamespaceSeparator } from "./protocol-table.js";
|
|
4
|
-
import { compileAllowList, inertEntryPhrase, readRuleEntry, renderListEntry } from "./allow-entry.js";
|
|
4
|
+
import { compileAllowList, compiledEntryName, inertEntryPhrase, readRuleEntry, renderListEntry } from "./allow-entry.js";
|
|
5
5
|
import { valueTypeLabel } from "./tool-name-list.js";
|
|
6
6
|
const SESSION_RULE_BUCKETS = { toolAllow: "allow", toolDeny: "deny", allowDirs: "dirs" };
|
|
7
7
|
const BUCKETS = Object.keys(SESSION_RULE_BUCKETS);
|
|
8
8
|
const ENTRY_FIELDS = BUCKETS.filter((f) => SESSION_RULE_BUCKETS[f] !== "dirs");
|
|
9
|
-
const STORE_STAMPS = new Set(["rev", "gen"]);
|
|
9
|
+
const STORE_STAMPS = new Set(["rev", "gen", "grammar"]);
|
|
10
|
+
export const SESSION_RULES_GRAMMAR = 1;
|
|
10
11
|
export class SessionPolicyError extends Error {
|
|
11
12
|
code;
|
|
12
13
|
detail;
|
|
@@ -49,13 +50,32 @@ function lexWithin(root, p) {
|
|
|
49
50
|
return true;
|
|
50
51
|
return np === nr || np.startsWith(nr + "/");
|
|
51
52
|
}
|
|
53
|
+
function grammarOf(value) {
|
|
54
|
+
const stamp = value.grammar;
|
|
55
|
+
if (stamp === undefined)
|
|
56
|
+
return { grammar: value.rev !== undefined ? 0 : SESSION_RULES_GRAMMAR };
|
|
57
|
+
if (typeof stamp !== "number" || !Number.isInteger(stamp) || stamp < 0) {
|
|
58
|
+
const got = typeof stamp === "number" ? "a number that is not a whole number of 0 or more" : valueTypeLabel(stamp);
|
|
59
|
+
return { got, sentence: `session rules carry a grammar stamp that is ${got} — the stamp is the whole number of the rule grammar the rules were written in (this engine reads grammar ${SESSION_RULES_GRAMMAR})` };
|
|
60
|
+
}
|
|
61
|
+
if (stamp > SESSION_RULES_GRAMMAR) {
|
|
62
|
+
return {
|
|
63
|
+
got: `${stamp}, a grammar newer than this engine's (${SESSION_RULES_GRAMMAR})`,
|
|
64
|
+
sentence: `session rules were written in rule grammar ${stamp}, newer than this engine reads (grammar ${SESSION_RULES_GRAMMAR}) — refusing rather than read their entries in an older grammar; an engine that reads grammar ${stamp} reads them`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return { grammar: stamp };
|
|
68
|
+
}
|
|
52
69
|
export function readSessionRulesShape(value) {
|
|
53
70
|
const fault = (field, got, sentence) => ({ fault: { field, got }, sentence });
|
|
54
71
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
55
72
|
const got = Array.isArray(value) ? "an array" : valueTypeLabel(value);
|
|
56
73
|
return fault("", got, `session rules must be an object of rule buckets (${BUCKETS.join(", ")}), got ${got}`);
|
|
57
74
|
}
|
|
58
|
-
const
|
|
75
|
+
const read = grammarOf(value);
|
|
76
|
+
if ("got" in read)
|
|
77
|
+
return fault("grammar", read.got, read.sentence);
|
|
78
|
+
const rules = { grammar: read.grammar };
|
|
59
79
|
for (const [key, v] of Object.entries(value)) {
|
|
60
80
|
if (STORE_STAMPS.has(key) || v === undefined)
|
|
61
81
|
continue;
|
|
@@ -78,34 +98,76 @@ export function readSessionRulesShape(value) {
|
|
|
78
98
|
return { rules };
|
|
79
99
|
}
|
|
80
100
|
export function normalizeRules(rules) {
|
|
101
|
+
return canonicalRules(shapeOrRefuse(rules));
|
|
102
|
+
}
|
|
103
|
+
function shapeOrRefuse(rules) {
|
|
81
104
|
const read = readSessionRulesShape(rules);
|
|
82
105
|
if ("fault" in read)
|
|
83
106
|
throw new SessionPolicyError("invalid_shape", read.sentence, read.fault);
|
|
107
|
+
return read.rules;
|
|
108
|
+
}
|
|
109
|
+
function canonicalRules(read) {
|
|
84
110
|
const out = {};
|
|
85
111
|
for (const field of BUCKETS) {
|
|
86
|
-
const list = read
|
|
112
|
+
const list = read[field];
|
|
87
113
|
if (list === undefined)
|
|
88
114
|
continue;
|
|
89
115
|
out[field] = SESSION_RULE_BUCKETS[field] === "dirs" ? list.map((d) => posix.normalize(d).replace(/\/+$/, "") || "/") : [...list];
|
|
90
116
|
}
|
|
91
117
|
return out;
|
|
92
118
|
}
|
|
93
|
-
function
|
|
94
|
-
return
|
|
119
|
+
function readsAsNothingIn(grammar, field, entry, compiled) {
|
|
120
|
+
return grammar === 0 && SESSION_RULE_BUCKETS[field] === "allow" && compiledEntryName(compiled) !== entry;
|
|
121
|
+
}
|
|
122
|
+
export function compileSessionRuleBucket(rules, field, roster) {
|
|
123
|
+
const list = compileAllowList(rules[field] ?? [], SESSION_RULE_BUCKETS[field], roster);
|
|
124
|
+
const rows = list.rows.filter((r) => !readsAsNothingIn(rules.grammar, field, r.entry, r.compiled));
|
|
125
|
+
if (rows.length === list.rows.length)
|
|
126
|
+
return list;
|
|
127
|
+
const earlier = list.rows.filter((r) => readsAsNothingIn(rules.grammar, field, r.entry, r.compiled)).map((r) => ({ entry: r.entry, reason: "earlier_grammar" }));
|
|
128
|
+
return { rows, inert: [...list.inert, ...earlier] };
|
|
129
|
+
}
|
|
130
|
+
const ADVISORY_ENTRIES_SHOWN = 5;
|
|
131
|
+
export function earlierGrammarAdvisory(sessionId, entries) {
|
|
132
|
+
const one = entries.length === 1;
|
|
133
|
+
const shown = entries.slice(0, ADVISORY_ENTRIES_SHOWN).map(renderListEntry).join(", ");
|
|
134
|
+
const rest = entries.length > ADVISORY_ENTRIES_SHOWN ? ` and ${entries.length - ADVISORY_ENTRIES_SHOWN} more` : "";
|
|
135
|
+
return (`session permission rules of session ${JSON.stringify(sessionId)}: toolAllow ${shown}${rest} ${one ? "was" : "were"} stored before the rule grammar stamp, when session rules compared an entry as a tool name as written, so a parenthesized entry named no tool — ` +
|
|
136
|
+
`${one ? "it admits" : "they admit"} nothing, as when written. To make ${one ? "it an allow rule" : "them allow rules"}, write the session's rules afresh through this engine (an operator write of a value without the stored row's rev; the write stamps grammar ${SESSION_RULES_GRAMMAR}); left as stored, ${one ? "it keeps" : "they keep"} admitting nothing.`);
|
|
137
|
+
}
|
|
138
|
+
export function earlierGrammarAnnouncer(sink) {
|
|
139
|
+
const announced = new Set();
|
|
140
|
+
return (entries) => {
|
|
141
|
+
const key = JSON.stringify(entries);
|
|
142
|
+
if (sink === undefined || entries.length === 0 || announced.has(key))
|
|
143
|
+
return;
|
|
144
|
+
announced.add(key);
|
|
145
|
+
try {
|
|
146
|
+
sink(entries);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function effectiveEntries(rules, field, mountedToolNames) {
|
|
153
|
+
return compileSessionRuleBucket(rules, field, mountedToolNames).rows.map((r) => r.entry);
|
|
95
154
|
}
|
|
96
155
|
function assertEntriesRead(rules, mountedToolNames) {
|
|
97
156
|
for (const field of ENTRY_FIELDS) {
|
|
98
157
|
for (const entry of rules[field] ?? []) {
|
|
99
|
-
const
|
|
158
|
+
const reading = readRuleEntry(entry, SESSION_RULE_BUCKETS[field], mountedToolNames);
|
|
159
|
+
const read = reading.kind === "row" && readsAsNothingIn(rules.grammar, field, entry, reading.compiled) ? { kind: "inert", reason: "earlier_grammar" } : reading;
|
|
100
160
|
if (read.kind === "row")
|
|
101
161
|
continue;
|
|
102
162
|
const { kind: _kind, ...why } = read;
|
|
103
163
|
void _kind;
|
|
104
|
-
const way = why.
|
|
105
|
-
? `
|
|
106
|
-
: why.
|
|
107
|
-
? `
|
|
108
|
-
:
|
|
164
|
+
const way = why.reason === "earlier_grammar"
|
|
165
|
+
? ` These rules are written in grammar ${rules.grammar} (a stored row from before the grammar stamp), in which this entry names no tool. To make it an allow rule, write the rules afresh — a value without the stored row's rev; the write stamps grammar ${SESSION_RULES_GRAMMAR} — or leave the entry out.`
|
|
166
|
+
: why.verdict === "retired"
|
|
167
|
+
? ` If this deployment mounts its own tool under ${renderListEntry(entry)}, declare it in the store's mountedToolNames.`
|
|
168
|
+
: why.currentName === undefined
|
|
169
|
+
? ` An entry is a tool name (Read; a protocol tool is named ${NAMESPACED_NAME_SHAPES}), a protocol namespace (mcp__<server>), or a rule in its tool's own grammar (Bash(<command>), Edit(<path>), Skill(<name>), WebFetch(domain:<host>)).`
|
|
170
|
+
: "";
|
|
109
171
|
const sentence = why.guidance !== undefined ? ` — ${why.guidance}` : "";
|
|
110
172
|
throw new SessionPolicyError("inert_entry", `session rules ${field} holds ${inertEntryPhrase({ entry, ...why })}, which ${SESSION_RULE_BUCKETS[field] === "deny" ? "refuses" : "admits"} nothing as written${sentence}; nothing was written.${way}`, { field, entry, ...why });
|
|
111
173
|
}
|
|
@@ -115,8 +177,9 @@ export function judgeSessionRulesWrite(prior, rules, opts, mountedToolNames = NO
|
|
|
115
177
|
if (opts?.expectedRev !== undefined && (prior?.rev ?? 0) !== opts.expectedRev) {
|
|
116
178
|
throw new SessionPolicyError("conflict", `session rules rev mismatch (expected ${opts.expectedRev}, have ${prior?.rev ?? 0})`);
|
|
117
179
|
}
|
|
118
|
-
const
|
|
119
|
-
|
|
180
|
+
const read = shapeOrRefuse(rules);
|
|
181
|
+
const clean = canonicalRules(read);
|
|
182
|
+
assertEntriesRead(read, mountedToolNames);
|
|
120
183
|
if (prior !== null && opts?.operator !== true) {
|
|
121
184
|
const stored = readSessionRulesShape(prior);
|
|
122
185
|
if ("fault" in stored) {
|
|
@@ -127,7 +190,7 @@ export function judgeSessionRulesWrite(prior, rules, opts, mountedToolNames = NO
|
|
|
127
190
|
throw new SessionPolicyError("loosen_forbidden", `a non-operator session-rule write may only tighten; refused: ${loosens.join("; ")}`);
|
|
128
191
|
}
|
|
129
192
|
}
|
|
130
|
-
return clean;
|
|
193
|
+
return { ...clean, grammar: SESSION_RULES_GRAMMAR };
|
|
131
194
|
}
|
|
132
195
|
export function loosenReasons(priorValue, nextValue, mountedToolNames = NO_DECLARED_TOOLS) {
|
|
133
196
|
const shapeOf = (side, value) => {
|
|
@@ -139,16 +202,16 @@ export function loosenReasons(priorValue, nextValue, mountedToolNames = NO_DECLA
|
|
|
139
202
|
const prior = shapeOf("prior", priorValue);
|
|
140
203
|
const next = shapeOf("next", nextValue);
|
|
141
204
|
const reasons = [];
|
|
142
|
-
const keptDeny = new Set(effectiveEntries("toolDeny",
|
|
143
|
-
for (const x of effectiveEntries("toolDeny",
|
|
205
|
+
const keptDeny = new Set(effectiveEntries(next, "toolDeny", mountedToolNames));
|
|
206
|
+
for (const x of effectiveEntries(prior, "toolDeny", mountedToolNames))
|
|
144
207
|
if (!keptDeny.has(x))
|
|
145
208
|
reasons.push(`removed toolDeny ${renderListEntry(x)}`);
|
|
146
209
|
if (prior.toolAllow !== undefined) {
|
|
147
210
|
if (next.toolAllow === undefined)
|
|
148
211
|
reasons.push("removed toolAllow allowlist (all allowed)");
|
|
149
212
|
else {
|
|
150
|
-
const had = new Set(effectiveEntries("toolAllow",
|
|
151
|
-
for (const x of effectiveEntries("toolAllow",
|
|
213
|
+
const had = new Set(effectiveEntries(prior, "toolAllow", mountedToolNames));
|
|
214
|
+
for (const x of effectiveEntries(next, "toolAllow", mountedToolNames))
|
|
152
215
|
if (!had.has(x))
|
|
153
216
|
reasons.push(`widened toolAllow with ${renderListEntry(x)}`);
|
|
154
217
|
}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -18,7 +18,8 @@ export type { PermissionMode } from "./ask-origin.js";
|
|
|
18
18
|
export type { ToolEffect, ToolContentOrigin, ReversibilityVerdict, ReadRootGrantCandidate, ToolSpec, ToolReturn, NestedUsage, NestedUsageAccum, ToolExecuteContext } from "./tool-spec.js";
|
|
19
19
|
export type { BeforeWriteRequest, BeforeWriteResult, BeforeWriteHook, TrackEditRequest, TrackEditResult, TrackFileEditHook, FileEditedNotice, FileEditedHook, HandsBandOptions } from "./hands-band.js";
|
|
20
20
|
export type { AgentDefinition, SkillSpec } from "./agent-definition.js";
|
|
21
|
-
export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit, McpRevocationLedger, McpMountIdentity } from "./mcp-server-spec.js";
|
|
21
|
+
export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse, OnElicit, McpRevocationLedger, McpMountIdentity, McpToolAxesRead } from "./mcp-server-spec.js";
|
|
22
|
+
export { readMcpToolAxes } from "./mcp-server-spec.js";
|
|
22
23
|
export type { TaskLimits } from "./task-limits.js";
|
|
23
24
|
export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult, HumanReviewGateRow } from "./task-result.js";
|
|
24
25
|
export type { TerminalCause, PausedCause } from "./terminal-cause.js";
|
package/dist/core/types.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { MODEL_ROLES } from "./model-seat.js";
|
|
2
|
+
export { readMcpToolAxes } from "./mcp-server-spec.js";
|
|
2
3
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
|
|
3
4
|
export { __resetMalformedDelegationSeatAnnouncement, backgroundChildTerminal, deliverDelegationLifecycle, emitsChildRowFrames, taskStartedFrame } from "./delegation-frames.js";
|
|
4
5
|
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, parentLegIds, settleOwedUserInput, undrainedUserInputNotices, USER_INPUT_UNDRAINED_CAUSES, USER_INPUT_UNDRAINED_FAMILIES } from "./engine-notice.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -76,7 +76,7 @@ export { WORKFLOW_SIZE_GUIDELINE_AGENT_CAPS } from "./orchestration/workflow-siz
|
|
|
76
76
|
export { ENGINE_AUTHORITY_ENVELOPE_TAGS } from "./core/untrusted-text.js";
|
|
77
77
|
export { materializeA2aTools, A2aRpcError, type MaterializedA2a, type A2aPeerStatus, type A2aRefreshResult, type A2aToolAxis } from "./core/a2a.js";
|
|
78
78
|
export { PROTOCOL_TABLE, MCP_NAMESPACE, A2A_NAMESPACE, protocolOf, type ProtocolNamespace, type ProtocolId } from "./core/protocol-table.js";
|
|
79
|
-
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, judgeSessionRulesWrite, readSessionRulesShape, type SessionPolicyStoreOptions, type SessionRuleShapeRefusal, type SessionRuleEntryRefusal, type SessionRuleEntryField, type SessionPolicyStore, type SessionPermissionRules, type StoredSessionRules, type SessionRulesRecord, type PutRulesOptions, } from "./core/session-policy-store.js";
|
|
79
|
+
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, judgeSessionRulesWrite, readSessionRulesShape, SESSION_RULES_GRAMMAR, compileSessionRuleBucket, type SessionRulesInGrammar, type SessionPolicyStoreOptions, type SessionRuleShapeRefusal, type SessionRuleEntryRefusal, type SessionRuleEntryField, type SessionPolicyStore, type SessionPermissionRules, type StoredSessionRules, type SessionRulesRecord, type PutRulesOptions, } from "./core/session-policy-store.js";
|
|
80
80
|
export { SAFETY_MERGE_CONFORMANCE_CORPUS, type SafetyMergeVector } from "./core/safety-merge-corpus.js";
|
|
81
81
|
export { SAFETY_AXIS_VOCABULARY } from "./core/safety-axis-vocab.js";
|
|
82
82
|
export { createSessionRulePolicy } from "./core/runner/session-rule-policy.js";
|
|
@@ -348,7 +348,8 @@ export { CONFIG_CATALOG_VERSION, describeConfigCatalog, resolveEffectiveConfig,
|
|
|
348
348
|
export { normalizeAgentName } from "./core/task-registry.js";
|
|
349
349
|
export { DELEGATION_MAX_CONCURRENT_DEFAULT, DELEGATION_MAX_PER_SESSION_DEFAULT, SUBAGENT_TRANSCRIPT_RETENTION_DAYS_DEFAULT, } from "./config/defaults.js";
|
|
350
350
|
export { COORDINATOR_ROLE_PROMPT, TEAMMATE_COMMUNICATION_ADDENDUM } from "./prompts/coordinator.js";
|
|
351
|
-
export
|
|
351
|
+
export type { BuiltinSubagentType } from "./agents/subagent.js";
|
|
352
|
+
export { createSubagentTool, FORK_SUBAGENT_TYPE, BUILTIN_SUBAGENT_TYPES, GENERAL_PURPOSE_SUBAGENT_TYPE, agentWhenToUseText, FORK_DIRECTIVE_FRAME, SUBAGENT_SYSTEM_NOTE, type SubagentToolOptions, resolveDelegationEntryCaps, type ResolvedDelegationEntryCaps, type SubagentSpawnContext, type SubagentSteerHandle, type SubagentStep, type SubagentEditedFile, } from "./agents/subagent.js";
|
|
352
353
|
export { getSessionRetainLedger, releaseSessionRetainLedger, } from "./agents/retain-ledger.js";
|
|
353
354
|
export { createSendMessageTool, createAgentContinuationVerb, SEND_MESSAGE_TOOL_NAME, type SendMessageToolOptions, type AgentContinuationReceipt } from "./agents/send-message-tool.js";
|
|
354
355
|
export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerLaneConfig, PEER_LANE_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, type PeerAdmission, type PeerLaneConfig, type PeerAdmissionOptions, type PeerAdmissionRequest, type PeerAdmissionVerdict, type PeerAdmissionRefusal, type PeerRefusalCode, type PeerAxisTag, type PeerIdentity, type PeerSelfRef, type PeerInboundChainRef, } from "./agents/peer-admission.js";
|
|
@@ -400,3 +401,5 @@ export { RULE_OFFERS_ABSENCES, type RuleOffersAbsence } from "./core/ask-origin.
|
|
|
400
401
|
export { BOUND_GRANT_ABSENCES, type BoundGrantAbsence } from "./core/skill-grant-binding.js";
|
|
401
402
|
export { DISPOSABLE_PROMPT_SECTIONS, type DisposablePromptSection, type PromptSectionEntry, type PromptSectionDisposition, type PromptSectionAuthor, type McpInstructionsEntry } from "./core/prompt-section-seat.js";
|
|
402
403
|
export type { McpRevocationLedger, McpMountIdentity } from "./core/mcp-server-spec.js";
|
|
404
|
+
export { readMcpToolAxes } from "./core/mcp-server-spec.js";
|
|
405
|
+
export type { McpToolAxesRead } from "./core/mcp-server-spec.js";
|
package/dist/index.js
CHANGED
|
@@ -62,7 +62,7 @@ export { WORKFLOW_SIZE_GUIDELINE_AGENT_CAPS } from "./orchestration/workflow-siz
|
|
|
62
62
|
export { ENGINE_AUTHORITY_ENVELOPE_TAGS } from "./core/untrusted-text.js";
|
|
63
63
|
export { materializeA2aTools, A2aRpcError } from "./core/a2a.js";
|
|
64
64
|
export { PROTOCOL_TABLE, MCP_NAMESPACE, A2A_NAMESPACE, protocolOf } from "./core/protocol-table.js";
|
|
65
|
-
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, judgeSessionRulesWrite, readSessionRulesShape, } from "./core/session-policy-store.js";
|
|
65
|
+
export { InMemorySessionPolicyStore, SessionPolicyError, loosenReasons, normalizeRules, judgeSessionRulesWrite, readSessionRulesShape, SESSION_RULES_GRAMMAR, compileSessionRuleBucket, } from "./core/session-policy-store.js";
|
|
66
66
|
export { SAFETY_MERGE_CONFORMANCE_CORPUS } from "./core/safety-merge-corpus.js";
|
|
67
67
|
export { SAFETY_AXIS_VOCABULARY } from "./core/safety-axis-vocab.js";
|
|
68
68
|
export { createSessionRulePolicy } from "./core/runner/session-rule-policy.js";
|
|
@@ -285,7 +285,7 @@ export { CONFIG_CATALOG_VERSION, describeConfigCatalog, resolveEffectiveConfig,
|
|
|
285
285
|
export { normalizeAgentName } from "./core/task-registry.js";
|
|
286
286
|
export { DELEGATION_MAX_CONCURRENT_DEFAULT, DELEGATION_MAX_PER_SESSION_DEFAULT, SUBAGENT_TRANSCRIPT_RETENTION_DAYS_DEFAULT, } from "./config/defaults.js";
|
|
287
287
|
export { COORDINATOR_ROLE_PROMPT, TEAMMATE_COMMUNICATION_ADDENDUM } from "./prompts/coordinator.js";
|
|
288
|
-
export { createSubagentTool, FORK_SUBAGENT_TYPE, GENERAL_PURPOSE_SUBAGENT_TYPE, agentWhenToUseText, FORK_DIRECTIVE_FRAME, SUBAGENT_SYSTEM_NOTE, resolveDelegationEntryCaps, } from "./agents/subagent.js";
|
|
288
|
+
export { createSubagentTool, FORK_SUBAGENT_TYPE, BUILTIN_SUBAGENT_TYPES, GENERAL_PURPOSE_SUBAGENT_TYPE, agentWhenToUseText, FORK_DIRECTIVE_FRAME, SUBAGENT_SYSTEM_NOTE, resolveDelegationEntryCaps, } from "./agents/subagent.js";
|
|
289
289
|
export { getSessionRetainLedger, releaseSessionRetainLedger, } from "./agents/retain-ledger.js";
|
|
290
290
|
export { createSendMessageTool, createAgentContinuationVerb, SEND_MESSAGE_TOOL_NAME } from "./agents/send-message-tool.js";
|
|
291
291
|
export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerLaneConfig, PEER_LANE_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, } from "./agents/peer-admission.js";
|
|
@@ -332,3 +332,4 @@ export { SHADOW_REASON, allowRuleShadowSentence, cardDisclosureOf } from "./core
|
|
|
332
332
|
export { RULE_OFFERS_ABSENCES } from "./core/ask-origin.js";
|
|
333
333
|
export { BOUND_GRANT_ABSENCES } from "./core/skill-grant-binding.js";
|
|
334
334
|
export { DISPOSABLE_PROMPT_SECTIONS } from "./core/prompt-section-seat.js";
|
|
335
|
+
export { readMcpToolAxes } from "./core/mcp-server-spec.js";
|
|
@@ -102,9 +102,9 @@ export declare function judgeSessionPolicyRowObject(raw: string): {
|
|
|
102
102
|
*
|
|
103
103
|
* Required: `rev` >= 1 (a rev-0 row would read as the live reader's SYNTHETIC empty seed); `gen`, when present, a
|
|
104
104
|
* whole number (a STRING `rev` poisons the CAS arithmetic); the rules themselves read by the ONE shape reading
|
|
105
|
-
* (`readSessionRulesShape` — every key a bucket, every bucket a list of strings
|
|
106
|
-
* rules (a key that is no bucket) is refused like any malformed row, never read as fewer rules.
|
|
107
|
-
* metadata is STRIPPED so the value is byte-identical to the in-memory twin's.
|
|
105
|
+
* (`readSessionRulesShape` — every key a bucket, every bucket a list of strings, a `grammar` this engine reads), so a row it
|
|
106
|
+
* cannot read as rules (a key that is no bucket, a later grammar) is refused like any malformed row, never read as fewer rules.
|
|
107
|
+
* The `__sid`/`__principal` metadata is STRIPPED so the value is byte-identical to the in-memory twin's.
|
|
108
108
|
*/
|
|
109
109
|
export declare function judgeSessionPolicyRowShape(row: Record<string, unknown>): {
|
|
110
110
|
rules: StoredSessionRules;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "design/87 L3 — frozen public export surface of src/index.ts (name -> kind). DO NOT edit by hand to silence a red test. A removed/changed entry = a BREAKING change: name every removed entry in the CHANGELOG's BREAKING lines (what was removed / who is hurt / what to read instead) and update this fixture in the SAME commit. Regenerate via REGEN in test/export-surface.test.ts.",
|
|
3
3
|
"_tierComment": "#435 v1 — machine-readable layering of the public surface: stable = demonstrated by README.md / src/examples; internal = an `Internal`-marked name or a runner/engine deep-subtree declaration (the model seam src/engine/llm is excluded — it is the BYOM contract, not an engine internal); advanced = a supported export the front door does not walk you through. THIS IS AN INITIAL HEURISTIC, derived mechanically and expected to be refined ticket by ticket: no human reviewed these 1700+ entries one by one, and nothing here claims otherwise. Known bias: a short or English-word export name (ok, err, Result, Usage) can match ordinary prose in README.md and land `stable` on a coincidence. Every export MUST carry a tier — a new export with no row fails the gate in export-surface.test.ts.",
|
|
4
|
-
"count":
|
|
4
|
+
"count": 2686,
|
|
5
5
|
"exports": {
|
|
6
6
|
"A2ATaskState": "type",
|
|
7
7
|
"A2ATaskStateReversal": "type",
|
|
@@ -199,6 +199,7 @@
|
|
|
199
199
|
"BOUND_GRANT_ABSENCES": "variable",
|
|
200
200
|
"BUILTIN_COMPLIANCE_DENIES": "variable",
|
|
201
201
|
"BUILTIN_READONLY_DENY_TOOLS": "variable",
|
|
202
|
+
"BUILTIN_SUBAGENT_TYPES": "variable",
|
|
202
203
|
"BackgroundAgentQuery": "interface",
|
|
203
204
|
"BackgroundAgentRecord": "interface",
|
|
204
205
|
"BackgroundAgentRowSummary": "interface",
|
|
@@ -236,6 +237,7 @@
|
|
|
236
237
|
"BreakerState": "interface",
|
|
237
238
|
"BudgetAxis": "type",
|
|
238
239
|
"BuildAutoModePromptOptions": "interface",
|
|
240
|
+
"BuiltinSubagentType": "type",
|
|
239
241
|
"BundleChallengeRow": "interface",
|
|
240
242
|
"BundleLineageRow": "interface",
|
|
241
243
|
"BundlePollutedSession": "interface",
|
|
@@ -794,6 +796,7 @@
|
|
|
794
796
|
"McpServerLiveness": "interface",
|
|
795
797
|
"McpServerSpec": "interface",
|
|
796
798
|
"McpServerStatus": "interface",
|
|
799
|
+
"McpToolAxesRead": "type",
|
|
797
800
|
"McpToolFace": "type",
|
|
798
801
|
"MediaDescriptor": "type",
|
|
799
802
|
"MediaStripInfo": "interface",
|
|
@@ -1391,6 +1394,7 @@
|
|
|
1391
1394
|
"SESSION_BOX_PREFIX": "variable",
|
|
1392
1395
|
"SESSION_CAPTURE_OPTOUT_DIR": "variable",
|
|
1393
1396
|
"SESSION_LOG_DIGEST_SCHEME": "variable",
|
|
1397
|
+
"SESSION_RULES_GRAMMAR": "variable",
|
|
1394
1398
|
"SETTLEMENT_IS_REFUSAL": "variable",
|
|
1395
1399
|
"SETTLEMENT_KINDS": "variable",
|
|
1396
1400
|
"SETTLEMENT_PARTIES": "variable",
|
|
@@ -1472,6 +1476,7 @@
|
|
|
1472
1476
|
"SessionRuleEntryRefusal": "interface",
|
|
1473
1477
|
"SessionRulePartition": "interface",
|
|
1474
1478
|
"SessionRuleShapeRefusal": "interface",
|
|
1479
|
+
"SessionRulesInGrammar": "type",
|
|
1475
1480
|
"SessionRulesRecord": "interface",
|
|
1476
1481
|
"SessionStorage": "interface",
|
|
1477
1482
|
"SessionStore": "interface",
|
|
@@ -1959,6 +1964,7 @@
|
|
|
1959
1964
|
"compactableToolNames": "function",
|
|
1960
1965
|
"compileAllowList": "function",
|
|
1961
1966
|
"compileReadDeny": "function",
|
|
1967
|
+
"compileSessionRuleBucket": "function",
|
|
1962
1968
|
"compileWriteDeny": "function",
|
|
1963
1969
|
"compileWriteProtection": "function",
|
|
1964
1970
|
"complianceCallDenial": "function",
|
|
@@ -2437,6 +2443,7 @@
|
|
|
2437
2443
|
"readIntentCredentials": "function",
|
|
2438
2444
|
"readJsonlRecords": "function",
|
|
2439
2445
|
"readMailboxPeerMeta": "function",
|
|
2446
|
+
"readMcpToolAxes": "function",
|
|
2440
2447
|
"readOnlyShellVerdict": "function",
|
|
2441
2448
|
"readPeerSessionRecord": "function",
|
|
2442
2449
|
"readPendingSteerQueue": "function",
|
|
@@ -2880,6 +2887,7 @@
|
|
|
2880
2887
|
"BOUND_GRANT_ABSENCES": "advanced",
|
|
2881
2888
|
"BUILTIN_COMPLIANCE_DENIES": "advanced",
|
|
2882
2889
|
"BUILTIN_READONLY_DENY_TOOLS": "advanced",
|
|
2890
|
+
"BUILTIN_SUBAGENT_TYPES": "advanced",
|
|
2883
2891
|
"BackgroundAgentQuery": "advanced",
|
|
2884
2892
|
"BackgroundAgentRecord": "advanced",
|
|
2885
2893
|
"BackgroundAgentRowSummary": "advanced",
|
|
@@ -2917,6 +2925,7 @@
|
|
|
2917
2925
|
"BreakerState": "stable",
|
|
2918
2926
|
"BudgetAxis": "internal",
|
|
2919
2927
|
"BuildAutoModePromptOptions": "advanced",
|
|
2928
|
+
"BuiltinSubagentType": "advanced",
|
|
2920
2929
|
"BundleChallengeRow": "advanced",
|
|
2921
2930
|
"BundleLineageRow": "advanced",
|
|
2922
2931
|
"BundlePollutedSession": "advanced",
|
|
@@ -3475,6 +3484,7 @@
|
|
|
3475
3484
|
"McpServerLiveness": "advanced",
|
|
3476
3485
|
"McpServerSpec": "advanced",
|
|
3477
3486
|
"McpServerStatus": "advanced",
|
|
3487
|
+
"McpToolAxesRead": "advanced",
|
|
3478
3488
|
"McpToolFace": "internal",
|
|
3479
3489
|
"MediaDescriptor": "advanced",
|
|
3480
3490
|
"MediaStripInfo": "advanced",
|
|
@@ -4072,6 +4082,7 @@
|
|
|
4072
4082
|
"SESSION_BOX_PREFIX": "advanced",
|
|
4073
4083
|
"SESSION_CAPTURE_OPTOUT_DIR": "advanced",
|
|
4074
4084
|
"SESSION_LOG_DIGEST_SCHEME": "internal",
|
|
4085
|
+
"SESSION_RULES_GRAMMAR": "advanced",
|
|
4075
4086
|
"SETTLEMENT_IS_REFUSAL": "advanced",
|
|
4076
4087
|
"SETTLEMENT_KINDS": "advanced",
|
|
4077
4088
|
"SETTLEMENT_PARTIES": "advanced",
|
|
@@ -4153,6 +4164,7 @@
|
|
|
4153
4164
|
"SessionRuleEntryRefusal": "advanced",
|
|
4154
4165
|
"SessionRulePartition": "advanced",
|
|
4155
4166
|
"SessionRuleShapeRefusal": "advanced",
|
|
4167
|
+
"SessionRulesInGrammar": "advanced",
|
|
4156
4168
|
"SessionRulesRecord": "advanced",
|
|
4157
4169
|
"SessionStorage": "internal",
|
|
4158
4170
|
"SessionStore": "advanced",
|
|
@@ -4640,6 +4652,7 @@
|
|
|
4640
4652
|
"compactableToolNames": "advanced",
|
|
4641
4653
|
"compileAllowList": "advanced",
|
|
4642
4654
|
"compileReadDeny": "advanced",
|
|
4655
|
+
"compileSessionRuleBucket": "advanced",
|
|
4643
4656
|
"compileWriteDeny": "advanced",
|
|
4644
4657
|
"compileWriteProtection": "advanced",
|
|
4645
4658
|
"complianceCallDenial": "advanced",
|
|
@@ -5118,6 +5131,7 @@
|
|
|
5118
5131
|
"readIntentCredentials": "advanced",
|
|
5119
5132
|
"readJsonlRecords": "advanced",
|
|
5120
5133
|
"readMailboxPeerMeta": "advanced",
|
|
5134
|
+
"readMcpToolAxes": "advanced",
|
|
5121
5135
|
"readOnlyShellVerdict": "advanced",
|
|
5122
5136
|
"readPeerSessionRecord": "advanced",
|
|
5123
5137
|
"readPendingSteerQueue": "advanced",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"kind": "function",
|
|
54
54
|
"tier": "advanced",
|
|
55
55
|
"at": [
|
|
56
|
-
"src/core/secret-env.ts:
|
|
56
|
+
"src/core/secret-env.ts:278",
|
|
57
57
|
"src/index.ts:515"
|
|
58
58
|
],
|
|
59
59
|
"criteriaCovered": false,
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"kind": "function",
|
|
76
76
|
"tier": "advanced",
|
|
77
77
|
"at": [
|
|
78
|
-
"src/core/secret-env.ts:
|
|
78
|
+
"src/core/secret-env.ts:341",
|
|
79
79
|
"src/index.ts:515"
|
|
80
80
|
],
|
|
81
81
|
"criteriaCovered": false,
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"kind": "function",
|
|
87
87
|
"tier": "advanced",
|
|
88
88
|
"at": [
|
|
89
|
-
"src/core/secret-env.ts:
|
|
89
|
+
"src/core/secret-env.ts:326",
|
|
90
90
|
"src/index.ts:515"
|
|
91
91
|
],
|
|
92
92
|
"criteriaCovered": false,
|
|
@@ -251,9 +251,9 @@
|
|
|
251
251
|
"SecretEnvFindingKind"
|
|
252
252
|
],
|
|
253
253
|
"sdk": [],
|
|
254
|
-
"note": "scanned cli@
|
|
254
|
+
"note": "scanned cli@d742f6fd server@52b73a9c sdk@304339d — a name listed is MENTIONED there today, which is evidence of consumption, not proof of it. Ledger files (**/docs/core-consumption/**, **/docs/wire-consumption/**, **/*LEDGER*.json) are not evidence of use — server: 8 name(s) matched ONLY in bookkeeping files and were set aside (ENGINE_CAPABILITIES, EngineCapability, ProtocolHttpAuth, declareWithheldEnv, headerOwnershipCollision, inheritEnvPolicyProblem, inheritedHostEnv, toolOutputBlockChars)"
|
|
255
255
|
},
|
|
256
256
|
"breakingCount": 0,
|
|
257
257
|
"breakingItems": [],
|
|
258
|
-
"toResolvedAt": "
|
|
258
|
+
"toResolvedAt": "a5c7c33244f7b139e674093f35159037fdfb63da"
|
|
259
259
|
}
|