Skip to content

Commit 038d2ae

Browse files
committed
fix(compaction): strip glued sentinel even when the token ends with dots
The skip existed so operator-authored trailing ellipsis stayed intact. A long start-at-0 token that itself ends with "..." still gets a glued spine sentinel, so Goal and Output harvests diverge the same way as a token without ellipsis. Short operator cases already match as one token and do not need the skip.
1 parent ec8bf3a commit 038d2ae

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

‎src/session/compaction-handoff.test.ts‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,34 @@ describe("iterative folding", () => {
773773
expect(withoutFile.artifact.goal).not.toContain(`${token} ${token}`);
774774
});
775775

776+
test("two without-file re-folds of a start-at-0 token ending with ellipsis keep one Output token", () => {
777+
const token = `FILES_DONE=${"src/session/compaction-handoff.ts/".repeat(8)}end...`;
778+
expect(token.length).toBeGreaterThan(160);
779+
expect(token.endsWith("...")).toBe(true);
780+
const goal = `${token} trailing prose after the standing token`;
781+
const first = buildHandoffFold([userTurn(goal)], "narrative");
782+
expect(first.artifact.goal).toBe(goal);
783+
expect(first.spineText).toContain(`Output: ${token}`);
784+
785+
const withoutFile = buildHandoffFold(
786+
[spineTurn(first.spineText), userTurn("Continue.")],
787+
"narrative",
788+
);
789+
const again = buildHandoffFold(
790+
[spineTurn(withoutFile.spineText), userTurn("Continue.")],
791+
"narrative",
792+
);
793+
794+
for (const fold of [withoutFile, again]) {
795+
expect(
796+
fold.spineText.split("\n").find((line) => line.startsWith("Output: ")),
797+
).toBe(`Output: ${token}`);
798+
expect(fold.artifact.goal).toBe(token);
799+
expect(fold.artifact.goal).not.toContain(`${token} ${token}`);
800+
expect(fold.artifact.goal).not.toContain(`${token}... ${token}`);
801+
}
802+
});
803+
776804
test("without-file re-fold of a start-at-0 comma-joined FILES_DONE keeps one token", () => {
777805
const token = `FILES_DONE=${Array.from({ length: 20 }, (_, i) => `src/session/file${i}.ts`).join(",")}`;
778806
expect(token.length).toBeGreaterThan(160);

‎src/session/compaction-handoff.ts‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,9 @@ function mergeStandingOutputToken(
156156
// cutSpineGoal glues "..." onto a start-at-0 token longer than the cap.
157157
// outputFormatTokenRe (\S+) eats that sentinel, so Goal's harvested token
158158
// is token+"..." and never equals the Output token. Strip the glued
159-
// sentinel and keep the standing token once.
160-
if (
161-
goal.endsWith(SPINE_CUT_SENTINEL) &&
162-
!token.endsWith(SPINE_CUT_SENTINEL)
163-
) {
159+
// sentinel and keep the standing token once, including when the standing
160+
// token already ends with "...".
161+
if (goal.endsWith(SPINE_CUT_SENTINEL)) {
164162
const prefix = goal.slice(0, -SPINE_CUT_SENTINEL.length);
165163
if (
166164
hasStandingOutputToken(prefix, token) ||

0 commit comments

Comments
 (0)