Skip to content
This repository was archived by the owner on Jul 16, 2026. It is now read-only.

feat(dashboard): add outbox card to surface bridge audit log (Phase 5.15) - #83

Merged
jgluck96 merged 1 commit into
dev-clientfrom
josh/phase-5.15-dashboard-outbox
Jun 2, 2026
Merged

jgluck96 merged 1 commit into
dev-clientfrom
josh/phase-5.15-dashboard-outbox

Conversation

@jgluck96

@jgluck96 jgluck96 commented Jun 2, 2026

Copy link
Copy Markdown

Summary

src/outbox_log.py is the audit log every bridge appends to after a successful outbound delivery. Stando has had the module + tests for some time, and slack-bridge.py already records to it on every reply (line 575) — but the data was invisible. Dashboard had no reader and no rendering card, so the writes accumulated as a JSONL file no one read. OSS sutando ships both pieces; this PR ports the missing half.

Changes

src/dashboard.py

  • Add get_outbox(limit: int = 10) -> list[dict] reader. Imports outbox_log lazily so its failure cannot break dashboard rendering (telemetry is a courtesy, never load-bearing); returns [] on any exception.
  • Add the Outbox card to the render flow between Capabilities Matrix and Keyboard Shortcuts. Hidden when empty via if outbox: — fresh installs and bridges that haven't recorded anything yet shouldn't see a stub card. Renders channel-typed emojis (slack/discord/telegram/imessage/whatsapp/email/x), truncated timestamps, recipient labels, and 80-char body previews — identical shape to OSS sutando.

tests/dashboard-outbox.test.py (new, 6 tests)

  • Happy path: append entries via outbox_log, read back via get_outbox.
  • Limit param honored + default (10) applied.
  • Fresh-install (no file) → [], not exception.
  • Fault tolerance: stub outbox_log.read_recent to raise → get_outbox returns [] without propagating.
  • Structural source guard: if outbox: gate on the render block (prevents future PR from accidentally showing a stub card).
  • get_outbox is a module-level callable (catches accidental scope-hiding refactors).

Audit context

  • Inventory of remaining src/ Python files identified dashboard.py as a 117-line divergence with one OSS-only def: get_outbox.
  • Other diff lines are deliberate stando-specific path-resolution (state_paths vs workspace_default, personal_path signature, DASHBOARD_PORT env override) — those were NOT touched per the minimal-divergence rule.
  • Writers beyond slack-bridge (OSS discord-bridge has ~4 outbox_log.append sites) are deferred — those would be much larger ports and require auditing which call sites are still relevant in stando's flow. Queued as Phase 5.16 candidate if the user wants outbox coverage for discord too.

Test plan

  • python3 tests/dashboard-outbox.test.py → 6/6 pass
  • Full Python regression sweep → 57/57 pass (was 56; +1 net-new file)
  • pnpm -s typecheck → clean
  • python3 -m py_compile src/dashboard.py → clean
  • Live smoke test: reader pulled 5 prior entries from the existing outbox file — confirms wiring works against real data

Followup queue

  • Phase 5.16 candidate: port outbox_log.append(...) write sites in discord-bridge.py (~4 sites in OSS) so discord deliveries also show up in the dashboard card.

Made with Cursor

….15)

`src/outbox_log.py` is the audit log every bridge appends to after a
successful outbound delivery. Stando has had the module + tests for
some time, and `slack-bridge.py` already records to it on every reply
(line 575) — but the data was invisible. Dashboard had no reader and
no rendering card, so the writes accumulated as a JSONL file no one
read. OSS sutando ships both pieces; this PR ports the missing half.

Changes:
- `src/dashboard.py`:
  - Add `get_outbox(limit: int = 10) -> list[dict]` reader. Imports
    `outbox_log` lazily so its failure cannot break dashboard rendering
    (telemetry is a courtesy, never load-bearing); returns `[]` on any
    exception.
  - Add the Outbox card to the render flow between Capabilities Matrix
    and Keyboard Shortcuts. Hidden when empty via `if outbox:` — fresh
    installs and bridges that haven't recorded anything yet shouldn't
    see a stub card. Renders channel-typed emojis (slack/discord/
    telegram/imessage/whatsapp/email/x), truncated timestamps,
    recipient labels, and 80-char body previews — identical shape to
    OSS sutando.

- `tests/dashboard-outbox.test.py` (new, 6 tests):
  - Happy path: append entries via outbox_log, read back via get_outbox.
  - Limit param honored + default (10) applied.
  - Fresh-install (no file) returns [] not exception.
  - Fault tolerance: stub outbox_log.read_recent to raise → get_outbox
    returns [] without propagating the exception.
  - Structural source guard: `if outbox:` gate on the render block.
  - get_outbox is a module-level callable (not a closure / hidden symbol).

Audit context:
- Inventory of remaining src/ Python files identified `dashboard.py`
  as a 117-line divergence with one OSS-only def: `get_outbox`. Other
  diff lines are deliberate stando-specific path-resolution (state_paths
  vs workspace_default, personal_path signature, DASHBOARD_PORT env
  override) — those were NOT touched per the minimal-divergence rule.
- Writers beyond slack-bridge (discord-bridge had ~4 outbox_log.append
  sites in OSS) are deferred — they'd be much larger ports and require
  audit of which call sites are still relevant in stando's flow.

Verification:
- `python3 tests/dashboard-outbox.test.py` → 6/6 pass.
- Full Python regression sweep → 57/57 pass (was 56; +1 net-new file).
- TypeScript typecheck clean.
- Smoke test of the live reader pulled 5 prior entries from the
  existing outbox file — confirms the wiring is correct.

Phase 5.15 of the OSS → private sync.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant