Skip to content

feat(dashboard): Telltale feedback adapter and its read seam - #65

Merged
adbarc92 merged 1 commit into
mainfrom
feat/dashboard-feedback-adapter
Aug 31, 2026
Merged

feat(dashboard): Telltale feedback adapter and its read seam#65
adbarc92 merged 1 commit into
mainfrom
feat/dashboard-feedback-adapter

Conversation

@adbarc92

Copy link
Copy Markdown
Owner

First half of the T5 integration (Telltale spec §6): turns user bug and crash reports into board state.

Adds the adapter and the one model change it needs. The transport wiring — api.ts, store.ts, Dashboard.svelte's SOURCE_LABEL + pollFeedback, and dashboard.rs with its generate_handler! registration — follows in a second PR, once the Worker is deployed and there is a real endpoint to verify against. The adapter is the pure, fully-testable half and stands on its own.

The §6.4 mapping

Precedence explicit, top row wins:

Condition Stage Detail
Any open telltale:crash with no assignee Blocked{ gate: 'manual', action: 'triage crash report', deepLink: <issue url> } n open · untriaged crash
Any other open issues Idle n open · m new this week

Why Idle and never Build. model.ts documents PIPELINE as where a project sits in its lifecycle, and sortedCards ranks Build above Review/Ship/Live — so mapping "has ≥1 open bug report" to Build would make one old bug outrank a project that is live in production.

Why no assignee and not a telltale:triaged label. blockedCount is the board's "NEEDS YOU" headline, so a Blocked condition that never clears is a permanent false positive on its most valuable signal. Assignee is native, free in the list response, self-clearing, and one click on github.com.

One card per project with at least one open issue. A card per registry project would pile ~10 permanently-grey Idle cards at the bottom of the grid (sortedCards ranks Idle at 99, below Archived), inflate the header's project total, and duplicate projects already on the board via the local source.

⚠️ Deliberate deviation from Telltale spec §6.2

§6.2 types the seam as issues(): Promise<TelltaleIssue[]>which discards the per-repo errors array that §6.3 makes required behaviour. "One bad repo would blank the entire feedback lane" is the exact failure §6.3 exists to prevent, and §5.3 says outright that some registry repos are archived and some are private with broken billing. A seam returning only the array makes §6.3 unimplementable.

So the seam returns the Worker's real { issues, errors } response. The TelltaleIssue shape itself is unchanged. This is documented in the adapter's file header and is worth correcting in the Telltale spec — flagged in adbarc92/telltale#3.

model.ts

Source union + 'feedback', and the file-header claim that adding a source is "one new adapter, zero board change" (locked decision #6) is retracted — §6.1 verified the real surface at seven files, and the local-tracker spec already retracted the same overclaim for itself.

Tests

12 new tests covering the §6.4 table — including both negative cases that make Blocked meaningful (an assigned crash, and an unassigned bug), §6.3 partial failure degrading only the affected project, a throwing reader falling back to the single synthetic __source__ card, and the §4 override/conflict contract.

Verification

  • npx vitest run154 passed, 21 files (12 new)
  • npm run check356 files, 0 errors, 0 warnings

First half of the T5 integration (Telltale spec §6): turns user bug and
crash reports into board state. Adds the adapter and the model change it
needs; the transport wiring (api.ts, store.ts, Dashboard.svelte,
dashboard.rs and its handler registration) follows once the Worker is
deployed and there is a real endpoint to verify against.

adapters/feedback.ts
  Written against a FeedbackReader seam rather than fetch, for the same
  reason halyard.ts is written against HalyardReader: environment-agnostic
  and unit-testable with fakes.

  §6.4 mapping, precedence top row wins:
  - open telltale:crash with NO assignee → Blocked, BlockedInfo{ gate:
    'manual', action: 'triage crash report', deepLink: <issue url> }
  - any other open issues            → Idle

  Idle and never Build: model.ts documents PIPELINE as where a project sits
  in its lifecycle, and sortedCards ranks Build above Review/Ship/Live — so
  mapping "has >=1 open bug" to Build would make one old bug outrank a
  project that is live in production.

  No assignee rather than a telltale:triaged label: blockedCount is the
  board's "NEEDS YOU" headline, so a Blocked condition that never clears is
  a permanent false positive on its most valuable signal. Assignee is
  native, free in the list response, self-clearing, and one click on
  github.com.

  One card per project WITH at least one open issue. Emitting a card per
  registry project would pile ~10 permanently-grey Idle cards at the bottom
  of the grid (sortedCards ranks Idle at 99, below Archived), inflate the
  header's project total, and duplicate projects already on the board via
  the local source.

  DEVIATION from spec §6.2, deliberate and documented in the file header.
  §6.2 types the seam as issues(): Promise<TelltaleIssue[]>, which discards
  the per-repo errors array that §6.3 makes required behaviour — "one bad
  repo would blank the entire feedback lane" is the exact failure it exists
  to prevent, and §5.3 says outright that some registry repos are archived
  or have broken billing. A seam returning only the array makes §6.3
  unimplementable, so the seam returns the Worker's real { issues, errors }
  response. The TelltaleIssue shape itself is unchanged. Worth correcting
  in the Telltale spec.

model.ts
  Source union + 'feedback'. Amends the file-header claim that adding a
  source is "one new adapter, zero board change" (locked decision #6) —
  §6.1 verified the real surface at seven files, and the local-tracker spec
  already retracted the same overclaim for itself.

12 tests cover the §6.4 table including both negative cases that make
Blocked meaningful (an assigned crash, and an unassigned bug), §6.3 partial
failure, reader-throws, and the §4 override contract.

Verified: vitest 154 passed (21 files); npm run check 356 files, 0 errors.
@adbarc92
adbarc92 merged commit c973aac into main Aug 31, 2026
16 checks passed
@adbarc92
adbarc92 deleted the feat/dashboard-feedback-adapter branch August 31, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant