generated from coulomb/repo-seed
Implement State Hub v0.2: dependency graph, next-steps suggestions, design boundary
S0 — Design boundary formalised across all integration surfaces:
- TOOLS.md restructured with Design Boundary section, Sanctioned Write Tools,
and Bootstrap-Only Tools (create_workstream, create_task) with explicit note
- project_claude_md.template and railiance CLAUDE.md updated with boundary note
and get_next_steps() in session start protocol
- Global ~/.claude/CLAUDE.md updated accordingly
S1 — Workstream dependency graph:
- WorkstreamDependency model (directed edge, CASCADE on delete, unique pair constraint)
- Alembic migration 0b547c153153; script.py.mako added (was missing)
- REST API: POST/GET /workstreams/{id}/dependencies/, DELETE …/{dep_id} (hard delete)
- StateSummary open_workstreams enriched with depends_on/blocks lists
- MCP tools: create_dependency(), list_dependencies()
- Dashboard workstreams page: Dependencies section with relationship cards
- Seeded: custodian-agent-runtime → llm-shared-library + phase-0-operational-baseline
S2 — Suggesting Next Steps (sanctioned write use case #2):
- GET /state/next_steps derives suggestions from recently resolved decisions
(→ first open task in same workstream) and cleared dependencies
(→ first todo task in now-unblocked workstream)
- StateSummary.next_steps included on every summary call
- MCP tool: get_next_steps()
- Dashboard: "What's next?" card grid above Registered Projects
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -108,6 +108,40 @@ display(html`<div class="grid grid-cols-4" style="gap:1rem;margin-bottom:1.5rem"
|
||||
</div>`);
|
||||
```
|
||||
|
||||
## What's next?
|
||||
|
||||
```js
|
||||
// next_steps comes from the summary poll (derived, never persisted)
|
||||
const nextSteps = summary.next_steps ?? [];
|
||||
|
||||
const typeLabel = {
|
||||
resolved_decision: "Decision resolved",
|
||||
dependency_cleared: "Dependency cleared",
|
||||
unblocked_task: "Task unblocked",
|
||||
};
|
||||
const typeBadgeClass = {
|
||||
resolved_decision: "ns-badge-decision",
|
||||
dependency_cleared: "ns-badge-dep",
|
||||
unblocked_task: "ns-badge-task",
|
||||
};
|
||||
|
||||
if (nextSteps.length === 0) {
|
||||
display(html`<p class="ns-empty">No actionable suggestions right now — all open workstreams are making progress or waiting on decisions.</p>`);
|
||||
} else {
|
||||
display(html`<div class="ns-grid">${nextSteps.map(s => html`
|
||||
<div class="ns-card">
|
||||
<div class="ns-card-header">
|
||||
<span class="ns-badge ${typeBadgeClass[s.type] ?? ''}">${typeLabel[s.type] ?? s.type}</span>
|
||||
<span class="ns-domain">${s.domain ?? "—"}</span>
|
||||
</div>
|
||||
<div class="ns-ws">${s.workstream_title ?? "—"}</div>
|
||||
<div class="ns-task">${s.task_title ? html`→ <strong>${s.task_title}</strong>` : ""}</div>
|
||||
<div class="ns-msg">${s.message}</div>
|
||||
</div>
|
||||
`)}</div>`);
|
||||
}
|
||||
```
|
||||
|
||||
## Registered Projects
|
||||
|
||||
```js
|
||||
@@ -358,4 +392,17 @@ display(Inputs.table((summary.recent_progress ?? []).map(e => ({
|
||||
.r-msg { font-size: 0.8rem; color: #b45309; }
|
||||
.r-copy { padding: 0.15rem 0.55rem; border-radius: 3px; border: 1px solid var(--theme-foreground-faint); background: var(--theme-background); color: var(--theme-foreground-muted); cursor: pointer; font-size: 0.75rem; }
|
||||
.r-copy:hover { background: var(--theme-background-alt); }
|
||||
/* What's next */
|
||||
.ns-empty { color: gray; font-style: italic; }
|
||||
.ns-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.75rem; }
|
||||
.ns-card { background: var(--theme-background-alt); border-radius: 8px; padding: 0.85rem 1rem; border-left: 4px solid #555; }
|
||||
.ns-card-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.4rem; }
|
||||
.ns-badge { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.15rem 0.45rem; border-radius: 10px; font-weight: 600; }
|
||||
.ns-badge-decision { background: #d4edda; color: #155724; }
|
||||
.ns-badge-dep { background: #cce5ff; color: #004085; }
|
||||
.ns-badge-task { background: #fff3cd; color: #856404; }
|
||||
.ns-domain { font-size: 0.75rem; color: gray; }
|
||||
.ns-ws { font-weight: 600; font-size: 0.9rem; margin-bottom: 0.2rem; }
|
||||
.ns-task { font-size: 0.85rem; margin-bottom: 0.35rem; }
|
||||
.ns-msg { font-size: 0.78rem; color: #555; line-height: 1.4; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user