Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/omni-offline-first/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Every Omni app works offline: it reads its shift working set from durable storag
classify: (err) => (err.status && err.status < 500 ? 'permanent' : 'retry'),
});
```
3. **Idempotency:** the event `id` (client UUID) is the idempotency key sent to the server; creates send a client GUID. Never generate ids that change on retry.
3. **Idempotency:** the event `id` (client UUID) is the idempotency key sent to the server; creates send a client GUID. Never generate ids that change on retry. A row shown optimistically under a placeholder id (IC board rows: `local-<eventId>`) may be acted on before its create is sent; the write queued then still names the placeholder, so the create's `afterAck` records the server's id and the later write's `send` swaps it in (IC `resolvedLocalIds`). Never let such a write reach the server with the placeholder and count as delivered.
4. **Ordering:** use `dependsOn` for real dependencies (e.g. close call only after close command) and `coalesceKey` for newest-wins streams (location fixes).
5. **Scope:** every queued event and stored record carries server + department + user (+ unit). Never replay one user's or server's events as another; hold them (7 days) and show them.
6. **Wipe:** logout, department switch and server switch wipe the working set and queue for that scope (preserved: device prefs like language, theme, server URL). Register stores with the reset registry.
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/resgrid-domain/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Sources (verify there before relying on a detail): Core at `../Core` (`CLAUDE.md
| Dispatch | Dispatcher CAD console: new/edit/close/pending/scheduled/archived calls, run cards, unit and personnel actions | Desktop/web, Electron |
| BigBoard | Unattended wall display: widget grid (personnel, units with status timers, unit alerts, calls, map, weather) | TV / monitor |

App login gates: `CanLoginToDispatchApp`, `CanLoginToCommandApp` in rights (permissions 29/30, default allow). The app identifies itself with `X-Resgrid-Client` (`responder|unit|dispatch|bigboard|command|ic|…`) → server claim `client_app`; the server changes behaviour per app (e.g. BigBoard gets a redacted "safe shell" for protected departments).
App login gates: `CanLoginToDispatchApp`, `CanLoginToCommandApp` in rights (permissions 29/30, default allow). `CanLoginToCommandApp` is also the department's **run-command** permission (establish command; work boards where the member holds incident capabilities). **View Command Boards** (permission 125, rights `CanViewCommandBoards`; no row = follows 30) decides who reads every board; members on an incident (command staff, lane leads, dispatched directly or via group/role/a unit they crew, placed on the board) always read that board. Per board, `IncidentRoles/GetMyCapabilities` (bitmask on the envelope, not `Data`) is exactly what Core accepts: commander and establisher get all, ICS roles parts, everyone else read-only — gate every board control on it. The app identifies itself with `X-Resgrid-Client` (`responder|unit|dispatch|bigboard|command|ic|…`) → server claim `client_app`; the server changes behaviour per app (e.g. BigBoard gets a redacted "safe shell" for protected departments).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kody code-review Kody Rules high

Authorization uses default-allow semantics for app login gates and board access: CanLoginToDispatchApp and CanLoginToCommandApp are rights permissions 29/30 with CanLoginToCommandApp also serving as the department's run-command permission, while CanViewCommandBoards is permission 125 where no row follows 30; this can grant access without an explicit permission, despite IncidentRoles/GetMyCapabilities being the exact Core-accepted per-board bitmask on the envelope, with commanders and establishers receiving all capabilities, ICS roles receiving their parts, and everyone else receiving read-only access. In .claude/skills/resgrid-domain/SKILL.md and docs/architecture/omni-plan.md:537, require deny-by-default policies that grant access only when the permission is present or an approved, narrowly scoped fallback is intentionally configured and audited, use incident participation for command staff, lane leads, members dispatched directly or through a group/role/unit they crew, or members placed on the board, gate every board control on the capability bitmask, and preserve the X-Resgrid-Client (responder|unit|dispatch|bigboard|command|ic|…) to client_app mapping and app-specific server behavior, including BigBoard's redacted safe shell for protected departments.

Kody rule violation: Implement RBAC with least privilege and deny-by-default

Prompt for LLM

File .claude/skills/resgrid-domain/SKILL.md:

Line 26:

Authorization uses default-allow semantics for app login gates and board access: `CanLoginToDispatchApp` and `CanLoginToCommandApp` are rights permissions 29/30 with `CanLoginToCommandApp` also serving as the department's run-command permission, while `CanViewCommandBoards` is permission 125 where no row follows 30; this can grant access without an explicit permission, despite `IncidentRoles/GetMyCapabilities` being the exact Core-accepted per-board bitmask on the envelope, with commanders and establishers receiving all capabilities, ICS roles receiving their parts, and everyone else receiving read-only access. In `.claude/skills/resgrid-domain/SKILL.md` and `docs/architecture/omni-plan.md:537`, require deny-by-default policies that grant access only when the permission is present or an approved, narrowly scoped fallback is intentionally configured and audited, use incident participation for command staff, lane leads, members dispatched directly or through a group/role/unit they crew, or members placed on the board, gate every board control on the capability bitmask, and preserve the `X-Resgrid-Client` (`responder|unit|dispatch|bigboard|command|ic|…`) to `client_app` mapping and app-specific server behavior, including BigBoard's redacted safe shell for protected departments.

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

​

​


## Vocabulary

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/omni-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ LiveKit store from U (Android routing via InCallAudioModule, room-switch race fi
| Units / personnel | R lists/cards/filters + D detail pages + U unit-type icon. |
| Check-in / PAR | R check-in target + D sheet + U timer card. |
| Video feeds | D (form, player) + U format utils. |
| Incident command | I canonical; tiers `view` (R/U), `assist` (D), `command` (I). |
| Incident command | I canonical; tiers `view` (R/U), `assist` (D), `command` (I). Assist and command gate every write on the server's per-board capabilities (`GetMyCapabilities`); IC treats the member's own board as fully theirs until they load. |
| Settings | Section registry: R items (Bluetooth, server URL, login info, audio device, navigation app) + U unit selection + U/D sounds; per-variant sections. |
| Navigation hand-off | R/U/I 10-app hand-off (`lib/navigation.ts` + `storage/navigation-app.ts`) for all variants. |
| Maps | MapLibre plan §8.1 wrapper in `@resgrid/maps`; component baselines: pin marker I + U active state + D memo, map pins R, pin detail U, legend R, pickers R + D web, static map I (then server static maps), POI set R, layers sheet I, Unit location marker/full-screen/camera U, Dispatch legend/focus banner D. |
Expand Down
Loading
Loading