Skip to content

Development Mode

Enter developmental agent mode — orient on architecture, key locations, and dev workflow for modifying work-buddy itself

When to use

When the user invokes /wb-dev, asks to build something in work-buddy, or needs to add/fix a skill, workflow, service, or dashboard feature

Slash command: /wb-dev

Linked workflow: dev/dev-orient

  • reload_skill_data
  • mode_toggle

Directions

You are a developmental agent, not an operational one. Your job is to modify the work-buddy codebase itself — add skills, fix bugs, improve workflows, extend services. You are not running morning routines or triaging tasks.

Step 1 — Orient before anything else

Start the orientation workflow:

`mcp__work-buddy__wb_run("dev-orient")`

This activates dev mode, forces you to search the knowledge store for the relevant subsystem, read the actual code, and declare what prior art you found — all before writing a single line. Do not skip it. The workflow's output is a structured record (three lists: units read, files read, wrappers found) that stays visible to the user, so "I already know this area" is not a valid reason to bypass.

If any list you advance with is empty or trivial, you have not oriented yet — go deeper and try again.

Architectural constructs (reference)

Three core constructs, with design heuristics for deciding between them:

  • Skills — kind: skill declarations whose op resolves to a registered Python implementation and which the shared registry loads as agent-invocable entries. A Skill executes immediately through wb_run("name", params).
  • Workflows — kind: workflow units, one Markdown file per definition under knowledge/store/. Each has an immutable workflow_id, mutable canonical workflow_name, optional executable workflow_aliases, and a computed workflow_revision; every invocation gets a separate workflow_run_id. Start one by canonical name, executable alias, or stable ID via wb_run, then advance a reasoning step with wb_advance(workflow_run_id=..., step_result=...).
  • Auto-run steps — workflow steps marked auto_run in the unit's frontmatter. The conductor executes these transparently in a subprocess; the agent never sees them. Use for deterministic code (config loading, data formatting) that needs no agent reasoning. A subprocess that times out is retried once automatically (transient host contention is the dominant cause); set auto_run.retry_on_timeout: false for steps that mutate external state where a second attempt would not be idempotent (git commits, outbound message sends, source-pipeline drives).

Decision heuristic. Can you write a unit test with a fixed expected output? → Skill. Does the "correct" output depend on interpretation, user input, or synthesis? → Workflow step. Is the step itself deterministic with no side effects? → Auto-run step.

For gateway design tenets (Progressive Disclosure, Just-in-Time Retrieval, etc.), see the dev/design-tenets knowledge unit.

For the MCP import discipline (asyncio deadlock hazard), see architecture/mcp-import-discipline.

Key locations

MCP skills (Op + declaration)

A skill is an Op (a Python callable) plus a declaration unit (a kind: skill Markdown unit that names the Op). At build time the registry resolves declarations against the Op registry via load_declared_skills — there is no registry.py Skill(...) builder anymore. See architecture/data-first-skills.

To add a skill: 1. Write the callable and register it in the relevant work_buddy/mcp_server/ops/<domain>_ops.py with register_op("op.wb.<name>", fn). 2. Author a declaration unit at knowledge/store/<domain>/<name>.md (kind: skill, with skill_name, op, category, and a parameters schema) — via the docs_edit workflow. 3. Restart the MCP server (Ctrl+R) so the new Op's code is imported and the skill enters the dispatcher. A new Op is new Python — reload_skill_data only refreshes data (declarations, workflows, and param schemas whose Op already exists), so it cannot pick up a brand-new Op. 4. Verify: mcp__work-buddy__wb_search("your_skill").

Workflows

A Workflow is a kind: workflow unit — one Markdown file per definition under knowledge/store/. The registry compiler in work_buddy/mcp_server/registry.py discovers definitions, validates identity and addresses, compiles references, and computes revisions. WorkflowService resolves and admits requests from MCP and sidecar adapters; work_buddy/mcp_server/conductor.py executes admitted runs. The steps DAG lives in YAML frontmatter; each step's prose lives under a ## <step-id> body section.

Identity fields have different jobs:

  • workflow_id is an opaque, immutable definition identity (wfd_...).
  • workflow_name is the mutable primary invocation address.
  • workflow_aliases are durable executable addresses; when renaming, retain the previous canonical name here.
  • Generic aliases remain search phrases, not invocation addresses.
  • workflow_revision is computed from the serialized authored definition snapshot, its directly bound Directions snapshot, and compiled child-Workflow target identities. Never author it. It is a start/admission guard and run marker, not a versioned-definition archive.
  • workflow_run_id (wf_...) identifies one execution.

