autoCompactWindow is set by flag and never read back — the #175 shape in a second place #232

Closed
opened 2026-09-02 13:00:53 +02:00 by ltms · 1 comment
Owner

Spotted by the #175 worker while fixing the model read-back, reported as out of scope. Filing it rather than losing it.

The shape

#175 was not really "a withdrawn model name". It was: fleetd sets a backend option by flag and treats the process starting as proof the option took effect. The backend is free to ignore, substitute, or clamp the value, and nothing checks.

OpenCodeLauncher.buildLaunch sets autoCompactWindow the same way. It goes out on the launch command and is never confirmed.

#175's own "Suggested direction" already named this as point 3, and it turned out to be right about the general case before anyone looked at the specific one.

Why this one is less severe than #175

Worth saying plainly, so nobody treats it as urgent:

  • A wrong autoCompactWindow does not move work onto a paid credential. It costs context, not money.
  • #214/#220 showed the failure is at least partly loud: an --autocompact 25 truncated by the pane's 1024-byte line made claude-code refuse to start, so the spawn died at the readiness gate rather than running silently wrong.

The quiet case is the one worth checking: a value the backend accepts but clamps or ignores. Then every member runs with a compaction window nobody chose, and the only symptom is members compacting earlier or later than the operator configured — which looks like normal variation.

What to do

  1. Establish whether either backend records the effective value anywhere readable. For opencode, the session table is already opened by the #209 late-resolve path and #175's read-back, so if it carries the value it is free to check there. Check session.metadata and the schema before assuming.
  2. If it is readable, compare it the way #175 does — and reuse #175's rules exactly: absent/incomplete/unparseable evidence is UNKNOWN, never a mismatch, and must never quarantine a working profile.
  3. If it is NOT readable anywhere, say so in this ticket and close it. "We checked and the backend does not report it" is a real answer and stops the question being reopened. Do not invent a probe.

Do not quarantine on this one. A wrong compaction window is not a reason to stop a credential. An ERROR log naming both values is the right response, and that difference from #175 is deliberate — match the response to the harm.

Acceptance

  • A written answer to "does either backend expose the effective value?", with the schema or output that settles it.
  • If checkable: the check runs on the late-resolve path where the evidence exists, not at spawn. #203 was closed for running at spawn, and #175's fix is the worked example of doing it correctly.
  • A test that proves the check runs on the real path, not one that injects the record.

Related

#175 (the same shape, fixed — reuse its mechanism and its UNKNOWN rules) · #203 (closed: ran at spawn, could never fire) · #209 (the late-resolve step both hook into) · #220 (why a long launch command is its own hazard) · #113 (checkers narrower than they look).

Spotted by the #175 worker while fixing the model read-back, reported as out of scope. Filing it rather than losing it. ## The shape #175 was not really "a withdrawn model name". It was: **fleetd sets a backend option by flag and treats the process starting as proof the option took effect.** The backend is free to ignore, substitute, or clamp the value, and nothing checks. `OpenCodeLauncher.buildLaunch` sets `autoCompactWindow` the same way. It goes out on the launch command and is never confirmed. #175's own "Suggested direction" already named this as point 3, and it turned out to be right about the general case before anyone looked at the specific one. ## Why this one is less severe than #175 Worth saying plainly, so nobody treats it as urgent: - A wrong `autoCompactWindow` does not move work onto a paid credential. It costs context, not money. - #214/#220 showed the failure is at least partly loud: an `--autocompact 25` truncated by the pane's 1024-byte line made claude-code refuse to start, so the spawn died at the readiness gate rather than running silently wrong. The quiet case is the one worth checking: a value the backend accepts but clamps or ignores. Then every member runs with a compaction window nobody chose, and the only symptom is members compacting earlier or later than the operator configured — which looks like normal variation. ## What to do 1. Establish whether either backend records the effective value anywhere readable. For opencode, the `session` table is already opened by the #209 late-resolve path and #175's read-back, so if it carries the value it is free to check there. Check `session.metadata` and the schema before assuming. 2. If it is readable, compare it the way #175 does — and reuse #175's rules exactly: absent/incomplete/unparseable evidence is UNKNOWN, never a mismatch, and must never quarantine a working profile. 3. If it is NOT readable anywhere, say so in this ticket and close it. "We checked and the backend does not report it" is a real answer and stops the question being reopened. Do not invent a probe. **Do not quarantine on this one.** A wrong compaction window is not a reason to stop a credential. An ERROR log naming both values is the right response, and that difference from #175 is deliberate — match the response to the harm. ## Acceptance - A written answer to "does either backend expose the effective value?", with the schema or output that settles it. - If checkable: the check runs on the late-resolve path where the evidence exists, not at spawn. #203 was closed for running at spawn, and #175's fix is the worked example of doing it correctly. - A test that proves the check runs on the real path, not one that injects the record. ## Related #175 (the same shape, fixed — reuse its mechanism and its UNKNOWN rules) · #203 (closed: ran at spawn, could never fire) · #209 (the late-resolve step both hook into) · #220 (why a long launch command is its own hazard) · #113 (checkers narrower than they look).
Author
Owner

