v1 plan: peer-to-peer support/ticketing built on hero_collab snapshot #1

Open
opened 2026-04-28 18:42:55 +00:00 by mik-tf · 0 comments
Owner

v1 plan — hero_assistance

Master tracking issue. SSOT for the v1 plan; supersedes prior chat. v1 is production-grade for real customers, not a demo.

Summary

A peer-to-peer support/ticketing system for the Hero stack. Two OpenRPC services in one monorepo, built by snapshot-copying hero_collab and pruning. Many-to-many topology — a client subscribes to multiple project servers; a server hosts multiple users (customers + support agents).

  • hero_assistance_server — one per customer-project. SQLite, OpenRPC, mycelium-bound TCP listener. Owns tickets, threaded messages, image attachments, and presence for that project.
  • hero_assistance_client — a library crate with a thin standalone binary wrapper. Embeddable as a "Support" tab in any project's existing UI, or run standalone for users juggling multiple projects.

Specs (chat 2026-04-27)

  • Tickets with copy-paste image attachments
  • Live presence ("someone is actively looking at this")
  • Many-to-many client/server topology
  • Multi-project view for the support team
  • Mycelium address as project identifier
  • OpenRPC throughout — both ends are servers (peer-to-peer)
  • Customer "just configures what the endpoint is" (manual config of project addresses)

Architecture

Three-layer identity

Layer Identifier Visible to user?
Project mycelium address + display_name Display name only
Device mycelium address (per machine) No — invisible
User email + magic-link auth Yes

A user has one account keyed on email. Multiple devices per user; each generates its own mycelium identity. Server-side device_bindings table maps mycelium_addr → user_id. Sales pre-enrolls customers by email; first connection from any device receives a magic link to bind that device.

Transport

Mycelium-IPv6. Server binds an Axum listener to the host's mycelium TUN IPv6 (queried at startup via mycelium RPC get_info()node_subnet). On accept, peer_addr.ip() is the cryptographically-authenticated peer device address — mycelium's daemon validates source addresses at the network layer; no userspace HMAC needed. Standalone client bundles a mycelium daemon as a subprocess (detects + reuses an existing system mycelium UDS if present; otherwise spawns its own with a per-app data directory). Mycelium identity (key) generated on first run, stored under ~/.local/share/hero_assistance/mycelium/.

Storage

SQLite, inherited from hero_collab. New tables:

  • users { id, email PRIMARY, display_name, role, status, created_at }
  • device_bindings { mycelium_addr PRIMARY, user_id FK, device_label, bound_at, last_seen }

Existing collab tables retained: messages, threads, attachments, presence — semantically remapped to tickets/comments/etc.

Crate layout

hero_assistance/
├── crates/
│   ├── hero_assistance_core/      shared types
│   ├── hero_assistance_server/    binary
│   ├── hero_assistance_client/    library (Dioxus components + RPC + presence)
│   ├── hero_assistance_app/       binary (thin standalone Dioxus wrapper)
│   ├── hero_assistance_sdk/       library (typed RPC client, generated)
│   └── hero_assistance/           binary (CLI lifecycle wrapper)
└── Cargo.toml

Locked decisions

  • D-01 Path: snapshot-copy hero_collab → hero_assistance. Prune huddles, canvases, reactions, mentions, voice. No fork tracking — all our code, snapshot-and-diverge.
  • D-02 Storage: SQLite, inherited from collab. No rewrite.
  • D-03 Crate layout: monorepo with crates above.
  • D-04 Three-layer identity: project / device / user. CallerIdentity{user_id, device_addr, role} newtype from day 1. Identity boundary is the single function at hero_collab main.rs:210–249; ~15 call sites updated.
  • D-05 Transport: mycelium-IPv6 binding (viability verified, 2026-04-28). Standalone client bundles mycelium daemon; detects + reuses system mycelium UDS where present.