To add a workflow: 1. Scaffold and author the unit with the docs_edit workflow: mcp__work-buddy__wb_run("docs-edit", {"path": "<domain>/<name>", "create": true, "kind": "workflow"}). The scaffold mints a fresh workflow_id; preserve it exactly. Then edit the remaining frontmatter, steps, and ## <step-id> body sections with your native Edit tool. The commit step validates identity/address collisions and the step DAG, then reconciles. 2. Create a matching slash command in .claude/commands/wb-<name>.md (thin launcher) if it's user-facing. 3. Create a behavioral directions unit (kind: directions) via docs_edit, loaded by the slash command. 4. Update CLAUDE.md if the workflow belongs in a user-facing table. 5. Reload with reload_skill_data — a new Workflow is data, so the data-only reload refreshes definitions, ID/alias indexes, and revisions without a process restart.

To edit an existing Workflow: use docs_edit and preserve its existing workflow_id; the resolve→commit guard carries the original value and rejects replacement. If workflow_name changes through a native/raw edit, append the former name to workflow_aliases. Use docs_move for a path move so the ID remains stable and path-based Directions bindings are rewritten. Structured editor updates also enforce ID immutability. Only a native edit performed entirely outside docs_edit lacks a pre-edit identity guard, so that author must preserve the existing value explicitly.

Knowledge units (any kind)

The system store is one Markdown file per unit (knowledge/store/<path>.md) — editing a unit is editing its file. Use the docs_edit workflow (wb_run("docs-edit", {"path": ...})): it returns the file path, you edit it with your native Edit tool, and the commit step validates (kind-aware) and reconciles the store cache + search index. create: true + kind scaffolds a new unit. dev_notes is just a frontmatter field — edit it inline.

A direct Edit of a unit's .md is equally valid; if you bypass the workflow, run agent_docs_rebuild afterward so the store and index reflect the change. For a Skill declaration or Workflow definition/address/schema edit, also run reload_skill_data after the active editing Workflow finishes so the live gateway registry reflects it. Structural operations that aren't content edits — deleting or moving a unit — use the docs_delete / docs_move skills. Skill units (kind: skill) are authored the same way (see "MCP skills" above for the Op + declaration pair).

Health system (preferences / requirements / components / fixers)

For "how do I add a new component / requirement / fixer / wizard check" — read architecture/health first. It frames the four-layer model (do I want this? / is it set up? / is it running? / how do I repair it?) and links to per-layer references.

Quick map:

  • Component — work_buddy/health/components.py. Register a ComponentDef. Runtime health-check functions live in work_buddy/health/checks.py. See architecture/health/components.
  • Requirement — work_buddy/health/requirements.py. Register a RequirementDef. Requirement check functions live in work_buddy/health/requirement_checks.py (no HTTP, no service pings — delegate to a checks.py helper if you need a runtime probe). See architecture/health/requirements.
  • Fixer — work_buddy/health/fixers.py. Wire it via the requirement's fix_kind (programmatic / input_required / agent_handoff) and matching fix_fn / fix_params / fix_agent_brief. See architecture/health/fixers.
  • Preferences — work_buddy/health/preferences.py plus config.local.yaml features.<id>.{wanted, reason}. Mostly automatic when a component is non-core. Behavioral guidance for agents: features/preferences.

The Settings tab UI picks up new components automatically via the control graph; you don't need to touch the dashboard frontend. A component registration is Python (in components.py), so restart the MCP server (Ctrl+R) to import it — reload_skill_data only refreshes data, not code. For the unified view-model + cascade rules + endpoint surface, see architecture/control-graph.

Doc hygiene after changes

/wb-dev-pr runs /wb-dev-document as a mandatory chained step (doc-update sits between the test and PII-scan steps in the dev-pr workflow). So committing through /wb-dev-pr already keeps the knowledge store in sync — do NOT run /wb-dev-document as a separate step first. Run /wb-dev-document standalone only when you want to preview the proposed doc edits outside the commit flow. It scans current changes against the knowledge store, proposes edits for stale units (and creates new ones where needed), and applies them via the sanctioned skills. Doc drift is a recurring failure mode; chaining it into /wb-dev-pr makes the check a DAG step that cannot be silently skipped.

Slash commands

.claude/commands/wb-*.md — thin launchers that load behavioral directions from the knowledge store via agent_docs. Behavioral guidance goes in the knowledge store directions unit, not in workflow step instructions (see the priming hazard note under dev/design-tenets).

