Skip to content

feat(daemon): v2 privileged-write-channel daemon scaffold (phase 2)#22

Merged
vilosource merged 6 commits into
developfrom
feature/v2-daemon-scaffold
May 16, 2026
Merged

feat(daemon): v2 privileged-write-channel daemon scaffold (phase 2)#22
vilosource merged 6 commits into
developfrom
feature/v2-daemon-scaffold

Conversation

@vilosource
Copy link
Copy Markdown
Owner

Phase 2 of the v2 privileged-write-channel (issue #1). Implements the
mykbd daemon scaffold against the frozen Phase 1 contract
(docs/v2-protocol-contract-DESIGN.md).

Strict TDD red→green per slice; full testing pyramid per contract §7
(unit transport/envelope → integration capability/handshake → contract
error-taxonomy → scenario socket end-to-end).

Slices landed so far

  • Slice 1 — L1 transport (src/daemon/transport.ts, errors.ts):
    length-prefixed frame codec per §4.1; full error taxonomy from §6;
    9 unit tests (round-trip, multibyte, oversize→BODY_TOO_LARGE,
    partial-frame reassembly, coalesced frames).
  • Slice 2 — JSON-RPC envelope (src/daemon/jsonrpc.ts): §4.2–4.3;
    named-object params only, no-notifications id rule, typed error
    serialization; 12 unit tests.

Further slices (L4 dispatch + capability gate, socket server + hello +
SO_PEERCRED, scenario e2e) land as subsequent commits on this branch.

WIP — do not merge until the scenario slice + full pyramid are green.

…ce 1)

First Phase 2 slice of the privileged-write-channel (issue #1), TDD red→green.

- src/daemon/errors.ts: DaemonError + the full kind→code taxonomy
  transcribed from v2-protocol-contract-DESIGN.md §6 (contract data;
  only BODY_TOO_LARGE exercised this slice, rest land with their slices).
- src/daemon/transport.ts: encodeFrame + streaming FrameDecoder per
  contract §4.1 (uint32 BE length ‖ UTF-8 body, 16 MiB cap).
- 9 unit tests (contract §7.1): round-trip, multibyte byte-count,
  oversize→BODY_TOO_LARGE on both encode and decode, partial-frame
  reassembly, coalesced frames, trailing-partial carry-over.

Stacked on the Phase 1 contract branch so the contract doc is in-tree.
TDD red→green. parseRequest/successResponse/errorResponse per
v2-protocol-contract-DESIGN.md §4.2–4.3:

- named-object params only (positional array → INVALID_REQUEST, the
  LSP-hazard guard from contract §2.1)
- no notifications in v2: missing/null id → INVALID_REQUEST
- malformed JSON → PARSE_ERROR; non-DaemonError throwable degrades to
  INTERNAL_ERROR so an untyped bug never leaks to the wire
- 12 unit tests
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 16, 2026

Warning

Rate limit exceeded

@vilosource has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 26 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9815f6e1-20eb-456c-8907-b893afddcd58

📥 Commits

Reviewing files that changed from the base of the PR and between fd37e8a and d99820a.

📒 Files selected for processing (14)
  • docs/v2-protocol-contract-DESIGN.md
  • package.json
  • src/daemon/capability.ts
  • src/daemon/dispatch.ts
  • src/daemon/errors.ts
  • src/daemon/jsonrpc.ts
  • src/daemon/main.ts
  • src/daemon/server.ts
  • src/daemon/transport.ts
  • tests/daemon/dispatch.test.ts
  • tests/daemon/dispatch.verbs.test.ts
  • tests/daemon/jsonrpc.test.ts
  • tests/daemon/server.scenario.test.ts
  • tests/daemon/transport.test.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…e 3)

TDD red→green. Thin Facade over today's src/core/* (re-homing, not
rewriting — parent DESIGN §What moves vs stays):

- capability.ts: SO_PEERCRED-derived Capability (operator|agent), §2.2.
- dispatch.ts: verb registry per contract §5 — knowledge add/lifecycle/
  read, workspace, area+maintenance, system; per-verb capability gate;
  core-error → typed-taxonomy translation (§6).
- Security checks enforced now even though envelope-v2 schema is unlanded:
  agent asserting trust:operator → TRUST_DENIED; verify_entry +
  operator-only maintenance verbs gated to operator capability.
- Forward-compat per §3.1a/§8: trust/validity/origin add-params accepted
  on the wire but not persisted pre-envelope-v2; supersede_entry reserved
  → UNSUPPORTED_OP until the superseded_by field exists (§3.1b).
- 17 integration tests (real src/core + temp brain, no socket yet).

Full daemon suite 38/38 (transport 9 + jsonrpc 12 + dispatch 17).
TDD red→green. Closes the Phase 2 daemon scaffold:

- server.ts: net.createServer Unix-socket listener; per-connection
  FrameDecoder → parseRequest → L4 dispatch → framed response (§4).
  Socket created mode 0600 (§4.1). Survives client crash mid-write
  (parent DESIGN §Experiments). Capability resolution injected as a
  Strategy/DIP seam — production SO_PEERCRED resolver is a Phase 6
  deliverable (Node exposes no public SO_PEERCRED API; faking it in the
  scaffold would be dishonest, so the seam is explicit instead).
- main.ts + npm run daemon:dev: dev-mode entrypoint (parent DESIGN
  §Dev-mode), SIGINT/SIGTERM clean shutdown.
- 4 scenario tests over a REAL Unix socket (contract §7 capstone):
  representative verb of each group as operator; operator-only verb
  denied to agent over the wire; socket mode 0600; split-write
  reassembly through the live server.

Daemon suite 42/42; full project sweep 623/623; lint clean.
…se 2 slice 5)

TDD red→green. Finishes Phase 2's contract §5 surface and fixes a
contract-fidelity bug:

- Adds CONTRACT_VERBS (the full §5 verb list). dispatch() now routes a
  contracted-but-unwired verb to UNSUPPORTED_OP and only a genuinely
  unknown verb to METHOD_NOT_FOUND — the §6 distinction. Previously every
  unwired contract verb wrongly returned METHOD_NOT_FOUND.
- Wires the remaining mechanical verbs: link/unlink_area,
  resolve_workspace_id, update_workspace_links, archive_workspace,
  clear_active_workspace, delete_note, clear_handoff, the full artifact
  group (add/read/read_content/update/delete/list/sync), recent_activity.
- area_stats + rebuild stay intentionally unwired (need MykbStore-internal
  db handle / CLI-inlined logic respectively) → UNSUPPORTED_OP, honestly
  reserved rather than faked.
- 12 tests. Daemon suite 53/53; full project sweep 634/634; lint clean.
Honest bookkeeping: what landed (L1/JSON-RPC/dispatch/capability/scenario,
53 daemon tests, full pyramid) vs what is explicitly deferred to a named
phase with a reason (SO_PEERCRED resolver → Phase 6; L2 StorageBackend
contract suite → when a 2nd backend exists; supersede/envelope params →
envelope-v2 phase 1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant