chore: register Phase 5 workplan (IHUB-WP-0005)
Some checks failed
Test / test (push) Has been cancelled

Registers Phase 5 (Agent-Assisted Distillation) workplan with 9 tasks
(T01–T09) covering schema, AgentProposalsController, Claude API
integration, and agent audit dashboard. Updates CLAUDE.md to point to
the Phase 5 workplan and adds IHP_ANTHROPIC_API_KEY to the required
env vars table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-29 14:17:59 +00:00
parent 878d2577ae
commit 1862bb295a
2 changed files with 428 additions and 7 deletions

View File

@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
**inter-hub** is the reference implementation of the **Interaction Hub Framework (IHF)** — a governed, observable interaction substrate for hub-based AI-enabled software systems. It treats every UI element as a governed artifact, creating a full traceability chain from rendered widget → user interaction → structured feedback → requirement candidate → decision record → implementation change → observed outcome.
**Current state:** Phases 13 complete. Phase 4 (Outcome Observation and Antifragility Loop) is the active implementation target.
**Current state:** Phases 14 complete. Phase 5 (Agent-Assisted Distillation and Suggestion) is the active implementation target.
For situational context, read `SCOPE.md`. For architecture depth, read `specs/InteractionHubFrameworkSpecification_v0.1.md`.
@@ -104,17 +104,18 @@ Key rules:
| `IHP_SESSION_SECRET` | Session encryption key |
| `DATABASE_URL` | Postgres connection string |
| `IHP_BASEURL` | External URL (e.g., `https://example.com`) |
| `IHP_ANTHROPIC_API_KEY` | Anthropic API key for Phase 5 agent-assisted distillation |
## Active Workplan
Phase 4 work is tracked in `workplans/IHUB-WP-0004-ihf-phase4-outcome-observation-and-antifragility.md` (9 tasks, T01T09). Use `/ralph-workplan workplans/IHUB-WP-0004-ihf-phase4-outcome-observation-and-antifragility.md` to drive implementation loops.
Phase 5 work is tracked in `workplans/IHUB-WP-0005-ihf-phase5-agent-assisted-distillation.md` (9 tasks, T01T09). Use `/ralph-workplan workplans/IHUB-WP-0005-ihf-phase5-agent-assisted-distillation.md` to drive implementation loops.
Phase 4 exit criteria:
- The platform can determine whether a change improved outcomes
- Recurrent friction becomes visible
- The system supports evidence-based UI evolution
Phase 5 exit criteria:
- AI assistance reduces triage and synthesis burden
- Human reviewers remain in control
- AI outputs are auditable and attributable
Completed workplans: IHUB-WP-0001 (Phase 1), IHUB-WP-0002 (Phase 2), IHUB-WP-0003 (Phase 3).
Completed workplans: IHUB-WP-0001 (Phase 1), IHUB-WP-0002 (Phase 2), IHUB-WP-0003 (Phase 3), IHUB-WP-0004 (Phase 4).
## Key Reference Docs

View File

