Commit Graph

15 Commits

Author SHA1 Message Date
dd9b8b2711 feat(safety): report, block and hide chat lines (MODULE_API 1.21.0)
Some checks failed
PR Checks / client-build (pull_request) Successful in 51s
PR Checks / frozen-manifest (pull_request) Successful in 53s
PR Checks / server-tests (pull_request) Failing after -17s
USER_SAFETY.md step 3, the module half of report, block and hide.

- server/safety.js registers the rust.chat report target (snapshot for one
  reader, null when they could not have seen the line; staff's hide and
  unhide) and the steam game identity (ownersOf from rust_account_links).
- The events feed filters chat per reader, in the query: lines from a
  blocked account's Steam ids, the reader's unlinked Steam-ID blocks and the
  lines they hid. Signed-in readers get canBlock on each chat line (false for
  their own and for staff-linked players). Lines staff hid for everyone are
  left out for everyone but staff, who get them with hidden: true.
- rust_events gains hidden_at and hidden_by (ALTER ... IF NOT EXISTS).
- POST /admin/rust/chat/:id/hide and /unhide (admin, moderator), logged.
- The feed's chat lines get a menu: Report, Hide for me, Block player,
  and for staff Hide for everyone / Show to everyone again.
- coreApi ^1.21.0; ci/core-ref.json pinned to the website#233 merge;
  routes.manifest.json and swagger-fragment.json regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-30 09:04:08 -05:00
b5573d9ae3 feat(links): unlink every Steam id before an account is deleted (MODULE_API 1.20.0)
All checks were successful
PR Checks / server-tests (pull_request) Successful in 1m1s
PR Checks / frozen-manifest (pull_request) Successful in 1m28s
PR Checks / client-build (pull_request) Successful in 43s
ACCOUNT_DELETION.md §4.4 (AD10). api.onUserDeleting calls links.unlinkForDeletion,
which runs the player's own unlinkOwned per link, logs rust.account.unlink with
reason 'account deleted', and marks every server's permission sync dirty so the
withdrawn grants reach the game on the next tick. coreApi ^1.20.0; core-ref pinned
to website#232's merge (7bd93b8); engagement manifest regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-29 20:38:30 -05:00
791f13235e chore(ci): pin core-ref to website#224's merge on main
All checks were successful
PR Checks / client-build (pull_request) Successful in 1m2s
PR Checks / server-tests (pull_request) Successful in 1m8s
PR Checks / frozen-manifest (pull_request) Successful in 1m35s
website#224 (MODULE_API 1.19.0, demoRefuses) merged as 69998ec on main.
The merge tree equals the branch head the pin held (cee4ab8), so
routes.manifest.json does not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-26 05:53:41 -05:00
7a0d0842ba feat(demo): the public demo's module-side locks and seed hook
All checks were successful
PR Checks / client-build (pull_request) Successful in 54s
PR Checks / server-tests (pull_request) Successful in 1m0s
PR Checks / frozen-manifest (pull_request) Successful in 1m19s
website/DEMO_MODE.md §3.2, §3.4, §3.5, §7.3 and §7.5 (step 2 of §10).
Nothing changes off the demo; everything below sits behind ctx.demoMode.

- demoLocks in module.json: PUT and DELETE /admin/rust/servers/:id.
- The console-command deny list (DM11): quit, restart, oxide.unload,
  oxide.reload, rcon.*, fps.limit and server.tickrate, by first word,
  with global. stripped and o. read as oxide. Refused at save through
  core's demoRefuses (MODULE_API 1.19.0, DM18) and again at run, with
  retry: false, before the rig is asked. Teardown commands too.
- The config editor (DM14): the bridge's files are left out of the
  list and refused for reading, writing and in the write history, by
  name (canonicalised) and by the catalogue's self. Other plugins'
  credential fields are redacted in the text and the form and made
  read-only; raw-JSON saves are refused; a file that does not parse is
  withheld. The admin server list leaves out the sidecar URL.
