Start a thread without placing a pin — leave general feedback about the page (or the review as a whole) instead of having to click an element first. Today starting a thread is element-anchored: CreateThreadBody mandates anchor (packages/core/src/contract/requests.ts:22), and the create flow begins with a click that captures the element fingerprint.
Status: parking lot — page-scoped first cut; global/cross-page threads can follow.
Shape. Most of the infrastructure already exists:
- Display is solved. Threads with no live pin already render as the detached
ThreadCard in the panel (the M8 orphan path). A pinless thread is essentially one born detached rather than orphaned by a DOM change.
- The data model anticipates it. The documented seam is
scope: "page" | "global" with pageKey: null "allowed for future global threads" (docs/architecture.md), though the live zod still hard-codes scope: z.literal('page') (packages/core/src/schemas/thread.ts).
Real gaps:
- Make
anchor optional in CreateThreadBody and pick the model shape — likely a distinct state, not reusing orphaned (orphaned means lost its anchor, not never had one; conflating them muddies the self-heal/re-match policy). The contract is TDD-first (ADR-0010): failing core/adapter tests before code.
- A create affordance that isn't an element click — e.g. a "comment on this page" button in the widget chrome that opens the composer straight into the panel.
- Page vs. global scope. The smaller first cut is page-scoped (anchor omitted but
pageKey set, so it shows in this page's panel and not others); truly cross-page/global threads (scope: "global", pageKey: null) follow.
Effort: medium — core schema + HTTP contract, both adapters' create/list, and a composer entry point. No anchoring/re-match work, since these threads opt out of that machinery. Worth an ADR note when picked up: it widens a public request shape and adds an anchor state.
Start a thread without placing a pin — leave general feedback about the page (or the review as a whole) instead of having to click an element first. Today starting a thread is element-anchored:
CreateThreadBodymandatesanchor(packages/core/src/contract/requests.ts:22), and the create flow begins with a click that captures the element fingerprint.Status: parking lot — page-scoped first cut; global/cross-page threads can follow.
Shape. Most of the infrastructure already exists:
ThreadCardin the panel (the M8 orphan path). A pinless thread is essentially one born detached rather than orphaned by a DOM change.scope: "page" | "global"withpageKey: null"allowed for future global threads" (docs/architecture.md), though the live zod still hard-codesscope: z.literal('page')(packages/core/src/schemas/thread.ts).Real gaps:
anchoroptional inCreateThreadBodyand pick the model shape — likely a distinct state, not reusingorphaned(orphanedmeans lost its anchor, not never had one; conflating them muddies the self-heal/re-match policy). The contract is TDD-first (ADR-0010): failing core/adapter tests before code.pageKeyset, so it shows in this page's panel and not others); truly cross-page/global threads (scope: "global",pageKey: null) follow.Effort: medium — core schema + HTTP contract, both adapters' create/list, and a composer entry point. No anchoring/re-match work, since these threads opt out of that machinery. Worth an ADR note when picked up: it widens a public request shape and adds an anchor state.