You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 roots — sourceClone 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.
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
tickets/, currentStatus:lines +issues/).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.)taskappears in both filtered views, visibly tagged.external-blocked-byhonored; unresolvable external Dependencies render blocked-unknown, never takeable."<ticket title> | /wayfinder <map ref> - resolve <ticket ref>"— title first so the agent harness derives a session name.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.rsand 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 branchresearch/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 specifyStatus:lines (claimed/resolved) +issues/under.scratch/;external-blocked-byis rare (1 of 47 tickets), path-based, and has no equivalent in the new dialect. Full inventory: local branchresearch/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, withmap.mdneeding 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 →Eitherand 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 ataskTicket 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:tPR↔tickets,J/Keffort filter,mmode cycle,pcopy prompt /ycopy URL (amended by Design the ticket detail page; originallyycopied the prompt). Closed tickets fully hidden. "Frontier" never "takeable" (CONTEXT.md amended). Prototype: local branchprototype/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;pcopies the handoff prompt,ythe URL (amends the list-surfacey); machinery = sibling modules (thirdViewModevariant,ticket_detail_items.rs) over the shared card/focus/markdown layer,normalize_detailmade 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 roots —
sourceClonemerges intomainWorktreePath(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 acrossgit worktree listworktrees (missing/prunable skipped, non-git base probed alone), probing per-repowayfinderRoots(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 rejectworktreeRoot, 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|Ticketaffinity 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-filteredblockedBylist (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 #115–Ticket 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