@phi-code-admin/phi-code 0.93.0 → 0.93.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.93.2] - 2026-07-12
4
+
5
+ ### Fixed
6
+
7
+ - /fix: a single shot that changed NOTHING (text-only reply, zero edits — a
8
+ measured 91s failure mode) no longer ends UNVERIFIED; in a git repo with a
9
+ clean tree it ESCALATES to the full pipeline (nothing to verify = the work
10
+ was not done). The shot instruction now states that acting with tools is
11
+ mandatory and a textual plan forfeits the attempt. +1 integration test.
12
+
13
+ ## [0.93.1] - 2026-07-12
14
+
15
+ ### Fixed
16
+
17
+ - /fix on PROSE input now has a real oracle: the single shot is instructed to
18
+ WRITE a literal reproduction (from the issue's exact snippets) and declare
19
+ it on a REPRO-CMD: handoff line; the driver oracle re-runs it. Without this,
20
+ prose inputs (e.g. SWE-bench problem statements) finished UNVERIFIED with
21
+ nothing to check. +2 tests.
22
+
3
23
  ## [0.93.0] - 2026-07-12
4
24
 
5
25
  ### Added — the escalation architecture the n=13 measurement demanded
@@ -315,10 +315,11 @@ export default function orchestratorExtension(pi: ExtensionAPI) {
315
315
  // untouched; "debug"/"build"/"fix" are driven by the separate linear generic
316
316
  // driver so /plan's fragile review-fix + "/5" logic is never engaged for them.
317
317
  let orchestrationMode: "plan" | "debug" | "build" | "fix" = "plan";
318
- // /fix escalation state: the failing state the command started from, and
319
- // whether the driver-level oracle already ran (it must run exactly once,
320
- // after the single-shot phase, before the run can finish).
321
- let fixContext: { state: FailingState; oracleRan: boolean } | null = null;
318
+ // /fix escalation state: the failing state the command started from, whether
319
+ // the driver-level oracle already ran (it must run exactly once, after the
320
+ // single-shot phase), and the reproduction the shot itself declared via its
321
+ // REPRO-CMD handoff line (prose inputs have no runnable check otherwise).
322
+ let fixContext: { state: FailingState; oracleRan: boolean; reproFromShot?: string } | null = null;
322
323
  // /debug --candidates N state: each FIX candidate's captured patch, the
323
324
  // reproduction command used for deterministic arbitration (from the input or
324
325
  // the REPRODUCE handoff's REPRO-CMD line), and whether arbitration ran.
@@ -1359,9 +1360,24 @@ Tag the note with relevant keywords for vector search.
1359
1360
  fixContext.oracleRan = true;
1360
1361
  const cwd = ctx.cwd || process.cwd();
1361
1362
  const sandbox = getSessionSandbox(cwd);
1362
- const reproCmd = fixContext.state.failingTest?.trim() || fixContext.state.reproCommand?.trim();
1363
+ const reproCmd =
1364
+ fixContext.state.failingTest?.trim() || fixContext.state.reproCommand?.trim() || fixContext.reproFromShot;
1363
1365
  const suiteCmd = sandbox.recipe.test?.trim();
1364
1366
 
1367
+ // A shot that changed NOTHING has nothing to verify — "UNVERIFIED" would be
1368
+ // a lie of omission (measured: a text-only 91s shot ended UNVERIFIED with
1369
+ // zero edits). In a git repo with a clean diff, escalate to the full
1370
+ // pipeline instead: the work simply was not done.
1371
+ const inGitRepo = passed(runCommand("git rev-parse --is-inside-work-tree", { cwd, timeoutMs: 15_000 }));
1372
+ if (inGitRepo && !gitIn(cwd, "diff").trim() && !gitIn(cwd, "status --porcelain").trim()) {
1373
+ ctx.ui.notify(
1374
+ `\n🔺 **/fix escalating: the single shot made NO changes** — nothing to verify, the full /debug pipeline takes over.`,
1375
+ "warning",
1376
+ );
1377
+ phaseQueue.push(...buildDebugPhases(fixContext.state));
1378
+ return false; // dispatch REPRODUCE
1379
+ }
1380
+
1365
1381
  if (!sandbox.available() && (reproCmd || suiteCmd)) {
1366
1382
  ctx.ui.notify(
1367
1383
  `\n⚠️ **/fix oracle: sandbox unavailable** (${sandbox.reason}) — the single shot cannot be verified. Treating it as UNVERIFIED.`,
@@ -1643,6 +1659,15 @@ Tag the note with relevant keywords for vector search.
1643
1659
  // handoff line (used later for deterministic arbitration);
1644
1660
  // - after each FIX candidate: capture its patch (git diff of tracked
1645
1661
  // files) and RESET the tree so the next candidate starts clean.
1662
+ // /fix: the single shot may have WRITTEN its own reproduction (prose
1663
+ // inputs) and declared it via REPRO-CMD — the driver oracle re-runs it.
1664
+ if (fixContext && currentPhase?.key === "shot" && !fixContext.reproFromShot) {
1665
+ fixContext.reproFromShot = parseReproCmd(outcome.handoff);
1666
+ if (fixContext.reproFromShot) {
1667
+ ctx.ui.notify(`\n🧷 Shot-declared reproduction registered: \`${fixContext.reproFromShot}\``, "info");
1668
+ }
1669
+ }
1670
+
1646
1671
  if (candidateContext && currentPhase) {
1647
1672
  const cwd = ctx.cwd || process.cwd();
1648
1673
  if (currentPhase.key === "reproduce" && !candidateContext.reproCmd) {
@@ -126,12 +126,18 @@ export function singleShotInstruction(state: FailingState): string {
126
126
  **The problem:**
127
127
  ${failing}
128
128
 
129
+ **You must ACT in this turn — call the read/edit/write tools and actually change the code. A textual plan or analysis with no edits counts as a FAILED shot (measured failure mode) and forfeits your attempt to the full pipeline.**
130
+
129
131
  **Do exactly this:**
130
132
  1. Read the relevant code and locate the root cause.
131
133
  2. Make the smallest change that addresses it. Do NOT edit tests. Every added guard/branch is a liability.
132
- 3. You MAY use \`sandbox_run\` to check your work (the project's real environment)recommended when a command is available.
133
- 4. After your change, the orchestrator will run the reproduction and the project suite in the sandbox itself: your work is judged by those REAL runs, not by your confidence. If they are red, a full diagnostic pipeline takes over from your change.
134
- 5. **Last action:** call \`phase_result\` with \`verdict: PASS\` and a one-line handoff describing what you changed and why.${DEBUG_RULES}`;
134
+ 3. If NO runnable check was provided above, WRITE a minimal reproduction script derived **literally from the issue** (copy its exact snippets/expected values not your paraphrase) into an untracked file (e.g. \`repro_issue.py\`), and confirm with \`sandbox_run\` that it fails before your change / passes after.
135
+ 4. You MAY use \`sandbox_run\` to check your work at any point (the project's real environment).
136
+ 5. After your change, the orchestrator re-runs the reproduction (and the suite when known) in the sandbox itself: your work is judged by those REAL runs, not by your confidence. If they are red, a full diagnostic pipeline takes over from your change.
137
+ 6. **Last action:** call \`phase_result\` with \`verdict: PASS\` and a handoff describing what you changed — and, when you wrote a reproduction, its exact command on a machine-readable line:
138
+ \`\`\`
139
+ REPRO-CMD: <the exact command, e.g. python repro_issue.py>
140
+ \`\`\`${DEBUG_RULES}`;
135
141
  }
136
142
 
137
143
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phi-code-admin/phi-code",
3
- "version": "0.93.0",
3
+ "version": "0.93.2",
4
4
  "description": "Coding agent CLI with persistent memory, sub-agents, intelligent routing, and orchestration",
5
5
  "type": "module",
6
6
  "piConfig": {