mirror of
https://github.com/wassname/pi-goals.git
synced 2026-09-12 12:50:58 +08:00
Skip small-context Ready compaction
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# Real Herdr acceptance — 2026-09-09
|
||||
|
||||
- revision tested: `f49be72a307bbc4d22fd3468d090255e72389bc9`
|
||||
- isolated repo: `/tmp/pi-goals-herdr-uat` (separate test pane `w8:p5V`; supervisor `w8:p5W`)
|
||||
- worker model: `gpt-5.6-terra`; supervisor model: `gpt-5.6-terra`
|
||||
- intervention: selected **Ready** in the worker's rendered plan menu; no implementation or sign-off was performed by the test driver.
|
||||
|
||||
## Observations
|
||||
|
||||
- The worker rendered a bounded plan and selected Ready opened a visible `goals-supervisor-...` pane.
|
||||
- The worker produced and committed `hello.txt` and `verification.txt`; the supervisor inspected both files and reran the byte check.
|
||||
- The supervisor recorded approval and sent the worker the exact `CompleteGoal` instruction. The worker invoked `CompleteGoal`; the plan was mechanically ticked `[x]`.
|
||||
- Direct inspection after the cycle:
|
||||
|
||||
> `xxd -g1 hello.txt` printed `68 65 6c 6c 6f 0a`.
|
||||
>
|
||||
> `verification.txt` says `status: exact match`.
|
||||
>
|
||||
> The plan log says `mechanically signed off "Create hello.txt and record its exact byte check in verification.txt" after matching supervisor approval`.
|
||||
|
||||
## Failure observed
|
||||
|
||||
The Ready compaction attempt visibly printed:
|
||||
|
||||
> `Error: Compaction failed: Nothing to compact (session too small)`
|
||||
|
||||
The extension caught that condition and continued: the supervisor opened and the full approval cycle succeeded. Functional acceptance still found an unresolved user-visible error for short plans. Skip the worker pre-fork `ctx.compact()` call when context use is below the existing 100k supervisor threshold, then run this same UAT again.
|
||||
|
||||
## Post-fix rerun attempt
|
||||
|
||||
- revision: `050f85c8d8346e64b0b260f454c57fd08d1e1fa0`
|
||||
- isolated repo: `/tmp/pi-goals-herdr-uat-smallcontext`; created test pane: `w8:p5X` with `--no-focus`
|
||||
- pre-run status: clean; existing dependencies installed locally with `npm ci`.
|
||||
|
||||
The real interactive rerun could not start because the normal Pi profile loaded its separately installed `pi-goals` extension first. Its installed `pi-intercom` reported no extension channel, then the test extension could not register the duplicate `pi-goals` namespace. This is an environment/profile dependency conflict, not a result from the changed small-context path; no Ready action, supervisor pane, or worker work was performed. The test pane was closed after capture. The focused mocked flow test covers the changed 57k-token path; a clean normal-profile Pi environment is still required to repeat the functional UAT.
|
||||
|
||||
-- PI[gpt-5.6-terra]
|
||||
+4
-2
@@ -28,7 +28,7 @@ import { GoalIntercom } from "./intercom.js";
|
||||
import { FOLD_LINE, foldPlan, GOAL_LINE } from "./plan.js";
|
||||
import { completeGoalDescription, completeGoalParamDescription, planDrafting, planningState, resync, supervisorPlanReview, workerCompaction } from "./prompts.js";
|
||||
import { RoleModels } from "./role-models.js";
|
||||
import { isVisibleSupervisor, registerVisibleSupervisor, restoredSupervisor } from "./supervisor-session.js";
|
||||
import { COMPACT_AT_TOKENS, isVisibleSupervisor, registerVisibleSupervisor, restoredSupervisor } from "./supervisor-session.js";
|
||||
import { workerView } from "./worker-view.js";
|
||||
|
||||
export { foldPlan } from "./plan.js";
|
||||
@@ -257,6 +257,8 @@ export function registerWorker(pi: ExtensionAPI): void {
|
||||
|
||||
/** Compact the agreed planning conversation once, before the supervisor forks it. */
|
||||
function compactApprovedWorker(ctx: ExtensionContext): Promise<void> {
|
||||
const tokens = ctx.getContextUsage()?.tokens;
|
||||
if (typeof tokens === "number" && tokens < COMPACT_AT_TOKENS) return Promise.resolve();
|
||||
return new Promise((resolve, reject) => {
|
||||
ctx.compact({
|
||||
customInstructions: workerCompaction(planPath(ctx)),
|
||||
@@ -680,7 +682,7 @@ export function registerWorker(pi: ExtensionAPI): void {
|
||||
pi.on("context", async (event, ctx) => {
|
||||
const messages = state.phase === "planning" ? event.messages : event.messages.filter((message) => (message as { customType?: string }).customType !== PLANNING_CONTEXT);
|
||||
const removedPlanningContext = messages.length !== event.messages.length;
|
||||
// Ready compacts the worker before changing phase. Its custom instructions already preserve
|
||||
// Ready may compact the worker before changing phase. Its custom instructions already preserve
|
||||
// the approved plan, so never append an extension message to that compaction transaction.
|
||||
if (state.phase === "planning" && planningContextPending && !readyAttempt) {
|
||||
planningContextPending = false;
|
||||
|
||||
@@ -11,7 +11,8 @@ import { approveGoalDescription, approveGoalParameters, goalApprovalRecorded, st
|
||||
import { RoleModels } from "./role-models.js";
|
||||
|
||||
const BOOTSTRAPPED = "pi-goals-visible-supervisor-v2";
|
||||
const COMPACT_AT_TOKENS = 100_000;
|
||||
/** Context size at which paired sessions compact before or during supervision. */
|
||||
export const COMPACT_AT_TOKENS = 100_000;
|
||||
|
||||
const ROLE_STATE = "pi-goals-supervisor-binding";
|
||||
|
||||
|
||||
+15
-1
@@ -215,6 +215,19 @@ describe("/goals flow", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("skips small-context worker compaction and still starts the visible supervisor", async () => {
|
||||
const flow = setup(["Ready"]);
|
||||
try {
|
||||
flow.ctx.getContextUsage = () => ({ percent: 25, tokens: 57_000 });
|
||||
await flow.commands.get("goals").handler("make the file", flow.ctx);
|
||||
approvedPlan(flow.cwd);
|
||||
await flow.hooks.get("agent_settled")({}, flow.ctx);
|
||||
expect(flow.ctx.compact).not.toHaveBeenCalled();
|
||||
expect(openSupervisorPane).toHaveBeenCalledOnce();
|
||||
expect(flow.entries.at(-1)?.data).toMatchObject({ phase: "working", supervisorPaneId: "pane-2" });
|
||||
} finally { rmSync(flow.cwd, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
it("forks a visible supervisor on Ready and keeps the main session as worker", async () => {
|
||||
const flow = setup(["Ready"]);
|
||||
try {
|
||||
@@ -528,9 +541,10 @@ it.each(["launch", "model"])("rejects plan content changes during Ready %s witho
|
||||
} finally { rmSync(flow.cwd, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
it("compacts the approved worker before forking the supervisor without injecting planning context", async () => {
|
||||
it("compacts the approved worker at the shared threshold before forking without injecting planning context", async () => {
|
||||
const flow = setup(["Ready"]);
|
||||
try {
|
||||
flow.ctx.getContextUsage = () => ({ percent: 25, tokens: 100_000 });
|
||||
let complete: (() => void) | undefined;
|
||||
flow.ctx.compact.mockImplementationOnce((options: any) => { complete = options.onComplete; });
|
||||
await flow.commands.get("goals").handler("make the file", flow.ctx);
|
||||
|
||||
Reference in New Issue
Block a user