@mjasnikovs/pi-task 0.18.29 → 0.18.31

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.
@@ -0,0 +1,112 @@
1
+ /**
2
+ * yolo — unattended auto-pick of the option pi-task already marks RECOMMENDED.
3
+ *
4
+ * GOAL: let a local model take a throwaway/test project end to end with nobody
5
+ * watching. Wherever pi-task would stop and ask, it takes the recommended option,
6
+ * STAMPS the artifact so a later audit can see a machine decided, and never
7
+ * notifies. OFF by default; never the behaviour of a normal run.
8
+ *
9
+ * WHY PER-SITE, NOT ONE HOOK (the trap this module exists to avoid): the single
10
+ * interactive choke point is SessionUI.ask() (remote/bridge.ts) — auto-picking
11
+ * "index 0" inside it would be one tiny patch, and it would be wrong. The
12
+ * verify-FAIL picker is reached ONLY AFTER MAX_AUTO_AUTOFIX unattended autofix
13
+ * attempts have already failed, yet it STILL tints AUTOFIX as recommended: a
14
+ * central hook would pick AUTOFIX forever and defeat the exact cap that exists to
15
+ * break a non-converging loop. So every site decides for itself, BEFORE ask() is
16
+ * called — which also means the prompt notification (the lone pushNotify in
17
+ * ask()) is suppressed structurally, with zero suppression code.
18
+ *
19
+ * Guard direction (repo constraint): an auto-pick may cost time, never work.
20
+ * Anything this module cannot stand behind — no recommendation to take, an answer
21
+ * the anti-synthesis guard proved unverifiable — steps ASIDE ('skip') rather than
22
+ * inventing a decision.
23
+ *
24
+ * The policy functions are PURE and take `enabled` explicitly, so each site's
25
+ * behaviour is unit-tested with the flag both ways; only {@link isYoloMode} reads
26
+ * the config.
27
+ */
28
+ import { getConfig } from '../config/config.js';
29
+ /**
30
+ * Visible provenance marker on EVERY artifact an auto-pick writes (gate trails,
31
+ * task-file Q&A, the debt ledger's reason text). A later audit reading only the
32
+ * artifacts must never mistake an auto-pick for a human decision — that is the
33
+ * same confusion the accept-debt origins were introduced to prevent.
34
+ */
35
+ export const YOLO_STAMP = '(YOLO)';
36
+ /** Is unattended auto-pick on for this run? The ONLY config read in this module. */
37
+ export function isYoloMode() {
38
+ return getConfig().yoloMode;
39
+ }
40
+ /**
41
+ * The clarify/grill policy: take the RECOMMENDED option — which is positional,
42
+ * index 0 of the card list (question-box.ts tints it green), i.e. `suggested`,
43
+ * falling back to the B-side `alt` when a fork offers only that.
44
+ *
45
+ * `unsafe` is the step-aside channel: a caller that KNOWS the recommendation must
46
+ * not be auto-accepted passes why, and the question is skipped instead. Its one
47
+ * producer today is the anti-synthesis demotion — an answer proven to name a
48
+ * hallucinated API identifier. Auto-accepting that would re-promote exactly the
49
+ * invention the demotion was built to stop (it reached requirements AND the VERIFY
50
+ * block in mx5 run 13), so a machine may never take it; a human still can.
51
+ */
52
+ export function yoloPickAnswer(enabled, opts) {
53
+ if (!enabled)
54
+ return null;
55
+ if (opts.unsafe !== undefined && opts.unsafe.length > 0) {
56
+ return { kind: 'skip', note: opts.unsafe };
57
+ }
58
+ const pick = opts.suggested ?? opts.alt;
59
+ if (pick === undefined || pick.trim().length === 0) {
60
+ return { kind: 'skip', note: 'no recommended option to take' };
61
+ }
62
+ return { kind: 'answer', answer: pick };
63
+ }
64
+ /**
65
+ * The same policy expressed over an {@link AutoAnswer}, for the grill site. Only
66
+ * the ANTI-SYNTHESIS unknown is unsafe: the other two producers (an integration
67
+ * unknown research could not ground, a child that threw) carry an ordinary
68
+ * best-effort recommendation, which is precisely what a human would be shown as
69
+ * the green card. The variants are told apart by the union's `reason` tag — never
70
+ * by pattern-matching the answer text.
71
+ */
72
+ export function yoloPickAutoAnswer(enabled, auto) {
73
+ if (!enabled)
74
+ return null;
75
+ if (auto.kind === 'answered')
76
+ return { kind: 'answer', answer: auto.text };
77
+ return yoloPickAnswer(enabled, {
78
+ ...(auto.suggested !== undefined && { suggested: auto.suggested }),
79
+ ...(auto.alt !== undefined && { alt: auto.alt }),
80
+ ...(auto.reason === 'api-synthesis' && {
81
+ unsafe: 'the suggested answer names an unverified API identifier — needs a human'
82
+ })
83
+ });
84
+ }
85
+ /**
86
+ * The verify-FAIL picker policy: ACCEPT (and write a debt), never AUTOFIX.
87
+ *
88
+ * Not a preference — a bound. Every branch that REACHES this picker has already
89
+ * spent its unattended budget: the loop auto-runs AUTOFIX while the research
90
+ * recommends it, up to MAX_AUTO_AUTOFIX consecutive failures, and only then hands
91
+ * over. Answering AUTOFIX here would restart that budget from a site whose whole
92
+ * purpose is that the budget ran out. So YOLO takes the terminal option and
93
+ * records the defect ('yolo-accepted' — an origin a human never produces).
94
+ */
95
+ export function yoloVerifyResolution(enabled) {
96
+ return enabled ? { action: 'accept' } : null;
97
+ }
98
+ /**
99
+ * The final-integration-gate policy: keep autofixing WHILE the picker still
100
+ * offers that card (the loop withdraws it after MAX_FINAL_GATE_AUTOFIX attempts),
101
+ * then leave the run FAILED.
102
+ *
103
+ * 'leave', not 'accept': an unattended run that cannot fix the whole-repo gate has
104
+ * not produced a working project, and the honest terminal state is a failed run a
105
+ * resume can re-enter — mx5 run 13 ended "FAIL accepted by user" on an app that
106
+ * 404'd at `/`, and that acceptance is what made the failure look like a success.
107
+ */
108
+ export function yoloFinalGateChoice(enabled, canAutofix) {
109
+ if (!enabled)
110
+ return null;
111
+ return canAutofix ? { action: 'autofix' } : { action: 'leave' };
112
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mjasnikovs/pi-task",
3
- "version": "0.18.29",
3
+ "version": "0.18.31",
4
4
  "description": "Deterministic task planning and spec-orchestration for local models — crash-safe /task pipelines with verify/enforce gates, a real-time remote web view, and web/docs/fetch/worker subagent tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",