@@ -0,0 +1,420 @@
---
id: IHUB-WP-0005
type: workplan
title: "IHF Phase 5 — Agent-Assisted Distillation and Suggestion"
domain: inter_hub
repo: inter-hub
status: active
owner: custodian
topic_slug: inter_hub
created: "2026-03-29"
updated: "2026-03-29"
state_hub_workstream_id: "535a6479-9852-4386-8ad0-f86397a018c5"
---
# IHF Phase 5 — Agent-Assisted Distillation and Suggestion
## Goal
Introduce bounded AI support into the interaction-governance loop. Phase 4
established the antifragility loop — outcome signals, regression detection,
recurrence tracking. Phase 5 adds AI capability to reduce the cognitive burden
on human reviewers: cluster summaries, drafted requirement candidates, duplicate
detection, policy-sensitivity flagging, and implementation path proposals.
All AI outputs are **attributable** (model_ref recorded), **reviewable**
(AgentReviewRecord), and **reversible** (proposals can be rejected). No
autonomous final decisions. No silent requirement promotion.
## Background
Phase 1 (IHUB-WP-0001) delivered the Minimal Interaction Core. Phase 2
(IHUB-WP-0002) delivered Structured Feedback and Triage. Phase 3
(IHUB-WP-0003) delivered Governance and Decision Linkage. Phase 4
(IHUB-WP-0004) delivered Outcome Observation and Antifragility. All Phase 4
exit criteria are met.
Phase 5 is the fifth of eight phases in the IHF specification
(`specs/InteractionHubFrameworkSpecification_v0.1.md`, §14 Phase 5).
**Technology stack:** IHP v1.5 (Haskell, Nix), PostgreSQL, Anthropic API
(claude-sonnet-4-6). Agent calls are synchronous HTTP in controller actions.
API key from `IHP_ANTHROPIC_API_KEY` environment variable.
Reference: `docs/ihp-overview.md`, `docs/ihp-data-and-queries.md`,
`docs/ihp-controllers-views-forms.md`, `docs/ihp-realtime.md`.
## Phase 5 Exit Criteria (from IHF spec §14 Phase 5)
- AI assistance reduces triage and synthesis burden
- Human reviewers remain in control
- AI outputs are auditable and attributable
## Data Artifacts Introduced (Phase 5)
`AgentProposal`, `AgentReviewRecord`, `ConfidenceAnnotation`
---
## Tasks
### T01 — Schema: AgentProposal, AgentReviewRecord, ConfidenceAnnotation
```task
id: IHUB-WP-0005-T01
status: todo
priority: high
state_hub_task_id: "6e1a9d31-a7e9-4d71-a726-44eaf739371c"
```
Add Phase 5 tables to `Application/Schema.sql` and write migration:
```sql
CREATE TABLE agent_proposals (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
proposal_type TEXT NOT NULL,
-- proposal_type values: summary | requirement_draft | duplicate_flag |
-- policy_flag | impl_proposal
source_widget_id UUID REFERENCES widgets(id) ON DELETE SET NULL,
source_candidate_id UUID REFERENCES requirement_candidates(id) ON DELETE SET NULL,
source_thread_id UUID REFERENCES annotation_threads(id) ON DELETE SET NULL,
source_decision_id UUID REFERENCES decision_records(id) ON DELETE SET NULL,
content TEXT NOT NULL,
model_ref TEXT NOT NULL, -- e.g. "claude-sonnet-4-6"
confidence NUMERIC CHECK (confidence BETWEEN 0 AND 1),
status TEXT NOT NULL DEFAULT 'pending',
-- status values: pending | accepted | rejected | superseded
created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL
);
CREATE INDEX agent_proposals_proposal_type_idx ON agent_proposals (proposal_type);
CREATE INDEX agent_proposals_status_idx ON agent_proposals (status);
CREATE INDEX agent_proposals_source_widget_id_idx ON agent_proposals (source_widget_id);
CREATE INDEX agent_proposals_created_at_idx ON agent_proposals (created_at DESC);
-- One review record per proposal (human decision on AI output)
CREATE TABLE agent_review_records (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
proposal_id UUID NOT NULL REFERENCES agent_proposals(id) ON DELETE CASCADE,
reviewer_id UUID REFERENCES users(id),
decision TEXT NOT NULL, -- accepted | rejected | modified
notes TEXT,
reviewed_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL,
UNIQUE (proposal_id)
);
CREATE INDEX agent_review_records_proposal_id_idx ON agent_review_records (proposal_id);
-- Confidence annotations — per-dimension breakdown of AI confidence
CREATE TABLE confidence_annotations (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY NOT NULL,
proposal_id UUID NOT NULL REFERENCES agent_proposals(id) ON DELETE CASCADE,
dimension TEXT NOT NULL,
-- dimension values: accuracy | relevance | completeness | policy_alignment
score NUMERIC NOT NULL CHECK (score BETWEEN 0 AND 1),
explanation TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL
);
CREATE INDEX confidence_annotations_proposal_id_idx ON confidence_annotations (proposal_id);
```
- `agent_proposals.status` transitions: `pending → accepted | rejected | superseded`
- `agent_review_records` has UNIQUE on `proposal_id` — one review per proposal
- Add `IHP_ANTHROPIC_API_KEY` to CLAUDE.md required env vars table
**Exit criteria:** `migrate` runs cleanly; all Phase 5 types available in GHCi.
---
### T02 — AgentProposalsController and views
```task
id: IHUB-WP-0005-T02
status: todo
priority: high
state_hub_task_id: "5a9b9d51-dcdf-4dad-b449-08a7091e4563"
```
1. Scaffold `AgentProposalsController`
2. Actions: `index`, `show`, `AcceptProposalAction`, `RejectProposalAction`
(no update/delete — proposals are immutable audit artifacts)
3. Index: table filterable by `proposal_type` and `status`:
- type badge (color per type), source widget name, confidence bar, status,
created_at
4. Show: content panel + confidence dimension breakdown + review form
(decision select + notes textarea) + attribution footer (model_ref, created_at)
5. After accept/reject: redirect to proposal show with success message
6. Accept/reject is idempotent — if review record already exists, redirect
with "Already reviewed" message
7. Add nav link "Agent" to global nav in `FrontController.hs`
**Proposal type colors:**
- `summary` → blue
- `requirement_draft` → indigo
- `duplicate_flag` → orange
- `policy_flag` → red
- `impl_proposal` → green
**Exit criteria:** Proposals can be listed, viewed, accepted, and rejected;
review record created correctly; idempotent guard works.
---
### T03 — Cluster summarization via Claude API
```task
id: IHUB-WP-0005-T03
status: todo
priority: high
state_hub_task_id: "630d8d95-a009-4406-82e2-27f62fabcd3c"
```
1. `SummarizeClusterAction { widgetId }` (POST from widget show page)
2. Fetch last 20 annotations + annotation threads for the widget
3. Build prompt:
- **System:** "You are a distillation assistant for a governed interaction
hub. Summarize the following user feedback cluster into a concise,
actionable summary (24 sentences). Be factual and neutral."
- **User:** formatted annotation text
4. Call Anthropic Messages API (`claude-sonnet-4-6`, `max_tokens=300`)
5. Create `AgentProposal`:
- `proposal_type = "summary"`
- `source_widget_id = widgetId`
- `model_ref = "claude-sonnet-4-6"`
- `content = response text`
- `confidence = NULL` (summaries have no numeric confidence)
6. On widget show page: "Summarize Feedback" button → POST; after POST
redirect back, show latest summary proposal in a collapsible panel
7. HTTP client: use `http-conduit` + `aeson`; API key from
`IHP_ANTHROPIC_API_KEY` env var (error if absent)
8. Handle API errors gracefully — set error flash, redirect back
**Exit criteria:** Summary proposal created and visible on widget show page;
API errors produce a user-visible error message (not a 500).
---
### T04 — AI-drafted requirement candidate
```task
id: IHUB-WP-0005-T04
status: todo
priority: high
state_hub_task_id: "4c9d23f7-1744-48c8-90b5-71854d9b7daf"
```
1. `DraftRequirementAction { widgetId }` (POST from widget show page)
2. Fetch last 20 annotations for the widget
3. Build prompt:
- **System:** "You are a requirements analyst. Given these friction
annotations, draft a single structured requirement candidate. Respond
with JSON: {\"title\": \"...\", \"description\": \"...\"}."
- **User:** formatted annotation text
4. Parse JSON response; create `AgentProposal`:
- `proposal_type = "requirement_draft"`
- `content = raw JSON string from response`
5. On `AcceptProposalAction` for a `requirement_draft` proposal:
- Parse `content` as JSON
- Create `RequirementCandidate`:
- `title` and `description` from parsed JSON
- `source_widget_id = proposal.source_widget_id`
- `category = "friction"`
- `status = "open"`
- Update proposal `status = "accepted"`
- Create `AgentReviewRecord` (decision = "accepted")
- Set success flash: "Requirement candidate created from AI draft"
6. "Draft Requirement" button on widget show page (only when ≥ 3 annotations)
**Exit criteria:** Draft proposal created; acceptance creates a
`RequirementCandidate`; review record present; no candidate created without
human acceptance.
---
### T05 — Duplicate candidate detection
```task
id: IHUB-WP-0005-T05
status: todo
priority: medium
state_hub_task_id: "969b7c7f-c3ba-4892-a1d0-faedf536d1c6"
```
1. `DetectDuplicatesAction { requirementCandidateId }` (POST from candidate
show page)
2. Fetch the candidate + all other `RequirementCandidate` records
3. Build prompt:
- **System:** "You are a deduplication assistant. Given a target candidate
and a list of existing candidates, identify likely duplicates. Respond
with JSON: {\"duplicates\": [{\"id\": \"uuid\", \"reason\": \"...\"}]}."
- **User:** target candidate + list of candidates (id, title, description)
4. Parse response; create `AgentProposal`:
- `proposal_type = "duplicate_flag"`
- `source_candidate_id = requirementCandidateId`
- `content = JSON string of duplicates array`
5. On candidate show page: "Check Duplicates" button → POST; show "Possible
Duplicates" panel with links to flagged candidates and rationale
6. Informational only — no automated merging or status changes
**Exit criteria:** Duplicate proposal created; flagged candidates rendered as
links on candidate show page; empty duplicates array handled gracefully.
---
### T06 — Policy-sensitive issue detection
```task
id: IHUB-WP-0005-T06
status: todo
priority: medium
state_hub_task_id: "475290e0-7842-4336-a57c-04fa62652094"
```
1. `DetectPolicySensitivityAction { requirementCandidateId }` (POST from
candidate show page)
2. Fetch candidate + widget `policy_scope` + existing `PolicyReference`
constraint notes for linked decisions
3. Build prompt:
- **System:** "You are a policy compliance assistant. Analyse this
requirement candidate for potential policy concerns. Valid scopes:
internal, external, regulatory, contractual, architectural. Respond
with JSON: {\"concerns\": [{\"scope\": \"...\", \"note\": \"...\"}],
\"severity\": \"low|medium|high\"}."
- **User:** candidate title/description + policy context
4. Create `AgentProposal`:
- `proposal_type = "policy_flag"`
- `content = JSON string`
- `confidence = severity mapped to numeric (low=0.3, medium=0.6, high=0.9)`
5. Create one `ConfidenceAnnotation` per concern scope dimension
6. On candidate show page: "Policy Check" panel — amber badge if concerns,
green badge if clean
**Exit criteria:** Policy proposal created with confidence annotation;
concern severity rendered correctly; clean result (empty concerns) handled.
---
### T07 — Implementation path proposal
```task
id: IHUB-WP-0005-T07
status: todo
priority: medium
state_hub_task_id: "7ee1274e-fa1b-4ae8-a360-4abafc1773f0"
```
1. `ProposeImplementationAction { decisionRecordId }` (POST from decision
show page)
2. Fetch decision + linked requirement + existing `ImplementationChangeReference`
records
3. Build prompt:
- **System:** "You are a traceability-aware implementation analyst. Propose
13 concrete implementation paths for this decision. Each path should
include a work_item_ref (e.g. PROJ-123), a system (github|linear|jira),
and a rationale. Respond with JSON: {\"proposals\": [{\"work_item_ref\":
\"...\", \"system\": \"...\", \"rationale\": \"...\"}]}."
- **User:** decision title, rationale, outcome, requirement description,
existing impl refs
4. Create `AgentProposal`:
- `proposal_type = "impl_proposal"`
- `source_decision_id = decisionRecordId`
- `content = JSON string`
5. On decision show page: "Propose Implementation" button; accepted proposals
pre-fill the AddImplementationRef form (first proposal in the array)
6. Surface as collapsed "AI Suggestions" panel on decision show page
**Exit criteria:** Impl proposal created; acceptance pre-fills the impl ref
form; multiple proposal paths rendered clearly.
---
### T08 — Agent attribution and audit dashboard (AutoRefresh)
```task
id: IHUB-WP-0005-T08
status: todo
priority: high
state_hub_task_id: "53b58abb-cb50-4985-a1c0-b05da17dfc3f"
```
1. Add `AgentAuditDashboardAction { hubId }` to `HubsController` wrapped
with `autoRefresh do`
2. Dashboard panels:
- **KPI row**: total proposals / pending / acceptance rate / rejection rate
- **Proposals by type**: count breakdown per `proposal_type`
- **Unreviewed queue**: proposals with `status = "pending"`, oldest first,
with "Review" links
- **Recent proposals** (last 20): type badge, source widget, status,
confidence, age
- **Attribution log**: `model_ref × proposal_type` count matrix
3. Link from hub Show page alongside Triage / Governance / Antifragility
4. Add "Agent" link to global nav
**Exit criteria:** Dashboard live-updates on proposal/review changes. All five
panels render with correct data.
---
### T09 — Phase 5 gate: tests, consistency, docs
```task
id: IHUB-WP-0005-T09
status: todo
priority: high
state_hub_task_id: "c7b8aef0-b241-4038-99c0-494c45f226a6"
```
1. **Integration tests** (`Test/`):
- AgentProposal create + fetch (all fields)
- AcceptProposalAction for `requirement_draft` → creates `RequirementCandidate`
- RejectProposalAction → sets `status = "rejected"`, creates review record
- Review record idempotency (second accept/reject → "Already reviewed")
- ConfidenceAnnotation create + link to proposal
- Duplicate detection: proposal with empty duplicates array
- Agent audit dashboard data fetch: compiles and returns correct counts
2. **Consistency sync** via State Hub MCP:
`check_repo_consistency(repo_slug="inter-hub", fix=True)`
3. **Documentation updates:**
- Update `SCOPE.md` current state section: Phase 5 complete
- Write `docs/phase5-summary.md`: what was built, governance constraints
upheld, known limitations, Phase 6 readiness
4. **Smoke test checklist:**
- Summarize feedback cluster on a widget with annotations
- Draft a requirement from the summary
- Accept the draft → verify RequirementCandidate created
- Check duplicates on a candidate
- Run policy check on a candidate
- Confirm agent audit dashboard shows all panels
**Exit criteria:** All tests pass; consistency sync reports no errors; smoke
test completed; SCOPE.md updated.
---
## Phase 5 Dependencies
- Phase 4 schema stable (Phase 4 tables needed as context for impl proposals)
- `http-conduit` and `aeson` available (already in IHP's Haskell ecosystem)
- `IHP_ANTHROPIC_API_KEY` set in environment
- Schema (T01) before all controller work (T02T08)
- `AgentProposalsController` (T02) before all agent action tasks (T03T07)
- All feature tasks (T01T08) before gate (T09)
## Notes
- **All AI outputs are attributed.** `model_ref` is recorded on every
`AgentProposal`. Reviewers see exactly which model produced the output.
- **No silent promotion.** A `requirement_draft` proposal only becomes a
`RequirementCandidate` when a human explicitly accepts it via
`AcceptProposalAction`. The controller enforces this.
- **Review record is idempotent.** UNIQUE constraint on
`agent_review_records.proposal_id`. Second accept/reject redirects with
"Already reviewed" message.
- **API errors do not crash.** All Claude API calls are wrapped in error
handling; failures produce a user-visible flash message and redirect.
- **Confidence is optional for summaries.** `AgentProposal.confidence` is
nullable — summary proposals do not produce a numeric confidence score.
Policy flag proposals derive confidence from severity (low/medium/high).
- **No ML infrastructure.** All intelligence is delegated to the Anthropic
API. Phase 5 adds no local model serving, no embeddings storage.