Skip to content

Map: Wayfinder ticket surface in legit #104

Description

@mayfieldiv

Destination

A spec sharp enough that implementation sessions can start adding a wayfinder-ticket surface to legit: a read-only ticket queue (toggled from the PR view) across Tracked Repos + cwd, reading both GitHub-tracked and local maps, filterable AFK/HITL, with a detail page and one-key copy of a fixed handoff prompt. The map closes when nothing is left to decide.

Notes

  • Planning only: tickets resolve decisions; implementation happens after this map closes, driven by the spec ticket's output.
  • Work with default wayfinder conventions — do not amend the skill or tracker docs. The tool parses tolerantly instead (both local dialects: older YAML-frontmatter + tickets/, current Status: lines + issues/).
  • Standing decisions from the charting grill:
    • Separate ticket-list surface for v1, reusing legit's list/detail/markdown machinery; no interleaving with the PR list.
    • Discovery: Tracked Repos + cwd; local efforts by probing well-known dirs (docs/wayfinder/, .wayfinder/, .scratch/) — wayfinder dirs are typically gitignored, so no git-index scan. (Refined by Design the config extension for local repos and wayfinder roots: probing fans out across all linked worktrees of a repo's main worktree.)
    • Modes: research→AFK, prototype/grilling→HITL; task appears in both filtered views, visibly tagged.
    • Cross-map external-blocked-by honored; unresolvable external Dependencies render blocked-unknown, never takeable.
    • Copy template (fixed): "<ticket title> | /wayfinder <map ref> - resolve <ticket ref>" — title first so the agent harness derives a session name.
    • Read-only: the TUI never claims or resolves tickets.
    • Vocabulary: Dependency (ticket edge; "blocked by" is ordinary prose), Blocks (reverse read, shown in summary/detail), Frontier (never "takeable" — see Design the ticket list surface). Overloading Blocker between people (PRs) and tickets is acceptable — context disambiguates. (Amended by Pin the ticket domain model into legit's CONTEXT.md; originally "Blocker stays people-only".)
  • Skills to consult per session: /grilling + /domain-modeling for decision tickets; /codebase-design for design tickets; /prototype for the list-surface ticket; /research for research tickets.
  • Read legit's AGENTS.md and CONTEXT.md before any session. Never post to GitHub without explicit user approval (legit house rule).

Decisions so far

  • Research the GitHub sub-issues and issue-dependencies API surface — one hand-written GraphQL query reads an entire map (label → sub-issues → dependency summary + blockedBy) at ~10 rate-limit points, so map reads go in graphql.rs and single-ticket refresh stays REST; octocrab 0.51 covers none of it (legit bypasses its models anyway); GA everywhere on github.com so the body-convention fallback is detect-and-degrade, not built up front. Traps: limiter.rs's PR-shaped affinity key needs generalizing, and the dependency summary is eventually consistent (~10s). Full findings: local branch research/github-subissues-dependencies, docs/research/github-subissues-dependencies.md.

  • Inventory the local wayfinder dialects — two divergent local dialects: all real data uses the older YAML-frontmatter + tickets/ layout (status: open|closed, assignee = claim), while current docs specify Status: lines (claimed/resolved) + issues/ under .scratch/; external-blocked-by is rare (1 of 47 tickets), path-based, and has no equivalent in the new dialect. Full inventory: local branch research/local-dialects, docs/research/local-wayfinder-dialects.md. (Addendum in Design the config extension for local repos and wayfinder roots: a third live layout exists — .wayfinder/ as a single effort directly at its root, with map.md needing case-insensitive matching.)

  • Pin the ticket domain model into legit's CONTEXT.md — glossary landed on PR #113: Effort (one per Tracked Repo, GitHub-vs-local is an attribute) / Map / Destination / Ticket / Type / Mode (AFK/HITL/Either, derived, unknown Types → Either and never hidden) / Claim / Dependency / External + Unknown Dependency / Blocks (reverse read) / Frontier. Lifecycle is two axes (Open/Closed + Claim), blocked-ness always derived; person-blocks are modelled as a Dependency on a task Ticket the person claims; the "Blocker stays people-only" standing decision was amended (see Notes).

  • Design the ticket list surface — winner: an "Efforts pane" layout — effort rail (All efforts + per-effort cards with destination) · takeability-tiered queue (Frontier/Claimed/Blocked, red Blocked header, unknown deps folded in) · summary panel with both dependency directions and the copy prompt. Columns Ticket|Repo|Type|Title|Block|Age (no Mode/State columns — Type cell coloured by mode, tiers+markers+summary carry state); red ↑deps / blue ↓dependents; local refs are file slugs, middle-ellipsized at 14. Keys: t PR↔tickets, J/K effort filter, m mode cycle, p copy prompt / y copy URL (amended by Design the ticket detail page; originally y copied the prompt). Closed tickets fully hidden. "Frontier" never "takeable" (CONTEXT.md amended). Prototype: local branch prototype/ticket-list-surface.

  • Design the ticket detail page — dependency rows are focusable/enterable with a nav stack (Esc pops) — the only route to closed tickets' resolutions; page = header (effort + destination, tier-vocabulary state) · body card · waits on (↑) all targets with state (open red, closed muted ✓, unknown red "can't find or read", never enterable) / blocks (↓) open dependents only · all comments as cards, no resolution detection; p copies the handoff prompt, y the URL (amends the list-surface y); machinery = sibling modules (third ViewMode variant, ticket_detail_items.rs) over the shared card/focus/markdown layer, normalize_detail made entity-agnostic; fetch contract (lazy body+comments drill-in, PrKey-typed limiter focus) handed to Fit ticket fetching into legit's refresh and priority-queue model.

  • Design the config extension for local repos and wayfinder rootssourceClone merges into mainWorktreePath (hard rename, precise unknown-field error as the migration path); an entry carries slug, path, or both (at least one); discovery starts there and fans out across git worktree list worktrees (missing/prunable skipped, non-git base probed alone), probing per-repo wayfinderRoots (replace-not-extend, relative to each worktree, absolute allowed, no global key) or the built-in defaults; cwd walks cwd→toplevel probing each level, explicit roots winning on a config match; validation stays shape-only with no existence checks; slug-less entries reject worktreeRoot, display by basename, dedup by canonical path; nothing reserved for the future cross-repo tracker beyond keeping discovery source and Effort attribution distinct steps. Glossary on PR #113: Tracked Repo broadened, Source Clone → Main Worktree, new Wayfinder Root.

  • Fit ticket fetching into legit's refresh and priority-queue model — the PR fetch design transposed, keyed by a new Fetch Unit concept (a PR's enrichment, or an Effort's ticket data) so nothing couples to effort shape: map reads ride the background lane like the listing, drill-in fetches ride Focus Promotion via a widened Pr|Ticket affinity key, r/R = refresh the unit backing the selection / all units in view scope (no Re-list split), Fetch Age stamps the unit, blocked-ness derives from the state-filtered blockedBy list (never the eventually-consistent counter), failures keep stale data with an explicit error card at startup, local probes bypass the limiter entirely. Ticket↔PR links spun out to Surface links between wayfinder Tickets and PRs.

  • Assemble the implementation-ready spec — the spec lives as Assemble the implementation-ready spec #112's resolution comment (deliberately not a repo file), compiling every decision above into implementation order and slicing it into eight implementation issues Config: rename sourceClone to mainWorktreePath, allow slug-less repos, add wayfinderRoots #115Ticket detail page #122 with native dependencies wired (Config: rename sourceClone to mainWorktreePath, allow slug-less repos, add wayfinderRoots #115, Ticket domain types, keys, and derivations #116 unblocked and ready-for-agent). The remaining fog item (narrow-width collapse) was delegated to the list-surface issue Ticket list surface #121 as implementation latitude. Map closed — nothing left to decide.

Not yet specified

None.

Out of scope

  • Interleaving tickets into the PR list (unified-queue endgame) — revisit as its own effort if the destination is redrawn.
  • Prompt-template customization.
  • Any TUI write actions (claim/resolve).
  • Amending wayfinder skill conventions or tracker docs.
  • GitLab tracker support.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions