paperlint 11.1.2 → 11.1.3
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/cli.d.ts +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/submission-confirm-hook.d.ts +27 -19
- package/dist/submission-confirm-hook.d.ts.map +1 -1
- package/dist/submission-confirm-hook.js +302 -95
- package/dist/submission-confirm-hook.js.map +1 -1
- package/docs/layout.md +22 -22
- package/docs/submission.md +32 -8
- package/package.json +1 -1
- package/skills/submission-portal/SKILL.md +18 -12
- package/skills/submission-portal/SKILL.md.spec.ts +17 -11
- package/src/cli.test.ts +3 -3
- package/src/cli.ts +2 -2
- package/src/submission-confirm-hook.test.ts +493 -60
- package/src/submission-confirm-hook.ts +448 -116
|
@@ -1,59 +1,77 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `submission-confirm` hook — no send to a venue's portal without the person's own yes.
|
|
2
|
+
* The `submission-confirm` hook — no send to a venue's portal without the person's own yes to it.
|
|
3
3
|
* PreToolUse on `Bash` (`plugin/hooks/hooks.json`): a command that sends a submission — `paperlint
|
|
4
|
-
* submission new|update` with `--save` or `--submit
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
4
|
+
* submission new|update` with `--save` or `--submit` — runs only when the person has said yes, in an
|
|
5
|
+
* `AskUserQuestion` asked since the last send, to a question naming the paper folder (its full path)
|
|
6
|
+
* and the sha256 of the PDF it sends.
|
|
7
|
+
* A command that names a portal's host runs only after a yes to a question naming that host and the
|
|
8
|
+
* command's first 60 characters. Without the yes the command is refused (`"permissionDecision":
|
|
9
|
+
* "deny"`), and the reason tells the agent exactly what to ask. Anything else: no output.
|
|
7
10
|
*
|
|
8
|
-
* ── WHY
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
11
|
+
* ── WHY A QUESTION, NOT CLAUDE CODE'S PERMISSION PROMPT ──────────────────────────
|
|
12
|
+
* It used to answer `ask` (paperlint#283). The Claude mobile app's permission card shows only the
|
|
13
|
+
* command line, not the hook's reason, so the person approved a shell line without seeing which
|
|
14
|
+
* paper or PDF it sends (paperlint#291). `AskUserQuestion` shows the whole question on every
|
|
15
|
+
* client, and a yes to a question that names the folder and the sha256 is a yes to those bytes in that
|
|
16
|
+
* folder: a stale build or a wrong PDF has another sha, and identical bytes in another folder (the
|
|
17
|
+
* same manuscript for another venue) have another path, so their yes does not count.
|
|
18
|
+
*
|
|
19
|
+
* ── WHERE THE YES IS READ ─────────────────────────────────────────────────────────
|
|
20
|
+
* The session's transcript (`transcript_path` in the hook's input, one JSON entry per line). A
|
|
21
|
+
* question is the assistant's `tool_use` named `AskUserQuestion`; its answer is the user entry that
|
|
22
|
+
* carries the matching `tool_result`, whose `toolUseResult.answers` maps each question's text to the
|
|
23
|
+
* option chosen. An answer is a yes when its first word is "yes". Every earlier `Bash` call that
|
|
24
|
+
* sends or names a portal — refused or not, but not this one (`tool_use_id`) — uses up the questions
|
|
25
|
+
* before it, so one yes lets one command through. Within one command each send takes an answer of
|
|
26
|
+
* its own: a yes that names two shas, or the same PDF sent twice, covers one send. When several
|
|
27
|
+
* questions name the same thing, the latest decides.
|
|
16
28
|
*
|
|
17
29
|
* ── WHAT IT SEES, AND WHAT IT IS NOT ──────────────────────────────────────────────
|
|
18
30
|
* A send is judged on the command as the shell reads it (`shellLeaves`: each simple command across
|
|
19
31
|
* `&&`, `;`, `|`, words unquoted, the commands inside a `bash -c "…"` string too), never on the raw
|
|
20
|
-
* text: `submission`, `new|update` and `--save|--submit` in one command's words
|
|
21
|
-
* in any word (a HotCRP-hosted site, or a host a venue preset declares), whatever program it runs
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
32
|
+
* text: `submission`, `new|update` and `--save|--submit` in one command's words; or a portal's host
|
|
33
|
+
* in any word (a HotCRP-hosted site, or a host a venue preset declares), whatever program it runs —
|
|
34
|
+
* such a command may send around paperlint's venue check, and has no PDF to name, so the question
|
|
35
|
+
* names the host and the command instead. When the presets cannot be read, only HotCRP-hosted sites
|
|
36
|
+
* and paperlint sends are recognised, and a refusal says so: one bad preset does not stop the shell.
|
|
37
|
+
* NOT SEEN: an upload from a script file that names the host only inside the file, or words built
|
|
38
|
+
* at run time (`$(…)`).
|
|
27
39
|
*
|
|
28
|
-
* The
|
|
29
|
-
*
|
|
40
|
+
* The agent writes the question, so a deliberately misleading question still passes. The hook
|
|
41
|
+
* catches an agent that sends without asking, or asks about other bytes; it is not a security
|
|
42
|
+
* boundary against an agent that deliberately disguises a send.
|
|
30
43
|
*
|
|
31
|
-
* ── IT FAILS
|
|
32
|
-
*
|
|
33
|
-
*
|
|
44
|
+
* ── IT FAILS CLOSED ───────────────────────────────────────────────────────────────
|
|
45
|
+
* A send whose PDF cannot be told for certain, a PDF that is not there, no transcript, a payload
|
|
46
|
+
* that is not JSON, a crash: refused, with what went wrong. A transcript line that is not JSON is
|
|
47
|
+
* not a reason to refuse every send for the rest of the session — real transcripts have them (an
|
|
48
|
+
* entry cut short and run into the next, measured in a live one) — so it counts as a send when its
|
|
49
|
+
* text may hold one, and a yes before it no longer counts. Only lines that may hold a question, an
|
|
50
|
+
* answer or a send are parsed, and the shell parser runs only on commands that say `submission` or
|
|
51
|
+
* a portal's host:
|
|
52
|
+
* a transcript of hundreds of megabytes is read in seconds.
|
|
34
53
|
*
|
|
35
54
|
* ── WHY IN-PROCESS, NOT A VIGILES PROGRAM ────────────────────────────────────────
|
|
36
55
|
* It reads the build's facts with this package's own parser and hashes the PDF; a shipped vigiles
|
|
37
56
|
* hook may import nothing but `vigiles/hook` (`src/folder-layout-hook.ts` says the rest). So
|
|
38
57
|
* `paperlint hook submission-confirm` runs it in-process (`runHook`, src/cli.ts).
|
|
39
58
|
*/
|
|
40
|
-
import {
|
|
59
|
+
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
41
60
|
import { callerPath } from "./caller-path.js";
|
|
42
61
|
import { bodyEnd } from "./domain/body-pages.js";
|
|
43
|
-
import { fieldOf } from "./domain/record.js";
|
|
62
|
+
import { fieldOf, isRecord } from "./domain/record.js";
|
|
44
63
|
import { sha256Hex } from "./domain/sha256.js";
|
|
45
64
|
import { messageOf } from "./domain/text.js";
|
|
46
65
|
import { factsPath, parseFactsText } from "./facts-file.js";
|
|
47
66
|
import { paperPreset } from "./presets.js";
|
|
48
67
|
import { paperPdf } from "./submission.js";
|
|
49
|
-
const
|
|
68
|
+
const deny = (reason) => ({
|
|
50
69
|
hookSpecificOutput: {
|
|
51
70
|
hookEventName: "PreToolUse",
|
|
52
|
-
permissionDecision: "
|
|
71
|
+
permissionDecision: "deny",
|
|
53
72
|
permissionDecisionReason: reason,
|
|
54
73
|
},
|
|
55
74
|
});
|
|
56
|
-
const LAST = "Allow only if you have read the dry run's venue check.";
|
|
57
75
|
/** The domain of HotCRP's hosted sites; a self-hosted portal is known by the host its preset declares. */
|
|
58
76
|
const HOTCRP_HOSTED = "hotcrp.com";
|
|
59
77
|
/**
|
|
@@ -92,25 +110,21 @@ function sendsIn(leaves, readSend) {
|
|
|
92
110
|
return [moved ? null : readSend(l.args.slice(at + 1))];
|
|
93
111
|
});
|
|
94
112
|
}
|
|
113
|
+
/** The words of the commands that may name a host: those with a dot, lowercased. */
|
|
114
|
+
const dottedWords = (leaves) => leaves
|
|
115
|
+
.flatMap((l) => [l.head, ...l.args])
|
|
116
|
+
.map((w) => w.toLowerCase())
|
|
117
|
+
.filter((w) => w.includes("."));
|
|
118
|
+
/** The portal hosts known: HotCRP's hosted sites always, then those `hosts` names; lowercased. */
|
|
119
|
+
const knownHosts = (hosts) => [HOTCRP_HOSTED, ...hosts].map((h) => h.toLowerCase()).filter((h) => h !== "");
|
|
95
120
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* the shell's words only, never on the raw text.
|
|
121
|
+
* The portal host a command names — a HotCRP-hosted site, or a host a venue preset declares
|
|
122
|
+
* (`hosts`), whatever program it runs, as a plain case-insensitive substring of a word — or null.
|
|
123
|
+
* Judged on the shell's words only, never on the raw text.
|
|
100
124
|
*/
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const words = leaves
|
|
105
|
-
.flatMap((l) => [l.head, ...l.args])
|
|
106
|
-
.map((w) => w.toLowerCase())
|
|
107
|
-
.filter((w) => w.includes("."));
|
|
108
|
-
if (words.length === 0)
|
|
109
|
-
return null;
|
|
110
|
-
const known = [HOTCRP_HOSTED, ...hosts()]
|
|
111
|
-
.map((h) => h.toLowerCase())
|
|
112
|
-
.filter((h) => h !== "");
|
|
113
|
-
return words.some((w) => known.some((h) => w.includes(h))) ? "direct" : null;
|
|
125
|
+
function portalHost(leaves, hosts) {
|
|
126
|
+
const words = dottedWords(leaves);
|
|
127
|
+
return (knownHosts(hosts).find((h) => words.some((w) => w.includes(h))) ?? null);
|
|
114
128
|
}
|
|
115
129
|
/** The body pages the build counted: up to the references or appendix, or banal's count. */
|
|
116
130
|
function bodyPages(f) {
|
|
@@ -144,43 +158,238 @@ function factsLines(paperDir, sha, files) {
|
|
|
144
158
|
return [...stale, bodyPages(f.value)];
|
|
145
159
|
}
|
|
146
160
|
/** One send, described: the paper, the PDF as the command resolves it, what the build saw. */
|
|
147
|
-
function
|
|
161
|
+
function describe(send, cwd, deps) {
|
|
148
162
|
const paperDir = resolve(cwd, send.paper ?? ".");
|
|
149
163
|
const p = paperPreset(paperDir, deps);
|
|
150
164
|
const own = paperPdf(paperDir, p.kind === "settings-problem" ? null : p.settings);
|
|
151
165
|
const pdf = send.pdf === null ? own : resolve(cwd, send.pdf);
|
|
152
166
|
const bytes = deps.files.readBytes(callerPath(pdf));
|
|
153
167
|
const sha = bytes === null ? null : sha256Hex(bytes);
|
|
154
|
-
return
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
168
|
+
return {
|
|
169
|
+
named: sha === null ? null : { folder: paperDir, sha: sha.slice(0, SHA_SHOWN) },
|
|
170
|
+
lines: [
|
|
171
|
+
`paper folder: ${paperDir}`,
|
|
172
|
+
`PDF: ${send.pdf ?? join(send.paper ?? ".", relative(paperDir, own))}${sha === null ? " — NOT FOUND" : `, sha256 ${sha.slice(0, SHA_SHOWN)}`}`,
|
|
173
|
+
...factsLines(paperDir, sha, deps.files),
|
|
174
|
+
],
|
|
175
|
+
};
|
|
159
176
|
}
|
|
177
|
+
/** How much of the sha256 the reason shows, and the question must contain. */
|
|
178
|
+
const SHA_SHOWN = 12;
|
|
160
179
|
/** A send whose PDF cannot be told for certain. */
|
|
161
180
|
const UNRESOLVED = "could not resolve which PDF this send uploads — check the dry run";
|
|
181
|
+
const NOT_SENT = "Not run: this sends the paper to the venue's portal";
|
|
182
|
+
const NAMES_PORTAL = "Not run: this command names a venue's submission portal";
|
|
183
|
+
/** What to ask, once every send's PDF is known. */
|
|
184
|
+
const HOW_TO_ASK = [
|
|
185
|
+
"Ask the person with AskUserQuestion first, then run this command again. In the question, give:",
|
|
186
|
+
"- the paper folder (the full path, as written above), the PDF and its sha256 as written above (the folder path and the sha256 must both be in the question text),",
|
|
187
|
+
"- what the lines above say about the build (the body pages, or that it is stale or missing),",
|
|
188
|
+
"- the dry run's venue check, quoted word for word (its `venue rules at their default options` line and every error under it).",
|
|
189
|
+
'Options: "Yes, send it" and "No". One yes lets one send through: ask one question per send, each naming its own folder and sha256.',
|
|
190
|
+
].join("\n");
|
|
191
|
+
/** How much of a command naming a portal the question must quote. */
|
|
192
|
+
const COMMAND_SHOWN = 60;
|
|
193
|
+
/** What to ask before a command that names a portal. */
|
|
194
|
+
const HOW_TO_ASK_PORTAL = [
|
|
195
|
+
"It may send to the portal around paperlint's venue check. Ask the person with AskUserQuestion first, then run this command again: the question must contain the portal host and the command start above, exactly as written, and say what the command does.",
|
|
196
|
+
'Options: "Yes, run it" and "No". One yes lets one command through. To send a paper, use `paperlint submission new|update --save` instead.',
|
|
197
|
+
].join("\n");
|
|
198
|
+
/** Each send's block: alone, or numbered when the command has several. */
|
|
199
|
+
function blocks(described) {
|
|
200
|
+
return described.length === 1
|
|
201
|
+
? described.flatMap((d) => d.lines)
|
|
202
|
+
: described.flatMap((d, n) => [
|
|
203
|
+
`send ${String(n + 1)} of ${String(described.length)}:`,
|
|
204
|
+
...d.lines,
|
|
205
|
+
]);
|
|
206
|
+
}
|
|
207
|
+
/** A transcript line that may hold a question, an answer or a send; no other line is parsed. */
|
|
208
|
+
const MAY_MATTER = /"tool_use"|"toolUseResult"/u;
|
|
209
|
+
/** Nothing asked or answered: the start, and the state right after a send. */
|
|
210
|
+
const CLEARED = { asked: new Set(), answers: [] };
|
|
211
|
+
/** A transcript line that is not JSON. */
|
|
212
|
+
const BROKEN = Symbol("broken");
|
|
162
213
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
214
|
+
* The person's answers to `AskUserQuestion` since the last send in the transcript, oldest first.
|
|
215
|
+
* A line that may matter and is not JSON (real transcripts have them: an entry cut short, run into
|
|
216
|
+
* the next) counts as a send when it may hold one, so a yes before it is used up — never wrongly
|
|
217
|
+
* kept; otherwise it is skipped, and a yes lost in it only means asking again.
|
|
166
218
|
*/
|
|
167
|
-
export function
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
219
|
+
export function answersSinceLastSend(transcript, earlier) {
|
|
220
|
+
return transcript.split("\n").reduce((since, line) => {
|
|
221
|
+
if (!MAY_MATTER.test(line))
|
|
222
|
+
return since;
|
|
223
|
+
const entry = parsedLine(line);
|
|
224
|
+
if (entry === BROKEN)
|
|
225
|
+
return earlier.mayHold(line) ? CLEARED : since;
|
|
226
|
+
const content = fieldOf(fieldOf(entry, "message"), "content");
|
|
227
|
+
return (Array.isArray(content) ? content : []).reduce((s, block) => fieldOf(block, "type") === "tool_result"
|
|
228
|
+
? toolResult(s, block, entry)
|
|
229
|
+
: toolUse(s, block, earlier), since);
|
|
230
|
+
}, CLEARED).answers;
|
|
231
|
+
}
|
|
232
|
+
/** One transcript line, parsed; BROKEN when it is not JSON. */
|
|
233
|
+
function parsedLine(line) {
|
|
234
|
+
try {
|
|
235
|
+
return JSON.parse(line);
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
return BROKEN;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/** A block the assistant wrote: a question is noted; an earlier send clears what was asked before it. */
|
|
242
|
+
function toolUse(s, block, earlier) {
|
|
243
|
+
const id = fieldOf(block, "id");
|
|
244
|
+
if (fieldOf(block, "type") !== "tool_use" || typeof id !== "string")
|
|
245
|
+
return s;
|
|
246
|
+
const name = fieldOf(block, "name");
|
|
247
|
+
if (name === "AskUserQuestion")
|
|
248
|
+
return { ...s, asked: new Set([...s.asked, id]) };
|
|
249
|
+
const command = fieldOf(fieldOf(block, "input"), "command");
|
|
250
|
+
const send = name === "Bash" &&
|
|
251
|
+
id !== earlier.current &&
|
|
252
|
+
typeof command === "string" &&
|
|
253
|
+
earlier.mayHold(command) &&
|
|
254
|
+
earlier.sends(command);
|
|
255
|
+
return send ? CLEARED : s;
|
|
256
|
+
}
|
|
257
|
+
/** The person's reply to a question asked since the last send: its answers, kept in order. */
|
|
258
|
+
function toolResult(s, block, entry) {
|
|
259
|
+
const id = fieldOf(block, "tool_use_id");
|
|
260
|
+
if (typeof id !== "string" || !s.asked.has(id))
|
|
261
|
+
return s;
|
|
262
|
+
const answers = fieldOf(fieldOf(entry, "toolUseResult"), "answers");
|
|
263
|
+
const given = Object.entries(isRecord(answers) ? answers : {}).flatMap(([question, answer]) => typeof answer === "string" ? [{ question, answer }] : []);
|
|
264
|
+
return { ...s, answers: [...s.answers, ...given] };
|
|
265
|
+
}
|
|
266
|
+
/** Whether an answer is a yes: its first word, in any case. */
|
|
267
|
+
const isYes = (a) => /^yes\b/iu.test(a.answer.trim());
|
|
268
|
+
/** Whether `text` contains every one of `keys`, in any case. */
|
|
269
|
+
const hasAll = (text, keys) => keys.every((k) => text.toLowerCase().includes(k.toLowerCase()));
|
|
270
|
+
/** `text` as a literal inside a regular expression. */
|
|
271
|
+
const literal = (text) => text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
272
|
+
/**
|
|
273
|
+
* Whether a question names the folder `folder` and not a longer path that starts with it
|
|
274
|
+
* (`/w/paper` is not `/w/paper2` or `/w/paper.old`), nor one it ends: the whole path, case-sensitive.
|
|
275
|
+
*/
|
|
276
|
+
const namesFolder = (question, folder) => new RegExp(`(?<![\\w.-])${literal(folder)}(?![\\w.-])`, "u").test(question);
|
|
277
|
+
/**
|
|
278
|
+
* The answers used up after one more need: it takes the latest answer not yet taken whose question
|
|
279
|
+
* `names` it, and that answer must be a yes; null when there is none, or it is not.
|
|
280
|
+
*/
|
|
281
|
+
function takeYes(answers, taken, names) {
|
|
282
|
+
if (taken === null)
|
|
283
|
+
return null;
|
|
284
|
+
const at = answers.findLastIndex((a, n) => !taken.has(n) && names(a.question));
|
|
285
|
+
const found = answers[at];
|
|
286
|
+
return found !== undefined && isYes(found) ? new Set([...taken, at]) : null;
|
|
287
|
+
}
|
|
288
|
+
/** What a yes to one send must name: its sha256 (any case) and its folder (the whole path, as written). */
|
|
289
|
+
const namesSend = (s) => (question) => hasAll(question, [s.sha]) && namesFolder(question, s.folder);
|
|
290
|
+
/** What a yes to a command that names a portal must name: the host (any case) and the command's start, literally. */
|
|
291
|
+
const namesPortal = (host, start) => (question) => hasAll(question, [host]) && question.includes(start);
|
|
292
|
+
/**
|
|
293
|
+
* Whether every send and the portal command (null for none) has a yes of its own. Each takes the
|
|
294
|
+
* latest answer not yet taken, in turn, from one shared set: a yes used up by a send cannot also
|
|
295
|
+
* approve the portal, one that names two shas covers one send, and the same PDF sent twice needs
|
|
296
|
+
* two. (A yes that two needs could share is given to the first; the second is refused and the
|
|
297
|
+
* person is asked again: it fails closed.)
|
|
298
|
+
*/
|
|
299
|
+
const everyNeedHasItsYes = (answers, sends, portal) => [...sends.map(namesSend), ...(portal === null ? [] : [portal])].reduce((taken, names) => takeYes(answers, taken, names), new Set()) !== null;
|
|
300
|
+
/** Every send in the command, described; an unresolved one has no sha. */
|
|
301
|
+
function describedSends(command, cwd, deps) {
|
|
302
|
+
const sends = /[`$]/u.test(command)
|
|
303
|
+
? []
|
|
304
|
+
: sendsIn(deps.shellLeaves(command), deps.readSend);
|
|
305
|
+
return (sends.length === 0 ? [null] : sends).map((x) => x === null ? { named: null, lines: [UNRESOLVED] } : describe(x, cwd, deps));
|
|
306
|
+
}
|
|
307
|
+
/** The refusal of a send whose PDF is not known or not there: there is no sha256 to ask about. */
|
|
308
|
+
const noPdf = (described) => [
|
|
309
|
+
`${NOT_SENT}, and paperlint cannot find the PDF it uploads, so there is no sha256 to ask the person about.`,
|
|
310
|
+
...blocks(described),
|
|
311
|
+
"Name the paper folder and the PDF plainly (no cd, no $…), build the PDF, run the dry run, and ask then.",
|
|
312
|
+
];
|
|
313
|
+
/** The presets' hosts; when they cannot be read, none, and why. */
|
|
314
|
+
function readHosts(cwd, deps) {
|
|
315
|
+
try {
|
|
316
|
+
return { hosts: deps.portalHosts(cwd), failed: null };
|
|
317
|
+
}
|
|
318
|
+
catch (e) {
|
|
319
|
+
return { hosts: [], failed: messageOf(e) };
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/** The line a refusal ends with when the presets could not be read; none when they could. */
|
|
323
|
+
const fallbackLines = (h) => h.failed === null
|
|
324
|
+
? []
|
|
325
|
+
: [
|
|
326
|
+
`The venue presets could not be read (${h.failed}), so only HotCRP-hosted sites and paperlint sends are recognised until they are fixed.`,
|
|
327
|
+
];
|
|
328
|
+
/**
|
|
329
|
+
* A command that sends: let through (null) when the person said yes to it since the last send —
|
|
330
|
+
* each paperlint send by its paper folder and its PDF's sha256, a yes of its own for each, a portal
|
|
331
|
+
* named by its host and the command's start —
|
|
332
|
+
* else the lines of the refusal, with what to ask.
|
|
333
|
+
*/
|
|
334
|
+
function decide(c, payload, deps) {
|
|
335
|
+
const described = c.paperlint ? describedSends(c.text, c.cwd, deps) : [];
|
|
336
|
+
const named = described.flatMap((d) => (d.named === null ? [] : [d.named]));
|
|
337
|
+
if (named.length < described.length)
|
|
338
|
+
return noPdf(described);
|
|
339
|
+
const base = c.paperlint ? NOT_SENT : NAMES_PORTAL;
|
|
340
|
+
const read = transcriptOf(payload, deps.files);
|
|
341
|
+
if (typeof read !== "string")
|
|
342
|
+
return [
|
|
343
|
+
`${base}, and ${read.failed}, so paperlint cannot see the person's yes.`,
|
|
344
|
+
];
|
|
345
|
+
const start = c.text.trim().slice(0, COMMAND_SHOWN);
|
|
346
|
+
const answers = answersSinceLastSend(read, earlierSend(c, payload, deps));
|
|
347
|
+
const portal = c.host === null ? null : namesPortal(c.host, start);
|
|
348
|
+
if (everyNeedHasItsYes(answers, named, portal))
|
|
349
|
+
return null;
|
|
350
|
+
return [
|
|
351
|
+
`${base}, and the person has not said yes to it since the last send.`,
|
|
352
|
+
...blocks(described),
|
|
353
|
+
...(c.paperlint ? [HOW_TO_ASK] : []),
|
|
354
|
+
...portalLines(c.host, start),
|
|
355
|
+
];
|
|
356
|
+
}
|
|
357
|
+
/** What a refusal says about a portal the command names: the host, the start, what to ask; none for none. */
|
|
358
|
+
const portalLines = (host, start) => host === null
|
|
359
|
+
? []
|
|
360
|
+
: [`portal host: ${host}`, `command start: ${start}`, HOW_TO_ASK_PORTAL];
|
|
361
|
+
/** How an earlier send is told in the transcript: by the same matching as this command. */
|
|
362
|
+
function earlierSend(c, payload, deps) {
|
|
363
|
+
const known = knownHosts(c.hosts.hosts);
|
|
364
|
+
return {
|
|
365
|
+
current: stringField(payload, "tool_use_id"),
|
|
366
|
+
mayHold: (text) => {
|
|
367
|
+
const plain = text.replace(/["'\\]/gu, "").toLowerCase();
|
|
368
|
+
return (plain.includes("submission") || known.some((h) => plain.includes(h)));
|
|
369
|
+
},
|
|
370
|
+
sends: (command) => {
|
|
371
|
+
const leaves = allLeaves(command, deps.shellLeaves);
|
|
372
|
+
return leaves.some(isSend) || portalHost(leaves, known) !== null;
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
/** A string field of the payload; null for none. */
|
|
377
|
+
function stringField(payload, key) {
|
|
378
|
+
const v = fieldOf(payload, key);
|
|
379
|
+
return typeof v === "string" ? v : null;
|
|
380
|
+
}
|
|
381
|
+
/** The session's transcript as text, or why it could not be read. */
|
|
382
|
+
function transcriptOf(payload, files) {
|
|
383
|
+
const path = stringField(payload, "transcript_path");
|
|
384
|
+
if (path === null || !isAbsolute(path))
|
|
385
|
+
return { failed: "the hook was given no transcript_path" };
|
|
386
|
+
const bytes = files.readBytes(callerPath(path));
|
|
387
|
+
return bytes === null
|
|
388
|
+
? { failed: `the transcript ${path} could not be read` }
|
|
389
|
+
: new TextDecoder().decode(bytes);
|
|
390
|
+
}
|
|
391
|
+
/** The refusal when the hook's input cannot be read at all: it cannot tell, so it does not let it run. */
|
|
392
|
+
export const UNREADABLE_INPUT = deny("Not run: paperlint could not read this command, so it cannot tell whether it sends a paper to a venue's portal.");
|
|
184
393
|
/** The payload, parsed; null when it is not JSON. */
|
|
185
394
|
function parsed(stdin) {
|
|
186
395
|
try {
|
|
@@ -190,41 +399,39 @@ function parsed(stdin) {
|
|
|
190
399
|
return null;
|
|
191
400
|
}
|
|
192
401
|
}
|
|
402
|
+
/** One command, judged: null to let it run, or the refusal. */
|
|
403
|
+
function judge(text, cwd, payload, deps) {
|
|
404
|
+
const leaves = allLeaves(text, deps.shellLeaves);
|
|
405
|
+
const paperlint = leaves.some(isSend);
|
|
406
|
+
// The presets are read only for a command that may send: anything else pays nothing.
|
|
407
|
+
if (!paperlint && dottedWords(leaves).length === 0)
|
|
408
|
+
return null;
|
|
409
|
+
const hosts = readHosts(cwd, deps);
|
|
410
|
+
const host = portalHost(leaves, hosts.hosts);
|
|
411
|
+
if (!paperlint && host === null)
|
|
412
|
+
return null;
|
|
413
|
+
const lines = decide({ text, cwd, paperlint, host, hosts }, payload, deps);
|
|
414
|
+
return lines === null
|
|
415
|
+
? null
|
|
416
|
+
: deny([...lines, ...fallbackLines(hosts)].join("\n"));
|
|
417
|
+
}
|
|
193
418
|
/**
|
|
194
|
-
* The hook on one payload, as Claude Code sends it on stdin:
|
|
195
|
-
* sends nothing
|
|
419
|
+
* The hook on one payload, as Claude Code sends it on stdin: a refusal, or null to let the command
|
|
420
|
+
* run (it sends nothing, or every send in it has the person's yes). Never throws: a crash refuses.
|
|
196
421
|
*/
|
|
197
422
|
export function submissionConfirm(stdin, deps) {
|
|
198
423
|
const payload = parsed(stdin);
|
|
199
424
|
if (payload === null)
|
|
200
425
|
return UNREADABLE_INPUT;
|
|
201
426
|
const raw = fieldOf(fieldOf(payload, "tool_input"), "command");
|
|
202
|
-
const
|
|
427
|
+
const text = typeof raw === "string" ? raw : "";
|
|
203
428
|
const given = fieldOf(payload, "cwd");
|
|
204
429
|
const cwd = typeof given === "string" && isAbsolute(given) ? given : resolve(".");
|
|
205
|
-
const kind = kindOf(command, cwd, deps);
|
|
206
|
-
if (kind === null)
|
|
207
|
-
return null;
|
|
208
|
-
if (kind !== "paperlint" && kind !== "direct")
|
|
209
|
-
return ask(kind.failed);
|
|
210
|
-
if (kind === "direct")
|
|
211
|
-
return ask(DIRECT);
|
|
212
|
-
try {
|
|
213
|
-
return ask(paperlintReason(command, deps.shellLeaves(command), cwd, deps));
|
|
214
|
-
}
|
|
215
|
-
catch (e) {
|
|
216
|
-
return ask(`${SENDS} paperlint could not say what will be sent: ${messageOf(e)}. ${LAST}`);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
/** What the command sends, or — when reading it failed — the reason to ask anyway. */
|
|
220
|
-
function kindOf(command, cwd, deps) {
|
|
221
430
|
try {
|
|
222
|
-
return
|
|
431
|
+
return judge(text, cwd, payload, deps);
|
|
223
432
|
}
|
|
224
433
|
catch (e) {
|
|
225
|
-
return {
|
|
226
|
-
failed: `paperlint could not tell what this command sends (${messageOf(e)}). ${LAST}`,
|
|
227
|
-
};
|
|
434
|
+
return deny(`Not run: paperlint could not check whether this command sends a paper: ${messageOf(e)}.`);
|
|
228
435
|
}
|
|
229
436
|
}
|
|
230
437
|
//# sourceMappingURL=submission-confirm-hook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission-confirm-hook.js","sourceRoot":"","sources":["../src/submission-confirm-hook.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"submission-confirm-hook.js","sourceRoot":"","sources":["../src/submission-confirm-hook.ts"],"names":[],"mappings":"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"}
|
package/docs/layout.md
CHANGED
|
@@ -136,28 +136,28 @@ A check runs at one of four moments:
|
|
|
136
136
|
The lint-only job skips what needs a build (pages, fonts, references).
|
|
137
137
|
- **On demand** — a skill, when you ask for what it does. A skill stops nothing; it writes.
|
|
138
138
|
|
|
139
|
-
| what | kind | when it runs | what it stops
|
|
140
|
-
| ------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------- |
|
|
141
|
-
| `paper-folder-layout` | hook | before an agent creates a file (Edit, Write) | a new entry the layout does not allow, at a paper's root or the top of its `repro/`; never an existing file
|
|
142
|
-
| `paper-edit-guard` | hook | before an agent's shell command | a shell command that writes or moves a paper's source, which would skip the hooks that run after an edit
|
|
143
|
-
| `submission-confirm` | hook | before an agent's shell command |
|
|
144
|
-
| `paper-skills-nudge` | hook | after an agent edits a paper's source | nothing: it shows the agent the pre-submit checklist
|
|
145
|
-
| `paper-status-gates` | hook | after an agent edits a paper's source | nothing: it prints the paper's readiness and its unrun gates, for a person reading the transcript
|
|
146
|
-
| [`paper/allowed-files-only`](rules/paper/allowed-files-only.md) | rule | every `paperlint lint`, and CI | a stray file or folder at a paper's root (error)
|
|
147
|
-
| [`repro/allowed-files-only`](rules/repro/allowed-files-only.md) | rule | every `paperlint lint`, and CI | a loose entry at the top of `repro/`, a folder that is not a study's, a study folder without `README.md` (error)
|
|
148
|
-
| [`repro/study-registered`](rules/repro/study-registered.md) | rule | every `paperlint lint`, and CI | a study folder without its row in `repro/studies.json`, a row that does not match, a measurement or plan that does not hold, an index out of sync (error)
|
|
149
|
-
| [`repro/study-plan-name`](rules/repro/study-plan-name.md) | rule | every `paperlint lint`, and CI | nothing: it warns when a study's plan is still named `prereg.json`
|
|
150
|
-
| [`repro/outputs-before-decision`](rules/repro/outputs-before-decision.md) | rule | every `paperlint lint`, and CI (with the whole history) | an output of a study decided before its run that git shows was not made after the decision
|
|
151
|
-
| `paperlint studies gate` | command | before a decide-first study's run | the run, until the decision is committed
|
|
152
|
-
| [`study/declare-sample`](rules/study/declare-sample.md) | rule | every `paperlint lint`, and CI, once a paper turns it on | a study's `prereg.json` without its population, strata, screens, coverage or the author's check (experimental, off by default)
|
|
153
|
-
| [`paper/folder-venue-leftover`](rules/paper/folder-venue-leftover.md) | rule | every `paperlint lint`, and CI | nothing: it warns when the folder is named after another venue
|
|
154
|
-
| `review/frontmatter`, `sibling/frontmatter` | rule | every `paperlint lint`, and CI | a review whose findings break the schema (error); a sibling card that does not say how much was read (warning)
|
|
155
|
-
| `paper/stages`, `paper/source` | rule | every `paperlint lint`, and CI | a stage whose frozen PDF or source is missing or changed (error)
|
|
156
|
-
| the rules on the source (`tex/*`, `paper/*`, `bib/*`) | rule | every `paperlint lint`, and CI | what each one's [row](rules.md) says
|
|
157
|
-
| the rules on what `paperlint build` measured (`pdf/*`, `format/page-limit`, the references) | rule | every `paperlint lint` after a build; CI's full job | a PDF over the page limit, in the wrong font or format, or with a bad reference
|
|
158
|
-
| `study-accepted-papers` | skill | when you ask; stage 2 (modes A, B) and stage 5 (modes C, D) | nothing: it fills the venue's corpus, and writes the strong-accept scorecard in `PIPELINE-STATUS.md`
|
|
159
|
-
| `build-benchmark` | skill | when you ask; stage 3 | nothing: it registers the study with `paperlint studies new`, writes its design, fills its `plan.json`, and updates its row when it ends
|
|
160
|
-
| `build-label-page` | skill | when you ask; stage 3 | nothing: it builds the labelling page, and exports the answers into the study's `data/`
|
|
139
|
+
| what | kind | when it runs | what it stops |
|
|
140
|
+
| ------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
141
|
+
| `paper-folder-layout` | hook | before an agent creates a file (Edit, Write) | a new entry the layout does not allow, at a paper's root or the top of its `repro/`; never an existing file |
|
|
142
|
+
| `paper-edit-guard` | hook | before an agent's shell command | a shell command that writes or moves a paper's source, which would skip the hooks that run after an edit |
|
|
143
|
+
| `submission-confirm` | hook | before an agent's shell command | a submission send (`--save`, `--submit`), or a command naming a portal's host, that the person has not said yes to in a question naming its PDF's sha256 (or the host and the command) |
|
|
144
|
+
| `paper-skills-nudge` | hook | after an agent edits a paper's source | nothing: it shows the agent the pre-submit checklist |
|
|
145
|
+
| `paper-status-gates` | hook | after an agent edits a paper's source | nothing: it prints the paper's readiness and its unrun gates, for a person reading the transcript |
|
|
146
|
+
| [`paper/allowed-files-only`](rules/paper/allowed-files-only.md) | rule | every `paperlint lint`, and CI | a stray file or folder at a paper's root (error) |
|
|
147
|
+
| [`repro/allowed-files-only`](rules/repro/allowed-files-only.md) | rule | every `paperlint lint`, and CI | a loose entry at the top of `repro/`, a folder that is not a study's, a study folder without `README.md` (error) |
|
|
148
|
+
| [`repro/study-registered`](rules/repro/study-registered.md) | rule | every `paperlint lint`, and CI | a study folder without its row in `repro/studies.json`, a row that does not match, a measurement or plan that does not hold, an index out of sync (error) |
|
|
149
|
+
| [`repro/study-plan-name`](rules/repro/study-plan-name.md) | rule | every `paperlint lint`, and CI | nothing: it warns when a study's plan is still named `prereg.json` |
|
|
150
|
+
| [`repro/outputs-before-decision`](rules/repro/outputs-before-decision.md) | rule | every `paperlint lint`, and CI (with the whole history) | an output of a study decided before its run that git shows was not made after the decision |
|
|
151
|
+
| `paperlint studies gate` | command | before a decide-first study's run | the run, until the decision is committed |
|
|
152
|
+
| [`study/declare-sample`](rules/study/declare-sample.md) | rule | every `paperlint lint`, and CI, once a paper turns it on | a study's `prereg.json` without its population, strata, screens, coverage or the author's check (experimental, off by default) |
|
|
153
|
+
| [`paper/folder-venue-leftover`](rules/paper/folder-venue-leftover.md) | rule | every `paperlint lint`, and CI | nothing: it warns when the folder is named after another venue |
|
|
154
|
+
| `review/frontmatter`, `sibling/frontmatter` | rule | every `paperlint lint`, and CI | a review whose findings break the schema (error); a sibling card that does not say how much was read (warning) |
|
|
155
|
+
| `paper/stages`, `paper/source` | rule | every `paperlint lint`, and CI | a stage whose frozen PDF or source is missing or changed (error) |
|
|
156
|
+
| the rules on the source (`tex/*`, `paper/*`, `bib/*`) | rule | every `paperlint lint`, and CI | what each one's [row](rules.md) says |
|
|
157
|
+
| the rules on what `paperlint build` measured (`pdf/*`, `format/page-limit`, the references) | rule | every `paperlint lint` after a build; CI's full job | a PDF over the page limit, in the wrong font or format, or with a bad reference |
|
|
158
|
+
| `study-accepted-papers` | skill | when you ask; stage 2 (modes A, B) and stage 5 (modes C, D) | nothing: it fills the venue's corpus, and writes the strong-accept scorecard in `PIPELINE-STATUS.md` |
|
|
159
|
+
| `build-benchmark` | skill | when you ask; stage 3 | nothing: it registers the study with `paperlint studies new`, writes its design, fills its `plan.json`, and updates its row when it ends |
|
|
160
|
+
| `build-label-page` | skill | when you ask; stage 3 | nothing: it builds the labelling page, and exports the answers into the study's `data/` |
|
|
161
161
|
|
|
162
162
|
The hooks are wired by `paperlint init` ([`install.md`](install.md)). A rule's level and options:
|
|
163
163
|
[`rules.md`](rules.md).
|