Sidecar services

Each service follows the pattern: work_buddy/<service>/service.py with Flask app, /health endpoint, and main() entry point. Configured in config.yaml under sidecar.services.

To add a service: 1. Create work_buddy/<name>/ with __init__.py, __main__.py, service.py. 2. Add entry to config.yaml under sidecar.services. 3. Service must have GET /health returning {"status": "ok"}. 4. Sidecar auto-starts, health-checks, and restarts it.

Dashboard

For dashboard user tasks and visible behavior, load dev/dashboard and its UX and verification directions. Apply them proportionally, including to generated surfaces changed by Python code.

work_buddy/dashboard/ — web UI on port 5127. See services/dashboard knowledge unit for the tab-adding pattern.

Dev workflow

Running Python

uv run python <args>   # e.g. uv run python -m pytest tests/unit/<file>.py
(uv is cross-platform and manages the project .venv itself, so no shell activation step is needed.)

Testing skills

`mcp__work-buddy__wb_run("reload_skill_data")`     # pick up declaration / workflow / param-schema edits (data only)
`mcp__work-buddy__wb_search("your_query")`              # verify discovery
`mcp__work-buddy__wb_run("skill_name", {...})`     # test execution

Caveat — data vs code: reload_skill_data makes data changes live with no restart: new/edited declarations (including param schemas) and Workflows, including their ID/alias indexes and computed revisions. It does NOT pick up edited gateway or Op Python or a brand-new Op module — those require Ctrl+R so the MCP client reconnects to the rebuilt process. Auto-run callables are freshly imported in their subprocess on each execution. (The retired mcp_registry_reload claimed to hot-patch code but silently did nothing in the long-lived FastMCP gateway — see dev/mcp-reload.)

Restarting services

uv run --frozen wbuddy restart
uv run --frozen wbuddy status

This restarts the sidecar-managed child services, including the dashboard. Gateway Python changes still require Ctrl+R in the agent client after the process is rebuilt so its cached MCP connection and tool schema are refreshed.

Live testing

Run /wb-dev-live-testing to drive an end-to-end test of an in-progress change against the running MCP server + sidecar + surfaces. Distinct from pytest — unit tests catch logic bugs; live tests catch wiring bugs (FastMCP tool registration, surface dispatchers, sidecar message routing, session-scoped storage). The protocol (precondition → trigger → user action → verify → cleanup) lives in dev/live-testing-directions; the slash command loads it. Use after any change that touches gateway entry points, notification surfaces, or session-scoped behavior.

Dependencies

Never use pip install. Use uv: - Production: uv add <package> - Temporary/testing: uv add --group dev <package> (cleanly removable)

Committing

work-buddy enforces a Developer Certificate of Origin: every commit must be signed off with git commit -s, which appends a Signed-off-by trailer. The DCO status check is required on main — a pull request with any unsigned commit cannot merge. /wb-dev-pr signs off in its commit step; if you commit by hand, always pass -s.

What NOT to do

  • Don't skip the orientation workflow. Every documented failure to orient has produced wrong code. You are the next data point if you skip.
  • Don't run operational workflows — you're here to build, not to operate.
  • Don't guess at imports — mcp__work-buddy__wb_search() first, then check the code.
  • Don't add features without slash commands — every user-facing skill needs one.
  • Don't start processes yourself. Use work_buddy.process (run_tool, spawn_worker, start_host or open_visible_terminal), never subprocess, os.system, os.startfile or creationflags, and fake launches in tests with the recording_runner fixture. tests/unit/architecture/test_process_boundary.py fails otherwise. See architecture/process-execution.
  • Don't double-run doc hygiene — /wb-dev-pr already runs /wb-dev-document as a chained step, so never tell the user (or yourself) to "run /wb-dev-document then /wb-dev-pr." Run /wb-dev-document standalone only to preview doc edits before the PR flow.
  • Reconcile after a direct file edit — a raw Edit of a unit's .md is fine, but run agent_docs_rebuild (or use the docs_edit workflow, which does it for you) so the store cache and search index pick up the change. If the unit is a Skill declaration or Workflow definition, follow with reload_skill_data after the editing Workflow completes so the executable registry is not stale.
  • Don't commit unrelated files — stage only what you changed.
  • Don't commit without -s — work-buddy enforces a DCO; an unsigned commit fails the required DCO check and blocks the PR.
  • Don't ship transient narrative in durable surfaces. See <<wb:dev/durable-surfaces>>.