# Anti-patterns — full table

(Core inlines the top offenders. This is the complete reference table.)

| Task                                            | Don't                                                                              | Do                                                                                |
| ----------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| List a markdown-heavy dir                       | `Bash: ls specs/`                                                                  | `exec("ls -A specs/")`                                                            |
| Find all SPEC.md files                          | `Glob: **/SPEC.md`                                                                 | `exec("find specs -name SPEC.md")`                                                |
| Find the most relevant page for a query         | `Grep: "pattern" *.md` then read three files                                       | `search({ query: "pattern" })` (ranked: title + body BM25 + recency)              |
| Find every literal occurrence of a phrase       | `Grep: "pattern" *.md`                                                             | `exec("grep -rn pattern <dir>")` (literal, grouped by file, with frontmatter)     |
| Read an individual doc                          | `Read: specs/foo/SPEC.md`                                                          | `exec("cat specs/foo/SPEC.md")`                                                   |
| Explore a markdown-heavy dir                    | `Agent(Explore): "..."`                                                            | Do `exec`-based exploration yourself                                              |
| Answer a direct business question from the corpus | answer in chat and move on (it evaporates), OR save every answer as a new doc      | answer with citations; *offer* to persist only when durable + multi-doc + not already covered (`references/corpus-qa.md`) |
| Wait for the server to tell you to open preview | Skip the session-start preview open and wait for the `attach-preview-once` hint    | Open the preview browser at session start; the hint is a fallback when you didn't |
| Ignore the attach hint                          | Skip the `warning: { action: "attach-preview-once" }` hint in write-tool responses | Open the preview when the hint fires (`preview_start`, or `preview_url`); otherwise do nothing |
| Make the Claude Code Desktop preview work       | Read / diagnose / edit `.claude/launch.json` (host-managed config)                 | Call `preview_start("open-knowledge-ui")` and nothing else; the OK lock-collision proxy bridges any port mismatch transparently |
| Open a doc/folder/skill in the app from a CLI  | Print the `previewUrl` / `openknowledge://` string for the user to click           | Run `ok open <name>` (doc or folder, auto-detected; `--skill <name>` for a skill) — deep-links into OK Desktop, browser fallback |
| Reference another doc                           | `` `[text](./page.md)` `` (backticked) or HTML `<a>`                               | `[text](./page.md)` (raw markdown)                                                |
| Embed an image                                  | `<img src="...">` (HTML), a `localhost:<port>` / `preview_url` server URL, or hot-linked external URL | Fetch + save locally + doc-relative `![meaningful alt](./assets/images/path)`     |
| Write a factual claim in a KB doc               | plausible prose without citation, OR inline `[source](https://URL)`                | `ingest` the source first, then cite the local path per Grounding                  |
| Cite a web source you just fetched              | inline `[source](https://...)` because YOU did the fetch (not the user)            | `ingest` it — agent-initiated fetches are not exempt from the closed-loop rule    |
| Finish a turn that changed KB content           | move on without checking for a log                                                 | check for a `log.md` and follow its contract per Log discipline                    |
| Add an image                                    | empty alt `![](./x.png)` or generic alt `![image](./x)`                            | meaningful alt + source caption below                                             |
| Catalog folder contents                         | create `INDEX.md` hub file                                                         | `edit({ folder: { path, frontmatter } })` writes `<folder>/.ok/frontmatter.yml` |
| Write a doc in an unfamiliar folder             | go straight to `write` with hand-authored markdown                        | `exec("ls -A <folder>")` first — read the folder description + `templates_available` before writing |
| Land in an existing repo without orienting      | go straight to `write` when no folder frontmatter / templates exist       | invoke `workflow({ kind: 'discover' })` once for the project — extracts conventions from siblings, sets folder frontmatter + templates, activates the link graph |
| Author a doc when a matching template exists    | `write({ document: { path, content: "..." } })` from scratch                                 | `write({ document: { path, template } })` — templates carry the folder's frontmatter + body discipline |
| Change a doc's title / tags                     | `edit({ document: { path, find, replace } })` to swap the YAML (rejected — HTTP 400 frontmatter-intersect) | `edit({ document: { path, frontmatter } })` for metadata; `write({ document: { path, content, frontmatter, position: "replace" } })` for full rewrites |
| Repeat the same frontmatter on sibling docs     | hand-set identical `tags` / `title` prefix on every new file                       | `write({ template })` once — new docs start from the template |
| Re-derive the same body skeleton repeatedly     | copy-paste the structure from a sibling each time                                  | `write({ template })` once, then pick from `templates_available` thereafter |
| Scaffold a new folder for a doc category        | set folder frontmatter and stop there                                     | pair `edit({ folder })` with `write({ template })` in the same turn |
| Delete a markdown doc                           | `Bash: rm` / `unlink` / native deletion on in-scope `.md`                          | `delete({ document })` — `checkpoint()` first if rollback may be needed |
| Fork a skill and expect no stomp                | Edit installed SKILL.md                                                            | `npx skills remove` before CLI upgrade                                            |
