Skip to content

Commit dc98a0d

Browse files
mpstatonclaude
andcommitted
new(changelog, context-v): ship-log the usability sweep; plan + three issues flip to Shipped
The sweep plan lands alongside the work it sequenced (evaluated against the codebase via three parallel explorations, decisions inline), the 2026-07-24 changelog entry records the three slices, and status discipline follows reality: #26 and #25 issues Shipped, #20 Partially-Shipped (per-card visibility shipped; the coverage roster defers into the component-library sweep). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UvYzx7vDWeafnkAi2nEQeb
1 parent b86f079 commit dc98a0d

5 files changed

Lines changed: 172 additions & 6 deletions
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
date_created: 2026-07-24
3+
date_modified: 2026-07-24
4+
title: "Workbench usability sweep — corpus entries visible, streams named and correctable, bio links promotable to affiliations"
5+
lede: "The first real workbench session filed seven issues; the three in today's scope ship together: person cards list their corpus entries instead of a bare count, pulse streams gain a user-facing name and an in-place kind/name editor, and a bio page on another org's site can be promoted to an affiliation in three clicks."
6+
publish: true
7+
authors:
8+
- Michael Staton
9+
augmented_with:
10+
- Claude Code on Claude Fable 5
11+
files_changed:
12+
- services/record-surrealdb-resolver/src/resolver.ts
13+
- services/record-surrealdb-resolver/src/person-resolver.ts
14+
- services/record-surrealdb-resolver/src/handlers.ts
15+
- services/workspace/src/capabilities.ts
16+
- apps/org-workbench/src/AdditiveList.svelte
17+
- apps/org-workbench/src/OrgCard.svelte
18+
- apps/org-workbench/src/PersonCard.svelte
19+
- apps/org-workbench/src/AddAffiliationInline.svelte
20+
- apps/org-workbench/src/lib/org-client.ts
21+
- apps/org-workbench/src/lib/types.ts
22+
tags:
23+
- Org-Workbench
24+
- Corpus
25+
- Pulse-Streams
26+
- Affiliations
27+
- Usability
28+
---
29+
30+
# Workbench usability sweep — three of the 2026-07-24 issues ship
31+
32+
The first real session with the org workbench (2026-07-24) produced seven jotted
33+
issues. Three made today's scope — the plan that evaluated them against the
34+
codebase is
35+
[[context-v/plans/Workbench-Usability-Sweep-Corpus-Visibility-Stream-Editing-Affiliation-Promotion|the sweep plan]],
36+
and each shipped as its own commit, closing GitHub issues
37+
[#20](https://github.com/lossless-group/augment-it/issues/20),
38+
[#26](https://github.com/lossless-group/augment-it/issues/26), and
39+
[#25](https://github.com/lossless-group/augment-it/issues/25).
40+
41+
## Corpus entries are visible on person cards (#20)
42+
43+
"Corpus items 3" with no list is a count you can't assure coverage with.
44+
`organization.affiliations` now carries `personal_corpus[]` alongside the count
45+
(eager, symmetric with `personal_links`), and the person card renders it with
46+
the same `AdditiveList` the links use — kind badge, host, date, plus the
47+
existing ➕ and 🔍. The Phase 1 count-only contract is formally disproven and
48+
retired. Entries render URL+kind for v1: `content_items` holds no titles today,
49+
so title hydration is a content-ingest rider, and the coverage roster ("which
50+
entities have NO corpus?") folds into the component-library sweep.
51+
52+
## Pulse streams get a name and an editable kind (#26)
53+
54+
"Today's Credentials" is not an `updates_index`. Stream entries gain an
55+
optional operator-facing `name` (hostname stays the display fallback), the ➕
56+
form takes it at add time, and a new `organization.streams.update` capability —
57+
the first patch on an entity-list entry — corrects `kind`/`name` on an existing
58+
row, matched by its de-facto key, the exact URL. Entries stay additive (no
59+
delete); fields on them are now correctable, with the same
60+
`client_access`/`last_touched` stamping `resolver.update_org` models. Safe
61+
because stream kind is descriptive-only today: `stream-scan` routes every kind
62+
down the same path. `inferStreamKind` also learns `topic_hub`, so `/topics/…`
63+
paths stop landing as `updates_index` in the first place.
64+
65+
## Bio-page links promote to affiliations (#25)
66+
67+
Jamie Merisotis's bipartisanpolicy.org bio was filed as an `other` identity
68+
link — correct, and two facts short: the affiliation it evidences, and the
69+
observation citing it. Person link rows now carry a **→ affiliation** action
70+
opening `AddAffiliationInline`: `AddPersonInline`'s gate inverted, person fixed
71+
and org being resolved. Candidates load from the bio's domain via
72+
`resolver.search` (D4 already matches `domains[*].domain`); the gate always
73+
shows — pick an existing org or create a thin one. `person.affiliate` does what
74+
it always did (match-or-create, N-per-person dedupe, automatic
75+
`affiliated_with` observation), now with the bio URL as the observation's
76+
source and one new input: `org_domain`, seeded into `domains[]` on create so a
77+
promotion-born org stays domain-matchable forever after.
78+
79+
## Verification
80+
81+
Resolver + workspace typechecks clean; org-workbench svelte-check 0/0; org-
82+
workbench and shell builds green. The write paths are not exercised headlessly
83+
per the additive-writes discipline — the operator walk-through is: Lumina →
84+
People → Jamie Merisotis → see the three corpus entries; rename the
85+
Today's Credentials stream and fix its kind; promote the bipartisanpolicy.org
86+
link and watch the affiliation + observation appear.

context-v/issues/Corpus-Items-Not-Visible-On-Person-Cards-Coverage-Hard-To-Assess.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ authors:
77
- Michael Staton
88
augmented_with:
99
- Claude Code on Claude Fable 5
10-
semantic_version: 0.0.0.1
10+
semantic_version: 0.0.0.2
1111
tags:
1212
- Issue
1313
- Usability
@@ -16,7 +16,9 @@ tags:
1616
- Org-Workbench
1717
- Persons
1818
- Coverage
19-
status: Open · Jotted
19+
status: Partially-Shipped
20+
date_first_published: 2026-07-24
21+
post_ship_note: "Layer 1 (per-card visibility) shipped 2026-07-24 — eager entries on organization.affiliations, AdditiveList render, no titles (content_items has none). Layer 2 (coverage roster) deferred into the component-library sweep. Per [[../plans/Workbench-Usability-Sweep-Corpus-Visibility-Stream-Editing-Affiliation-Promotion]]; gh #20 closed."
2022
---
2123

2224
# Corpus items invisible on person cards; coverage unassessable

context-v/issues/Person-Bio-Pages-Are-Affiliation-Signals-Not-Just-Identity-Links.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ authors:
77
- Michael Staton
88
augmented_with:
99
- Claude Code on Claude Fable 5
10-
semantic_version: 0.0.0.1
10+
semantic_version: 0.0.0.2
1111
tags:
1212
- Issue
1313
- Usability
@@ -16,7 +16,9 @@ tags:
1616
- Persons
1717
- Identity-Links
1818
- Org-Workbench
19-
status: Open · Jotted
19+
status: Shipped
20+
date_first_published: 2026-07-24
21+
post_ship_note: "Shipped 2026-07-24 — → affiliation row action + AddAffiliationInline (gate inverted), org_domain seeded on create, bio URL as observation source (no has_bio_at predicate for v1). Riders named not built: server inferLinkKind bio vocabulary, search-and-add rail promotion, didi-chat verb. Per [[../plans/Workbench-Usability-Sweep-Corpus-Visibility-Stream-Editing-Affiliation-Promotion]]; gh #25 closed."
2022
---
2123

2224
# Person bio pages are affiliation signals

context-v/issues/Pulse-Streams-Need-Editable-Kind-And-User-Facing-Names.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@ authors:
77
- Michael Staton
88
augmented_with:
99
- Claude Code on Claude Fable 5
10-
semantic_version: 0.0.0.1
10+
semantic_version: 0.0.0.2
1111
tags:
1212
- Issue
1313
- Usability
1414
- Augment-It
1515
- Pulse-Streams
1616
- Org-Workbench
1717
- Media-Streams
18-
status: Open · Jotted
18+
status: Shipped
19+
date_first_published: 2026-07-24
20+
post_ship_note: "Shipped 2026-07-24 — name on ShapedStream + ➕ form, organization.streams.update (match-by-URL patch; the update-vs-additive question resolved as sparse patch per the updateOrg precedent), in-place kind/name editor, topic_hub in inferStreamKind. Kind confirmed descriptive-only (stream-scan ignores it). Per [[../plans/Workbench-Usability-Sweep-Corpus-Visibility-Stream-Editing-Affiliation-Promotion]]; gh #26 closed."
1921
---
2022

2123
# Pulse streams need editable kind + user-facing names
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: "Workbench usability sweep — corpus visibility, stream editing, and promote-to-affiliation (issues #20 · #26 · #25)"
3+
lede: "Today's scope from the first real workbench session: make the person card's three invisible corpus items visible, let the operator fix a stream's kind and give it its real name, and turn a bio-page link row into a three-click affiliation."
4+
date_created: 2026-07-24
5+
date_modified: 2026-07-24
6+
date_first_published: 2026-07-24
7+
authors:
8+
- Michael Staton
9+
augmented_with:
10+
- Claude Code on Claude Fable 5
11+
semantic_version: 0.0.0.2
12+
tags:
13+
- Plan
14+
- Augment-It
15+
- Org-Workbench
16+
- Corpus
17+
- Pulse-Streams
18+
- Affiliations
19+
- Usability
20+
status: Shipped
21+
post_ship_note: "All three slices landed 2026-07-24 as commits 90dd83b (#20), 895a6a6 (#26), b86f079 (#25). The operator walk-through (steps 4/9/14's live halves) remains the human rung; browser-drive rung deferred — Playwright MCP loads next session."
22+
---
23+
24+
# Workbench usability sweep — #20 · #26 · #25
25+
26+
## Issue references
27+
28+
Executes three of the 2026-07-24 workbench-session issues, in ascending complexity:
29+
30+
- **A.** [[../issues/Corpus-Items-Not-Visible-On-Person-Cards-Coverage-Hard-To-Assess]][gh #20](https://github.com/lossless-group/augment-it/issues/20)
31+
- **B.** [[../issues/Pulse-Streams-Need-Editable-Kind-And-User-Facing-Names]][gh #26](https://github.com/lossless-group/augment-it/issues/26)
32+
- **C.** [[../issues/Person-Bio-Pages-Are-Affiliation-Signals-Not-Just-Identity-Links]][gh #25](https://github.com/lossless-group/augment-it/issues/25)
33+
34+
Branch: `rebuild/turbo-rsbuild`. All UI lands in `apps/org-workbench`; service changes are confined to `services/record-surrealdb-resolver` + the capability map in `services/workspace`. Close each gh issue as its slice ships (the new create-task/close-task habit), and move each issue doc's `status` on the same commit.
35+
36+
## Decisions taken in this plan (resolving the issues' open questions)
37+
38+
1. **#20 goes eager, not lazy.** Extend `listOrgAffiliations` to carry `personal_corpus[]` alongside the existing count. Rejected lazy (`affiliation.detail` on expand): `PersonCard` mounts with the already-loaded affiliation row and no detail wrapper exists in `org-client.ts` — lazy is *not* zero-work on this frontend, and eager makes corpus symmetric with `personal_links`, which are already eager. Payload is single-digit entries per person; the 8MB NATS ceiling is nowhere near.
39+
2. **#20 v1 renders URL+kind, no titles.** `content_items` has **no title field at all today** (`findOrCreateContent` writes only url/domain/kind/counters — `resolver.ts:364-369`); "titles live in the ledger" was optimistic. Title hydration = a rider for the content-ingest path, not this sweep.
40+
3. **#20's coverage roster (layer 2) is out of scope today.** The per-card fix ships now; the "which entities have NO corpus?" roster folds into the component-library sweep ([[../issues/No-Component-Library-UI-Improvised-Not-Component-Based]] / gh #22) where thin-row rosters get built once, properly.
41+
4. **#26's update verb is a match-by-URL patch, not remove+re-add.** Precedent: `resolver.update_org` (`resolver.ts:709-767`) already does sparse `SET` patches with `last_touched_*` stamping. URL is the de-facto stream key everywhere (dedupe, scan). Safe because stream `kind` has **zero routing effect today**`stream-scan.ts` declares `stream_kind` and ignores it; every scan routes to `runOfficialBlogPack`.
42+
5. **#26 also adds `topic_hub` to `inferStreamKind`** — one regex line fixes the `/topics/…` misclassification at the source; the editable kind remains the correction path for everything else.
43+
6. **#25 v1 lives on the link row, not in didi-chat.** The `AdditiveList` `entryaction` slot exists and is unused on person links — that's the mounting point. A chat verb (`CURATOR_CHAT_VERBS` block + `CHAT_CAPABILITY_NAMES` allow-list, `chat.ts:87-129`) is a named follow-up, not this sweep.
44+
7. **#25 creates orgs thin — but with a domain.** `resolveOrgRow`'s create branch seeds no `domains[]` (`resolver.ts:606-614`), so an org created from a bio link would be invisible to future D4 domain matching. Extend `PersonAffiliateInput` with optional `org_domain`, seeded into `domains[]` on the create branch only. No full org-resolution gate for v1.
45+
8. **#25's observation is `affiliated_with` with the bio URL as `source`.** `PersonAffiliateInput.source` already exists and flows into the auto-observation (`person-resolver.ts:562-568`) — pass the link URL; no separate `has_bio_at` predicate for v1 (free-text predicates via `person.add_observation` remain available if the distinction earns its keep later).
46+
47+
## Steps
48+
49+
### A — Corpus items visible on person cards (gh #20)
50+
51+
1. **Query**`listOrgAffiliations` (`services/record-surrealdb-resolver/src/person-resolver.ts:857-864`): add `in.personal_corpus ?? [] AS personal_corpus` beside the existing `array::len(...) AS personal_corpus_count` (count stays — `PeopleReveal`'s collapsed rows use it).
52+
2. **Types**`AffiliatedPerson` gains `personal_corpus: ShapedLink[]` in both mirrors: `person-resolver.ts:835-843` and `apps/org-workbench/src/lib/types.ts:61`.
53+
3. **Render**`PersonCard.svelte:82-108`: replace the count-only corpus block with an `AdditiveList` (same reuse as links at `:74-80`): title "Corpus items", entries `person.personal_corpus`, `onadd` → existing `person.corpus.add`, `onsearch` → existing corpus-target envelope. Row shape comes free: kind badge · host · date (`AdditiveList.svelte:106-118`). Delete the bespoke count/➕/🔍 markup; also remove the now-false scope comment at `PersonCard.svelte:2-6`.
54+
4. **Verify** — svelte-check + build org-workbench + shell build regression; then live: Lumina → People → Jamie Merisotis shows the three entries that today render as "Corpus items 3" and nothing.
55+
56+
### B — Stream name + editable kind (gh #26)
57+
58+
5. **Shape**`ShapedStream` (`resolver.ts:32-38`) and `shapeStream` (`:146-157`) gain optional `name`; `OrgStreamAddInput` (`:838`) gains `name?`, passed through `addOrgStream` (`:841-854`). SurrealDB is schemaless — no migration.
59+
6. **Classifier**`inferStreamKind` (`resolver.ts:117-133`): add `topic_hub` for paths matching `topics|/tag/|/category/`, ahead of the `updates_index` fallback.
60+
7. **Update verb** — new `updateOrgStream(db, {org_slug, url, kind?, name?, client})` beside `addOrgStream`: load `media_streams`, patch the entry whose trimmed `url` matches, `UPDATE ... SET media_streams = $patched` + the `client_access` union / `last_touched_*` stamps `updateOrg` already models (`resolver.ts:739-741`). Throw if no entry matches. New subscription `organization.streams.update.requested` in `handlers.ts` (beside `:182-198`); capability + 30s timeout in `services/workspace/src/capabilities.ts` (beside `:184`/`:291`); wrapper in `apps/org-workbench/src/lib/org-client.ts` (beside `addOrgStream`, `:61-69`).
61+
8. **UI**`AdditiveList.svelte`: add form (`:81-101`) gains a name input, threaded through `onadd`; entry rows render `name` (falling back to `host(url)`) at `:110`; kind badge (`:109`) and name become click-to-edit by adapting `apps/records-surface/src/components/EditableField.svelte`, committing via a new optional `onedit(url, patch)` prop so the component stays generic — `OrgCard.svelte` passes it only for the streams list (→ `updateOrgStream` → existing `makeAdd`-style refetch + `augment-it:entity-updated`). The "Additive only" header comment (`AdditiveList.svelte:1-7`) gets amended: additive entries, patchable fields.
62+
9. **Verify** — builds as in step 4; live: rename Lumina's `todays-credentials` stream to "Today's Credentials", correct its kind, confirm the row survives a refetch and a scan still routes (kind is not consumed by `stream-scan.ts` — confirm no regression, not new behavior).
63+
64+
### C — Promote a bio link to an affiliation (gh #25)
65+
66+
10. **Verb extension**`PersonAffiliateInput` (`person-resolver.ts:507-519`) gains `org_domain?`; `resolveOrgRow`'s create branch (`resolver.ts:606-614`) seeds `domains: [{domain: $org_domain}]` when provided. The `affiliatePerson` wrapper (`org-client.ts:118-134`) un-hardwires `org_action: 'match'` and exposes the full input.
67+
11. **`AddAffiliationInline.svelte`** — new org-workbench component: `AddPersonInline`'s form → gate → writing state machine (`AddPersonInline.svelte:28-83`) inverted — person fixed (from the card), org being resolved. Seeded from the link row: org-name field pre-filled empty, domain pre-filled from the link's hostname; candidates via `resolver.search` (D4 domain clause already matches `domains[*].domain``resolver.ts:327`), queried with the domain. Gate ALWAYS: pick a candidate (`org_action:'match'`, its slug) or "Create new org + affiliate" (`org_action:'create'`, typed name + seeded `org_domain`). Optional role input → `role`. `source` = the bio URL. On success: dispatch `augment-it:entity-updated {person_uuid}` (the existing refetch path, `PeopleReveal.svelte:50-55`).
68+
12. **Mounting**`PersonCard.svelte:74-80`: pass `entryaction: {label: '→ affiliation', fn: openPromote(entry)}` on the personal-links `AdditiveList` (slot exists unused — `AdditiveList.svelte:25-27, 111-115`); the action opens `AddAffiliationInline` under the list, bound to that entry.
69+
13. **Riders, named not built** — (a) port the bio-relevant kinds (`author_bio`, `team_page`, `publication`) from `apps/person-enrichment/src/pulse-dimensions/LinkList.svelte:41-51` into the server `inferLinkKind` (`resolver.ts:91-114`) so future bio links stop badging `other`; (b) same promote affordance on search-and-add result rows (`ResultRow.svelte` + `verbFor`, `search-client.ts:65-82`); (c) didi-chat promotion verb per Decision 6. Each is a small follow-up once v1 proves the flow.
70+
14. **Verify** — builds as in step 4. The write path is NOT exercised headlessly — `person.affiliate` creates real canonical orgs/edges/observations, and the additive-writes discipline reserves browser-driven writes for the designated safe target (Aspen Institute card). Mechanical drive: browser-drive the gate open/candidates/cancel path read-only (Playwright MCP is wired in `.mcp.json` but loads next session — if unavailable, this rung falls to the walk-through). Operator walk-through: Jamie Merisotis → bipartisanpolicy.org row → "→ affiliation" → gate shows candidates (or none) → create "Bipartisan Policy Center" with domain → affiliation + observation appear; re-open the gate on the same row → the new org now domain-matches.
71+
72+
### Tail
73+
74+
15. **Changelog** entry per [[changelog-conventions]]; commit per [[git-conventions]] (one commit per slice: `fix(org-workbench, corpus): …`, `new(streams, resolver): …`, `new(org-workbench, affiliations): …`); push; `gh issue close 20/26/25 --reason completed` as each slice lands; flip the three issue docs to `Shipped` with `date_first_published` on the same commits.

0 commit comments

Comments
 (0)