- onDemoSeed (DM15): upserts the rig's server row with an encrypted
  token and demo-player's stand-in Steam link.
- The release's install manifest carries protocol, read from
  PROTOCOL_VERSION, for the wipe's bundle match (DM12).

coreApi is ^1.19.0; ci/core-ref.json pins website#224's head.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-26 03:40:30 -05:00
3453bc1867 ci(rust): pin core to main at the cutover (website#220)
All checks were successful
PR Checks / client-build (pull_request) Successful in 31s
PR Checks / frozen-manifest (pull_request) Successful in 59s
PR Checks / server-tests (pull_request) Successful in 7m15s
website#220 cut website edge over to main as 6890a74. The pin pointed at
9a1654f, the sha website#218 merged into edge as, which its own note said
moves to main when the cutover lands. The new tree adds the last fixes'
core half (website#219, no MODULE_API bump), whose route changes are only
core's own event routes, so routes.manifest.json does not change. The
frozen-manifest job, replayed locally at this ref, passes (89 routes, all
documented).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-22 05:45:25 -05:00
885485d153 ci(rust): pin core to the sha website#218 merged as
All checks were successful
PR Checks / client-build (pull_request) Successful in 26s
PR Checks / frozen-manifest (pull_request) Successful in 51s
PR Checks / server-tests (pull_request) Successful in 7m14s
#218 (Steam sign-in, MODULE_API 1.17.0) merged into website edge as
9a1654f. The pin pointed at the PR's branch head, 5e398d8, while it was
open. The two trees differ by one core test file, so routes.manifest.json
does not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-21 00:38:15 -05:00
8172454683 ci(rust): pin core to website feat/steam-signin (MODULE_API 1.17.0)
All checks were successful
PR Checks / server-tests (pull_request) Successful in 37s
PR Checks / client-build (pull_request) Successful in 21s
PR Checks / frozen-manifest (pull_request) Successful in 48s
coreApi is ^1.17.0, which no core on main offers yet, so the frozen-manifest
job is proved against the head of the open website PR. Moves to the sha it
merges as.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-19 20:28:25 -05:00
bfe9b5b18d feat(rust): Dangerous Treasures — feed, map, Treasure Hunter, Start a Dangerous Treasures event (PLAN_REDESIGNS §14.3.4)
All checks were successful
PR Checks / client-build (pull_request) Successful in 27s
PR Checks / frozen-manifest (pull_request) Successful in 46s
PR Checks / server-tests (pull_request) Successful in 7m23s
Stage 5 of the §14.3 integration plan, on protocol 14 (docs
rust-link/PROTOCOL.md §20.8).

- dt.started and dt.won are public kinds, dt.ended a staff kind. The new
  dangerousTreasures.js reads each row per viewer: grid and invaderCount for
  everyone, the winner's name for the presence audience (D376), the position,
  the step's key, the winner's Steam id and the invaders for staff.
- Feed lines in the World events filter: "A Dangerous Treasures event has
  started · K12", "Alice won the treasure · K12 · 3 players fought for it".
- Triggers rust.dt.started (with byEvent) and rust.dt.won, public, cooldown
  subject the server, names only.
- eventDangerousTreasures.js: rust.dt.start, "Start a Dangerous Treasures
  event" (risk change, reversible none, budget rust.dt.events), server and
  difficulty. Refused at verify where the server said DT is not loaded or
  console.plugins is false (Rust-Plugins#34). dt-not-ready answers "Dangerous
  Treasures is not ready yet" with retryAfterMs 600000 (D365, D371);
  dt-no-spot retries on core's delay; DT's own refusals are permanent.
- Treasure Hunter (D375): treasuresWon -> treasures_won, the title category
  treasureswon, and a sortable Treasures column shown where the server
  reports DT or a row counts one.
- The map draws a running chest on the world layer; the server settings'
  plugin line names DT and whether a step can start one, from the
  integrations read's new `console`.
- coreApi ^1.15.0, ci/core-ref.json pinned to website main at #215's merge.
  ci/bundle.json ships the two new files; swagger fragment and engagement
  manifest regenerated; README lists DT.

Server 627/627 (16 new in test/dangerousTreasures.test.js) and every check;
client 92/92, build and externals. Booted against the pinned core: 45
triggers, 13 actions, 11 budgets, 21 option sources; 89 routes unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-15 06:45:30 -05:00
11d32436a4 chore(ci): pin the core to website main at #213's merge
All checks were successful
PR Checks / client-build (pull_request) Successful in 28s
PR Checks / server-tests (pull_request) Successful in 37s
PR Checks / frozen-manifest (pull_request) Successful in -1m34s
website#213 (MODULE_API 1.14.0, the `multiple` param) merged as a981b2b.
Its tree is identical to the branch head 743f1bc this was pinned to, so
routes.manifest.json is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-14 04:18:53 -05:00
63c82d5a2f feat(rust): permissions as event rewards — lend or give any registered permission (PLAN_REDESIGNS §12)
All checks were successful
PR Checks / client-build (pull_request) Successful in 20s
PR Checks / server-tests (pull_request) Successful in 27s
PR Checks / frozen-manifest (pull_request) Successful in -1m32s
D342-D346 (docs#342). Two steps over the permission mirror's own tables, so
no plugin, sidecar or protocol change:

- rust.perm.lend, "Permissions until the event ends": a kit reward's lease,
  one rust_perm_run_grants row per recipient per permission, the message on
  one row each; change/ledger with rust.kit.entitle's revert and reconcile;
  budget rust.permissions.
- rust.perm.give, "Permissions for good": a standing rust_perm_grants row per
  website user per permission, scoped to the step's server, source `event`,
  note "event run <run>, step <step>"; a grant already there is left alone,
  and a retry's own grants are counted as given; the message rides a
  notice-only run-grant row; irreversible/none; budget rust.permissions.kept.
- Both: several permissions through core's `multiple` param (MODULE_API
  1.14.0, at most 10); a required "I am sure" toggle refused unticked in the
  dry run and at run time, naming the permissions (D343); a permission the
  server's catalogue lacks refused by name; a blank message tells nobody.
- rust.options.permissions: the enabled servers' catalogues, grouped by the
  registering plugin (by prefix when none), sorted plugin then permission
  without case, a row noted "Only on X" when not on every server.
- Permission manager: an event-given grant shows "given by event run N,
  step M"; staff turn it off like any grant.
- coreApi ^1.14.0; ci/core-ref.json pinned to website#213's head until it
  merges; engagement-triggers.json regenerated; routes.manifest.json
  unchanged (no new routes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-12 15:49:44 -05:00
a64ae68158 chore(ci): re-pin core to website main at #212's merge
All checks were successful
PR Checks / server-tests (pull_request) Successful in 33s
PR Checks / frozen-manifest (pull_request) Successful in 55s
PR Checks / client-build (pull_request) Successful in 7m23s
website#212 (MODULE_API 1.13.0) merged as ca7ec53, whose tree is the
same as the branch head e58857c this repo was pinned to while it was
open. Only the pin moves; routes.manifest.json is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-12 05:08:39 -05:00
d21a9e2c0d feat(rust): the kit weekend, linked rewards, reward messages and the kit warning (protocol 14)
All checks were successful
PR Checks / client-build (pull_request) Successful in 3m46s
PR Checks / frozen-manifest (pull_request) Successful in 6m12s
PR Checks / server-tests (pull_request) Successful in 7m30s
PLAN_REDESIGNS §2, the Rust half (D164, D192, D332, D333):
- rust.template.kit_weekend (core registerEventTemplates, MODULE_API 1.13.0):
  inputs kit/minutes/message/delivery; one phase advance after the weekend,
  core.lease rust.group.permission default/<kit permission> + rust.kit.entitle
  linked. Steps only where the kit can use them; validated by the real core.
- rust.kit.entitle: recipients 'linked' (every linked player who has played
  on the server, no tally, refused past the bound), optional message ({kit})
  and delivery, stored per row (rust_perm_run_grants.notice*).
- perm.sync notices: the untold set to the picked account, keyed
  run:step:user, in the digest; the report's noticesTold marks them told.
- rust.options.grouppermissions notes a kit's permission rows via kits.uses
  (cached a minute per server; a failure is no note).
- duration: 'minutes' on rust.zone.open and rust.participation.open; the
  group-permission lease's value example is true.
- protocol 13 -> 14, coreApi ^1.13.0; ci/core-ref.json pinned to website#212's
  head while it is open; engagement-triggers.json regenerated (coreApi line).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-12 02:25:06 -05:00
0fb6767692 chore(ci): pin core back to main now website#209 has merged
All checks were successful
PR Checks / client-build (pull_request) Successful in 17s
PR Checks / server-tests (pull_request) Successful in 21s
PR Checks / frozen-manifest (pull_request) Successful in 40s
The frozen-manifest job was pinned to website#209's branch head while
MODULE_API 1.11.0 was unmerged. It merged as f0e7d2a on main.

Refs #21

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-27 03:28:08 -05:00
478c52e7a1 ci(rust): pin frozen-manifest to website#209 while coreApi is ^1.11.0
All checks were successful
PR Checks / client-build (pull_request) Successful in 22s
PR Checks / server-tests (pull_request) Successful in 23s
PR Checks / frozen-manifest (pull_request) Successful in 39s
The job cloned a MODULE_API 1.10.0 main and the loader refused the module
("needs core API ^1.11.0, this core is 1.10.0"), so it added no routes and
failed by construction. Pinned to #209's head (cc1f49a), where the job's own
steps pass: core alone 280 routes up to date, with this module 49 routes all
documented. Re-pin to #209's main merge sha once it lands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-09-26 22:08:39 -05:00
b33d21d71b feat(ci): packaging, release and the frozen manifest
All checks were successful
PR Checks / server-tests (pull_request) Successful in 21s
PR Checks / client-build (pull_request) Successful in 21s
PR Checks / frozen-manifest (pull_request) Successful in 39s
Phase 2 of docs/modules/rust/PLAN.md. Phase 1 built five guards and ran them by
hand; this repo had no workflows at all, so nothing gated the branch that gets
released and there was no way to release it.

Three pieces:

- **release.yml** — the derived-version engine link, installer and Module-uo
  already run (conventional-commit subjects since the newest tag; module.json's
  version survives as a floor; workflow_dispatch as the backdoor), assembling the
  bundle from an include list and publishing the tarball, the install manifest
  carrying its sha256, and SHA256SUMS. The tag is the number that ships and CI
  stamps it into the bundle's own module.json.
- **pr-checks.yml** — server tests, check:imports, check:bundle, check:swagger,
  the client build, client tests and check:externals, plus frozen-manifest.
- **frozen-manifest** — clones core at the sha pinned in ci/core-ref.json,
  generates its route table without this module and with it, and takes the
  difference. It ran locally against that exact ref: six routes, all documented,
  no core route moved. That is the first proof by a running core that /rust
  collides with nothing — phase 1 could only check it by reading, because core
  mounts /status and /version at a tier root where the loader's own collision
  probe cannot see them.

The bundle carries no node_modules, because the shipped half declares no runtime
dependencies (org lead, phase 2). checkBundle.js holds both halves of that: the
include list still covers everything server/index.js reaches, and no dependency
has appeared without the release learning to pack it. Verified by breaking it —
dropping "model" from the list names the exact edit and exits 1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
2026-09-16 02:10:07 -05:00