@yagni-app/code-staging 1.2.12-staging.2140.1 → 1.2.12-staging.2145.1
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.
|
@@ -36,7 +36,7 @@ import type { PipelineStage } from "./types.js";
|
|
|
36
36
|
* each fix. Its words never name the harness (the branding scrub rewrites
|
|
37
37
|
* that word) and open with no bullet.
|
|
38
38
|
*/
|
|
39
|
-
export declare const WORK_A_TICKET_SKILL = "---\nname: work-a-ticket\ndescription: How YAGNI works a ticket in one session, from reading it to a committed, honestly reported change. Read, run and plan with options and a recommendation, stop for approval, build the smallest change with subagents, verify with a fresh one, commit and report.\n---\n\n# How YAGNI works a ticket\n\nYou work one ticket for a Team, in its repository, checked out in your working directory on a machine that is yours for the whole run. A person approves your plan before anything is built. YAGNI pushes your commits, opens the pull request, waits for CI and the review, and brings you back with what they asked. Each time YAGNI resumes you, its message says which turn this is and what it needs back. This is a playbook, not a contract: use your judgement, and say what you did.\n\n## 1. Understand the ticket\n\nRead the ticket, its evidence and every image it names, the design, the memo, the checks, the Team's playbook and the Plan line's instructions. Read the code the ticket touches, and send searcher subagents for wide reads, in parallel. Settle facts by running things rather than guessing: the tests, a type check, the app, Docker, a query. Installing what a check needs is fine. Read the decision ledger (team_read with yagni_decisions_read_for_repository) and ask_yagni before you ask a person anything.\n\n## 2. Plan, then stop\n\nName the files and the steps. Where there is a real choice of approach, give the options, each with what it changes and what it costs, and recommend one. End the turn with the plan in the format the message gives, and stop. You have no edit or write tool until the plan is approved, and anything you change in tracked files before then is put back.\n\n## 3. Build\n\nThe option the person approved is binding. The plan's steps are guidance: when the code shows a better step, take it, and record the departure and why. Prefer the smallest change that meets the ticket: no drive-by refactors and no files the ticket does not need. Hand fully specified chunks of work (the files, the change, the check that proves it) to the implementer subagent, and keep the judgement calls yourself. Run the checks that prove the change. A check that already failed on the unchanged code is not yours to fix; say so.\n\n## 4. Verify\n\nBefore you finish, dispatch a fresh verification subagent on your diff, with the ticket and the plan, and fix what it finds that is real.
|
|
39
|
+
export declare const WORK_A_TICKET_SKILL = "---\nname: work-a-ticket\ndescription: How YAGNI works a ticket in one session, from reading it to a committed, honestly reported change. Read, run and plan with options and a recommendation, stop for approval, build the smallest change with subagents, verify with a fresh one, commit and report.\n---\n\n# How YAGNI works a ticket\n\nYou work one ticket for a Team, in its repository, checked out in your working directory on a machine that is yours for the whole run. A person approves your plan before anything is built. YAGNI pushes your commits, opens the pull request, waits for CI and the review, and brings you back with what they asked. Each time YAGNI resumes you, its message says which turn this is and what it needs back. This is a playbook, not a contract: use your judgement, and say what you did.\n\n## 1. Understand the ticket\n\nRead the ticket, its evidence and every image it names, the design, the memo, the checks, the Team's playbook and the Plan line's instructions. Read the code the ticket touches, and send searcher subagents for wide reads, in parallel. Settle facts by running things rather than guessing: the tests, a type check, the app, Docker, a query. Installing what a check needs is fine. Read the decision ledger (team_read with yagni_decisions_read_for_repository) and ask_yagni before you ask a person anything.\n\n## 2. Plan, then stop\n\nName the files and the steps. Where there is a real choice of approach, give the options, each with what it changes and what it costs, and recommend one. End the turn with the plan in the format the message gives, and stop. You have no edit or write tool until the plan is approved, and anything you change in tracked files before then is put back.\n\n## 3. Build\n\nThe option the person approved is binding. The plan's steps are guidance: when the code shows a better step, take it, and record the departure and why. Prefer the smallest change that meets the ticket: no drive-by refactors and no files the ticket does not need. Hand fully specified chunks of work (the files, the change, the check that proves it) to the implementer subagent, and keep the judgement calls yourself. Run the checks that prove the change. A check that already failed on the unchanged code is not yours to fix; say so.\n\n## 4. Verify\n\nBefore you finish, dispatch a fresh verification subagent on your diff, with the ticket and the plan, and fix what it finds that is real. Send one. Only for a risky change (a migration, auth, money, data that cannot be restored) send two or three with different lenses and treat their agreement as confirmation.\n\n## 5. Commit and report\n\nCommit on the branch you are on, with clear messages. Never push, never open or edit a pull request, and never change the git identity or config. Write the report the message asks for last, and honestly: each check you ran with its real exit code, what you could not verify and why, and every departure from the plan and why. A check you did not run is not a pass.\n\n## Rules that always hold\n\nNever fabricate a path, a result or a check: \"not found\" and \"not verified\" are answers. Never print, commit or send a token or a variable's value. If the disk fills (\"no space left on device\"), stop and say so; do not delete or prune to go on. Call record_decision only for a consequential product or architecture call the plan did not settle.\n";
|
|
40
40
|
/** Persona body keyed by the agent name referenced in `stages.ts`. */
|
|
41
41
|
export declare const PERSONA_BODIES: Record<string, string>;
|
|
42
42
|
/**
|
|
@@ -103,7 +103,7 @@ The option the person approved is binding. The plan's steps are guidance: when t
|
|
|
103
103
|
|
|
104
104
|
## 4. Verify
|
|
105
105
|
|
|
106
|
-
Before you finish, dispatch a fresh verification subagent on your diff, with the ticket and the plan, and fix what it finds that is real.
|
|
106
|
+
Before you finish, dispatch a fresh verification subagent on your diff, with the ticket and the plan, and fix what it finds that is real. Send one. Only for a risky change (a migration, auth, money, data that cannot be restored) send two or three with different lenses and treat their agreement as confirmation.
|
|
107
107
|
|
|
108
108
|
## 5. Commit and report
|
|
109
109
|
|
|
@@ -62,7 +62,13 @@ export interface SubagentDef {
|
|
|
62
62
|
/** The agent's system prompt (the markdown body). */
|
|
63
63
|
body: string;
|
|
64
64
|
source: SubagentSource;
|
|
65
|
+
/** This agent's own wall clock, when shorter than {@link SUBAGENT_WALL_TIMEOUT_MS}. */
|
|
66
|
+
wallTimeoutMs?: number;
|
|
65
67
|
}
|
|
68
|
+
/** How long one verification subagent may run: a review of a finished diff,
|
|
69
|
+
* not a second build (on staging 2026-10-28, advanced-tier verifiers ran 34
|
|
70
|
+
* minutes after an 11-minute build). */
|
|
71
|
+
export declare const VERIFICATION_WALL_TIMEOUT_MS: number;
|
|
66
72
|
/** Claude Code model names → YAGNI tiers; YAGNI tiers pass through. */
|
|
67
73
|
export declare function mapModelTier(model: string | undefined): ModelTier;
|
|
68
74
|
/**
|
|
@@ -154,7 +160,7 @@ export declare const SUBAGENT_WALL_TIMEOUT_MS: number;
|
|
|
154
160
|
* Exported so a test can pin the composed policy the production path actually
|
|
155
161
|
* runs (every unit test injects runStageImpl instead).
|
|
156
162
|
*/
|
|
157
|
-
export declare function subagentRunPolicy(): ResiliencePolicy;
|
|
163
|
+
export declare function subagentRunPolicy(wallTimeoutMs?: number): ResiliencePolicy;
|
|
158
164
|
/**
|
|
159
165
|
* The per-attempt telemetry adapter: one content-free error-sink row per
|
|
160
166
|
* resilience attempt (agent, taskIndex, outcome, timeoutKind, exit code,
|
|
@@ -212,23 +212,29 @@ What you could not check, and why.
|
|
|
212
212
|
|
|
213
213
|
A HOLDS after real digging is valuable; a rubber stamp is not. If you found
|
|
214
214
|
nothing, say exactly what you tried to break and how.`;
|
|
215
|
+
/** How long one verification subagent may run: a review of a finished diff,
|
|
216
|
+
* not a second build (on staging 2026-10-28, advanced-tier verifiers ran 34
|
|
217
|
+
* minutes after an 11-minute build). */
|
|
218
|
+
export const VERIFICATION_WALL_TIMEOUT_MS = 15 * 60_000;
|
|
215
219
|
/** The diamond's reduce layer: refute-first review of completed work on the
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
* /go's reviewer — not a
|
|
220
|
+
* peak tier (judgment is the whole job, so the premium is worth paying; the
|
|
221
|
+
* server exempts this caller from its advanced ceiling for subagents). One by
|
|
222
|
+
* default, on a fifteen-minute clock. It has no edit/write tools; bash is
|
|
223
|
+
* included for `git diff`-style inspection and is restricted to read-only USE
|
|
224
|
+
* by the persona, the same prompt-level stance as /go's reviewer — not a
|
|
225
|
+
* technical guarantee. */
|
|
221
226
|
const VERIFICATION_AGENT = {
|
|
222
227
|
name: "verification",
|
|
223
228
|
description: "Adversarial verification of completed work: tries to refute a change, " +
|
|
224
229
|
"plan, or claim and reports concrete failure scenarios. Does not edit " +
|
|
225
|
-
"files.
|
|
226
|
-
"codebase fit) for
|
|
227
|
-
"confirmation.",
|
|
228
|
-
model: "
|
|
230
|
+
"files. Send one; send two or three with different lenses (correctness, " +
|
|
231
|
+
"edge cases, codebase fit) only for a risky change such as a migration, " +
|
|
232
|
+
"auth or money, and treat agreement as confirmation.",
|
|
233
|
+
model: "peak",
|
|
229
234
|
tools: ["read", "grep", "find", "ls", "bash", "ask_yagni"],
|
|
230
235
|
body: VERIFICATION_BODY,
|
|
231
236
|
source: "builtin",
|
|
237
|
+
wallTimeoutMs: VERIFICATION_WALL_TIMEOUT_MS,
|
|
232
238
|
};
|
|
233
239
|
// Concrete tiers a subagent can actually run on. `balanced` is deliberately NOT
|
|
234
240
|
// a member here even though it is a member of `ModelTier`: a subagent needs
|
|
@@ -485,8 +491,8 @@ export const SUBAGENT_WALL_TIMEOUT_MS = 2 * 60 * 60_000;
|
|
|
485
491
|
* Exported so a test can pin the composed policy the production path actually
|
|
486
492
|
* runs (every unit test injects runStageImpl instead).
|
|
487
493
|
*/
|
|
488
|
-
export function subagentRunPolicy() {
|
|
489
|
-
return { ...DEFAULT_RESILIENCE_POLICY, wallTimeoutMs
|
|
494
|
+
export function subagentRunPolicy(wallTimeoutMs = SUBAGENT_WALL_TIMEOUT_MS) {
|
|
495
|
+
return { ...DEFAULT_RESILIENCE_POLICY, wallTimeoutMs, retryWallTimeout: false };
|
|
490
496
|
}
|
|
491
497
|
/**
|
|
492
498
|
* The per-attempt telemetry adapter: one content-free error-sink row per
|
|
@@ -525,10 +531,22 @@ export function makeSubagentTool(deps = {}) {
|
|
|
525
531
|
// text). The write-gate keys on the resolved agent's tools,
|
|
526
532
|
// passed per task below — the synthetic stage id is "implement" and would
|
|
527
533
|
// otherwise block retry of a read-only verifier forever.
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
534
|
+
// One wrapped runner per wall clock: an agent with its own (verification)
|
|
535
|
+
// gets a runner built on it, every other agent shares the lane's default.
|
|
536
|
+
const runners = new Map();
|
|
537
|
+
const runFor = (def) => {
|
|
538
|
+
if (deps.runStageImpl)
|
|
539
|
+
return deps.runStageImpl;
|
|
540
|
+
const wall = def.wallTimeoutMs ?? SUBAGENT_WALL_TIMEOUT_MS;
|
|
541
|
+
let runner = runners.get(wall);
|
|
542
|
+
if (!runner) {
|
|
543
|
+
runner = withResilience(runStage, subagentRunPolicy(wall), {
|
|
544
|
+
telemetry: subagentTelemetry(deps.env ?? process.env),
|
|
545
|
+
});
|
|
546
|
+
runners.set(wall, runner);
|
|
547
|
+
}
|
|
548
|
+
return runner;
|
|
549
|
+
};
|
|
532
550
|
const discover = deps.discover ?? discoverSubagents;
|
|
533
551
|
const grounded = deps.grounded !== false;
|
|
534
552
|
// Resolve the effective body for a spawned subagent: the grounding-free
|
|
@@ -647,7 +665,7 @@ export function makeSubagentTool(deps = {}) {
|
|
|
647
665
|
outcomes = await Promise.all(resolved.map(async ({ def, task }, index) => {
|
|
648
666
|
const progress = progresses[index];
|
|
649
667
|
const { stage, ctx: stageCtx } = buildSubagentStage(def, task, { grounded });
|
|
650
|
-
const result = await
|
|
668
|
+
const result = await runFor(def)(stage, stageCtx, {
|
|
651
669
|
cwd,
|
|
652
670
|
signal,
|
|
653
671
|
// Write-gate input: whether the agent's DECLARED tool list has
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yagni-app/code-staging",
|
|
3
|
-
"version": "1.2.12-staging.
|
|
3
|
+
"version": "1.2.12-staging.2145.1",
|
|
4
4
|
"description": "YAGNI Code: a terminal coding agent that already knows your company. One YAGNI login routes the model and grounds the agent in your team's context.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "YAGNI, Inc. <jack@yagni.app> (https://yagni.app)",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"turndown": "^7.2.4",
|
|
59
59
|
"typebox": "^1.3.15"
|
|
60
60
|
},
|
|
61
|
-
"yagniSourceSha": "
|
|
61
|
+
"yagniSourceSha": "4064b7ebffbbfcea04ce43830817cd6e35df7d77"
|
|
62
62
|
}
|