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
feat(didi-chat), skill(triage-inbox): relations + tags verbs in the workbench slab; aboutness routing lands as step 5b
didi can now speak the family tree: the workbench slab teaches
organization.relations / organization.relate / organization.tag.add with a
propose-first discipline — relations are judgment calls, so didi invokes
only when the operator stated the relationship themselves, quoting their
phrasing into the edge's description. Both-orgs-must-exist and
peers-not-hierarchies (funds / partners_with) are spelled out.
Triage integration per the plan's Phase 3: the ACTIVE_SKILLS slab gains
step 5b (aboutness routing — parent content on the parent, initiative
content on the child, reference_of pointer across the seam; real-actor
initiatives with no row get minted + related + tagged instead of parked),
and the initiative_hub stream kind sheds its "while parent/child modeling
is unresolved" caveat. SKILL.md updated in the same commit per the
update-both-together rule: the parent-child open decision flips to MODEL
LANDED with the new routing recorded in place.
Verified: workspace tsc clean; service rebuilt and serving.
Refs #55.
Files changed:
- services/workspace/src/chat.ts
- context-v/agent-skills/triage-inbox-w-suggestions/SKILL.md
- changelog/2026-07-27_01_Organizations-Learn-Their-Family-Tree-Parent-Child-Peer-Relations-Plus-Org-Tags.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RW28dw3kQAKXr2ZNefCukE
Copy file name to clipboardExpand all lines: changelog/2026-07-27_01_Organizations-Learn-Their-Family-Tree-Parent-Child-Peer-Relations-Plus-Org-Tags.md
+16Lines changed: 16 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -163,3 +163,19 @@ the drive's click literally couldn't reach them. Now opacity-based with
163
163
`:focus-within`, so Tab reveals them too. The drive proving the buttons
164
164
*work* is exactly the rung that caught the button you couldn't Tab to;
165
165
the human walk-through still judges whether the surface is *usable*.
166
+
167
+
### didi learns the family tree, and triage learns to ask "parent or child?" (#55)
168
+
169
+
`WORKBENCH_CHAT_VERBS` now carries `organization.relations / relate /
170
+
tag.add` with the relations discipline: **propose by default** — a
171
+
relation is a judgment call, so didi chat_invokes only when the operator
172
+
stated the relationship themselves ("X is an initiative of Y"), quoting
173
+
their phrasing into the edge's `description`. The triage slab gains
174
+
**step 5b (aboutness routing)**: when a destination org has relations or
175
+
the page names an initiative of a parent, ask which entity the content is
176
+
*about* before filing — and an initiative that's a real actor with no row
177
+
yet gets minted, related, and tagged `Initiative` instead of parked. The
178
+
triage SKILL.md's parent-child open decision flips to **MODEL LANDED**,
179
+
and the `initiative_hub` stream kind sheds its "while parent/child
180
+
modeling is unresolved" caveat — it's now only for initiatives that don't
Copy file name to clipboardExpand all lines: services/workspace/src/chat.ts
+18-1Lines changed: 18 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -129,6 +129,22 @@ VERB RECOGNITION SHORTCUTS:
129
129
- "/crawl-team <org-slug>" → chat_invoke organization.crawl with target "team".
130
130
- A bare "/crawl-links" / "/crawl-streams" / "/crawl-team" (no argument), or "this org" / "this organization", targets the focused organization from context when one is present — chat_invoke directly with its org_slug. No focused org and no argument → ask.
131
131
- Natural phrasings ("crawl for relevant pulse streams for X", "find X's team members") map to the same targets — chat_invoke when the org is unambiguous, chat_propose otherwise.
organization.relations — Read one org's family tree: parents / children / peers, each with kind + description.
136
+
args: { org_slug: string, client: string }
137
+
138
+
organization.relate — Connect two EXISTING orgs. rel is relative to org_slug: "parent" = other_slug is the parent. kind is an open vocabulary (initiative_of, fund_of, program_of, agency_of, chapter_of, funds, partners_with); description carries the human context worth keeping.
- Relations are judgment calls — chat_propose by default; chat_invoke only when the operator stated the relationship themselves ("X is an initiative of Y" → relate X→parent Y, kind initiative_of, and quote their phrasing into description).
146
+
- Both orgs must already exist — if one is missing, propose creating it first (resolver.search before ever proposing a mint).
147
+
- Not every pairing is a hierarchy: funders/grantees and partners are rel "peer" with kind "funds" / "partners_with".
132
148
`;
133
149
134
150
// Slab 3 — active skills. First resident (2026-07-25): the condensed
@@ -154,7 +170,7 @@ resolver.apply — Mint a new organization row (action "create"). Long-form full
154
170
resolver.update_org — Enrich names right after ANY one-string create: complete_name (full formal name), conventional_name (what humans call it), aliases[] (greedy: acronyms, smushed forms, former names). Also renames slugs (old slug auto-preserved as alias).
organization.streams.add — Register a rolling page as a pulse stream on an org. Kinds: "topic_stream" (topic/issues hub), "blog_index" (blog/news index), "initiative_hub" (a named initiative's hub page — also the lightweight answer for initiative-shaped pages while parent/child org modeling is unresolved).
173
+
organization.streams.add — Register a rolling page as a pulse stream on an org. Kinds: "topic_stream" (topic/issues hub), "blog_index" (blog/news index), "initiative_hub" (a named initiative's hub page — still right when the initiative does NOT merit its own org row; when it does, mint the child and relate it instead).
3. Rolling index page (topic hub / blog index / initiative hub) on a tracked org? → organization.streams.add, not corpus content. A one-time capture of a page that keeps pulsing is worthless.
164
180
4. Fetch-blocked capture (403/CAPTCHA/paywall)? → gated, not discarded: the URL is still wanted. Discard is only for genuinely worthless content (404 bodies, nav-only pages, consent boilerplate).
165
181
5. Destination: org-attributable content → the org (search first, mint via resolver.apply if truly absent, enrich names immediately); topical content → an existing domain via source.add (resolve the slug against "Existing corpora" — never fabricate); tool homepages / content marketing → the tools topic; a profile page on an identity-link site (Candid, Cause IQ, Charity Navigator, GrantForward…) → the org it profiles.
182
+
5b. Parent or child? When the destination org has relations (organization.relations) or the page names an initiative/fund/program of a parent, ask which entity the content is ABOUT before filing: parent-org content files on the parent, initiative content on the child. Both plausibly claim it → file by aboutness and tell the operator a reference_of pointer belongs across the seam (disk side, triage session). Initiative with no org row yet → propose minting the child + organization.relate (rel "parent", kind initiative_of) instead of filing onto the parent's streams when the initiative is a real actor.
166
183
6. Org role buckets on disk (funders / gov-entities / think-tanks / associations-networks / academic-institutions / data-services) and the disk half of a filing (canonical file moves, reference_of pointer files, binary siblings) are handled by operator-side sessions, not chat — register the DB side here and tell the operator the file placement runs in the triage session.
0 commit comments