toolroll 0.9.34 → 0.9.37
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 +102 -0
- package/README.md +7 -0
- package/dist/assignment-adapters.d.ts +12 -48
- package/dist/assignment-adapters.js +33 -43
- package/dist/assignment.d.ts +1 -0
- package/dist/assignment.js +2 -2
- package/dist/browser-workspace.d.ts +3 -3
- package/dist/build-review.d.ts +1 -1
- package/dist/build-review.js +2 -1
- package/dist/builder.js +4 -7
- package/dist/chat-acceptance.d.ts +2 -2
- package/dist/chat-actions.d.ts +18 -12
- package/dist/chat-actions.js +15 -65
- package/dist/chat-ask.js +5 -5
- package/dist/chat-decide.d.ts +14 -1
- package/dist/chat-decide.js +12 -6
- package/dist/chat-delivery-state.d.ts +12 -70
- package/dist/chat-delivery-state.js +17 -135
- package/dist/chat-delivery.js +58 -30
- package/dist/chat-flow.js +8 -6
- package/dist/chat-inbox.js +1 -1
- package/dist/coding-context.d.ts +2 -39
- package/dist/coding-context.js +2 -1
- package/dist/coding-handoff.d.ts +6 -25
- package/dist/coding-handoff.js +11 -5
- package/dist/coding-types.d.ts +2 -26
- package/dist/coding-workspace.d.ts +2 -0
- package/dist/coding-workspace.js +50 -14
- package/dist/contracts/acceptance-terms.d.ts +14 -0
- package/dist/contracts/acceptance-terms.js +16 -0
- package/dist/contracts/chat-actions.d.ts +328 -0
- package/dist/contracts/chat-actions.js +133 -0
- package/dist/contracts/chat-callback-rows.d.ts +59 -0
- package/dist/contracts/chat-callback-rows.js +46 -0
- package/dist/contracts/chat-content.d.ts +276 -0
- package/dist/contracts/chat-content.js +127 -0
- package/dist/contracts/chat-tables.d.ts +6 -0
- package/dist/contracts/chat-tables.js +136 -0
- package/dist/contracts/coding-context.d.ts +97 -0
- package/dist/contracts/coding-context.js +60 -0
- package/dist/contracts/coding-handoff.d.ts +44 -0
- package/dist/contracts/coding-handoff.js +47 -0
- package/dist/contracts/coding-workspace.d.ts +165 -0
- package/dist/contracts/coding-workspace.js +71 -0
- package/dist/contracts/contract.d.ts +40 -7
- package/dist/contracts/contract.js +155 -19
- package/dist/contracts/decision.d.ts +45 -0
- package/dist/contracts/decision.js +45 -0
- package/dist/contracts/discord-callback.d.ts +45 -0
- package/dist/contracts/discord-callback.js +34 -0
- package/dist/contracts/flow-card.d.ts +50 -0
- package/dist/contracts/flow-card.js +46 -0
- package/dist/contracts/flow-propose.d.ts +325 -0
- package/dist/contracts/flow-propose.js +41 -0
- package/dist/contracts/flow-send.d.ts +119 -0
- package/dist/contracts/flow-send.js +112 -0
- package/dist/contracts/flow.d.ts +19405 -0
- package/dist/contracts/flow.js +364 -0
- package/dist/contracts/gateway-tools.d.ts +374 -0
- package/dist/contracts/gateway-tools.js +94 -0
- package/dist/contracts/handoff.d.ts +91 -0
- package/dist/contracts/handoff.js +82 -0
- package/dist/contracts/lead-context.d.ts +165 -0
- package/dist/contracts/lead-context.js +73 -0
- package/dist/contracts/lead-tools.d.ts +1905 -0
- package/dist/contracts/lead-tools.js +265 -0
- package/dist/contracts/memory-pass.d.ts +158 -0
- package/dist/contracts/memory-pass.js +102 -0
- package/dist/contracts/project-knowledge.d.ts +126 -0
- package/dist/contracts/project-knowledge.js +93 -0
- package/dist/contracts/project-memory.d.ts +117 -0
- package/dist/contracts/project-memory.js +51 -0
- package/dist/contracts/project-skills.d.ts +121 -0
- package/dist/contracts/project-skills.js +76 -0
- package/dist/contracts/proof.d.ts +136 -0
- package/dist/contracts/proof.js +110 -0
- package/dist/contracts/review-findings.d.ts +46 -0
- package/dist/contracts/review-findings.js +48 -0
- package/dist/contracts/route.d.ts +484 -0
- package/dist/contracts/route.js +128 -0
- package/dist/contracts/scope.d.ts +105 -0
- package/dist/contracts/scope.js +114 -0
- package/dist/contracts/scout-report.d.ts +234 -0
- package/dist/contracts/scout-report.js +141 -0
- package/dist/contracts/slack-callback.d.ts +43 -0
- package/dist/contracts/slack-callback.js +35 -0
- package/dist/contracts/sort-answer.d.ts +83 -0
- package/dist/contracts/sort-answer.js +77 -0
- package/dist/contracts/stage-output.d.ts +127 -0
- package/dist/contracts/stage-output.js +166 -0
- package/dist/contracts/task-sizing.d.ts +24 -0
- package/dist/contracts/task-sizing.js +28 -0
- package/dist/contracts/teammate-turn.d.ts +43 -0
- package/dist/contracts/teammate-turn.js +51 -0
- package/dist/contracts/teams-callback.d.ts +14 -0
- package/dist/contracts/teams-callback.js +14 -0
- package/dist/contracts/telegram-callback.d.ts +120 -0
- package/dist/contracts/telegram-callback.js +97 -0
- package/dist/contracts/verification-receipt.d.ts +148 -0
- package/dist/contracts/verification-receipt.js +87 -0
- package/dist/decision.d.ts +11 -20
- package/dist/decision.js +86 -167
- package/dist/demo.js +28 -11
- package/dist/discord-chat.js +31 -20
- package/dist/evidence.d.ts +3 -40
- package/dist/evidence.js +5 -1
- package/dist/flow-engine.js +14 -17
- package/dist/flow-gallery.d.ts +3 -2
- package/dist/flow-items.d.ts +4 -13
- package/dist/flow-items.js +1 -15
- package/dist/flow-send.d.ts +6 -37
- package/dist/flow-send.js +18 -14
- package/dist/flow-share.d.ts +10 -32
- package/dist/flow-share.js +72 -84
- package/dist/flow-sort.d.ts +7 -26
- package/dist/flow-sort.js +25 -20
- package/dist/flow-starters.d.ts +2 -1
- package/dist/flow-steps.js +3 -2
- package/dist/flow-triggers.d.ts +15 -72
- package/dist/flow-triggers.js +94 -83
- package/dist/flows.d.ts +37 -220
- package/dist/flows.js +356 -387
- package/dist/invoke.js +4 -4
- package/dist/lead-context.d.ts +4 -2
- package/dist/lead-context.js +24 -17
- package/dist/mate-tools.d.ts +4 -0
- package/dist/mate-tools.js +111 -308
- package/dist/mcp-connect.d.ts +27 -4
- package/dist/mcp-connect.js +92 -17
- package/dist/mcp.js +84 -216
- package/dist/memory-pass.d.ts +17 -42
- package/dist/memory-pass.js +54 -26
- package/dist/operate.js +31 -2
- package/dist/phase-routing.d.ts +19 -72
- package/dist/phase-routing.js +34 -164
- package/dist/plan.d.ts +5 -5
- package/dist/plan.js +5 -25
- package/dist/process-recovery-eligibility.d.ts +2 -2
- package/dist/process-recovery-eligibility.js +13 -8
- package/dist/project-knowledge.d.ts +16 -35
- package/dist/project-knowledge.js +42 -21
- package/dist/project-memory.d.ts +2 -28
- package/dist/project-memory.js +28 -13
- package/dist/project-skills.d.ts +16 -38
- package/dist/project-skills.js +41 -32
- package/dist/project-tools.d.ts +1 -0
- package/dist/project-tools.js +4 -4
- package/dist/proof.d.ts +15 -91
- package/dist/proof.js +90 -249
- package/dist/provider.d.ts +2 -0
- package/dist/provider.js +4 -16
- package/dist/result-evidence-readers.d.ts +42 -0
- package/dist/result-evidence-readers.js +91 -0
- package/dist/result-shots.d.ts +1 -1
- package/dist/result-shots.js +2 -1
- package/dist/review-switch.d.ts +3 -8
- package/dist/reviewer.d.ts +8 -12
- package/dist/reviewer.js +11 -35
- package/dist/scope.d.ts +21 -43
- package/dist/scope.js +42 -128
- package/dist/scout-report.d.ts +9 -194
- package/dist/scout-report.js +113 -264
- package/dist/scout.js +15 -11
- package/dist/serve.js +17 -101
- package/dist/slack-chat.js +26 -20
- package/dist/slack-state.js +2 -1
- package/dist/store.d.ts +9 -32
- package/dist/store.js +18 -15
- package/dist/structured-output.js +2 -1
- package/dist/subscription-chat.d.ts +4 -0
- package/dist/subscription-chat.js +4 -1
- package/dist/surface.js +8 -1
- package/dist/task-review-brief.d.ts +69 -0
- package/dist/task-review-brief.js +179 -0
- package/dist/task-sizing.d.ts +3 -27
- package/dist/task-sizing.js +11 -26
- package/dist/task-text.d.ts +0 -5
- package/dist/task-text.js +1 -3
- package/dist/teammate-question.js +7 -5
- package/dist/teammate-work.js +9 -5
- package/dist/teammates.d.ts +13 -64
- package/dist/teammates.js +32 -33
- package/dist/teams-chat.js +20 -11
- package/dist/telegram-flow.js +4 -3
- package/dist/telegram-mate.d.ts +4 -14
- package/dist/telegram-mate.js +8 -7
- package/dist/telegram-team.d.ts +2 -19
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +52 -42
- package/dist/text-limits.d.ts +212 -1
- package/dist/text-limits.js +214 -1
- package/dist/tools-ui.d.ts +2 -1
- package/dist/tools-ui.js +7 -4
- package/dist/verification-evidence.js +24 -12
- package/package.json +1 -1
package/dist/project-skills.js
CHANGED
|
@@ -6,6 +6,10 @@ import { parseDocument } from "yaml";
|
|
|
6
6
|
import { acceptedIdentities, learningIdentity, learningSha } from "./project-learning.js";
|
|
7
7
|
import { scanForSecrets } from "./evidence.js";
|
|
8
8
|
import { fileTaskProposal } from "./proposal.js";
|
|
9
|
+
import { TEXT_LIMITS } from "./text-limits.js";
|
|
10
|
+
import { contractError } from "./contracts/contract.js";
|
|
11
|
+
import { SKILL_COUNTS, SKILL_LIMITS, readSkillsSnapshotPayload, savedSkillPackageSchema, savedSkillsSnapshotSchema, skillPackageSchema, skillSelectionSchema, } from "./contracts/project-skills.js";
|
|
12
|
+
export { SKILL_LIMITS };
|
|
9
13
|
export const SKILLS_SCHEMA = `
|
|
10
14
|
CREATE TABLE IF NOT EXISTS skill_package (sha TEXT PRIMARY KEY, payload TEXT NOT NULL);
|
|
11
15
|
CREATE TABLE IF NOT EXISTS skill_owner (sha TEXT NOT NULL REFERENCES skill_package(sha), actor TEXT NOT NULL, at TEXT NOT NULL, PRIMARY KEY(sha,actor));
|
|
@@ -14,14 +18,6 @@ CREATE TABLE IF NOT EXISTS skill_snapshot (run INTEGER PRIMARY KEY REFERENCES ru
|
|
|
14
18
|
CREATE TABLE IF NOT EXISTS skill_test (task_ref INTEGER PRIMARY KEY REFERENCES task_ref(id), package TEXT NOT NULL REFERENCES skill_package(sha), actor TEXT NOT NULL, request_sha TEXT NOT NULL, sample TEXT NOT NULL, source_run INTEGER REFERENCES run(id), feedback TEXT, identity TEXT NOT NULL);
|
|
15
19
|
${["skill_package", "skill_owner", "project_skill_change", "skill_snapshot", "skill_test"].map((t) => `CREATE TRIGGER IF NOT EXISTS ${t}_no_update BEFORE UPDATE ON ${t} BEGIN SELECT RAISE(ABORT,'Skill history is immutable'); END; CREATE TRIGGER IF NOT EXISTS ${t}_no_delete BEFORE DELETE ON ${t} BEGIN SELECT RAISE(ABORT,'Skill history is immutable'); END;`).join("\n")}
|
|
16
20
|
`;
|
|
17
|
-
export const SKILL_LIMITS = {
|
|
18
|
-
files: 64,
|
|
19
|
-
packageBytes: 1024 * 1024,
|
|
20
|
-
fileBytes: 256 * 1024,
|
|
21
|
-
bodyBytes: 24 * 1024,
|
|
22
|
-
enabled: 8,
|
|
23
|
-
selectionBytes: 2 * 1024 * 1024,
|
|
24
|
-
};
|
|
25
21
|
const controls = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f\u200b-\u200f\u202a-\u202e\u2066-\u2069\ufffd]/u;
|
|
26
22
|
const text = (value, max, label) => {
|
|
27
23
|
if (typeof value !== "string" ||
|
|
@@ -44,7 +40,7 @@ export function validateSkill(files, source) {
|
|
|
44
40
|
.map((file) => {
|
|
45
41
|
if (!file ||
|
|
46
42
|
typeof file.path !== "string" ||
|
|
47
|
-
file.path.length >
|
|
43
|
+
file.path.length > TEXT_LIMITS.skillPath ||
|
|
48
44
|
!/^[a-zA-Z0-9_. -]+(?:\/[a-zA-Z0-9_. -]+)*$/.test(file.path) ||
|
|
49
45
|
file.path
|
|
50
46
|
.split("/")
|
|
@@ -91,13 +87,13 @@ export function validateSkill(files, source) {
|
|
|
91
87
|
}
|
|
92
88
|
if (!front || typeof front !== "object" || Array.isArray(front))
|
|
93
89
|
throw Error("Skill metadata must contain a name and description.");
|
|
94
|
-
const name = text(front["name"],
|
|
90
|
+
const name = text(front["name"], TEXT_LIMITS.skillNameBytes, "Skill name");
|
|
95
91
|
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name))
|
|
96
92
|
throw Error("Use a lowercase skill name with hyphens between words.");
|
|
97
|
-
const description = text(front["description"],
|
|
93
|
+
const description = text(front["description"], TEXT_LIMITS.skillDescriptionBytes, "Description");
|
|
98
94
|
const requirements = front["compatibility"] === undefined
|
|
99
95
|
? ""
|
|
100
|
-
: text(front["compatibility"],
|
|
96
|
+
: text(front["compatibility"], TEXT_LIMITS.skillRequirementsBytes, "Requirements");
|
|
101
97
|
const extensions = Object.keys(front).filter((k) => !["name", "description", "license", "compatibility", "metadata"].includes(k));
|
|
102
98
|
const warnings = [];
|
|
103
99
|
if (extensions.length || safe.some((f) => f.path === "agents/openai.yaml"))
|
|
@@ -106,14 +102,21 @@ export function validateSkill(files, source) {
|
|
|
106
102
|
warnings.push("Dynamic shell substitutions are not evaluated by the skill manager.");
|
|
107
103
|
if (safe.some((f) => f.path.startsWith("scripts/")))
|
|
108
104
|
warnings.push("Includes scripts. Agents may run them only within their task permissions.");
|
|
109
|
-
return {
|
|
105
|
+
return written(skillPackageSchema, {
|
|
110
106
|
name,
|
|
111
107
|
description,
|
|
112
|
-
source: text(source,
|
|
108
|
+
source: text(source, TEXT_LIMITS.skillSourceBytes, "Source"),
|
|
113
109
|
requirements,
|
|
114
110
|
warnings,
|
|
115
111
|
files: safe,
|
|
116
|
-
};
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/** A payload through its schema before it is written; a refusal names the field. */
|
|
115
|
+
function written(schema, value) {
|
|
116
|
+
const read = schema.safeParse(value, { reportInput: true });
|
|
117
|
+
if (!read.success)
|
|
118
|
+
throw Error(`This skill could not be saved: ${contractError(read.error).join("; ")}`);
|
|
119
|
+
return read.data;
|
|
117
120
|
}
|
|
118
121
|
function admit(store, repo, actor, write = false) {
|
|
119
122
|
if (!store.schemaCurrent() ||
|
|
@@ -125,18 +128,24 @@ function admit(store, repo, actor, write = false) {
|
|
|
125
128
|
/** Revisions under any identity this project accepts, as a bound JSON list. */
|
|
126
129
|
const IN_ACCEPTED = "identity IN (SELECT value FROM json_each(?))";
|
|
127
130
|
const listOf = (accepted) => JSON.stringify([...accepted]);
|
|
128
|
-
|
|
131
|
+
/** Saved bytes are checked against their digest first; only then are they parsed through their schema. */
|
|
132
|
+
function unpack(payload, sha, read) {
|
|
129
133
|
if (typeof payload !== "string" || learningSha(payload) !== sha)
|
|
130
134
|
throw Error("Saved skills could not be verified.");
|
|
131
|
-
|
|
135
|
+
const value = read(JSON.parse(payload));
|
|
136
|
+
if (value === null)
|
|
137
|
+
throw Error("Saved skills could not be verified.");
|
|
138
|
+
return value;
|
|
132
139
|
}
|
|
140
|
+
const through = (schema) => (input) => { const read = schema.safeParse(input); return read.success ? read.data : null; };
|
|
141
|
+
const unpackSelection = (payload, sha) => unpack(payload, sha, through(skillSelectionSchema));
|
|
133
142
|
function packageOf(store, sha) {
|
|
134
143
|
const row = store.handle
|
|
135
144
|
.prepare("SELECT payload FROM skill_package WHERE sha=?")
|
|
136
145
|
.get(sha);
|
|
137
146
|
if (!row)
|
|
138
147
|
throw Error("That skill version is unavailable.");
|
|
139
|
-
return { ...unpack(row["payload"], sha), sha };
|
|
148
|
+
return { ...unpack(row["payload"], sha, through(savedSkillPackageSchema)), sha };
|
|
140
149
|
}
|
|
141
150
|
function current(store, repo, accepted) {
|
|
142
151
|
const row = store.handle
|
|
@@ -148,7 +157,7 @@ function current(store, repo, accepted) {
|
|
|
148
157
|
throw Error("The project changed. Its previous skills have not been applied.");
|
|
149
158
|
return {
|
|
150
159
|
revision: Number(row["revision"]),
|
|
151
|
-
selection:
|
|
160
|
+
selection: unpackSelection(row["payload"], row["sha"]),
|
|
152
161
|
};
|
|
153
162
|
}
|
|
154
163
|
export function skillsView(store, repo, actor) {
|
|
@@ -173,7 +182,7 @@ export function skillsView(store, repo, actor) {
|
|
|
173
182
|
}
|
|
174
183
|
}
|
|
175
184
|
if (row)
|
|
176
|
-
for (const c of Object.values(
|
|
185
|
+
for (const c of Object.values(unpackSelection(row["payload"], row["sha"])))
|
|
177
186
|
visible.add(c.sha);
|
|
178
187
|
}
|
|
179
188
|
for (const c of Object.values(value.selection))
|
|
@@ -192,7 +201,7 @@ export function skillsView(store, repo, actor) {
|
|
|
192
201
|
revision: Number(r["revision"]),
|
|
193
202
|
actor: String(r["actor"]),
|
|
194
203
|
at: String(r["at"]),
|
|
195
|
-
enabled: Object.entries(
|
|
204
|
+
enabled: Object.entries(unpackSelection(r["payload"], r["sha"]))
|
|
196
205
|
.filter(([, c]) => c.enabled)
|
|
197
206
|
.map(([name, c]) => ({ name, version: c.sha.slice(0, 10) })),
|
|
198
207
|
}));
|
|
@@ -215,7 +224,7 @@ export function skillsVersion(store, repo, actor, revision) {
|
|
|
215
224
|
const row = store.handle.prepare(`SELECT payload,sha FROM project_skill_change WHERE repo=? AND ${IN_ACCEPTED} AND revision=?`).get(repo, listOf(accepted), revision);
|
|
216
225
|
if (!row)
|
|
217
226
|
throw Error("That skills version is unavailable.");
|
|
218
|
-
const selection =
|
|
227
|
+
const selection = unpackSelection(row["payload"], row["sha"]);
|
|
219
228
|
for (const choice of Object.values(selection))
|
|
220
229
|
packageOf(store, choice.sha);
|
|
221
230
|
return selection;
|
|
@@ -229,7 +238,7 @@ export function importSkill(store, repo, actor, files, source, now = new Date())
|
|
|
229
238
|
.get(sha, actor) &&
|
|
230
239
|
Number(store.handle
|
|
231
240
|
.prepare("SELECT COUNT(*) AS n FROM skill_owner WHERE actor=?")
|
|
232
|
-
.get(actor)?.["n"]) >=
|
|
241
|
+
.get(actor)?.["n"]) >= SKILL_COUNTS.library)
|
|
233
242
|
throw Error("Your library has 100 saved versions. Reuse an existing version.");
|
|
234
243
|
store.handle
|
|
235
244
|
.prepare("INSERT OR IGNORE INTO skill_package VALUES (?,?)")
|
|
@@ -255,7 +264,7 @@ export function changeSkills(store, args, now = new Date()) {
|
|
|
255
264
|
.get(args.repo, listOf(accepted), args.restore ?? -1);
|
|
256
265
|
if (!row)
|
|
257
266
|
throw Error("That version is unavailable.");
|
|
258
|
-
selection =
|
|
267
|
+
selection = unpackSelection(row["payload"], row["sha"]);
|
|
259
268
|
}
|
|
260
269
|
else {
|
|
261
270
|
const skill = view.library.find((p) => p.sha === args.sha);
|
|
@@ -274,7 +283,7 @@ export function changeSkills(store, args, now = new Date()) {
|
|
|
274
283
|
if (enabled.length > SKILL_LIMITS.enabled ||
|
|
275
284
|
Buffer.byteLength(JSON.stringify(enabled)) > SKILL_LIMITS.selectionBytes)
|
|
276
285
|
throw Error("Enable up to 8 skills, totaling at most 2 MB.");
|
|
277
|
-
const payload = JSON.stringify(selection);
|
|
286
|
+
const payload = JSON.stringify(written(skillSelectionSchema, selection));
|
|
278
287
|
store.handle
|
|
279
288
|
.prepare("INSERT INTO project_skill_change VALUES (?,?,?,?,?,?,?)")
|
|
280
289
|
.run(args.repo, identity, view.revision + 1, args.actor, now.toISOString(), payload, learningSha(payload));
|
|
@@ -316,7 +325,7 @@ export function readSkillsSnapshot(store, runId) {
|
|
|
316
325
|
const run = store.getRun(runId);
|
|
317
326
|
if (!run || store.refForId(run.taskRef)?.repo !== row["repo"])
|
|
318
327
|
throw Error("Saved skills belong to another project.");
|
|
319
|
-
const saved = unpack(row["payload"], row["sha"]);
|
|
328
|
+
const saved = unpack(row["payload"], row["sha"], (input) => { const read = readSkillsSnapshotPayload(input); return read.ok ? read.value : null; });
|
|
320
329
|
const { packageShas, ...facts } = saved;
|
|
321
330
|
if (packageShas.length &&
|
|
322
331
|
!acceptedIdentities(store, String(row["repo"])).has(facts.identity))
|
|
@@ -401,10 +410,10 @@ export function freezeSkills(store, runId) {
|
|
|
401
410
|
}
|
|
402
411
|
}
|
|
403
412
|
const { packages, ...facts } = snapshot;
|
|
404
|
-
const payload = JSON.stringify({
|
|
413
|
+
const payload = JSON.stringify(written(savedSkillsSnapshotSchema, {
|
|
405
414
|
...facts,
|
|
406
415
|
packageShas: packages.map((p) => p.sha),
|
|
407
|
-
});
|
|
416
|
+
}));
|
|
408
417
|
store.handle
|
|
409
418
|
.prepare("INSERT INTO skill_snapshot VALUES (?,?,?,?)")
|
|
410
419
|
.run(runId, ref.repo, payload, learningSha(payload));
|
|
@@ -474,11 +483,11 @@ export function testSkill(store, args, now = new Date()) {
|
|
|
474
483
|
const skill = view.library.find((p) => p.sha === args.sha);
|
|
475
484
|
if (!skill)
|
|
476
485
|
throw Error("Choose an available skill.");
|
|
477
|
-
const sample = text(args.sample,
|
|
478
|
-
if (sample.length >
|
|
486
|
+
const sample = text(args.sample, TEXT_LIMITS.skillSampleBytes, "Sample request");
|
|
487
|
+
if (sample.length > TEXT_LIMITS.skillSample)
|
|
479
488
|
throw Error("Keep the sample request to 800 characters.");
|
|
480
|
-
const feedback = args.feedback === undefined ? null : text(args.feedback,
|
|
481
|
-
if (feedback && feedback.length >
|
|
489
|
+
const feedback = args.feedback === undefined ? null : text(args.feedback, TEXT_LIMITS.skillFeedbackBytes, "Feedback");
|
|
490
|
+
if (feedback && feedback.length > TEXT_LIMITS.skillFeedback)
|
|
482
491
|
throw Error("Keep feedback to 500 characters.");
|
|
483
492
|
if (args.sourceRun !== undefined) {
|
|
484
493
|
const source = skillTestResult(store, args.sourceRun, args.actor);
|
package/dist/project-tools.d.ts
CHANGED
|
@@ -201,6 +201,7 @@ export declare function prepareRunTools(store: Pick<Store, "projectTools" | "get
|
|
|
201
201
|
now: Date;
|
|
202
202
|
includeModel: boolean;
|
|
203
203
|
readOnly?: Readonly<Record<string, readonly string[]>>;
|
|
204
|
+
withheld?: Readonly<Record<string, string>>;
|
|
204
205
|
}): ToolLaunchArgs;
|
|
205
206
|
/** When a launch's tools cannot be prepared, it still gets none of anything else's: the same isolation with an empty list. */
|
|
206
207
|
export declare function noToolsArgs(provider: "claude" | "codex" | "openrouter" | "gemini", includeModel: boolean): ToolLaunchArgs;
|
package/dist/project-tools.js
CHANGED
|
@@ -694,7 +694,7 @@ export function toolLaunchFor(store, runId, home = homedir()) {
|
|
|
694
694
|
* with `argv`/`env` and calls `cleanup` when the process is done.
|
|
695
695
|
*/
|
|
696
696
|
export function prepareRunTools(store, runId, provider, options) {
|
|
697
|
-
const launch = limitedTo(toolLaunchFor(store, runId, options.home), options.readOnly);
|
|
697
|
+
const launch = limitedTo(toolLaunchFor(store, runId, options.home), options.readOnly, options.withheld);
|
|
698
698
|
const enabledTools = options.readOnly === undefined ? {} : { enabledTools: options.readOnly };
|
|
699
699
|
const prepared = provider === "claude" ? claudeToolArgs(launch)
|
|
700
700
|
: provider === "codex" ? codexToolArgs(launch, { includeModel: options.includeModel, ...enabledTools })
|
|
@@ -710,14 +710,14 @@ export function prepareRunTools(store, runId, provider, options) {
|
|
|
710
710
|
}), options.now);
|
|
711
711
|
return prepared;
|
|
712
712
|
}
|
|
713
|
-
/** A research step's launch: only the servers it may read, each limited to its read-only actions; the rest left out, saying why. */
|
|
714
|
-
function limitedTo(launch, readOnly) {
|
|
713
|
+
/** A research step's launch: only the servers it may read, each limited to its read-only actions; the rest left out, saying why (`withheld`, when a service has its own reason). */
|
|
714
|
+
function limitedTo(launch, readOnly, withheld = {}) {
|
|
715
715
|
if (readOnly === undefined)
|
|
716
716
|
return launch;
|
|
717
717
|
const readable = (name) => (readOnly[name] ?? []).length > 0;
|
|
718
718
|
return {
|
|
719
719
|
tools: launch.tools.filter(one => readable(one.spec.name)),
|
|
720
|
-
skipped: [...launch.skipped, ...launch.tools.filter(one => !readable(one.spec.name)).map(one => ({ name: one.spec.name, reason: "research reads only connected services' read-only actions" }))],
|
|
720
|
+
skipped: [...launch.skipped, ...launch.tools.filter(one => !readable(one.spec.name)).map(one => ({ name: one.spec.name, reason: withheld[one.spec.name] ?? "research reads only connected services' read-only actions" }))],
|
|
721
721
|
};
|
|
722
722
|
}
|
|
723
723
|
/** When a launch's tools cannot be prepared, it still gets none of anything else's: the same isolation with an empty list. */
|
package/dist/proof.d.ts
CHANGED
|
@@ -18,31 +18,12 @@
|
|
|
18
18
|
* returned — is gathered by the caller (`builder.ts`) and handed in as data,
|
|
19
19
|
* so the review itself stays testable without a filesystem or a database.
|
|
20
20
|
*/
|
|
21
|
-
import {
|
|
21
|
+
import type { EvidenceKind } from "./scope.js";
|
|
22
|
+
import { type ContractProblem } from "./contracts/contract.js";
|
|
23
|
+
import type { VerifyCommandFacts } from "./contracts/verification-receipt.js";
|
|
24
|
+
import { type CriterionEvidenceRef, type ParsedProof } from "./contracts/proof.js";
|
|
25
|
+
export { PROOF_LIMITS, type CriterionEvidenceRef, type ParsedCheck, type ParsedCriterion, type ParsedProof, type ParsedScreenshot } from "./contracts/proof.js";
|
|
22
26
|
export type ProofVerdict = "verified" | "attested" | "short" | "refuted";
|
|
23
|
-
/** One typed reference the proof cites to answer a criterion's required
|
|
24
|
-
* evidence: `ref` names an existing check's command, an existing
|
|
25
|
-
* screenshot's path, a path inside `changed`, or (kind `manual-review`)
|
|
26
|
-
* free-text pointing at nothing machine-checkable. Additive (v39): a
|
|
27
|
-
* criterion with no `evidence` array parses the same as one that always
|
|
28
|
-
* had none — legacy proofs, and every proof against a rubric-less scope,
|
|
29
|
-
* are untouched. */
|
|
30
|
-
export type CriterionEvidenceRef = {
|
|
31
|
-
kind: EvidenceKind;
|
|
32
|
-
ref: string;
|
|
33
|
-
};
|
|
34
|
-
export type ParsedCriterion = {
|
|
35
|
-
id: string;
|
|
36
|
-
statement: string;
|
|
37
|
-
/** pending-verification asserts all agent-owned work is met; only the
|
|
38
|
-
* machine-owned final check remains. It never upgrades a legacy failure. */
|
|
39
|
-
verdict: "met" | "not-met" | "not-checked" | "pending-verification";
|
|
40
|
-
how: string;
|
|
41
|
-
/** v39: typed references answering a SIGNED criterion by exact id.
|
|
42
|
-
* `[]` for a criterion the agent added beyond the rubric, or for any
|
|
43
|
-
* proof written before this migration. */
|
|
44
|
-
evidence: CriterionEvidenceRef[];
|
|
45
|
-
};
|
|
46
27
|
/** v39: the rubric side of a criterion, as `adjudicate` reads it — the
|
|
47
28
|
* SIGNED id, statement, and required evidence kinds. Never `how` (never
|
|
48
29
|
* signed). Empty = nothing signed: `adjudicate` runs the v1 rules,
|
|
@@ -54,31 +35,7 @@ export type ApprovedCriterion = {
|
|
|
54
35
|
};
|
|
55
36
|
/** Only submission defects. A truthful not-met answer is not malformed. */
|
|
56
37
|
export declare function proofSubmissionProblems(proof: ParsedProof, rubric: readonly ApprovedCriterion[]): string[];
|
|
57
|
-
export type
|
|
58
|
-
command: string;
|
|
59
|
-
exitCode: number;
|
|
60
|
-
summary: string;
|
|
61
|
-
};
|
|
62
|
-
/** A screenshot the agent claims proves UI-facing work. `path` is the
|
|
63
|
-
* repository-relative path the file lived at in the worktree when the
|
|
64
|
-
* agent wrote the proof — validated as a path shape here; validated as an
|
|
65
|
-
* actual bounded PNG/JPEG, and read, by the caller. */
|
|
66
|
-
export type ParsedScreenshot = {
|
|
67
|
-
path: string;
|
|
68
|
-
caption: string;
|
|
69
|
-
};
|
|
70
|
-
export type ParsedProof = {
|
|
71
|
-
version: 1;
|
|
72
|
-
criteria: ParsedCriterion[];
|
|
73
|
-
checks: ParsedCheck[];
|
|
74
|
-
changed: string[];
|
|
75
|
-
caveats: string[];
|
|
76
|
-
screenshots: ParsedScreenshot[];
|
|
77
|
-
};
|
|
78
|
-
export type ProofProblem = {
|
|
79
|
-
reason: string;
|
|
80
|
-
message: string;
|
|
81
|
-
};
|
|
38
|
+
export type ProofProblem = ContractProblem;
|
|
82
39
|
export type ProofParseResult = {
|
|
83
40
|
ok: true;
|
|
84
41
|
proof: ParsedProof;
|
|
@@ -86,31 +43,14 @@ export type ProofParseResult = {
|
|
|
86
43
|
ok: false;
|
|
87
44
|
problems: ProofProblem[];
|
|
88
45
|
};
|
|
89
|
-
/**
|
|
90
|
-
* the
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
readonly criterionId: 40;
|
|
95
|
-
readonly criterionStatement: 300;
|
|
96
|
-
readonly criterionHow: 500;
|
|
97
|
-
readonly evidencePerCriterion: 4;
|
|
98
|
-
readonly evidenceRef: 300;
|
|
99
|
-
readonly checks: 12;
|
|
100
|
-
readonly checkCommand: 300;
|
|
101
|
-
readonly checkSummary: 300;
|
|
102
|
-
readonly changed: 64;
|
|
103
|
-
readonly changedPath: 300;
|
|
104
|
-
readonly caveats: 8;
|
|
105
|
-
readonly caveat: 300;
|
|
106
|
-
readonly screenshots: 8;
|
|
107
|
-
readonly screenshotPath: 300;
|
|
108
|
-
readonly screenshotCaption: 300;
|
|
109
|
-
};
|
|
46
|
+
/**
|
|
47
|
+
* Read a proof: the payload byte cap and JSON first, then the proof schema (version 2 as itself, the version 1 a
|
|
48
|
+
* builder writes upgraded, a newer one refused plainly), then the plain-code rules. Every problem names its path and
|
|
49
|
+
* is reported at once; fail closed.
|
|
50
|
+
*/
|
|
110
51
|
export declare function parseProof(raw: string): ProofParseResult;
|
|
111
|
-
/**
|
|
112
|
-
*
|
|
113
|
-
* is exactly what this parser admitted, key order and all. */
|
|
52
|
+
/** Serialize the validated shape, never the agent's raw bytes (the scout report's rule, `scout.ts`): what is stored
|
|
53
|
+
* and later hash-verified is exactly what the schema admitted, in its key order. */
|
|
114
54
|
export declare function serializeProof(proof: ParsedProof): string;
|
|
115
55
|
/** One caveat that admits an exception to a criterion the same proof marks
|
|
116
56
|
* `met` — the proof's own verdict disagreeing with its own words (atomic
|
|
@@ -255,24 +195,8 @@ export declare function frozenCriterionProblems(submitted: ParsedProof, correcte
|
|
|
255
195
|
* correction and re-reads it after that correction and after the final
|
|
256
196
|
* gate; a reading that differs is never adjudicated from the cached one. */
|
|
257
197
|
export declare function sameDiffStatFacts(a: DiffStatFacts | null, b: DiffStatFacts | null): boolean;
|
|
258
|
-
/**
|
|
259
|
-
|
|
260
|
-
* configured" and "configured but the run could not attempt it" — the
|
|
261
|
-
* latter is distinguished by `attemptFailed`, which downgrades to `short`
|
|
262
|
-
* rather than `refuted`: "we could not check" is not "the claim is false". */
|
|
263
|
-
export type VerifyCommandFacts = {
|
|
264
|
-
configured: false;
|
|
265
|
-
} | {
|
|
266
|
-
configured: true;
|
|
267
|
-
ran: false;
|
|
268
|
-
attemptFailed: true;
|
|
269
|
-
failure?: "spawn-failed" | "timed-out" | "dependency-missing" | "setup-stale" | "setup-failed" | "own-install-failed" | "tracked-files-changed" | "setup-changed-files" | "checkout-moved" | "cleanliness-unavailable" | "dependency-still-missing" | "retry-spawn-failed" | "retry-timed-out" | "custody-lost";
|
|
270
|
-
} | {
|
|
271
|
-
configured: true;
|
|
272
|
-
ran: true;
|
|
273
|
-
exitCode: number;
|
|
274
|
-
setupReplayed?: true;
|
|
275
|
-
};
|
|
198
|
+
/** What the approved verification command did (the receipt's `result`); its schema lives with the receipt. */
|
|
199
|
+
export type { VerifyCommandFacts } from "./contracts/verification-receipt.js";
|
|
276
200
|
export type AdjudicateInput = {
|
|
277
201
|
/** New captures may assess the signed goal directly when the builder wrote
|
|
278
202
|
* no optional proof. Historical calls retain their original contract. */
|