@yagni-app/code-staging 0.3.1-staging.1107.1 → 0.3.1-staging.1110.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.
- package/dist/extension/execPolicy.js +63 -0
- package/dist/extension/permission.d.ts +1 -1
- package/dist/extension/permission.js +53 -5
- package/dist/extension/pipeline/invocation.d.ts +24 -2
- package/dist/extension/pipeline/invocation.js +30 -2
- package/dist/extension/pipeline/personas.js +1 -1
- package/dist/extension/subagents.js +13 -0
- package/package.json +2 -2
|
@@ -612,6 +612,16 @@ function classifySegmentTokens(rawTokens, policy, opts) {
|
|
|
612
612
|
}
|
|
613
613
|
const { tokens: strippedTokens, stripped } = stripLeadingTokens(rawTokens);
|
|
614
614
|
if (strippedTokens.length === 0) {
|
|
615
|
+
// env standalone: `env` or `env VAR=val` with no following command prints
|
|
616
|
+
// environment variables — a read-only operation. stripLeadingTokens removes
|
|
617
|
+
// `env` as a wrapper word, leaving empty tokens. Recognize this case instead
|
|
618
|
+
// of returning "empty command segment" (YAG-549).
|
|
619
|
+
if (!opts.forbiddenOnly && rawTokens.length > 0 && basenameToken(rawTokens[0]) === "env") {
|
|
620
|
+
const onlyEnvAndAssignments = rawTokens.every((t) => basenameToken(t) === "env" || ENV_ASSIGNMENT_RE.test(t));
|
|
621
|
+
if (onlyEnvAndAssignments) {
|
|
622
|
+
return { decision: "allow", justification: "print environment variables (read-only)" };
|
|
623
|
+
}
|
|
624
|
+
}
|
|
615
625
|
return opts.forbiddenOnly
|
|
616
626
|
? { decision: "allow", justification: "no forbidden match" }
|
|
617
627
|
: { decision: "prompt", justification: "empty command segment" };
|
|
@@ -894,6 +904,59 @@ export const DEFAULT_EXEC_POLICY = {
|
|
|
894
904
|
{ pattern: ["pnpm", "list"], decision: "allow", justification: "list installed packages" },
|
|
895
905
|
{ pattern: ["pnpm", "--version"], decision: "allow", justification: "check pnpm version" },
|
|
896
906
|
{ pattern: ["tsc", "--version"], decision: "allow", justification: "check typescript version" },
|
|
907
|
+
// --- allow: CLI tool reads (YAG-549, based on prod Guardian data) ---
|
|
908
|
+
// linear CLI — read subcommands; write subcommands (create/update/delete/start/pr/attach/comment) stay prompt
|
|
909
|
+
{ pattern: ["linear", "issue", "comment", "list"], decision: "allow", justification: "list Linear issue comments (read-only)" },
|
|
910
|
+
{
|
|
911
|
+
pattern: ["linear", "issue"],
|
|
912
|
+
decision: "allow",
|
|
913
|
+
justification: "read Linear issue data",
|
|
914
|
+
unlessTokens: ["start", "create", "update", "delete", "pull-request", "pr", "attach", "comment"],
|
|
915
|
+
},
|
|
916
|
+
{ pattern: ["linear", ["--help", "-h"]], decision: "allow", justification: "show Linear CLI help" },
|
|
917
|
+
{ pattern: ["linear", ["--version", "-V"]], decision: "allow", justification: "show Linear CLI version" },
|
|
918
|
+
// gh api — REST GET (no params, no method override) and GraphQL queries (no mutation)
|
|
919
|
+
// gh api defaults to POST when -f/-F params are present, so params are disqualifying.
|
|
920
|
+
// GraphQL is always POST, but queries are reads; mutations/subscriptions are disqualifying.
|
|
921
|
+
{
|
|
922
|
+
pattern: ["gh", "api", "graphql"],
|
|
923
|
+
decision: "allow",
|
|
924
|
+
justification: "GraphQL query (read-only)",
|
|
925
|
+
unlessTokens: ["query=mutation*", "query=subscription*"],
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
pattern: ["gh", "api"],
|
|
929
|
+
decision: "allow",
|
|
930
|
+
justification: "GitHub API GET request (read-only)",
|
|
931
|
+
unlessTokens: ["--method", "-X", "-X*", "graphql", "POST", "PATCH", "DELETE", "PUT", "-f", "-F", "--raw-field", "--field"],
|
|
932
|
+
},
|
|
933
|
+
{ pattern: ["gh", "release", ["list", "view"]], decision: "allow", justification: "read GitHub release data" },
|
|
934
|
+
{ pattern: ["gh", "label", "list"], decision: "allow", justification: "list GitHub labels" },
|
|
935
|
+
{ pattern: ["gh", "milestone", "list"], decision: "allow", justification: "list GitHub milestones" },
|
|
936
|
+
{ pattern: ["gh", "auth", "status"], decision: "allow", justification: "show GitHub auth status" },
|
|
937
|
+
// git read-only subcommands
|
|
938
|
+
{ pattern: ["git", "tag"], decision: "allow", justification: "list tags (read-only)" },
|
|
939
|
+
{ pattern: ["git", "reflog"], decision: "allow", justification: "show reference log" },
|
|
940
|
+
{ pattern: ["git", "ls-remote"], decision: "allow", justification: "list remote refs" },
|
|
941
|
+
{ pattern: ["git", "cat-file"], decision: "allow", justification: "inspect git objects (read-only)" },
|
|
942
|
+
{ pattern: ["git", "for-each-ref"], decision: "allow", justification: "enumerate refs (read-only)" },
|
|
943
|
+
{ pattern: ["git", "rev-list"], decision: "allow", justification: "walk commit history (read-only)" },
|
|
944
|
+
{ pattern: ["git", "show-ref"], decision: "allow", justification: "list all refs" },
|
|
945
|
+
{ pattern: ["git", "name-rev"], decision: "allow", justification: "map commit to name (read-only)" },
|
|
946
|
+
{ pattern: ["git", "merge-base"], decision: "allow", justification: "find common ancestor (read-only)" },
|
|
947
|
+
// package manager test/lint — routine dev-loop operations
|
|
948
|
+
{ pattern: ["pnpm", "test"], decision: "allow", justification: "run tests (routine dev-loop operation)" },
|
|
949
|
+
{ pattern: ["pnpm", "lint"], decision: "allow", justification: "run linter (routine dev-loop operation)" },
|
|
950
|
+
{ pattern: ["npm", "test"], decision: "allow", justification: "run tests (routine dev-loop operation)" },
|
|
951
|
+
{ pattern: ["npm", "run", "lint"], decision: "allow", justification: "run linter (routine dev-loop operation)" },
|
|
952
|
+
{ pattern: ["npx", "tsc", "--noEmit"], decision: "allow", justification: "typecheck only (no file writes)" },
|
|
953
|
+
{ pattern: ["npx", "tsx", "--test"], decision: "allow", justification: "run tests (routine dev-loop operation)" },
|
|
954
|
+
{ pattern: ["npx", "vitest"], decision: "allow", justification: "run vitest tests (routine dev-loop operation)" },
|
|
955
|
+
{ pattern: ["npx", "vitest", "run"], decision: "allow", justification: "run vitest tests (routine dev-loop operation)" },
|
|
956
|
+
{ pattern: ["npx", "jest"], decision: "allow", justification: "run jest tests (routine dev-loop operation)" },
|
|
957
|
+
// misc read-only commands
|
|
958
|
+
{ pattern: ["printenv"], decision: "allow", justification: "print environment variables (read-only)" },
|
|
959
|
+
{ pattern: ["npm", ["view", "info"]], decision: "allow", justification: "read package metadata from registry" },
|
|
897
960
|
// --- prompt: potentially destructive but context-dependent ---
|
|
898
961
|
{ pattern: ["rm"], decision: "prompt", justification: "file deletion — review the target" },
|
|
899
962
|
{ pattern: ["git", "commit"], decision: "prompt", justification: "creates a commit — confirm intent" },
|
|
@@ -184,7 +184,7 @@ export interface RegisterPermissionDeps {
|
|
|
184
184
|
export declare const MODE_CONTEXT_TYPE = "yagni-mode-context";
|
|
185
185
|
/** Legacy alias — the original plan-mode tag, kept for backward compat. */
|
|
186
186
|
export declare const PLAN_CONTEXT_TYPE = "yagni-mode-context";
|
|
187
|
-
export declare const PLAN_CONTEXT_MESSAGE = "[PLAN MODE ACTIVE]\nYou are in plan mode: explore and design, change nothing.\n- write, edit, and
|
|
187
|
+
export declare const PLAN_CONTEXT_MESSAGE = "[PLAN MODE ACTIVE]\nYou are in plan mode: explore and design, change nothing.\n- Read-only bash commands (ls, grep, git status, gh pr view, etc.) run freely to help you explore.\n- Ambiguous bash commands are reviewed by the Guardian; if non-mutating they run, if potentially mutating you will be asked.\n- write, edit, file_ticket, and update_ticket_status are held by the permission gate; do not attempt them.\n- Read, search, and ask_yagni freely to ground the plan in how this company works.\n- Produce a concrete numbered plan of the steps you would take, with the files involved.\n- End by asking the user to review the plan; they run /mode auto (or /mode review) to execute it.\n- Once executing, track the plan's steps with todo_write.";
|
|
188
188
|
/** Build the mode-awareness context message for the current permission mode. */
|
|
189
189
|
export declare function buildModeContextMessage(mode: PermissionMode): string;
|
|
190
190
|
/**
|
|
@@ -56,6 +56,42 @@ export const DEFAULT_PERMISSION_POLICY = {
|
|
|
56
56
|
*/
|
|
57
57
|
export function decideGate(toolName, params, mode, policy) {
|
|
58
58
|
if (mode === "plan") {
|
|
59
|
+
// Non-bash tools in planBlockTools are held outright — they are
|
|
60
|
+
// inherently mutating (write, edit, file_ticket, update_ticket_status).
|
|
61
|
+
// Bash is the exploration tool: run it through the exec policy so
|
|
62
|
+
// read-only commands (git status, ls, grep, gh pr view) work, and
|
|
63
|
+
// prompt-band commands are routed to the Guardian. The gate handler
|
|
64
|
+
// ensures Guardian-unavailable/capped/disabled states fail closed.
|
|
65
|
+
if (toolName === "bash") {
|
|
66
|
+
const command = typeof params.command === "string" ? params.command.trim() : "";
|
|
67
|
+
if (command) {
|
|
68
|
+
try {
|
|
69
|
+
const execPolicy = policy.execPolicy ?? DEFAULT_EXEC_POLICY;
|
|
70
|
+
const classification = classifyCommand(command, execPolicy);
|
|
71
|
+
if (classification.decision === "allow")
|
|
72
|
+
return { block: false };
|
|
73
|
+
if (classification.decision === "forbidden") {
|
|
74
|
+
return {
|
|
75
|
+
block: true,
|
|
76
|
+
reason: `${classification.justification}. Do not attempt the same outcome via a workaround or indirect execution — use a materially safer alternative, or ask the user.`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// prompt — Guardian reviews. The gate handler runs the Guardian
|
|
80
|
+
// and handles allow/ask/deny. Grants and cache are skipped in
|
|
81
|
+
// plan mode (they can cover writes). Guardian unavailable/capped/
|
|
82
|
+
// disabled → block (fail closed).
|
|
83
|
+
return { block: false, classify: "prompt", classifyJustification: classification.justification };
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// classifyCommand threw — fail closed in plan mode.
|
|
87
|
+
return {
|
|
88
|
+
block: true,
|
|
89
|
+
reason: `plan mode: could not classify this bash command and it is held. Switch to /mode auto to apply changes.`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { block: false };
|
|
94
|
+
}
|
|
59
95
|
if (policy.planBlockTools.includes(toolName)) {
|
|
60
96
|
return {
|
|
61
97
|
block: true,
|
|
@@ -122,7 +158,9 @@ const AUTO_MARKER = "[AUTO MODE]";
|
|
|
122
158
|
const REVIEW_MARKER = "[REVIEW MODE]";
|
|
123
159
|
export const PLAN_CONTEXT_MESSAGE = `${PLAN_MARKER}
|
|
124
160
|
You are in plan mode: explore and design, change nothing.
|
|
125
|
-
-
|
|
161
|
+
- Read-only bash commands (ls, grep, git status, gh pr view, etc.) run freely to help you explore.
|
|
162
|
+
- Ambiguous bash commands are reviewed by the Guardian; if non-mutating they run, if potentially mutating you will be asked.
|
|
163
|
+
- write, edit, file_ticket, and update_ticket_status are held by the permission gate; do not attempt them.
|
|
126
164
|
- Read, search, and ask_yagni freely to ground the plan in how this company works.
|
|
127
165
|
- Produce a concrete numbered plan of the steps you would take, with the files involved.
|
|
128
166
|
- End by asking the user to review the plan; they run /mode auto (or /mode review) to execute it.
|
|
@@ -414,7 +452,9 @@ export function registerPermissionGate(pi, deps = {}) {
|
|
|
414
452
|
}
|
|
415
453
|
}
|
|
416
454
|
// 2. Session exact-command approval cache (ticket 4.5).
|
|
417
|
-
|
|
455
|
+
// Skipped in plan mode: a cached approval can cover a write command,
|
|
456
|
+
// and plan mode's contract is no mutations without Guardian review.
|
|
457
|
+
if (modeAtEntry !== "plan" && command && approvedCommands.has(cacheKey(cwd, command))) {
|
|
418
458
|
emitGateEvent({ ...eventBase, outcome: "cached_allow", consulted: false });
|
|
419
459
|
return {};
|
|
420
460
|
}
|
|
@@ -423,13 +463,13 @@ export function registerPermissionGate(pi, deps = {}) {
|
|
|
423
463
|
if (guardianAvailable && guardianState.read().reviews >= limits.maxReviews) {
|
|
424
464
|
// Sliding-window consult cap (capacity recovers as old reviews age
|
|
425
465
|
// out — a long-lived session is never bricked). Review mode falls
|
|
426
|
-
// through to its ordinary confirm (no LLM cost); auto
|
|
427
|
-
if (modeAtEntry === "auto") {
|
|
466
|
+
// through to its ordinary confirm (no LLM cost); auto and plan block.
|
|
467
|
+
if (modeAtEntry === "auto" || modeAtEntry === "plan") {
|
|
428
468
|
if (ctx?.hasUI)
|
|
429
469
|
ctx.ui.notify(`Guardian review cap reached (${limits.maxReviews} in the last hour).`, "warning");
|
|
430
470
|
return { block: true, reason: `Guardian review cap reached (${limits.maxReviews} in the last hour). Capacity recovers as older reviews age out; switch to /mode review to approve manually, or retry this step later.` };
|
|
431
471
|
}
|
|
432
|
-
// fall through to decision.confirm below
|
|
472
|
+
// review mode: fall through to decision.confirm below
|
|
433
473
|
}
|
|
434
474
|
else if (guardianAvailable) {
|
|
435
475
|
// Circuit breaker (pre-consult). With a UI, escalate to ONE ask per
|
|
@@ -675,6 +715,14 @@ export function registerPermissionGate(pi, deps = {}) {
|
|
|
675
715
|
// approval cache were already consulted above.
|
|
676
716
|
return {};
|
|
677
717
|
}
|
|
718
|
+
else if (modeAtEntry === "plan") {
|
|
719
|
+
// Guardian disabled or not wired in plan mode: fail closed. Without
|
|
720
|
+
// the Guardian to verify the command is non-mutating, the plan-mode
|
|
721
|
+
// contract (no changes) cannot be upheld. The user can switch to
|
|
722
|
+
// /mode auto or /mode review to proceed.
|
|
723
|
+
emitGateEvent({ ...eventBase, outcome: "breaker_blocked", consulted: false });
|
|
724
|
+
return { block: true, reason: "Guardian unavailable in plan mode. Switch to /mode auto to run commands, or /mode review to approve manually." };
|
|
725
|
+
}
|
|
678
726
|
// review mode with Guardian disabled/capped: fall through to confirm.
|
|
679
727
|
}
|
|
680
728
|
if (decision.confirm) {
|
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
* `buildLaunch` (no spawn, no fs).
|
|
4
4
|
*
|
|
5
5
|
* `buildStageInvocation` produces the per-stage pi PASSTHROUGH argv exactly as
|
|
6
|
-
* the subagent example assembles it (runSingleAgent L294-330)
|
|
6
|
+
* the subagent example assembles it (runSingleAgent L294-330), with an added
|
|
7
|
+
* honesty preamble delivered as the FIRST `--append-system-prompt` so the
|
|
8
|
+
* anti-fabrication rule appears before the persona body in the child's
|
|
9
|
+
* assembled system prompt:
|
|
7
10
|
* --mode json -p --no-session --model <tier> --tools <csv>
|
|
8
|
-
* --append-system-prompt <file> 'Task: <rendered>'
|
|
11
|
+
* --append-system-prompt <honesty> --append-system-prompt <file> 'Task: <rendered>'
|
|
12
|
+
*
|
|
13
|
+
* Pi concatenates multiple `--append-system-prompt` values with `\n\n` in
|
|
14
|
+
* array order, so the child sees: [pi base] + [honesty] + [persona] +
|
|
15
|
+
* [project_context]. The preamble is placed first so open-weight models
|
|
16
|
+
* encounter the anti-fabrication rule before their role identity.
|
|
9
17
|
*
|
|
10
18
|
* `groundedChildArgv` prepends the grounding pi-args the yagni-code launcher
|
|
11
19
|
* would otherwise add (`-e <self> --provider yagni`) because v1 spawns pi
|
|
@@ -17,6 +25,20 @@
|
|
|
17
25
|
* chain's `step.task.replace(/{previous}/g, …)`.
|
|
18
26
|
*/
|
|
19
27
|
import type { PipelineStage, ReviewLens } from "./types.js";
|
|
28
|
+
/**
|
|
29
|
+
* Anti-fabrication preamble injected as the first `--append-system-prompt` on
|
|
30
|
+
* every child pi process (both /go stages and subagent tool calls). The
|
|
31
|
+
* driver-only `ENGINEERING_PRACTICE_SECTION` never reaches children (it's a
|
|
32
|
+
* launcher flag, and children build their own argv); this preamble ensures
|
|
33
|
+
* the honesty rule is present in every child regardless.
|
|
34
|
+
*
|
|
35
|
+
* Content constraints (same as the enrichment section — the branding scrub's
|
|
36
|
+
* `scrubOutsideProjectContext` replaces whole-word \bpi\b and the
|
|
37
|
+
* `PI_DOCS_BLOCK_RE` regex consumes consecutive `- ` bullet lines that follow
|
|
38
|
+
* a docs header): must not contain the standalone word "pi", must not open
|
|
39
|
+
* with a `- ` bullet line, no emojis.
|
|
40
|
+
*/
|
|
41
|
+
export declare const CHILD_HONESTY_PREAMBLE: string;
|
|
20
42
|
/** Fill {ticket}/{previous}; an absent var renders as empty string. */
|
|
21
43
|
export declare function renderTemplate(tmpl: string, vars: {
|
|
22
44
|
ticket?: string;
|
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
* `buildLaunch` (no spawn, no fs).
|
|
4
4
|
*
|
|
5
5
|
* `buildStageInvocation` produces the per-stage pi PASSTHROUGH argv exactly as
|
|
6
|
-
* the subagent example assembles it (runSingleAgent L294-330)
|
|
6
|
+
* the subagent example assembles it (runSingleAgent L294-330), with an added
|
|
7
|
+
* honesty preamble delivered as the FIRST `--append-system-prompt` so the
|
|
8
|
+
* anti-fabrication rule appears before the persona body in the child's
|
|
9
|
+
* assembled system prompt:
|
|
7
10
|
* --mode json -p --no-session --model <tier> --tools <csv>
|
|
8
|
-
* --append-system-prompt <file> 'Task: <rendered>'
|
|
11
|
+
* --append-system-prompt <honesty> --append-system-prompt <file> 'Task: <rendered>'
|
|
12
|
+
*
|
|
13
|
+
* Pi concatenates multiple `--append-system-prompt` values with `\n\n` in
|
|
14
|
+
* array order, so the child sees: [pi base] + [honesty] + [persona] +
|
|
15
|
+
* [project_context]. The preamble is placed first so open-weight models
|
|
16
|
+
* encounter the anti-fabrication rule before their role identity.
|
|
9
17
|
*
|
|
10
18
|
* `groundedChildArgv` prepends the grounding pi-args the yagni-code launcher
|
|
11
19
|
* would otherwise add (`-e <self> --provider yagni`) because v1 spawns pi
|
|
@@ -16,6 +24,24 @@
|
|
|
16
24
|
* `renderTemplate` does the {ticket}/{previous} substitution, mirroring the
|
|
17
25
|
* chain's `step.task.replace(/{previous}/g, …)`.
|
|
18
26
|
*/
|
|
27
|
+
/**
|
|
28
|
+
* Anti-fabrication preamble injected as the first `--append-system-prompt` on
|
|
29
|
+
* every child pi process (both /go stages and subagent tool calls). The
|
|
30
|
+
* driver-only `ENGINEERING_PRACTICE_SECTION` never reaches children (it's a
|
|
31
|
+
* launcher flag, and children build their own argv); this preamble ensures
|
|
32
|
+
* the honesty rule is present in every child regardless.
|
|
33
|
+
*
|
|
34
|
+
* Content constraints (same as the enrichment section — the branding scrub's
|
|
35
|
+
* `scrubOutsideProjectContext` replaces whole-word \bpi\b and the
|
|
36
|
+
* `PI_DOCS_BLOCK_RE` regex consumes consecutive `- ` bullet lines that follow
|
|
37
|
+
* a docs header): must not contain the standalone word "pi", must not open
|
|
38
|
+
* with a `- ` bullet line, no emojis.
|
|
39
|
+
*/
|
|
40
|
+
export const CHILD_HONESTY_PREAMBLE = "Never fabricate file paths, file contents, function signatures, enum values, or code. " +
|
|
41
|
+
"If you cannot find something, say so explicitly — an honest \"not found\" is more valuable " +
|
|
42
|
+
"than a plausible-sounding invention. Every file path you cite must be a path you actually " +
|
|
43
|
+
"read with a tool. If you are uncertain whether something exists, say you are uncertain " +
|
|
44
|
+
"rather than presenting a guess as a finding.";
|
|
19
45
|
/** Fill {ticket}/{previous}; an absent var renders as empty string. */
|
|
20
46
|
export function renderTemplate(tmpl, vars) {
|
|
21
47
|
return tmpl
|
|
@@ -41,6 +67,8 @@ export function buildStageInvocation(stage, ctx) {
|
|
|
41
67
|
"--tools",
|
|
42
68
|
stage.tools.join(","),
|
|
43
69
|
"--append-system-prompt",
|
|
70
|
+
CHILD_HONESTY_PREAMBLE,
|
|
71
|
+
"--append-system-prompt",
|
|
44
72
|
ctx.promptFilePath,
|
|
45
73
|
`Task: ${task}`,
|
|
46
74
|
];
|
|
@@ -107,7 +107,7 @@ Risk taxonomy:
|
|
|
107
107
|
Outcome rules:
|
|
108
108
|
- "deny" is reserved for actions you are VERY CONFIDENT are very dangerous: irreversible destruction, exfiltration of sensitive data, credential probing, production-impacting security weakening. If you are not sure it is that bad, do not deny.
|
|
109
109
|
- "allow" when you are confident the action is safe: read-only, routine dev-loop, or clearly scoped and reversible.
|
|
110
|
-
- "ask" for
|
|
110
|
+
- "ask" for actions where a specific, concrete risk makes you unsure — the action has a plausible path to harm that you cannot rule out by reading the command. Do not ask just because a command "might" do something; ask when you can name the specific thing you are worried about. If you cannot articulate a concrete risk, allow. Prefer allow over ask: routine dev-loop operations, local file writes within a project, and standard git operations (add, commit, fetch) are safe — the agent is already operating in the user's repository with their consent.
|
|
111
111
|
|
|
112
112
|
Rationale rules:
|
|
113
113
|
- For "ask", the rationale MUST be a specific question addressed to the user, naming the concrete effect that made you unsure — e.g. "This pushes 3 commits to the shared main branch — do you want to publish them now?". You may be told why the static policy routed the command to you; your rationale must ADD information beyond that policy text, not restate it.
|
|
@@ -72,6 +72,8 @@ const GENERAL_BODY = `You are a capable software-engineering subagent with a fre
|
|
|
72
72
|
|
|
73
73
|
You are grounded in how THIS company works: call ask_yagni before inferring a convention, an ownership rule, or anything organization-specific.
|
|
74
74
|
|
|
75
|
+
Never fabricate file paths, contents, or findings. If you cannot find something, say so.
|
|
76
|
+
|
|
75
77
|
Your final message is your report back to the driving agent, which has NOT seen what you read or did. Make it compressed and complete: what you did, what you found, exact file paths and key excerpts, and anything the driver must know before continuing.`;
|
|
76
78
|
const GENERAL_AGENT = {
|
|
77
79
|
name: GENERAL_AGENT_NAME,
|
|
@@ -87,6 +89,11 @@ not write code and you do not run commands; you read and report.
|
|
|
87
89
|
You are grounded in how THIS company works: call ask_yagni before inferring a
|
|
88
90
|
convention, an ownership rule, or anything organization-specific.
|
|
89
91
|
|
|
92
|
+
Never fabricate file paths, contents, or code. Every path you cite must be
|
|
93
|
+
one you actually read with a tool. If you cannot find something, say "not
|
|
94
|
+
found" — a plausible-sounding invention is worse than no answer because the
|
|
95
|
+
driving agent trusts your report.
|
|
96
|
+
|
|
90
97
|
Your final message is your report back to the driving agent, which has NOT
|
|
91
98
|
seen what you read. Make it compressed and complete: exact file paths, the
|
|
92
99
|
key excerpts, and a one-paragraph map of how the pieces relate. Say what you
|
|
@@ -112,6 +119,9 @@ your final message instead of guessing.
|
|
|
112
119
|
You are grounded in how THIS company works: call ask_yagni before inferring a
|
|
113
120
|
convention, an ownership rule, or anything organization-specific.
|
|
114
121
|
|
|
122
|
+
Never fabricate file paths or results. Report what you actually did and what
|
|
123
|
+
you actually found.
|
|
124
|
+
|
|
115
125
|
Your final message is your report back to the driving agent, which has NOT
|
|
116
126
|
seen what you did. List every file you touched, what changed in each, the
|
|
117
127
|
commands you ran with their outcomes, and anything you deliberately left
|
|
@@ -141,6 +151,9 @@ verifiers.
|
|
|
141
151
|
You are grounded in how THIS company works: call ask_yagni before inferring
|
|
142
152
|
a convention, an ownership rule, or anything organization-specific.
|
|
143
153
|
|
|
154
|
+
Never fabricate file paths or findings. If you could not verify something,
|
|
155
|
+
say exactly what you tried and why you could not.
|
|
156
|
+
|
|
144
157
|
Your final message is your verdict back to the driving agent, which has NOT
|
|
145
158
|
seen what you read. Format:
|
|
146
159
|
## Verdict
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yagni-app/code-staging",
|
|
3
|
-
"version": "0.3.1-staging.
|
|
3
|
+
"version": "0.3.1-staging.1110.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)",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"smol-toml": "^1.8.0",
|
|
40
40
|
"typebox": "^1.3.11"
|
|
41
41
|
},
|
|
42
|
-
"yagniSourceSha": "
|
|
42
|
+
"yagniSourceSha": "95876e9f6b0c4a81a474224dcf37cf6939df7f6d"
|
|
43
43
|
}
|