feat(bridge): protocol 8 — the leases (phase 12) #8

Merged
whitlocktech merged 1 commits from feat/phase-12-leases into edge 2026-09-23 23:03:02 -05:00
Member

Phase 12 of module-rust. Plan and as-built record: docs/modules/rust/PLAN.md §27; protocol: docs/rust-link/PROTOCOL.md §14 (docs PR alongside).

What

  • lease.list / lease.apply / lease.release, plus a lease.expired event. The plugin holds the allowlist (decay.scale, 18 *.population, spawn.min_rate, spawn.min_density, and group.permission), the seven-day ceiling (a longer hold is refused, never clamped, D77) and the deadline, which it enforces itself every second. Release is compare-and-set, and a drifted value is left alone.
  • leases.json under the data dir records each hold with its bootId. On a plugin reload every hold is re-armed. On a new boot a convar hold is dropped, because the restart already restored it, while a group-permission hold is re-armed, because the framework kept it.
  • EventsEnabled (default false, D76) gates apply only. A write from the site's config editor to the bridge's own file now applies it at once.
  • The permission mirror defers to a leased pair: it is reported as leased, never foreign, and the site's wish is recorded on the hold and applied at release.
  • Saved convars are refused, because serverauto.cfg would outlive the restart that should end the hold.
  • overlay.toml protocol → 8.

Two defects the walk found here, fixed

  • GrantGroupPermission(…, this) is a silent no-op for any permission another plugin registered (confirmed in decompiled Oxide.Core.Libraries.Permission). Grants now pass a null owner.
  • EventsEnabled saved from the site had no effect, because the bridge never reloads itself (§21.3).

Raised, NOT fixed here

The phase-7 mirror (EnsureGroupPermission / EnsureGrant) has the same owner bug and counts the grant without reading it back. See PLAN.md §27.6.

Walked

Oxide and Carbon, through real core. Every key's effect was seen in the game and restored. The walk also covered the deadline with core stopped, drift, reload and restart in the middle of a hold, and the switch. node scripts/checkPlugin.js passes.

  • AI-assisted: Claude Code (Claude Opus 5.5)

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

Phase 12 of module-rust. Plan and as-built record: `docs/modules/rust/PLAN.md` §27; protocol: `docs/rust-link/PROTOCOL.md` §14 (docs PR alongside). ## What - **`lease.list` / `lease.apply` / `lease.release`**, plus a `lease.expired` event. The plugin holds the allowlist (`decay.scale`, 18 `*.population`, `spawn.min_rate`, `spawn.min_density`, and `group.permission`), the **seven-day ceiling** (a longer hold is refused, never clamped, D77) and **the deadline**, which it enforces itself every second. Release is compare-and-set, and a drifted value is left alone. - **`leases.json`** under the data dir records each hold with its `bootId`. On a plugin reload every hold is re-armed. On a new boot a convar hold is dropped, because the restart already restored it, while a group-permission hold is re-armed, because the framework kept it. - **`EventsEnabled`** (default `false`, D76) gates `apply` only. A write from the site's config editor to the bridge's own file now applies it at once. - The **permission mirror defers to a leased pair**: it is reported as `leased`, never `foreign`, and the site's wish is recorded on the hold and applied at release. - `Saved` convars are refused, because `serverauto.cfg` would outlive the restart that should end the hold. - `overlay.toml` protocol → 8. ## Two defects the walk found here, fixed - `GrantGroupPermission(…, this)` is a **silent no-op** for any permission another plugin registered (confirmed in decompiled `Oxide.Core.Libraries.Permission`). Grants now pass a `null` owner. - `EventsEnabled` saved from the site had no effect, because the bridge never reloads itself (§21.3). ## Raised, NOT fixed here **The phase-7 mirror (`EnsureGroupPermission` / `EnsureGrant`) has the same owner bug** and counts the grant without reading it back. See PLAN.md §27.6. ## Walked Oxide and Carbon, through real core. Every key's effect was seen in the game and restored. The walk also covered the deadline with core stopped, drift, reload and restart in the middle of a hold, and the switch. `node scripts/checkPlugin.js` passes. - [x] AI-assisted: Claude Code (Claude Opus 5.5) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-09-23 21:14:45 -05:00
feat(bridge): protocol 8 — the leases (PLAN.md §27)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 20s
594fc09141
lease.list / lease.apply / lease.release and a lease.expired event. The plugin holds the allowlist (decay.scale, 18 populations, the two minimum spawn scalars, and group permissions), the seven-day ceiling (refused, never clamped) and the deadline, which it enforces on its own. Release is compare-and-set. Holds persist in the data directory with their boot: a restart ends a convar hold, while a group-permission hold survives it and is re-armed.

EventsEnabled (default off) gates apply only, and a write from the site's config editor now takes effect at once. The permission mirror defers to a leased pair: it is reported as leased, never foreign.

Grants pass a null owner: with an owner, Oxide silently refuses any permission another plugin registered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech merged commit dcf4e34fee into edge 2026-09-23 23:03:02 -05:00
whitlocktech deleted branch feat/phase-12-leases 2026-09-23 23:03:03 -05:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Rust-Plugins#8
No description provided.