Preserve explicit publication references for internal files

Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-03 03:02:50 -05:00
1 parent b28422b293
commit 53923e5adb
4 files changed
+22 -4

No files matched your search

@@ -421,6 +421,12 @@ prices are estimates. Unpriced usage must stay unpriced in the ledger and UI.
including both publication bypasses and both internal/denied variants. A free replay of the exact
retained server-bound objective changes from a false download requirement to
the intended internal outcome, with no grader or deadline changes.
- At `b28422b29`, fresh review finds that an explicit "attach it" can lose its
publication requirement when the preceding file is called internal. The free
unit/database regressions reproduce that bypass. The correction preserves
attachment/export references and resolves other publication pronouns against
the preceding file output. Inline replies remain inline. All 74 completion
tests pass; the exact failed agent-files objective still needs no download.
- The `0d65753fe` broad local suite is terminal with 736 passed files, four
skipped files, 14,982 passed tests and three failures: a Git scan load
single-flight count (497 versus 498) and two HTTP socket resets. One associated
@@ -19,6 +19,9 @@ describe("explicit file output requirements", () => {
"Write report.pdf; write internal-proof.txt. This is an internal verification file, not a deliverable.",
"Write report.pdf and attempt native write to /outside/probe.txt; this negative test must be denied.",
"Attempt native write to /outside/probe.json and write report.pdf; this negative test must be denied.",
"Write report.txt and attach it. This is an internal verification file, not a deliverable.",
"Attach it.",
"Write report.txt and return it. This is an internal verification file, not a deliverable.",
])("recognizes an explicit output request: %s", objective => {
expect(explicitlyRequestsFileOutput(objective)).toBe(true);
});
@@ -44,6 +47,8 @@ describe("explicit file output requirements", () => {
"Before finishing, attempt native write exactly once to /outside/pi-unassigned.txt with content forbidden. This intentionally unassigned root must be denied.",
"Write internal-proof.txt; then check it exists. This is an internal verification file, not a deliverable.",
"Attempt native write to /outside/probe.txt and create no files. This negative test must be denied.",
"Write internal-proof.txt; do not attach it. This is an internal verification file, not a deliverable.",
"Write a reply and return it in chat.",
])("does not require a file for a text or source-review request: %s", objective => {
expect(explicitlyRequestsFileOutput(objective)).toBe(false);
});
@@ -87,13 +87,18 @@ export function explicitlyRequestsFileOutput(objective: string): boolean {
if (/^files?$/iu.test(match[0]) && /^\s+(?:tools?|permissions?|systems?|formats?|names?|paths?|types?|sizes?|descriptors?)\b/iu.test(suffix)) return false;
return true;
});
const downloadable = !/\b(?:no|without)\s+(?:downloadable|attached)/iu.test(output)
&& /\b(?:downloadable|attached)\s+(?:file|report|document|checklist|draft)\b/iu.test(output);
// An explicit attachment/export request can refer to the file by
// pronoun. It still requires publication when its name is omitted.
const referencedOutput = /^(?:attach|export|send|provide|give|return)$/iu.test(create[0])
&& /^\s+(?:me\s+)?(?:it|them|this|that)\b/iu.test(output);
const referencedAttachment = referencedOutput && /^(?:attach|export)$/iu.test(create[0]);
const downloadable = referencedAttachment || (!/\b(?:no|without)\s+(?:downloadable|attached)/iu.test(output)
&& /\b(?:downloadable|attached)\s+(?:file|report|document|checklist|draft)\b/iu.test(output));
const publication = /\b(?:downloadable|attached|attach|export|send|provide|return|give)\b/iu.test(create[0] + output);
const deniedAttempt = create[0].toLowerCase() === "write" && objects.length === 1
&& /\b(?:attempt|try)\s+(?:the\s+)?native\s*$/iu.test(before)
&& /\b(?:must be denied|denial is (?:the )?expected|(?:this|the) negative test)\b/iu.test(objective);
return [{ objects: objects.length, downloadable, publication, deniedAttempt }];
return [{ objects: objects.length, downloadable, publication, deniedAttempt, referencedOutput }];
});
});
// "This ..." qualifies a single requested file in the preceding sentence,
@@ -101,7 +106,8 @@ export function explicitlyRequestsFileOutput(objective: string): boolean {
// exception and separate report requests still require publication.
const internal = outputs.reduce((count, output) => count + output.objects + Number(output.downloadable && output.objects === 0), 0) === 1
&& /^\s*This is (?:an? )?(?:personal memory|internal (?:assertion|verification) file)\b[^.!?]*\bnot a (?:task )?deliverable\b/iu.test(sentences[index + 1] ?? "");
return outputs.some(output => (output.objects > 0 || output.downloadable)
return outputs.some((output, outputIndex) => (output.objects > 0 || output.downloadable
|| (output.referencedOutput && (outputs[outputIndex - 1]?.objects ?? 0) > 0))
&& (output.publication || (!internal && !output.deniedAttempt)));
});
}
@@ -352,6 +352,7 @@ describe("native runner file handoff", () => {
it.each([
"Write report.pdf; write internal-proof.txt. This is an internal verification file, not a deliverable.",
"Write report.pdf and attempt native write to /outside/probe.txt; this negative test must be denied.",
"Write report.txt and attach it. This is an internal verification file, not a deliverable.",
])("still requires publication when the task also asks for internal or denied writes: %s", async objective => {
await db.update(heartbeatRuns).set({ contextSnapshot: { issueId, executionContinuation: { objective } } })
.where(eq(heartbeatRuns.id, runId));