- council-v2-live.ts: coder/reviewer now use createCoderRole/createReviewerRole
- Removed inline runCursorAgent (moved to agent-executor.ts)
- reviewer verdict via LLM₂ tool_choice instead of includes('rejected')
- Live verified: architect→coder→reviewer(approved)→closer in 135s
- createAgentExecutorRole: prepPrompt → agent.run → LLM₂ tool_choice → meta
- createCursorRunner: extracts Cursor CLI into AgentRunner interface
- Coder role: LLM₂ extracts filesChanged + testsPassed via tool_choice
- Reviewer role: LLM₂ extracts verdict via tool_choice (no more includes hack)
- defaultMeta fallback when LLM₂ fails or returns no tool_call
- 5 new agent-executor tests, 24 total pass
Simplified structure with inline code block for WorkflowType,
streamlined section headings, and tighter prose while retaining
all key topics: START/END automaton, pure roles, Moore-machine
diff-driven ticks, and source file references.
Made-with: Cursor
- Role<Meta> = (chain, topicId, store) => Promise<Meta>
- MetaOf<R> extracts Meta from Role type
- RoleOutput<Roles> = discriminated union { role: K, meta: MetaOf<Roles[K]> }
- Moderator receives RoleOutput, switch on role narrows meta type
- WorkflowType simplified: no projection field, just name + roles + moderator
- Adapter builds per-topic summary internally
- coding-workflow: ArchitectMeta, CoderMeta, ReviewerMeta, CloserMeta
- -538/+326 lines — simpler AND more type-safe
Add 'upulse topic create' to write coding.created events with
auto-generated slugified topicId, and 'upulse topic list' to
display topics grouped by state with --all flag for closed topics.
Made-with: Cursor
executorLoop fire-and-forgets each effect execution. Multiple concurrent
execute() calls each invoke topicTicker(), causing concurrent tick() calls
that bypass Moore diff (both read same prevSnapshotJson before either updates).
Fix: chain tick() calls via promise serialization. Critical section
(read → diff → update baseline) is now guaranteed sequential.
- store.ts: add PRAGMA busy_timeout = 5000 after WAL mode (both paths)
- topic-rule-adapter: accept optional logStore for role execution logs
- role-started/completed/failed events written to logStore (not business store)
- role errors caught gracefully, other actions continue
- meta includes scope field for source identification
- no logStore = no logging (graceful degradation)
- coding-task.ts: projection unchanged (role logs never enter business store)
- tests: 8 passing (echo+logStore, role-failed, no-logStore, Moore diff,
baseline, coding lifecycle, rejection, log isolation)
小橘 🍊 (NEKO Team)
Moore machine baseline must update BEFORE role execution starts,
not after. This prevents duplicate dispatch when tick() is called
again while a slow role (e.g. Cursor ~60s) is still running.
Added test: 'baseline updates before execution' verifies that a
concurrent tick sees snapshot === baseline and skips.
The Moore machine should fire outputs only when STATE changes,
not when ACTIONS change. Compare JSON-serialized snapshot baseline
to determine if a new tick needs to run moderator + roles.
Covers TopicType interface (events, projection, roles, moderator),
Topic-as-Rule pattern, one-rule-per-type design, and Moore machine
diff-driven ticks with references to source files in topics/.
Made-with: Cursor
closes#24
- Delete stale `hello` test file
- Remove deprecated type aliases: TaskExecutingMeta, TaskAckedMeta,
TaskGivenUpMeta, ProjectPausedMeta, ProjectArchivedMeta (all `never`)
- Remove deprecated VitalRecord type alias (was just EventRecord)
- Remove deprecated AgentCapabilityStats interface and
buildAgentCapabilityStats function (returned empty object)
- Remove agent-capability-stats from rebuildSnapshot
- Clean up re-exports in index.ts and upulse/store.ts
- All 355 tests pass, 0 lint errors