Limitations accepted

  • L-01: Manual configuration of project endpoints (matches spec). Embedded clients pre-fill.
  • L-02: Customers behind firewalls blocking mycelium can't connect in v1. Web gateway is post-v1.

Explicitly deferred — NOT in v1

None of these were in the original spec; all are real, all post-v1:

  • Public Forgejo registry for project discovery
  • Status URLs / health badges
  • SQLite FTS5 "similar tickets" search
  • Tickets-as-markdown auto-export to private backup repos
  • Deep-link URL scheme (hero-assist://...)
  • Auto-pending approval queue with role gating
  • Invite tokens / signed enrollment links
  • Web gateway for zero-install access
  • AI summarization / auto-categorization
  • Mycelium pub-sub broadcasts
  • Cross-project federation
  • Multilingual auto-translation

Phase plan

# Phase Estimate
0 Workspace bootstrap (ai-pipeline /bootstrap); D-01..D-05 + L-01..L-02 written; initial repo skeleton committed 0.5 day
1 Snapshot hero_collab → hero_assistance; rename packages, paths, references; baseline build green 1 day
2 Prune huddles, canvases, reactions, mentions, Dioxus admin app; tests still pass 2 days
3 Identity layer: CallerIdentity newtype, users + device_bindings schema, magic-link enrollment RPC, ~15 call sites updated 3 days
4 Mycelium transport: query own address at startup, bind Axum to mycelium IPv6, peer_addr extraction middleware 1–2 days
5 Bundled mycelium subprocess (detect existing + spawn own logic) 1 day
6 Client library restructure + standalone wrapper binary 2–3 days
7 Multi-project subscription aggregator; presence variant viewing_ticket_id 2 days
8 UI prune (channels → tickets, message → comment) 2 days
9 End-to-end tests, single-host then cross-host via mycelium 1–2 days
10 UX validation gate (methodology Rule 6) — actually click through 1 day
11 Polish, README, operator runbook, release 1 day

Total: ~17–19 working days (~3.5 weeks). Some phases can overlap.

v1 acceptance criteria

Demonstrable on real cross-host machines:

  1. Customer installs hero_assistance_client on a fresh machine without separately installing mycelium.
  2. Customer enters a project's mycelium address + their email. Receives magic link. Clicks it. Device bound.
  3. Customer files a ticket including a pasted image.
  4. Support agent on a different machine sees the ticket appear live.
  5. Both sides see "actively looking at this" presence when viewing the same ticket.
  6. Support agent replies; customer sees the reply live.
  7. Customer adds a second project (different mycelium address). Both projects' tickets appear.
  8. Support agent's standalone client subscribes to all team projects; sees consolidated cross-project list.
  9. No TLS required (mycelium provides transport encryption); plain HTTP over mycelium IPv6 works.
  10. All tests pass; bash scripts/start.sh exits 0.

Risks / known unknowns

  • Bundled mycelium binary size — adds ~10–30 MB to installer. Acceptable for desktop; matters for mobile (post-v1).
  • Per-device resource use — each client runs a mycelium relay node by design. Small but non-zero CPU/network overhead. Measure before claiming "free."
  • Firewall compatibility — corporate networks may block mycelium. Captured as L-02; web gateway is the post-v1 mitigation.
  • Mycelium upstream version tracking — bundled daemon needs an update process. Establish before shipping.
  • Threat model rests on mycelium daemon trust at host level. Compromised daemon could forge packets. Standard overlay-as-trust-boundary assumption.

Methodology

This project uses the ai-pipeline v1 multi-session workflow. Local workspace at /home/pctwo/Documents/temp/assistance_work/. After this issue is filed, /bootstrap runs in the workspace; D-01..D-05 + L-01..L-02 lift into decisions/ and limitations/ files. Each phase above corresponds to one or more sessions; prompt.md §3 carries the next-session entry point.

Branching & commits

Hero conventions: default branch development; feature branches development_<name> (underscores); squash-merge back to development. Conventional-commit messages with absolute issue URL reference; no AI attribution.

# v1 plan — hero_assistance Master tracking issue. SSOT for the v1 plan; supersedes prior chat. v1 is production-grade for real customers, not a demo. ## Summary A peer-to-peer support/ticketing system for the Hero stack. Two OpenRPC services in one monorepo, built by snapshot-copying hero_collab and pruning. Many-to-many topology — a client subscribes to multiple project servers; a server hosts multiple users (customers + support agents). - **`hero_assistance_server`** — one per customer-project. SQLite, OpenRPC, mycelium-bound TCP listener. Owns tickets, threaded messages, image attachments, and presence for that project. - **`hero_assistance_client`** — a library crate with a thin standalone binary wrapper. Embeddable as a "Support" tab in any project's existing UI, or run standalone for users juggling multiple projects. ## Specs (chat 2026-04-27) - Tickets with copy-paste image attachments - Live presence ("someone is actively looking at this") - Many-to-many client/server topology - Multi-project view for the support team - Mycelium address as project identifier - OpenRPC throughout — both ends are servers (peer-to-peer) - Customer "just configures what the endpoint is" (manual config of project addresses) ## Architecture ### Three-layer identity | Layer | Identifier | Visible to user? | |---|---|---| | Project | mycelium address + display_name | Display name only | | Device | mycelium address (per machine) | No — invisible | | User | email + magic-link auth | Yes | A user has one account keyed on email. Multiple devices per user; each generates its own mycelium identity. Server-side `device_bindings` table maps mycelium_addr → user_id. Sales pre-enrolls customers by email; first connection from any device receives a magic link to bind that device. ### Transport Mycelium-IPv6. Server binds an Axum listener to the host's mycelium TUN IPv6 (queried at startup via mycelium RPC `get_info()` → `node_subnet`). On accept, `peer_addr.ip()` is the cryptographically-authenticated peer device address — mycelium's daemon validates source addresses at the network layer; no userspace HMAC needed. Standalone client bundles a mycelium daemon as a subprocess (detects + reuses an existing system mycelium UDS if present; otherwise spawns its own with a per-app data directory). Mycelium identity (key) generated on first run, stored under `~/.local/share/hero_assistance/mycelium/`. ### Storage SQLite, inherited from hero_collab. New tables: - `users { id, email PRIMARY, display_name, role, status, created_at }` - `device_bindings { mycelium_addr PRIMARY, user_id FK, device_label, bound_at, last_seen }` Existing collab tables retained: messages, threads, attachments, presence — semantically remapped to tickets/comments/etc. ### Crate layout ``` hero_assistance/ ├── crates/ │ ├── hero_assistance_core/ shared types │ ├── hero_assistance_server/ binary │ ├── hero_assistance_client/ library (Dioxus components + RPC + presence) │ ├── hero_assistance_app/ binary (thin standalone Dioxus wrapper) │ ├── hero_assistance_sdk/ library (typed RPC client, generated) │ └── hero_assistance/ binary (CLI lifecycle wrapper) └── Cargo.toml ``` ## Locked decisions - **D-01 Path:** snapshot-copy hero_collab → hero_assistance. Prune huddles, canvases, reactions, mentions, voice. No fork tracking — all our code, snapshot-and-diverge. - **D-02 Storage:** SQLite, inherited from collab. No rewrite. - **D-03 Crate layout:** monorepo with crates above. - **D-04 Three-layer identity:** project / device / user. `CallerIdentity{user_id, device_addr, role}` newtype from day 1. Identity boundary is the single function at hero_collab `main.rs:210–249`; ~15 call sites updated. - **D-05 Transport:** mycelium-IPv6 binding (viability verified, 2026-04-28). Standalone client bundles mycelium daemon; detects + reuses system mycelium UDS where present. ## Limitations accepted - **L-01:** Manual configuration of project endpoints (matches spec). Embedded clients pre-fill. - **L-02:** Customers behind firewalls blocking mycelium can't connect in v1. Web gateway is post-v1. ## Explicitly deferred — NOT in v1 None of these were in the original spec; all are real, all post-v1: - Public Forgejo registry for project discovery - Status URLs / health badges - SQLite FTS5 "similar tickets" search - Tickets-as-markdown auto-export to private backup repos - Deep-link URL scheme (`hero-assist://...`) - Auto-pending approval queue with role gating - Invite tokens / signed enrollment links - Web gateway for zero-install access - AI summarization / auto-categorization - Mycelium pub-sub broadcasts - Cross-project federation - Multilingual auto-translation ## Phase plan | # | Phase | Estimate | |---|---|---| | 0 | Workspace bootstrap (ai-pipeline `/bootstrap`); D-01..D-05 + L-01..L-02 written; initial repo skeleton committed | 0.5 day | | 1 | Snapshot hero_collab → hero_assistance; rename packages, paths, references; baseline build green | 1 day | | 2 | Prune huddles, canvases, reactions, mentions, Dioxus admin app; tests still pass | 2 days | | 3 | Identity layer: `CallerIdentity` newtype, `users` + `device_bindings` schema, magic-link enrollment RPC, ~15 call sites updated | 3 days | | 4 | Mycelium transport: query own address at startup, bind Axum to mycelium IPv6, `peer_addr` extraction middleware | 1–2 days | | 5 | Bundled mycelium subprocess (detect existing + spawn own logic) | 1 day | | 6 | Client library restructure + standalone wrapper binary | 2–3 days | | 7 | Multi-project subscription aggregator; presence variant `viewing_ticket_id` | 2 days | | 8 | UI prune (channels → tickets, message → comment) | 2 days | | 9 | End-to-end tests, single-host then cross-host via mycelium | 1–2 days | | 10 | UX validation gate (methodology Rule 6) — actually click through | 1 day | | 11 | Polish, README, operator runbook, release | 1 day | **Total: ~17–19 working days (~3.5 weeks).** Some phases can overlap. ## v1 acceptance criteria Demonstrable on real cross-host machines: 1. Customer installs hero_assistance_client on a fresh machine without separately installing mycelium. 2. Customer enters a project's mycelium address + their email. Receives magic link. Clicks it. Device bound. 3. Customer files a ticket including a pasted image. 4. Support agent on a different machine sees the ticket appear live. 5. Both sides see "actively looking at this" presence when viewing the same ticket. 6. Support agent replies; customer sees the reply live. 7. Customer adds a second project (different mycelium address). Both projects' tickets appear. 8. Support agent's standalone client subscribes to all team projects; sees consolidated cross-project list. 9. No TLS required (mycelium provides transport encryption); plain HTTP over mycelium IPv6 works. 10. All tests pass; `bash scripts/start.sh` exits 0. ## Risks / known unknowns - **Bundled mycelium binary size** — adds ~10–30 MB to installer. Acceptable for desktop; matters for mobile (post-v1). - **Per-device resource use** — each client runs a mycelium relay node by design. Small but non-zero CPU/network overhead. Measure before claiming "free." - **Firewall compatibility** — corporate networks may block mycelium. Captured as L-02; web gateway is the post-v1 mitigation. - **Mycelium upstream version tracking** — bundled daemon needs an update process. Establish before shipping. - **Threat model rests on mycelium daemon trust** at host level. Compromised daemon could forge packets. Standard overlay-as-trust-boundary assumption. ## Methodology This project uses the ai-pipeline v1 multi-session workflow. Local workspace at `/home/pctwo/Documents/temp/assistance_work/`. After this issue is filed, `/bootstrap` runs in the workspace; D-01..D-05 + L-01..L-02 lift into `decisions/` and `limitations/` files. Each phase above corresponds to one or more sessions; `prompt.md §3` carries the next-session entry point. ## Branching & commits Hero conventions: default branch `development`; feature branches `development_<name>` (underscores); squash-merge back to `development`. Conventional-commit messages with absolute issue URL reference; no AI attribution.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_assistance#1
No description provided.