Skip to content

feat(trellis): history settings and Run maintenance in Settings → Trellis - #21

Merged
Andrey170170 merged 6 commits into
dev_v2from
trellis-v2/c-history-settings
Oct 3, 2026
Merged

Andrey170170 merged 6 commits into
dev_v2from
trellis-v2/c-history-settings

Conversation

@Andrey170170

Copy link
Copy Markdown
Owner

Trellis v1 Stage C, Lane T3 step 3 part 2: history settings in Settings → Trellis.

Change

  • RPCs.
    • trellis.getHistorySettings (read scope) wraps Trellis GET /v1/settings/history (Add new poem.md with "Small Arrival" poem pingdotgg/t3code#40) and returns values, defaults, snapshot counts per kind, and the last thinning.
    • trellis.updateHistorySettings (operate scope) wraps PUT /v1/settings/history with any subset of the eight keys and returns the values in force and wouldRemove.
    • trellis.runMaintenance (operate scope) wraps POST /v1/maintenance.
    • Decoding is lenient. An older Trellis without the route gets a message naming the Trellis version it needs.
  • History section (between Bases and Trash):
    • One number field per setting, with its unit and what 0 means: snapshot timer; turn snapshots keep-all / daily; timer snapshots keep-all / hourly; trashed ideas, discarded forks and incoming copies expiry.
    • "Default: N" and a reset arrow when a value differs from its default.
    • A value is saved when the field loses focus, on Enter, or on each +/- or arrow step, sending only that key.
    • Trellis's refusals show inline and the field reverts. A toast reports wouldRemove when it is above 0.
    • Read-only rows show live snapshots by kind and the last thinning, with Run now (maintenance at once; it never purges projects).
  • Ordering: writes go one at a time per environment and each field is settled by its latest write. An edit is compared with pending values, so 30 → 14 → 30 is not lost. Returned values show at once, and a failed refresh shows a stale notice beside the cached values.
  • docs/user/trellis.md: one paragraph.

Checks

  • Tests:
    • Trellis.test.ts: GET decoding, a PUT with all eight keys (snake_case out, camelCase back), a 400 refusal, the older-Trellis message, and maintenance.
    • Web logic tests: deciding what an edit sends, revision guarding, pending-value comparison, and the notes and counts text.
  • End-to-end against /trellis/dev-t3 (Trellis 0bed1e8):
    • Two ArrowUp presses on "Incoming copies" kept focus and saved 32 (checked with curl).
    • The reset arrow brought it back to 30.
    • Run now showed "Maintenance done" and updated the last thinning (removed 0).
    • The dev root's settings are as found.
    • The first worker check of the refusal and toast paths ran against a fake socket; screenshots are kept locally in /tmp/stagec-history-*.png and /tmp/stagec-hist/.
  • Local CI: knip:check, vp check, vpr typecheck and release-smoke pass. t3 tests fail only on the known CodexInstallation and AcpSessionRuntime.processTree failures. Package tests fail only on the known desktop libsecret and snapshot file-mode failures (desktop rerun after an Electron install race); client-runtime, relay and mobile pass when run separately. build:desktop fails on the known libsecret helper.
  • Reviews: Codex gpt-6.1-sol (lost edit, write ordering, saved values showing late; fixed), then gpt-6-astra (arrow stepping remounted the field; fixed by controlling the field).

🤖 Generated with Claude Code

Andrey170170 and others added 3 commits October 2, 2026 16:56
Shows and edits Trellis's history settings (snapshot timer, turn and timer
snapshot retention, trash and incoming expiry) through two new RPCs,
trellis.getHistorySettings and trellis.updateHistorySettings, backed by
GET/PUT /v1/settings/history. Each value commits on blur, Enter or the
step buttons and sends only that key; Trellis's refusal shows under the
row, and a save that the next thinning acts on says how many snapshots go.
Live snapshot counts per kind and the last thinning are shown read only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…t write

- Unchanged-detection compares with the field's pending value, else the
  value in force, so 30 -> 14 -> 30 before the answer still sends 30.
