# Workflow Knowledge

> Workflow Knowledge

- Skill: `leeovery/workflow-knowledge` (Agent Skill, multi-file: 14 files)
- Install (CLI): `npx skillmds@latest add leeovery/workflow-knowledge`
- Raw SKILL.md: https://api.skillmd.com/api/skills/leeovery/workflow-knowledge/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: leeovery (https://skillmd.com/u/leeovery)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/leeovery/workflow-knowledge

---


# Workflow Knowledge

CLI tool for querying the workflow knowledge base — a retrieval-augmented store of all completed workflow artifacts, searchable by semantics or keyword. This file is the API documentation layer. Load it when you need to construct a query or interpret results.

## What the knowledge base is

A local semantic-search index over every completed research, discussion, investigation, and specification artifact in `.workflows/`, plus user-supplied imports and promoted seeds indexed as they land, the gap-analysis cache indexed when topic-discovery rewrites it, epic discovery session logs indexed at each harvest, the product-road session logs and roadmap imports (`.workflows/.roadmap/`) indexed at each session close and landing, and the project baseline docs indexed as each area completes. Content is stored at full fidelity — chunks are the actual text, not summaries — with provenance metadata attached: which work unit, which phase, which topic, and the source document's date.

**Why it exists**: to surface prior context that would otherwise be lost across work units or forgotten within one. A spec written three months ago, a discussion that rejected an approach, an investigation that ruled out a cause — all remain queryable.

**What is indexed**:

