mtech-ai-local-runner 0.1.92 → 0.1.94
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/README.md
CHANGED
|
@@ -1,3 +1,46 @@
|
|
|
1
|
+
## Unreleased: bounded report drafting and offline preflight
|
|
2
|
+
|
|
3
|
+
The final writing guidance targets 1,200 UTF-16 code units in `report`, below
|
|
4
|
+
the unchanged 2,000-unit acceptance limit. Findings and uncertainty belong in
|
|
5
|
+
the short report; detailed citations belong in `evidence`. No automatic
|
|
6
|
+
truncation, content repair, model retry, new tool or launch permission is added.
|
|
7
|
+
Prompt guidance alone cannot guarantee model compliance: an oversized final
|
|
8
|
+
response still fails closed. These changes are source-only, not part of the
|
|
9
|
+
installed/reviewed 0.1.93 package.
|
|
10
|
+
|
|
11
|
+
From the `runners/local-agent` source checkout, before another live validation,
|
|
12
|
+
replay saved **final response text**, not a transcript or stream-JSON wrapper,
|
|
13
|
+
through the production completion validator (the script is a repository-only
|
|
14
|
+
rehearsal utility, not an installed Runner command):
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npm run build
|
|
18
|
+
node scripts/check-completion-report.mjs /absolute/path/to/final-response.txt
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This offline script reads a bounded UTF-8 file, emits only counts and fixed
|
|
22
|
+
diagnostics, and never rewrites the input, calls a model, accesses Gateway or
|
|
23
|
+
starts work. Exit 0 means valid transport (including a truthful `blocked`
|
|
24
|
+
report), 1 means rejected transport, and 2 means usage/read/encoding/input-size
|
|
25
|
+
failure. A reported `completed` status does not verify the investigation,
|
|
26
|
+
citations or Work Item completion. The exact 2026-11-05 failure is preserved as
|
|
27
|
+
an untrusted technical test fixture; its claims are not accepted as true.
|
|
28
|
+
|
|
29
|
+
No package publication, Gateway registration, Runner replacement or new live
|
|
30
|
+
execution has been performed for this source change. Those require separate
|
|
31
|
+
release review, exact hashes and execution approval.
|
|
32
|
+
|
|
33
|
+
## 0.1.93: strict investigation JSON completion guidance
|
|
34
|
+
|
|
35
|
+
Claude uses native-stream progress guidance and receives scoped tool/correction
|
|
36
|
+
context before the final JSON completion contract. A draft for owner review
|
|
37
|
+
still returns the structured report to the Runner without answering the original
|
|
38
|
+
request. Markdown remains rejected; no repair call or automatic retry is added.
|
|
39
|
+
Source verification does not prove live model compliance. Existing attempts,
|
|
40
|
+
contracts, Loop limits and security policies are unchanged. Installation needs
|
|
41
|
+
freshly reviewed package/runtime hashes; Gateway deployment alone does not
|
|
42
|
+
replace an installed Runner.
|
|
43
|
+
|
|
1
44
|
## Unreleased: Gateway-managed verification budget (P3E)
|
|
2
45
|
|
|
3
46
|
D6 owner revision `fbc30fbe-cac9-45d1-9eff-bccec6ee6a54` selects a separate
|
|
@@ -27,5 +27,18 @@ export function compilePrompt(taskPackage, options) {
|
|
|
27
27
|
const { toolInventory = "local-tools-v1", ...brief } = options;
|
|
28
28
|
localToolNames(toolInventory);
|
|
29
29
|
const correction = renderBundleCorrectionBrief(taskPackage);
|
|
30
|
-
|
|
30
|
+
// Claude progress is observed from its native stream, not model-authored lifecycle JSON.
|
|
31
|
+
// Keep the final report contract last, including after untrusted correction findings.
|
|
32
|
+
return compileBrief(taskPackage, { ...brief, progressReporting: "native_messages" }, [
|
|
33
|
+
repositoryScope(taskPackage),
|
|
34
|
+
LOCAL_TOOL_GUIDANCE,
|
|
35
|
+
`${claudePathRules(toolInventory)}${correction}`,
|
|
36
|
+
"## Investigation result and transport boundary\n" +
|
|
37
|
+
"Put concise findings in report and source citations in evidence, not a standalone Markdown report. " +
|
|
38
|
+
"A draft for owner review still requires this final JSON transport report; returning it to the Runner " +
|
|
39
|
+
"does not submit an answer to the original request or authorize external publication. " +
|
|
40
|
+
"Distinguish source inspection from tests actually executed; a successful read is not a passed test. " +
|
|
41
|
+
"Before finalizing, check the required keys, report/evidence size limits and accurate pending_work. " +
|
|
42
|
+
"If unfinished, return one blocked report; never invent evidence or claim completion to satisfy the format.",
|
|
43
|
+
]);
|
|
31
44
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { completionEnvelope, completionEvent, COMPLETION_REPORT_LIMITS } from './completion-report.js';
|
|
2
|
+
/** Offline diagnostics only: never rewrites output, creates evidence, or authorizes execution. */
|
|
3
|
+
export function completionReportPreflight(raw) {
|
|
4
|
+
const options = { earlierCodeBlocks: true };
|
|
5
|
+
const envelope = completionEnvelope(raw, options);
|
|
6
|
+
const event = completionEvent(raw, undefined, options);
|
|
7
|
+
const rejection = event.payload?.completion_rejection;
|
|
8
|
+
const valid = event.eventType === 'completed' || event.payload?.reason === 'executor_blocked';
|
|
9
|
+
return {
|
|
10
|
+
valid_transport: valid,
|
|
11
|
+
// This is transport status only, not independent review or Work Item completion.
|
|
12
|
+
completed: event.eventType === 'completed',
|
|
13
|
+
status: valid ? (event.eventType === 'completed' ? 'completed' : 'blocked') : 'rejected',
|
|
14
|
+
rejection_code: rejection?.code ?? null,
|
|
15
|
+
report_code_units: typeof envelope?.report === 'string' ? envelope.report.length : null,
|
|
16
|
+
report_limit: COMPLETION_REPORT_LIMITS.reportCodeUnits,
|
|
17
|
+
evidence_count: Array.isArray(envelope?.evidence) ? envelope.evidence.length : null,
|
|
18
|
+
pending_work_count: Array.isArray(envelope?.pending_work) ? envelope.pending_work.length : null,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -22,6 +22,14 @@ export function reportRejectionCounts(value, total) {
|
|
|
22
22
|
const MAX_EVIDENCE_ITEMS = 20;
|
|
23
23
|
const MAX_EVIDENCE_CHARS = 500;
|
|
24
24
|
const MAX_REPORT_ENVELOPE_CHARS = 16_000;
|
|
25
|
+
/** Construction/rehearsal hints; acceptance always goes through completionEvent. */
|
|
26
|
+
export const COMPLETION_REPORT_LIMITS = Object.freeze({
|
|
27
|
+
reportCodeUnits: MAX_EVENT_SUMMARY_CHARS,
|
|
28
|
+
targetReportCodeUnits: Math.min(1200, MAX_EVENT_SUMMARY_CHARS),
|
|
29
|
+
listItems: MAX_EVIDENCE_ITEMS,
|
|
30
|
+
itemCodeUnits: MAX_EVIDENCE_CHARS,
|
|
31
|
+
envelopeCodeUnits: MAX_REPORT_ENVELOPE_CHARS,
|
|
32
|
+
});
|
|
25
33
|
const REPORT_FAILURE_CODES = ["CODEX_COMPLETION_REPORT_MISSING", "CODEX_COMPLETION_REPORT_INVALID", "CODEX_COMPLETION_REPORT_MULTIPLE", "CODEX_COMPLETION_REPORT_NOT_FINAL", "CODEX_TURN_INCOMPLETE"];
|
|
26
34
|
const REPORT_DIAGNOSTIC_CODES = [...REPORT_FAILURE_CODES, "CODEX_COMPLETION_REPORT_BLOCKED"];
|
|
27
35
|
/** Pair counts only; no item IDs, text, stable digests or arbitrary keys. */
|
|
@@ -68,6 +76,11 @@ export const COMPLETION_REPORT_NOTICE = "Do the assigned work yourself using the
|
|
|
68
76
|
"Your final response must be one JSON object, without Markdown fences: " +
|
|
69
77
|
'{"status":"completed","report":"actual findings and results","evidence":["file path and observed finding, or command and actual result"],"pending_work":[]}. ' +
|
|
70
78
|
`The report must be nonempty and at most ${MAX_EVENT_SUMMARY_CHARS} characters. ` +
|
|
79
|
+
`Aim for at most ${COMPLETION_REPORT_LIMITS.targetReportCodeUnits} UTF-16 code units in the decoded report string; the hard limit remains ${MAX_EVENT_SUMMARY_CHARS}. ` +
|
|
80
|
+
"Count decoded string length, not tokens, words, UTF-8 bytes or JSON escape characters; an emoji can count as two units. " +
|
|
81
|
+
"Use short findings for the requested topics, then uncertainty and verification limits. Put detailed source citations in evidence instead of repeating them in report. " +
|
|
82
|
+
"Do not fill the available limit or duplicate a narrative before the JSON. Before sending your single final response, shorten your own draft to the target and recheck all fields. " +
|
|
83
|
+
"Never drop uncertainty or pending work to fit the report; use blocked and accurate pending_work when work is incomplete. " +
|
|
71
84
|
`Include 1-${MAX_EVIDENCE_ITEMS} nonempty evidence strings, each at most ${MAX_EVIDENCE_CHARS} characters. ` +
|
|
72
85
|
"Address the assigned objective and each applicable acceptance criterion with observed evidence, not a plan or promise. " +
|
|
73
86
|
"Only attest to executor work you observed; Gateway records transport, completion, and review receipts separately. " +
|
|
@@ -120,7 +120,8 @@ function continuationContext(taskPackage) {
|
|
|
120
120
|
+ "Do not replay a completed side effect. Never answer a human-only question or approve on another actor's behalf. "
|
|
121
121
|
+ "Required review, completion and publication gates remain separate; report only observed work and evidence, not delivery or operational success inferred from a local result.";
|
|
122
122
|
}
|
|
123
|
-
|
|
123
|
+
/** Adapter-owned context stays ahead of the final wire-format contract. */
|
|
124
|
+
export function compilePrompt(taskPackage, options, adapterSections = []) {
|
|
124
125
|
const contract = record(taskPackage.contract);
|
|
125
126
|
if (!contract) {
|
|
126
127
|
throw new Error("task package is missing a contract");
|
|
@@ -167,6 +168,7 @@ export function compilePrompt(taskPackage, options) {
|
|
|
167
168
|
options.progressReporting === "native_messages"
|
|
168
169
|
? `## Native progress and terminal reporting\n${NATIVE_PROGRESS_NOTICE}`
|
|
169
170
|
: `## Event and checkpoint obligations\n${EVENT_SCHEMA_NOTICE}`,
|
|
171
|
+
...adapterSections,
|
|
170
172
|
`## Final completion report\n${COMPLETION_REPORT_NOTICE}`,
|
|
171
173
|
];
|
|
172
174
|
return sections.join("\n\n");
|