Checked. opencode does not report it. Closing with no code change.

This is outcome 3 from the ticket's own "What to do": "We checked and the backend does not report it." No probe was invented and no code changed.

The evidence

Read-only against the live database, ~/.local/share/opencode/opencode.db:

SELECT sql FROM sqlite_master WHERE type='table' AND name='session';
CREATE TABLE `session` (
  `id` text PRIMARY KEY, `project_id` text NOT NULL, `workspace_id` text,
  `parent_id` text, `slug` text NOT NULL, `directory` text NOT NULL, `path` text,
  `title` text NOT NULL, `version` text NOT NULL, `share_url` text,
  `summary_additions` integer, `summary_deletions` integer, `summary_files` integer,
  `summary_diffs` text, `metadata` text, `cost` real DEFAULT 0 NOT NULL,
  `tokens_input` integer DEFAULT 0 NOT NULL, `tokens_output` integer DEFAULT 0 NOT NULL,
  `tokens_reasoning` integer DEFAULT 0 NOT NULL, `tokens_cache_read` integer DEFAULT 0 NOT NULL,
  `tokens_cache_write` integer DEFAULT 0 NOT NULL, `revert` text, `permission` text,
  `agent` text, `model` text, `time_created` integer NOT NULL,
  `time_updated` integer NOT NULL, `time_compacting` integer, `time_archived` integer,
  CONSTRAINT `fk_session_project_id_project_id_fk` FOREIGN KEY (`project_id`)
    REFERENCES `project`(`id`) ON DELETE CASCADE
)

29 columns, and none of them holds a context or compaction window size.

The ticket asked specifically about metadata. It is empty:

SELECT count(*), sum(metadata IS NOT NULL AND metadata!=''),
       sum(time_compacting IS NOT NULL) FROM session;
-- 125 | 0 | 0

So metadata is NULL on all 125 rows and time_compacting is NULL on all 125 rows. time_compacting would not have helped anyway — it is a timestamp meaning "a compaction is running now", not the configured window.

I then swept every table in the database for a column named like compact|context|window|limit, rather than only looking at session. Two hits:

  • time_compacting, covered above.
  • session_context_epoch(session_id, baseline, snapshot, baseline_seq) — 0 rows. It records baseline/snapshot state, not a configured window.

Full table list, for anyone who wants to re-check: account, account_state, control_account, credential, data_migration, event, event_sequence, message, migration, part, permission, project, project_directory, session, session_context_epoch, session_input, session_message, session_share, todo, workspace.

The answer

No. opencode does not record the effective auto-compact / context window anywhere readable. So the #175 read-back cannot be reproduced here: there is no evidence to compare the requested value against, on the late-resolve path or anywhere else.

autoCompactWindow therefore stays fire-and-forget for opencode. That is a limitation of the backend, not a gap in fleetd, and it is now written down so the question does not get reopened.

What is still true, and what would change this

The underlying risk from the ticket has not gone away: a value opencode accepts but clamps or ignores would still be invisible. What changed is that we now know the database cannot tell us. Reopen this if opencode adds a column that carries the effective value — session.metadata is the obvious place, and it exists but is unused today, so a future version filling it in is exactly the trigger.

Two smaller notes for whoever reads this next:

  • session.cost is 0.0 on every row, so it is not an alternative signal either. That was already recorded on #175.
  • The scope difference from #175 was deliberate and is now moot: this check would have logged an ERROR and never quarantined, because a wrong compaction window costs context, not money.

Housekeeping

Verified independently before closing: the worker's worktree is clean (git status --porcelain empty) and its branch worker/cb232-autocompact-readback-323c18-3 is an ancestor of origin/main — no commits, no PR, nothing to merge. mvn clean install on that untouched tree: Tests run: 1117, Failures: 0, Errors: 0, Skipped: 0, BUILD SUCCESS.