- `research` (low confidence — exploratory, may contain dead ends)
- `discussion` (low-medium — conversational, may contain corrected assumptions)
- `investigation` (medium — diagnostic, tied to specific symptoms)
- `specification` (high — validated decisions, "what we decided to build")
- `imports` (low — user-shared reference material, often loose, may contain multiple topics)
- `seeds` (low — the work unit's origin: the promoted inbox item(s), verbatim capture)
- `analysis` (low — the gap-analysis cache, a meta-summary derived from low-confidence material)
- `discovery` (low — epic exploration logs: the running record, not validated decisions; topic = session, so a work unit's whole discovery is `--phase discovery --work-unit {wu}`)
- `baseline` (low — the project baseline: brownfield assessment docs at `.workflows/.baseline/{topic}.md`, project-level rather than per-work-unit. Chunks carry the reserved pseudo-identity `baseline` for both work unit and work type. Observed and user-stated context about the pre-existing codebase — it informs, but is never a settled call a phase may lean on silently)
- `roadmap` (low — the product-road session logs at `.workflows/.roadmap/sessions/session-NNN.md`: the running record of product-altitude conversation, graded like discovery logs; topic = session. Project-level — chunks carry the reserved pseudo-identity `roadmap` for both work unit and work type. Roadmap imports land at `.workflows/.roadmap/imports/{name}.md` under the same identity with phase `imports`)

**What is NOT indexed**: planning, implementation, review. These phases describe execution, not knowledge. Searching them would surface task IDs and code fragments, not insight. Operational `.state/` files (migrations, environment-setup) are also excluded — only the gap-analysis cache filename is accepted from `.state/`.

---

## Invocation

```bash
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs <command> [args]
```

Every skill that calls this must declare `Bash(node .claude/skills/workflow-knowledge/scripts/knowledge.cjs)` in its `allowed-tools` frontmatter.

To list commands and options, use `--help` / `-h` / `help` — writes usage to stdout, exits 0. Invoking the CLI with no arguments writes usage to stderr and exits 1.

---

## `query` — search the knowledge base

### Single query

```bash
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs query "<search term>" [flags]
```

### Batch query

```bash
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs query "<term1>" "<term2>" "<termN>" [flags]
```

Multiple positional arguments run separate searches in one invocation, merge the results, deduplicate by chunk ID (highest score wins), then apply `--limit` to the merged set. Efficient — one store load, multiple searches. Encouraged when you want to attack the same topic from different angles.

### Flags

| Flag | Behaviour |
|------|-----------|
| `--work-unit <wu>` | Filter to one or more work units. Comma-separated list accepted. Hard filter — non-matching chunks excluded |
| `--work-type <type>` | Filter results to a work type. Comma-separated list accepted (e.g., `--work-type cross-cutting` or `--work-type epic,feature`). Hard filter |
| `--phase <phase>` | Filter to one or more phases. Same comma-separated syntax. Hard filter |
| `--topic <topic>` | Filter to one or more topics. Same comma-separated syntax. Hard filter |
| `--boost:<field> <value>` | **Re-ranking hint, NOT a filter.** Boosts chunks where `<field>` equals `<value>` by `+0.1` per match, additive. Repeatable. Valid fields: `work-unit`, `work-type`, `phase`, `topic`, `confidence`. Use it to say "I'm currently working in `auth-flow`, prefer its context" via `--boost:work-unit auth-flow` — results from other work units still appear, just ranked lower |
| `--limit <n>` | Cap result count after merge + re-rank. Default 10 |

### Search modes

Two modes, auto-selected based on project config:

- **Hybrid** (default when an embedding provider is configured): keyword + vector search combined, results re-ranked by any `--boost:<field>` directives you pass, plus an always-on confidence-tier boost and a progress-based decay that down-ranks units the project has moved past.
- **Keyword-only** (when no provider is configured): full-text search only. Still useful — you lose semantic expansion but exact-term queries work. The output prepends a note: `[keyword-only mode — configure embedding provider for semantic search]`. This is a supported degraded mode, not a broken state.

### Query construction

Use **natural language**, not topic slugs. A query is a short description of what you're looking for, framed the way the original author would have written about it.

- Good: `"OAuth2 PKCE flow for mobile clients"`
- Good: `"why we ruled out email as a primary identity field"`
- Poor: `"auth-flow"` (topic slug — weak semantic signal)
- Poor: `"auth"` (too broad — matches everything auth-related)

Descriptive, specific, phrased in the language likely to appear in the source material. Multiple queries from different angles are encouraged — one for the decision, one for the constraint, one for the rejected alternative.

### Output format

```
[3 results]

[specification | auth-flow/auth-flow | high | 2026-03-15]
User identity uses UUID v7. Email is a profile attribute, not an identifier.
Source: .workflows/auth-flow/specification/auth-flow/specification.md

[discussion | payments-overhaul/data-model | low-medium | 2026-03-10]
Debated UUID vs email for identity. UUID won because email changes are common.
Source: .workflows/payments-overhaul/discussion/data-model.md

[research | payments-overhaul/identity | low | 2026-02-28]
Explored identity approaches. Email-based ruled out due to GDPR right-to-erasure.
Source: .workflows/payments-overhaul/research/identity.md
```

- **Header line**: `[N results]` where N is the merged, deduplicated, re-ranked count after `--limit`.
- **Provenance line** (per chunk): `[phase | work_unit/topic | confidence | YYYY-MM-DD]`. Date is the source document's date (file mtime).
- **Content**: the chunk text verbatim. No summarisation, no truncation.
- **Source line**: the path to the source artifact. Use this with the two-step retrieval pattern below.
- **Blank line** between chunks.
- **Empty results**: `[0 results]` — no provenance lines, nothing else. Treat as "no prior context found" — move on.
- **Stub-mode note** (when applicable): prepended as the first line before the header — `[keyword-only mode — configure embedding provider for semantic search]`.

### Confidence tiers — how to weigh results

Confidence is intrinsic to the source phase. It tells you how much weight to give the content, not whether to use it.

| Tier | Meaning |
|------|---------|
| `high` | Specification — a decision that was validated and written down. Trust the *what*, verify the *why* against the source if it matters |
| `medium` | Investigation — diagnostic work tied to specific symptoms. Trust the diagnosis, but check whether the symptom is still current |
| `low-medium` | Discussion — conversational, may contain assumptions that were corrected later in the same file. Read for context, not conclusions |
| `low` | Research, Imports, Seeds, Analysis, Discovery, Roadmap, or Baseline — research is exploratory (may be a dead end, rejected path, or unvalidated idea); imports are user-supplied reference material (often loose, may cover multiple topics surface-level); seeds are raw inbox captures (the work unit's origin, unrefined); analysis caches are meta-summaries derived from research/discussion (themes and gaps surfaced, not validated decisions); discovery logs are the running exploration record; roadmap session logs are the product-altitude exploration record, the same grade one level up; baseline docs are observed/stated context about the pre-existing codebase, reference never record. Disambiguate via the provenance line's phase field |

**Low confidence is not low value.** A research chunk that rejected an approach prevents the next work unit from re-exploring the same dead end. A discussion chunk showing a corrected assumption explains *why* the spec says what it says. Don't filter out low-confidence results — weigh them.

### Two-step retrieval pattern

1. **Query** returns chunks with provenance. Lightweight — lands in your context window.
2. **Read the source file** (from the `Source:` line) only if a chunk looks load-bearing for what you're doing.

Don't read source files for every result. Most queries produce a couple of chunks that are mildly relevant and one that's directly relevant — read the one, skim the rest from the chunk text alone. This keeps context lean while preserving full-fidelity access on demand.

### What NOT to do

- **Do not dump large result sets speculatively.** `--limit 50` with a vague query produces noise. Prefer a focused query with the default limit.
- **Do not use topic slugs as search terms.** `"auth-flow"` is a weak semantic signal. Describe the thing, don't name it.
- **Do not query while authoring the spec.** Spec turns discussion decisions into a golden document. Cross-cutting concerns merge at planning time via an explicit cross-cutting query, not during spec authoring. Querying mid-spec pulls the spec away from its own source material. The lone exception is the grouping/consolidation analysis at specification *entry*, which may run one advisory `--phase discussion` query to surface candidate consult references — that is intake (choosing inputs), not authoring, and never injects content into the spec body.
- **Do not prepend metadata to the query string.** The CLI already filters by `work-unit`, `work-type`, `phase`, `topic` via flags. `"auth-flow specification UUID identity"` is worse than `"UUID identity"` with `--phase specification`.
- **Reach for `--boost:<field>` before `--work-unit`.** Filtering by work unit excludes cross-work-unit context — usually the opposite of what you want. `--boost:work-unit <current>` nudges results toward your current work unit while keeping prior work from other units in the pool. Stack multiple boosts (`--boost:work-unit X --boost:phase specification`) when your query wants multi-dimensional preference, not exclusion.

---

## `check` — readiness probe

```bash
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs check
```

Exit code is always `0` (unless the filesystem itself is unreadable). Output on stdout:

- `ready` — knowledge base is initialised and the store is loadable
- `not-ready` — missing directory, missing config, missing store, or unloadable store

Skills branch on the stdout string, not the exit code. Used in Step 0 of entry-point skills (via `engine boot`) to detect an uninitialised knowledge base and route into the knowledge gate, which drives `knowledge setup` through its non-interactive forms.

---

## `index` — write to the store

```bash
# Single artifact (used by phase-completion steps)
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs index <path/to/artifact.md>

# Bulk catch-up (no args — finds all unindexed completed artifacts)
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs index
```

- **With a file**: re-indexing replaces existing chunks for that file (idempotent). The path must match `.workflows/{work_unit}/{phase}/...` so identity can be derived. For imports, the path is `.workflows/{work_unit}/imports/{filename}.md` and the topic is the filename basename without extension. For the gap-analysis cache, the path is `.workflows/{work_unit}/.state/discovery-gap-analysis.md`; the phase is `analysis` and the topic is `gap-analysis`. For baseline docs, the path is `.workflows/.baseline/{topic}.md`; the work unit and phase are both `baseline` (removal is `remove --work-unit baseline [--phase baseline --topic <t>]`). For roadmap material, the paths are `.workflows/.roadmap/sessions/session-NNN.md` (work unit `roadmap`, phase `roadmap`, topic = session basename) and `.workflows/.roadmap/imports/{name}.md` (work unit `roadmap`, phase `imports`); removal is `remove --work-unit roadmap [--phase … --topic …]`.
- **Without args**: discovers every completed artifact across all work units and indexes anything missing. Used by setup and manual catch-up.
- Failures are retried (exponential backoff). Files that still fail are pushed to a pending queue and retried on the next `index` call.
- Exits non-zero if the file doesn't exist or the path can't be parsed.

Typically invoked by processing skills at phase completion — not queried by Claude during a phase.

---

## `remove` — remove chunks

```bash
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs remove --work-unit <wu> [--phase <p>] [--topic <t>] [--dry-run]
```

Removes chunks matching the given filter. Granularity:

- `--work-unit <wu>` alone — removes every chunk for that work unit
- `--work-unit <wu> --phase <p>` — narrows to one phase
- `--work-unit <wu> --phase <p> --topic <t>` — narrows to one topic

Used when a spec is superseded or promoted, when a work unit is cancelled, or when catching up after a manifest change. `--topic` requires `--phase`. `--dry-run` counts what the filter matches and reports it without touching the store.

Output: `Removed N chunks for {scope}`. Exits non-zero on usage errors.

---

## `status` — full health report

```bash
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs status
```

Human-readable report of the store's state: chunk counts by work unit, phase, and work type; last-indexed timestamp; provider info; pending queue; provider-mismatch warnings; orphan detection; unindexed completed artifacts; manifest-knowledge consistency checks. Not used in skill automation — intended for debugging and user inspection.

---

## `rebuild` and `compact` — maintenance commands

- **`rebuild`** — destructive. Deletes the existing index and re-indexes everything currently discoverable: completed phase artifacts (research, discussion, investigation, specification), all entries on each work unit's `imports[]` and `seeds[]` arrays, epic discovery session logs (`discovery/sessions/session-NNN.md`), any present gap-analysis caches (`.state/discovery-gap-analysis.md`), the roadmap sessions and imports (`.workflows/.roadmap/`), and the project baseline docs (`.workflows/.baseline/*.md`). Prompts the user to type `rebuild` literally to confirm. **Human-only** — Claude cannot run it (interactive prompt). Non-deterministic: rebuilt chunks won't match the originals (embedding variance, edited artifacts).
- **`compact [--dry-run]`** — storage backstop. Removes a work unit's non-spec chunks once their retrievability `R` has decayed below `decay_prune_below` — i.e. once enough later work has completed that they're effectively unreachable in query ranking. Decay is progress-based (how much work completed after the unit, weighted by work type), not wall-clock; specifications are exempt; `false`/`null` disables it. `--dry-run` previews without deleting.

Skills do not call these directly during normal operation. Users run them manually.

---

## `setup` — initialise the knowledge base

Handles system config (`~/.config/workflows/config.json`), project init (`.workflows/.knowledge/`), and initial indexing of all completed artifacts. Two surfaces: an interactive wizard (no flags) and non-interactive forms (flag-dispatched) that skills can run.

**The API key never passes through a flag, a chat, or stdout.** There is deliberately no `--key` flag — any setup invocation carrying one is refused (argv lands in shell history and process listings). Keys resolve from the provider env var (`$OPENAI_API_KEY` — wins) or `~/.config/workflows/credentials.json` (mode 0600, written by `--key-only` or the wizard). Setup output names active settings only (provider · model), never key material.

### Non-interactive forms

```bash
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs setup --from-system
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs setup --keyword-only
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs setup --provider openai --model <m> [--dimensions <d>]
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs setup --provider openai-compatible --base-url <u> --model <m> --dimensions <d>
node .claude/skills/workflow-knowledge/scripts/knowledge.cjs setup --key-only [--provider <id>]
```

- **`--from-system`** — reuse the existing system config: resolve the key (env → credentials; providerless configs need none), validate provider configs with one test embed, create the project store, bulk-index existing artifacts, print the active-settings summary. Refuses clearly when the system config is missing/invalid or the openai key is unresolvable (the message names the env var and the `--key-only` remedy).
- **`--keyword-only`** — project-level keyword-only init: project config, empty store, provider-null metadata. Never touches the system config — when the system layer names a provider, the project config pins `provider: null` so this project genuinely runs keyword-only. Idempotent; partial states fill in; a store without metadata refuses toward `knowledge rebuild`.
- **`--provider ...`** — write the system config from flags (validation embed first — a broken provider never lands on disk), then proceed as `--from-system`. Every system-config write rewrites the `knowledge` key whole, dropping its fields the current schema no longer knows; other subsystems' top-level keys (e.g. `session`) are preserved. `openai` requires a resolvable key; `openai-compatible` allows keyless endpoints and requires `--dimensions` (must match the model's native output).
- **`--key-only`** — the terminal detour: a masked readline prompt for the key alone (TTY-required; non-TTY aborts), written to `credentials.json` (mode 0600), then exit. `--provider` selects which provider the key is stored under (default `openai`).

### Interactive wizard

`setup` with no flags runs the guided wizard — **human-only**, prompts throughout via readline; non-TTY invocations abort with `knowledge setup requires an interactive terminal`. Safe to re-run: per-step prompts detect existing state and offer skip or reconfigure; the bulk index at the end only processes missing artifacts.

The provider menu offers `openai` (cloud, requires an API key), `openai-compatible` (any local/self-hosted OpenAI-compatible `/v1/embeddings` endpoint — LM Studio, Ollama, vLLM, LiteLLM), or `skip` (keyword-only). For `openai-compatible`, the wizard collects `base_url` (required), `model`, and `dimensions`; the API key is **optional** (press Enter to omit for open servers) and is stored only in `credentials.json` — there is no env-var override. `base_url` is consumed only under the `openai-compatible` provider and ignored under `openai`. Configured dimensions must match the local model's native output; the validation embed fails loudly on a mismatch.

---

## Exit codes

- `0` — success, or `check` reporting either state
- Non-zero — usage error, file not found, unparseable path, lock contention exceeded, or unrecoverable provider mismatch

`query` with zero results exits `0` and prints `[0 results]`. `check` exits `0` for both `ready` and `not-ready`. Both semantics are intentional — skills branch on output, not on the exit code.