- updateHistorySettings runs serially per environment; each write carries
  a per-field revision, and only a field's latest write clears its draft or
  shows its refusal, so a stale failure never undoes a newer edit.
- A successful write's returned values show at once (until a newer read),
  and a failed refresh shows a stale notice beside the cached values.

The edit state lives in TrellisSettings.logic.ts with unit tests; the
server test also maps all eight keys out in one PUT.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e number fields mounted while stepping

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-03T02:31:44.528093Z 692431f New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL labels Oct 3, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0bca20a78b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +120 to +123
runMaintenance: createEnvironmentRpcCommand(connectionAtomRuntime, {
label: "environment-data:trellis:run-maintenance",
tag: WS_METHODS.trellisRunMaintenance,
concurrency: { mode: "serial", key: ({ environmentId }) => environmentId },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Serialize maintenance behind pending history updates

When a user edits a retention/expiry field and immediately clicks Run now—clicking the button can itself blur and commit the field—the update and maintenance commands use separate schedulers, so these identical environment keys do not serialize with each other. The maintenance request can therefore begin before the PUT completes and apply the previous policy; notably, changing an expiry to 0 and running maintenance could still remove data under the old nonzero expiry. Use a shared scheduler/lane or prevent maintenance until all pending writes settle.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid: the history section now chains its saves, and Run now awaits that chain before calling maintenance, so a field committed by the click (blur happens first) is saved before maintenance applies the policy. Fixed in 79e2682.

Comment on lines +109 to +113
label: "environment-data:trellis:history-settings",
tag: WS_METHODS.trellisGetHistorySettings,
staleTimeMs: 30_000,
idleTtlMs: 60_000,
}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Refresh history data while the section remains mounted

This query has a stale threshold but no refresh interval or manual refresh action, so after the initial read its settings, snapshot counts, and last-thinning value remain unchanged indefinitely unless this client saves a setting or runs maintenance. Scheduled hourly maintenance and changes from another connected client therefore leave the open Settings page displaying stale values; add periodic/focus-triggered refresh behavior similar to the adjacent Trellis details query. Multi-device behavior is explicitly a supported case.

AGENTS.md reference: AGENTS.md:L74-L74

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid: the history query now refreshes every minute while shown, like the details query, so hourly maintenance and other clients' changes appear. Fixed in 79e2682.

…ngs refresh every minute

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 79e268211d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +700 to +701
await writes.current.catch(() => undefined);
const result = await runMaintenance({ environmentId, input: {} });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Abort maintenance when an awaited history save fails

When the blur-triggered save fails—for example, a transient PUT failure followed by a successful POST—runAtomCommand fulfills its promise with a _tag: "Failure", so this catch does not run and maintenance still applies the previous retention or expiry policy. That can permanently remove data the user had just attempted to preserve. Fresh evidence beyond the earlier ordering race is that the follow-up waits for settlement but never inspects the settled command result; track failed writes and skip maintenance until the save succeeds.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid: the save chain now resolves to whether every save since the last Run now succeeded (a Failure result counts, not just a rejection), and Run now stops with a toast instead of running maintenance under the previous settings; the chain resets afterwards so a later run proceeds. Fixed in 692431f.

…ted for failed

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 692431ffaa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +701 to +702
const saved = await writes.current;
writes.current = Promise.resolve(true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep tracking writes started while maintenance waits

Fresh evidence beyond the fixed blur-ordering case: while Run now is awaiting an already-pending save, the number fields remain enabled, so another edit can append a newer save to writes.current. This code awaits only the previously captured promise and then overwrites the ref with a resolved promise; because updates and maintenance use separate scheduler lanes, maintenance can race that newer PUT and apply the old policy—for example, expiring data before a newly entered 0 expiry takes effect. Disable edits while waiting, drain the evolving save chain atomically, or serialize both operations on a shared lane.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid: while Run now waits for earlier saves and runs maintenance, the number fields are disabled and commits (including reset arrows) are ignored, so no save can start after the awaited chain was captured; the chain is reset only after it settled. Fixed in cd03fb4.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Andrey170170
Andrey170170 merged commit 6617439 into dev_v2 Oct 3, 2026
8 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant