Skip to content

feat: session-scoped off-peak protection (/offpeak session on|off) - #15

Merged
lutzkind merged 2 commits into
mainfrom
session-protection
Oct 16, 2026
Merged

lutzkind merged 2 commits into
mainfrom
session-protection

Conversation

@lutzkind

Copy link
Copy Markdown
Owner

Implements the session-scoped on/off control for off-peak protection.

  • /offpeak session off disables off-peak protection for the current interactive
    session only: verified PEAK-priced requests (primary, compaction, title,
    generate) run immediately, and a request already held for off-peak is released
    through the existing engine signal — no re-send, no duplicate provider call,
    no polling, no timer. /offpeak session on restores the default.
  • Default ON for every session; only explicit overrides persist in OpenCode
    plugin storage (opencode-offpeak/session-overrides-v1) and survive TUI
    restarts, plugin reloads, and server restarts. The supported session.deleted
    event reaps entries; stale entries are cleaned lazily and only on a confident
    not-found signal.
  • Current session resolved from the supported TUI context (ui.router.current(),
    then the active tab); no session ID typing. Refuses on the home screen.
  • Fail-closed invariants preserved: UNKNOWN and invalid configuration still
    block, OFF_PEAK/FLAT/UNTRACKED unchanged, queue tasks never inherit the
    override, refused/committed holds are never recalled or resurrected.
  • Precedence documented: the explicit per-session grant applies even while the
    plugin is globally OFF, for that one session only; /offpeak off itself
    remains passive.
  • Status shows Session protection: ON|OFF and Requests: ALLOWED (session override) while PEAK with protection off; pricing is never misreported.
  • 19 new deterministic tests (134 total); all 115 prior tests unchanged.

Real OpenCode 2.0.30 TUI + local fixture validation (zero paid traffic):
hold → session off → immediate release before the boundary with exactly one
provider request; a second session stays held through the same peak window;
session on → next request waits again; the override survives opencode reload
and a full server restart; compaction runs immediately under the override with
no pending-compaction marker, while compact-first with protection on is
unchanged.

/offpeak session off disables off-peak protection for the current
interactive OpenCode session only; /offpeak session on restores it.
Default is ON for every session; the explicit override persists in
OpenCode plugin storage until changed or the session is deleted (no
timer, no expiry, no second store).

- src/store.ts: SessionOverridesRepository (opencode-offpeak/session-overrides-v1)
- src/engine.ts: setSessionProtection/sessionProtection/forgetSession plus
  bounded lazy pruning on start, session commands, status and the supported
  session.deleted event; verified-PEAK requests of an overridden session are
  allowed immediately, a held request wakes through the existing signal, and
  the same rule releases deferred/retry/pending-title/pending-compaction
  recoveries for that session without clobbering other classes or sessions.
  Queue-owned sessions never inherit the override, UNKNOWN and invalid
  configuration still fail closed, and committed or refused holds are never
  recalled or resurrected.
- src/server.ts: session-off/session-on RPC actions, status sessionID,
  session.deleted cleanup, explicit not-found errors for missing sessions.
- src/tui.ts: /offpeak session on|off resolved from the supported TUI route
  (ui.router first, active tab fallback), status shows Session protection and
  'Requests: ALLOWED (session override)' while PEAK, resume kind override.
- tests: 19 new deterministic cases (134 total) covering the full matrix.
…ile current-state wording

- README: install #v0.1.10, validation includes 2.0.30, session on/off section
  (current session only, default ON, persistent, no timer, UNKNOWN still
  blocked, queue tasks unaffected, status output, compaction behavior,
  explicit global precedence)
- CHANGELOG 0.1.10, RELEASING current release, docs/configuration and
  docs/troubleshooting updated; ARCHITECTURE session-protection section;
  DECISIONS entry for the per-session authorization
- HANDOFF lower current-state sections: package/install now v0.1.10, verified
  CLI includes 2.0.30, implemented-behavior list includes session controls
@lutzkind
lutzkind merged commit b2ce8f0 into main Oct 16, 2026
2 checks passed
@lutzkind
lutzkind deleted the session-protection branch October 16, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant