Skip to content

Commit dc676d4

Browse files
mpstatonclaude
andcommitted
new(context-v, plans): the didi-crawl build plan — three targets, relevance brief, staged team ingest
Grounded in a three-way code read (workspace chat gateway, social-search substrate, search-and-add surface). Key decision: the crawl rides Anthropic server-side web_search in prompt-runner — the LLM gateway already wires web_search_20260209 with the pause_turn loop — rather than orchestrating the social-search packs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UvYzx7vDWeafnkAi2nEQeb
1 parent e9fa802 commit dc676d4

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
title: "Didi crawl — three targets (links, streams, team members), the relevance brief, and staged team ingest"
3+
lede: "Implements the spec's §v1.2 crawl contract: one organization.crawl capability in prompt-runner riding Anthropic server-side web_search, candidates rendered through search-and-add's crawl mode (links/streams) and a staged people section on the workbench (team), all driven by a per-workspace operator-editable relevance brief."
4+
date_created: 2026-07-24
5+
date_modified: 2026-07-24
6+
authors:
7+
- Michael Staton
8+
augmented_with:
9+
- Claude Code on Claude Fable 5
10+
semantic_version: 0.0.0.1
11+
tags:
12+
- Plan
13+
- Augment-It
14+
- Org-Workbench
15+
- Search-And-Add
16+
- Didi-Chat
17+
- Crawl
18+
- Relevance-Brief
19+
status: Implementing
20+
---
21+
22+
# Didi crawl — the v1.2 build
23+
24+
## Spec reference
25+
26+
Implements [[../specs/Augment-From-DB-Flow]] §v1.2 (v0.1.2.0). Composes with
27+
[[Didi-Chat-In-Org-Workbench-Verify-Team-Page-Into-People-Objects]] (which
28+
keeps the chat-rail context plumbing). Branch: `rebuild/turbo-rsbuild`.
29+
30+
## Decisions (closing the spec's v1.2 open questions, grounded in a three-way code read)
31+
32+
1. **Crawl substrate: Anthropic server-side web_search in prompt-runner**
33+
NOT the social-search packs. `prompt-runner` is the LLM gateway
34+
(workspace never touches the SDK, by invariant `chat.ts:8-10`), and it
35+
already wires `web_search_20260209` with the `pause_turn` resume loop
36+
(`request.ts:27-30`, `anthropic.ts:66-70`). One model call composes
37+
queries, searches, filters by the brief, and returns structured
38+
candidates — the packs/connectors stay the manual 🔍's substrate. The
39+
social-search option (7 social packs + firecrawlScrape + Haiku fallback)
40+
is the documented fallback if model-driven quality disappoints.
41+
2. **Brief storage: server-side, resolver-owned** (shipped ahead of this
42+
plan): `relevance_briefs` table, `client.brief.get`/`set` capabilities.
43+
The crawl handler reads the brief itself over NATS (single source of
44+
truth for button and chat doors); the UI editor is a workbench panel.
45+
3. **Candidate UI: search-and-add crawl mode** for links/streams — the
46+
Phase-5 scan-mode precedent exactly (`crawl?: boolean` on the envelope, a
47+
third fire path, same ResultsList/ResultRow, per-row ➕ already routed by
48+
`verbFor(target)`). Team members do NOT go through search-and-add — they
49+
stage on the workbench's people reveal with per-row accept
50+
(no-candidate rows flow: `person.apply` create + `person.affiliate`;
51+
ambiguous rows open the candidate gate — the didi-chat plan's step 4
52+
discipline).
53+
4. **Doors:** crawl is a header-level action (the whole list is the
54+
subject, unlike per-entry scan): AdditiveList gains an optional
55+
`oncrawl` header button (links + streams lists); PeopleReveal gains a
56+
"crawl team" header button; chat door = `organization.crawl` added to
57+
`CHAT_CAPABILITY_NAMES` + a verb-slab entry (focused-org context
58+
plumbing stays with the didi-chat plan).
59+
5. **Org context is fetched server-side**, not stuffed into envelopes: the
60+
crawl handler NATS-requests `organization.detail` (name, domains,
61+
existing list URLs for dedupe) and `client.brief.get`, then prompts.
62+
63+
## Capability contract
64+
65+
`organization.crawl``organization.crawl.requested` (prompt-runner),
66+
timeout 300s. Input `{ org_slug, target: 'links'|'streams'|'team', client,
67+
max_results? }`. Replies:
68+
69+
- links/streams: `{ ok, provider: 'didi-crawl', results: ConnectorResult[] }`
70+
(url/title/content — content carries the model's one-line relevance
71+
reason; deduped against the org's existing URLs server-side).
72+
- team: `{ ok, people: [{name, role, headline?, linkedin_url?, bio_url?}],
73+
filtered_note, source_urls[] }` — selection per the brief's people policy
74+
(default: all major leadership + all team members covering Education &
75+
Workforce Development and related strategies/topics), with the
76+
filtered-out count named, never silent.
77+
78+
## Steps
79+
80+
1. **prompt-runner: `crawl.ts`**`registerCrawlHandler(nc)`: fetch
81+
`organization.detail` + `client.brief.get` over NATS; per-target system
82+
prompt (org identity + existing URLs + brief + strict JSON output
83+
contract); `buildRequest` with `tools:['web_search']`; `runPrompt`;
84+
tolerant JSON extraction (fence-stripping); dedupe vs existing; reply.
85+
Register in prompt-runner `server.ts`.
86+
2. **workspace:** capability map + 300s timeout; `organization.crawl` into
87+
`CHAT_CAPABILITY_NAMES` + a WORKBENCH slab line describing the three
88+
targets and args.
89+
3. **search-and-add crawl mode:** `crawl?: true` on `SearchRequestDetail`
90+
(both type mirrors); `crawlSearch` wrapper; `crawlMode` derived + third
91+
fire path + status bar arm in App.svelte (scan-mode pattern verbatim).
92+
4. **org-workbench doors:** AdditiveList `oncrawl` header prop (🤖);
93+
OrgCard passes it for links + streams (envelope `{entity, target,
94+
seed_term:'', crawl:true}`); BriefPanel (header toggle → textarea →
95+
`client.brief.get/set` wrappers).
96+
5. **Team staging:** PeopleReveal "crawl team" button → `crawlOrg(team)`
97+
staged rows (name · role · links) with per-row Accept/skip;
98+
accept → `person.candidates` → empty: `person.apply`(create) +
99+
`person.affiliate` (role, source = team-page URL); non-empty: inline
100+
candidate gate (pick match or create). `filtered_note` rendered under
101+
the staged section.
102+
6. **Verify:** typechecks + svelte-checks + builds; rebuild prompt-runner,
103+
workspace, resolver containers; live smoke of `organization.crawl`
104+
against the Aspen safe target if NATS reachable, else operator
105+
walk-through: Gates Foundation → crawl links (candidates appear, ➕
106+
one) → crawl streams → crawl team (staged people per policy) → edit the
107+
brief and re-crawl to see selection change.
108+
7. Changelog + gh issue close + spec revision note.
109+
110+
## Non-goals (this pass)
111+
112+
- Chat-rail focused-org context and conversational triggering UX — the
113+
didi-chat plan owns it; this pass only makes the capability chat-legal.
114+
- Headshots/enrichment of staged people (person-enrichment owns).
115+
- Corpus-target crawl (search-and-add's manual flow already covers corpus;
116+
revisit after the metadata work in the corpus-items issue).

0 commit comments

Comments
 (0)