The database was only ever opened read-only.

Related: #175 (the same shape, fixed, because the evidence existed there) · #203 (closed: ran at spawn, could never fire) · #209 (the late-resolve step) · #113 (checkers narrower than they look).

## Checked. opencode does not report it. Closing with no code change. This is outcome 3 from the ticket's own "What to do": *"We checked and the backend does not report it."* No probe was invented and no code changed. ### The evidence Read-only against the live database, `~/.local/share/opencode/opencode.db`: ```sql SELECT sql FROM sqlite_master WHERE type='table' AND name='session'; ``` ``` CREATE TABLE `session` ( `id` text PRIMARY KEY, `project_id` text NOT NULL, `workspace_id` text, `parent_id` text, `slug` text NOT NULL, `directory` text NOT NULL, `path` text, `title` text NOT NULL, `version` text NOT NULL, `share_url` text, `summary_additions` integer, `summary_deletions` integer, `summary_files` integer, `summary_diffs` text, `metadata` text, `cost` real DEFAULT 0 NOT NULL, `tokens_input` integer DEFAULT 0 NOT NULL, `tokens_output` integer DEFAULT 0 NOT NULL, `tokens_reasoning` integer DEFAULT 0 NOT NULL, `tokens_cache_read` integer DEFAULT 0 NOT NULL, `tokens_cache_write` integer DEFAULT 0 NOT NULL, `revert` text, `permission` text, `agent` text, `model` text, `time_created` integer NOT NULL, `time_updated` integer NOT NULL, `time_compacting` integer, `time_archived` integer, CONSTRAINT `fk_session_project_id_project_id_fk` FOREIGN KEY (`project_id`) REFERENCES `project`(`id`) ON DELETE CASCADE ) ``` 29 columns, and none of them holds a context or compaction window size. The ticket asked specifically about `metadata`. It is empty: ```sql SELECT count(*), sum(metadata IS NOT NULL AND metadata!=''), sum(time_compacting IS NOT NULL) FROM session; -- 125 | 0 | 0 ``` So `metadata` is NULL on all 125 rows and `time_compacting` is NULL on all 125 rows. `time_compacting` would not have helped anyway — it is a timestamp meaning "a compaction is running now", not the configured window. I then swept **every** table in the database for a column named like `compact|context|window|limit`, rather than only looking at `session`. Two hits: - `time_compacting`, covered above. - `session_context_epoch(session_id, baseline, snapshot, baseline_seq)` — **0 rows**. It records baseline/snapshot state, not a configured window. Full table list, for anyone who wants to re-check: `account`, `account_state`, `control_account`, `credential`, `data_migration`, `event`, `event_sequence`, `message`, `migration`, `part`, `permission`, `project`, `project_directory`, `session`, `session_context_epoch`, `session_input`, `session_message`, `session_share`, `todo`, `workspace`. ### The answer **No.** opencode does not record the effective auto-compact / context window anywhere readable. So the #175 read-back cannot be reproduced here: there is no evidence to compare the requested value against, on the late-resolve path or anywhere else. `autoCompactWindow` therefore stays fire-and-forget for opencode. That is a limitation of the backend, not a gap in fleetd, and it is now written down so the question does not get reopened. ### What is still true, and what would change this The underlying risk from the ticket has not gone away: a value opencode accepts but clamps or ignores would still be invisible. What changed is that we now know the database cannot tell us. Reopen this if opencode adds a column that carries the effective value — `session.metadata` is the obvious place, and it exists but is unused today, so a future version filling it in is exactly the trigger. Two smaller notes for whoever reads this next: - `session.cost` is `0.0` on every row, so it is not an alternative signal either. That was already recorded on #175. - The scope difference from #175 was deliberate and is now moot: this check would have logged an ERROR and **never** quarantined, because a wrong compaction window costs context, not money. ### Housekeeping Verified independently before closing: the worker's worktree is clean (`git status --porcelain` empty) and its branch `worker/cb232-autocompact-readback-323c18-3` is an ancestor of `origin/main` — no commits, no PR, nothing to merge. `mvn clean install` on that untouched tree: `Tests run: 1117, Failures: 0, Errors: 0, Skipped: 0`, `BUILD SUCCESS`. The database was only ever opened read-only. Related: #175 (the same shape, fixed, because the evidence existed there) · #203 (closed: ran at spawn, could never fire) · #209 (the late-resolve step) · #113 (checkers narrower than they look).
ltms closed this issue 2026-09-03 04:10:23 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: fleet/fleetd#232