xiaoju
8d92928951
fix(daemon): address PR #22 review — 6 issues fixed
...
Critical:
1. replayAndResume: remove double moderate() call, reuse loop result
2. drainAndRespawn: check workflow still in config before respawn
3. drain: mark in-flight runs as 'interrupted' in DB before clearing
Should fix:
4. crash recovery: dedup runId before re-queuing/re-activating
5. drain timeout: DEFAULT_DRAIN_TIMEOUT_MS > WORKER_SHUTDOWN_TIMEOUT_MS
6. crash-loop protection: max 5 crashes in 60s window, then stop respawn
5 new tests added. All 173 tests pass.
小橘 🍊 (NEKO Team)
2026-04-22 13:25:35 +00:00
xiaoju
49ed65a330
feat(daemon): Phase 3 — crash recovery, hot reload & incremental config
...
- workflow-manager: crash detection, worker respawn, thread resume from
persisted events, drainAndRespawn() for hot reload
- log-store: getTriggerPayload(), getThreadEvents() for crash recovery
- file-watcher: detect workflow .ts file changes under workflows/
- kernel: handleWorkflowFileChange(), incremental workflow config updates
on reloadConfig() (add/remove/update concurrency)
- ipc: resume-thread message type for crash recovery
- workflow-worker: handle resume-thread, rebuild ThreadState from events
28 new tests across 4 test files. All 168 tests pass.
小橘 🍊 (NEKO Team)
2026-04-22 13:25:35 +00:00
xiaomo
b7dfe42a96
Merge pull request 'fix: init runtime bugs - missing dir, .ts/.js mismatch, TS annotations' ( #26 ) from fix/init-runtime-bugs into main
2026-04-22 13:22:52 +00:00
xingyue
a887fc04ca
fix: init creates data/senses dir, generates .js templates without TS annotations
...
- Add mkdirSync for data/senses/ in init command (#23 )
- Add defensive mkdirSync in sense-runtime before DB open (#23 )
- Change init template output from index.ts to index.js (#24 )
- Remove TypeScript type annotations from CPU usage template (#25 )
Closes #23 , closes #24 , closes #25
2026-04-22 21:15:42 +08:00
xiaomo
d5931a9e19
Merge pull request 'feat: Workflow Engine Phase 2 — Kernel Integration' ( #21 ) from feat/workflow-engine-phase2 into main
2026-04-22 12:45:43 +00:00
xiaoju
f12f187d8d
feat(daemon): Phase 2 — kernel ↔ workflow integration
...
- kernel.ts: create WorkflowManager, expose on Kernel, wire into
ReflexScheduler via workflowTriggerFn, add activeWorkflows to
KernelHealth, graceful shutdown ordering
- reflex-scheduler.ts: handle kind:'workflow' reflexes — subscribe to
bus signals and delegate to workflowTriggerFn
- workflow-manager.ts: add totalActiveCount(), updateConfig() for hot
reload support
All 140 tests pass.
小橘 🍊 (NEKO Team)
2026-04-22 12:40:57 +00:00
xiaomo
1512113a01
Merge pull request 'feat: Workflow Engine Phase 1' ( #17 ) from feat/workflow-engine-phase1 into main
2026-04-22 12:20:12 +00:00
xiaoju
8f495cf92e
fix: address all 8 PR #17 review issues
...
Critical fixes:
1. triggerPayload spread → safe field assignment with validation
2. Graceful shutdown stopping flag → no false crash warnings
3. Shutdown awaits in-flight work (10s timeout) before exit
4. Thread loop safety valve (MAX_STEPS=1000)
5. active counter: bare number → Set<string> by runId
Should-fix:
6. ThreadEventMessage.eventType → union type with validation
7. SQLite status cast → runtime validateWorkflowRunStatus()
8. getActiveWorkflowRuns → pre-compiled prepared statements
小橘 <xiaoju@shazhou.work >
2026-04-22 12:13:29 +00:00
xiaoju
a68338c4e9
feat: implement Workflow Engine Phase 1 ( #16 )
...
- Core types: WorkflowDefinition, ThreadState, CommandEvent, ModerateResult, etc.
- IPC: StartThreadMessage, ResumeThreadMessage, ThreadEventMessage, WorkflowErrorMessage
- WorkflowManager: concurrency control (drop/queue overflow), worker lifecycle
- Workflow worker: moderate→execute loop, user code loading
- LogStore: workflow_runs materialized table, appendWithWorkflowUpdate
- 131 tests passing
RFC-002 Phase 1 complete.
小橘 <xiaoju@shazhou.work >
2026-04-22 11:49:50 +00:00
xiaoju
9802f68380
docs: add RFC-002 Workflow Engine
...
Defines the workflow execution engine design:
- Thread lifecycle with event sourcing
- Concurrency control (drop/queue overflow)
- WorkflowManager, workflow worker process model
- IPC extension, crash recovery, hot reload
- 4-phase implementation plan
小橘 <xiaoju@shazhou.work >
2026-04-22 11:26:28 +00:00
xiaomo
f245224320
Merge pull request 'Phase 7: Structured Logging System' ( #15 ) from feat/phase-7-logging into main
2026-04-22 11:21:47 +00:00
xiaoju
1b995379f9
feat: Phase 7 — structured logging system (RFC §2.4/§5.4)
...
- log-store.ts: SQLite append-only log store with query API and meta table
- kernel: system start/stop logs, signal/error logging, file watcher events
- reflex-scheduler: run_start/run_complete logging per compute
- Exports: createLogStore, LogStore, LogEntry, LogQuery
- Tests: log-store CRUD, query filters, meta, integration with reflex
Closes #14
小橘 🍊 (NEKO Team)
2026-04-22 11:20:29 +00:00
xiaomo
ea6bc5610b
Merge pull request 'Phase 6: Hot Reload & Error Handling' ( #13 ) from feat/phase-6-hot-reload into main
2026-04-22 11:12:38 +00:00
xiaoju
49d078b144
fix: address PR #13 review — per-sense timeout, reload restart, await ready
...
- reloadConfig: restart existing groups when new senses added
- sense-worker: per-sense timeout/gracePeriod lookup at compute time (RFC §5.3)
- restartGroup: await worker ready promise before returning
- Comments: scheduler in-flight state loss, fs.watch Linux caveats, grace period blast radius
小橘 🍊 (NEKO Team)
2026-04-22 11:07:33 +00:00
xiaoju
9ca8c8ecb8
feat: Phase 6 — hot reload, error isolation, grace period, nerve-health
...
- file-watcher.ts: watch nerveRoot for .ts and nerve.yaml changes
- kernel.ts: restartGroup(), reloadConfig(), getHealth(), auto-respawn on crash
- sense-worker.ts: compute try/catch error isolation, grace_period hard kill
- ipc.ts: new message types for health, restart, reload
- examples/senses/nerve-health.ts: built-in daemon health sense
- Integration tests for hot reload, error isolation, grace period
小橘 🍊 (NEKO Team)
2026-04-22 10:57:00 +00:00
xiaomo
00c1932144
Merge pull request 'feat: Phase 5 — CLI & User Workspace' ( #12 ) from feat/phase-5-cli-workspace into main
2026-04-22 10:33:53 +00:00
xiaoju
097a4790be
fix: address PR #12 review — cross-platform, pkg manager detection, exports
...
- status.ts: wrap /proc in try/catch, fallback to PID file mtime (macOS safe)
- init.ts: detect pnpm > yarn > npm instead of hardcoding pnpm
- init.ts: use dirname() instead of join(.., '..')
- index.ts: restore createKernel/Kernel re-exports (non-breaking)
- start.ts: use fileURLToPath(import.meta.url) for daemon spawn
- start.ts: use logStream.fd instead of double type cast
- validate.ts: remove misleading error numbering
小橘 🍊 (NEKO Team)
2026-04-22 10:32:06 +00:00
xiaoju
ad2b40dd4f
feat: implement Phase 5 CLI & User Workspace
...
- Restructure CLI with citty multi-command framework
- nerve init: create workspace skeleton at ~/.uncaged-nerve/
- nerve start: foreground + daemon (-d) modes with graceful shutdown
- nerve stop: SIGTERM → 10s wait → SIGKILL, PID file cleanup
- nerve status: show pid, uptime, senses, workers
- nerve validate: parse nerve.yaml with error reporting
- workspace.ts: shared utilities (PID file, paths, isRunning)
- Example cpu-usage sense with realistic os.cpus() compute
小橘 🍊 (NEKO Team)
2026-04-22 10:16:41 +00:00
xiaomo
31d1eae44a
Merge pull request 'feat(cli,daemon): Phase 4 — Process Manager & Isolation' ( #11 ) from feat/phase-4-process-manager into main
2026-04-22 09:59:43 +00:00
xiaoju
b4ef669607
fix: address all 9 PR #11 review issues
...
Critical:
- cli.ts: add shuttingDown guard to prevent double shutdown race
- kernel.ts: check child.connected before IPC send
Warning:
- Rewrite IPC round-trip test to verify actual signal flow
- Rewrite crash recovery test to kill kernel-managed worker
- parseArgs: explicitly handle 'start' subcommand
- Respawn: reset scheduler in-flight state for crashed group
Suggestions:
- Re-export KernelOptions from index.ts
- Add comment explaining mock-worker.mjs format
- Replace setTimeout with pollUntil helper
小橘 🍊 (NEKO Team)
2026-04-22 09:57:06 +00:00
xiaoju
22b3690327
feat(cli,daemon): Phase 4 — Process Manager & Isolation
...
- CLI entry point: `nerve start [--root <path>]` with SIGINT/SIGTERM handling
- Kernel exports groups/senseCount for startup logging
- daemon tsup builds sense-worker.ts as separate entry point
- Integration tests with mock worker (IPC round-trip, crash recovery, graceful shutdown)
- CLI re-exports createKernel/Kernel from daemon
59 tests (was 54), all green. biome check passes.
Closes #5
小橘 🍊 (NEKO Team)
2026-04-22 09:45:19 +00:00
xiaomo
7bb5df301d
Merge pull request 'feat(daemon): Signal Bus, Reflex Scheduler & Kernel (Phase 3)' ( #10 ) from feat/signal-bus-reflex into main
2026-04-22 09:36:56 +00:00
xiaoju
9443406703
fix(daemon): address all 12 PR #10 review items
...
🔴 Critical:
1. parseWorkerMessage() in ipc.ts — validates worker→parent IPC messages
2. signalIdCounter moved inside createKernel closure
3. throttle deferred trigger — pending trigger fires after window ends
⚠️ Warnings:
4. worker respawn on crash with backoff
5. stop() awaits worker exit with SIGKILL fallback
6. signal-bus handler errors caught, no re-throw
7. removed unnecessary as SenseReflexConfig cast
8. config validates sense reflex has at least one trigger
💡 Suggestions:
9. signal ID documented as process-scoped (solved by #2 )
10. +3 throttle-pending tests
11. +6 kernel unit tests (mock fork, message routing)
12. example imports verified correct
54 tests (was 45), all green. biome check passes.
小橘 🍊 (NEKO Team)
2026-04-22 09:34:13 +00:00
xiaoju
d9355a6299
feat(daemon): Signal Bus, Reflex Scheduler & Kernel (Phase 3)
...
- signal-bus: in-memory pub/sub for Signal dispatch, sync broadcast,
subscriber error isolation
- reflex-scheduler: interval + event-driven triggers, throttle enforcement,
merge/coalesce (pending flag, no unbounded queue), workflow reflexes skipped
- kernel: orchestrator tying workers, signal bus, and scheduler together,
graceful shutdown
- examples/nerve.yaml: cpu-usage (10s), disk-usage (30s), system-health
(on: [cpu-usage, disk-usage])
- 20 new tests (45 total): signal bus (8) + reflex scheduler (12)
Closes #4
小橘 🍊 (NEKO Team)
2026-04-22 08:56:38 +00:00
xiaomo
bf60047186
Merge pull request 'feat(daemon): Sense Runtime — Worker, IPC, Migrations, Peer Isolation' ( #9 ) from feat/sense-runtime into main
2026-04-22 08:48:30 +00:00
xiaoju
c80a6b9fa8
fix(daemon): address all 6 PR review items
...
🔴 Must fix:
1. compute timeout — AbortController + configurable timeoutMs, soft timeout
returns error Result (RFC §5.3)
2. migration journal — _migrations table tracks applied files, skips
already-executed migrations
3. IPC validation — parseParentMessage() validates type field, rejects
malformed messages with Result error
⚠️ Also fixed:
4. Self DB excluded from peers map
5. Per-sense compute serialization (mutex via Promise chain)
6. Unhandled rejection — .catch() on compute promise, errors sent via IPC
+10 new tests (25 total), biome check + vitest all green.
小橘 🍊 (NEKO Team)
2026-04-22 08:45:19 +00:00
xiaoju
a38986acdb
feat(daemon): sense runtime — worker, IPC, migrations, peer isolation
...
Implements the Sense observation engine runtime per RFC-001:
- IPC types: discriminated union for parent↔worker messages
- sense-runtime: openSenseDb (WAL), openPeerDb (readonly), runMigrations,
loadComputeFn, executeCompute with Result<T> error handling
- sense-worker: CLI bootstrap, reads nerve.yaml, inits per-sense DB,
builds peer map, enters IPC event loop
- examples/cpu-usage: sample sense with Drizzle schema + migration
- 15 unit tests covering migrations, DB ops, compute, peer isolation
小橘 🍊 (NEKO Team)
2026-04-22 08:45:19 +00:00
xiaomo
cf55f3bc3a
Merge pull request 'feat(core): Phase 1 — Core Types & Config Parsing' ( #8 ) from feat/phase-1-core-types into main
2026-04-22 08:43:36 +00:00
xiaoju
852cad9c60
docs(rfc-001): archival watermark + workflow_runs materialized table
...
- Cold archival: meta table with archived_up_to watermark for crash-safe recovery
- Workflow state: workflow_runs materialized table (UPSERT in same txn as log write)
- O(active) queries instead of full table scan
- Derivable from logs if lost
小橘 <xiaoju@shazhou.work >
2026-04-22 08:15:28 +00:00
xiaoju
f5c561173d
docs(rfc-001): add Log concept, append-only storage architecture, workflow event sourcing
...
- §2.4: Log as data asset, not trigger source (anti-avalanche constraint)
- §3: Add Log to terminology table
- §5.4: New storage architecture section
- Unified logs table (append-only SQLite)
- Workflow state via event sourcing (no mutable tables)
- Cold archival: >30d data exported to daily JSONL files
- §5.6: Error handling now writes logs instead of error signals
- §8: Directory structure updated with logs.db and archive/
- §10: Design principles updated (8 principles, +1 log rule)
- Thread outputs are now Logs, not Signals
小橘 <xiaoju@shazhou.work >
2026-04-22 08:06:09 +00:00
xiaoju
636b00c0a3
fix(core): address PR #8 review — gracePeriod, maxQueue default, drop+maxQueue guard, workflow name validation
...
- SenseConfig: add gracePeriod field (RFC §5.3 two-tier timeout)
- WorkflowConfig: discriminated union (DropOverflowConfig | QueueOverflowConfig)
- overflow: queue defaults maxQueue to 100
- overflow: drop + max_queue now returns validation error
- Cross-validate workflow reflex references against defined workflows
- Update tests: 21 cases covering all new behaviors
小橘 <xiaoju@shazhou.work >
2026-04-22 07:55:23 +00:00
xiaoju
8784a4edc4
refactor: duration fields → number|null (milliseconds)
...
- throttle, timeout, interval: string|null → number|null
- parseDurationField now returns parsed ms (5s→5000, 10m→600000, 1h→3600000)
- biome.json: ignore dist/** from checks
小橘 <xiaoju@shazhou.work >
2026-04-22 07:41:22 +00:00
xiaoju
1949007c99
refactor: ban optional properties, use T|null + discriminated unions
...
- Add coding convention: no '?:', use explicit 'T | null'
- ReflexConfig → discriminated union (SenseReflexConfig | WorkflowReflexConfig)
- All optional fields → explicit null (throttle, timeout, interval, on, maxQueue, workflows)
- Add exactOptionalPropertyTypes to tsconfig
- Add lib: ES2022 to tsconfig
- Refactor validateReflexConfig to reduce cognitive complexity
小橘 <xiaoju@shazhou.work >
2026-04-22 07:33:14 +00:00
xiaoju
3159d3713d
feat(core): add autoincrement id to Signal type
...
Timestamp alone can't guarantee strict total ordering (multiple signals
in the same millisecond). An autoincrement id provides a reliable
sequence for ordering and cursor-based pagination.
小橘 <xiaoju@shazhou.work >
2026-04-22 07:22:10 +00:00
xiaoju
3eba156b6b
feat(core): Phase 1 — core types & config parsing
...
- Define Signal, SenseConfig, ReflexConfig, WorkflowConfig, NerveConfig types
- Implement Result<T,E> with ok()/err() helpers
- Implement parseNerveConfig() with full YAML validation
- 14 unit tests covering normal and error paths
- pnpm run check passes with 0 errors
Closes #2
小橘 <xiaoju@shazhou.work >
2026-04-22 07:16:49 +00:00
xiaoju
3b22fde79c
chore(biome): 强化 lint 规则 — 用工具约束 coding conventions
...
- noDefaultExport: 禁止 default export
- noParameterProperties: 禁止 class 参数属性
- noNamespace: 禁止 namespace
- noExplicitAny: 禁止 any
- noUnusedVariables/Imports: 禁止未使用变量和 import
- noForEach: 用 for-of 替代
- useArrowFunction: 回调用箭头函数
- useImportType: type-only import
- useConst/noVar: 不可变优先
- noStaticOnlyClass: 禁止纯静态 class(用函数)
- cognitive complexity <= 15
2026-04-22 06:31:34 +00:00
xiaoju
d643ccf5af
fix: rename packages to @uncaged/nerve-{core,cli,daemon}
2026-04-22 06:29:08 +00:00
xiaoju
a7126c453f
chore: monorepo scaffolding — pnpm workspaces, biome, tsup, coding conventions
...
- packages/core, packages/cli, packages/daemon
- biome: noDefaultExport, useNodejsImportProtocol, noStaticOnlyClass
- docs/coding-conventions.md: 函数式优先,type over interface
2026-04-22 06:05:21 +00:00
xiaoju
643c353cc3
feat(rfc-001): 回应小墨 review — runtime 注入 db/peers、migration rollback、drizzle config、schema 新鲜度
2026-04-22 05:54:56 +00:00
xiaoju
8a3937f0e1
feat(rfc-001): Drizzle 作为 Sense schema 标准工具链
...
- schema.ts 为 single source of truth,migration 由 drizzle-kit 自动生成
- Sense 目录结构从单文件改为目录(schema.ts + index.ts + migrations/)
- 设计理由:开发者是 Coding Agent,确定性工具链优于概率模型自律
- 更新 §4.1 存储设计、§8 目录结构
小橘 <xiaoju@shazhou.work >
2026-04-22 05:36:17 +00:00
xiaoju
8379dae585
fix(rfc-001): 解决小墨 review 的生产风险问题
...
- 删除 Guard 表达式(when),条件判断由 Workflow 自己处理
- Workflow queue 加 max_queue 上限(默认 100)
- compute 超时改为两级:soft timeout + grace_period hard kill
- 热更新加 drain_timeout,防止长 thread 阻塞 reload
小橘 <xiaoju@shazhou.work >
2026-04-22 05:12:58 +00:00
xiaoju
6e49deaf99
refactor(rfc-001): Reflex 作为 Event Mesh,Sense 不知道 Workflow
...
- 删除 Sense → Workflow 桥接(ThreadStart payload),Sense 只产出数据
- Reflex 新增两种 action:TriggerCompute / StartWorkflow
- 引入 Event Mesh 概念:所有事件路由声明在 Reflex 中
- 更新依赖图、Haskell 类型签名、设计原则
- 删除 should-cleanup sense(改由 Reflex when 守卫实现)
小橘 <xiaoju@shazhou.work >
2026-04-22 05:02:14 +00:00
xiaoju
aba4580ff6
docs: polish RFC — fix Signal definition for Maybe, dedupe YAML config, merge §7 into §5, renumber
2026-04-22 04:28:41 +00:00
xiaoju
99d5549630
docs: unify compute return type to Maybe (T | null)
2026-04-22 04:25:51 +00:00
xiaoju
f08f37e14e
docs: clarify engine as kernel/event-hub, worker isolation, signal bus in-memory
2026-04-22 04:21:32 +00:00
xiaoju
96c740d175
docs: add §5 runtime model (process isolation, persistence, hot reload, error handling)
2026-04-22 03:39:29 +00:00
xiaoju
aa5b0c6349
docs: workflow concurrency/overflow, signal-thread boundary
...
Signal only kicks off Thread. Thread has its own event loop.
Thread output signals are execution logs for retrospection only.
小橘 <xiaoju@shazhou.work >
2026-04-22 03:12:42 +00:00
xiaoju
162c50b326
docs: Event → Signal terminology, add senses config with throttle, update reflex semantics
...
- Signal replaces Event/Observation as the term for Sense output
- Senses config in nerve.yaml for runtime properties (throttle)
- ReflexCondition: OnInterval | OnSignal [SenseId]
- OnDemand is engine-builtin, not declared
小橘 <xiaoju@shazhou.work >
2026-04-22 02:56:28 +00:00
xiaoju
b3beaf5e19
docs: add reflex semantics — interval origin, event compensation, idempotency
...
小橘 <xiaoju@shazhou.work >
2026-04-22 02:46:17 +00:00
xiaoju
a1785cf36a
fix: remove unused type parameter from Sense compute
...
小橘 <xiaoju@shazhou.work >
2026-04-22 02:40:02 +00:00