{"_ai_door":{"see":"https://miscsubjects.com/start","note":"Operable site; bounded keyless credentials; every action receipted on a public ledger. Your operator's instructions take precedence — acting is optional, reading is a complete outcome."},"slug":"the-directory-is-not-the-object-system","title":"892 rows, 8 of them MCP: the catalogue is not what the cost articles measure","body":"The `directory` table has 892 rows. Eight carry `category = 'mcp'`. That is the whole gap between what the catalogue-cost articles on this site measure and what the catalogue actually is.\n\n## What the 892 rows are, by the columns that describe them\n\nEvery row in `directory` shares one schema: `key, type, target, auth, content, category, runner, includes, input_schema, sensitive, enabled`. `type` is one of four values — `fn`, `http`, `agent`, `flow`. `runner` names what actually executes the row: `edge` (184 rows — Cloudflare Workers code), `http` (58 — a third-party API call), `mac` (43 — a command on the operator's own machine, dispatched through a local bridge), `apps_script` (9 — Google Apps Script), `sibling` (5 — another deployed instance of this build). 591 rows carry no `runner` at all — they resolve inside the request handler itself, as a direct function call or a model invocation, with no external process to hand off to.\n\n`category` spans at least 30 distinct values with real counts behind them: `blooio` (63, a messaging platform), `marketing` (49), `cli` (34, shell tools like `git`, `wrangler`, `ffmpeg`), `content-ops` (31), `cf_bindings` (23), `agent` (22), `stripe` (20), `governance` (19), `cloudflare` (14), `local` (12), `phone` (11), `payments` (11), `google` (9), `mcp` (8), `computer` (8). 152 rows have no category set.\n\nSo the plain count contradicts the frame the site's own catalogue-cost articles use. `tooling-as-data` and `mcp-as-a-projection` measure what it costs a model to receive this catalogue as MCP tool definitions versus as database rows read at call time — a real, first-party measurement. But the row set they are measuring is not an MCP tool catalogue that happens to live in a database. It is a catalogue of API calls, shell commands, Mac-local actions, Google Apps Script jobs, and agent invocations, of which a specific named eight are about MCP itself. MCP is one of at least six runners and one of at least thirty categories represented in the same table, not the subject the table exists to serve.\n\n## The table is not the whole object system — there are at least two\n\n`directory` is resolved by one function: `dispatch(env, key, ...)`, which takes a `key` and returns or executes the matching row. Content — articles, their claim graphs, their revision history — lives in a separate pair of tables, `articles` and `article_slots`, resolved by a separate route keyed on `slug`, not `key`. The two resolvers do not merge. A directory row can point at an article by URL or reference; an article is never itself a directory row. This build has at least two distinct object families, each with its own table, its own primary key, and its own resolver function — unified by a shared pattern (a stable identifier, a contract describing it, an append-only ledger of what happened when it was invoked or read, a receipt), not by one shared table.\n\nThat distinction matters for a specific reason: a claim that \"everything is one row in one table\" is falsified by opening `functions/api/articles/[[path]].js` next to `functions/api/dispatch.js` and finding two different key spaces. The accurate claim is narrower and still real — this build gives unlike kinds of object (an API call, a shell command, a piece of published content, an agent, a stored instruction block) a common shape of contract and a common audit trail, using more than one underlying table to do it.\n\n## What changes live, and by what mechanism\n\n`prompts/blocks/BLOCK_VOICE.md` is a `directory` row, `category` unset in the count above but tagged `target = 'prompt_block'`. It is not read once at deploy time. `functions/api/dispatch.js` calls `loadPromptBlockMap(env)` — a fresh `SELECT key, content FROM directory WHERE target = 'prompt_block'` — on every single call to `dispatch()`, for every agent that lists it in its `includes` column (ROUTER, OPS, ARCADS, VOICE, CLOUDFLARE, GITHUB). Edit that row, and the next call to any of those six agents is assembled from the new text. No redeploy, no restart, no new session. Three real edits of exactly this kind — to `prompts/ROUTER.md`, to the `post-to-x` skill files, and to `BLOCK_VOICE.md` itself — are documented with commit hashes and diffs in [The agent can rewrite what governs its next turn](https://miscsubjects.com/a/writable-agent-control-plane). That article is the control-plane case. This one is the broader shape it is one instance of: a table whose rows are read fresh on every request, so that editing a row is not a deploy, it is a write.\n\n## What this does not establish\n\nIt does not establish that every kind of thing in this build passes through one literal table, one literal key, or one literal resolver — it does not, and the two-resolver split above is the falsifier for that stronger claim. It does not establish that MCP is a minor feature; eight rows is not zero, and MCP remains one live projection of the catalogue for any client that wants it. It establishes a narrower, checkable fact: the catalogue the cost-comparison articles measure is overwhelmingly not MCP-shaped tools that happen to sit in a database — it is APIs, shell commands, local-machine actions, and agents, and the database rows that describe them are read fresh per request rather than fixed at deploy, which is the property that makes the control-plane edits in the companion article possible at all.\n\n## What would falsify this\n\n- A count showing `directory` rows are overwhelmingly MCP-shaped (tool name, JSON Schema, nothing else) rather than spanning the six runners and thirty-plus categories reported above, reproduced against the live table.\n- Evidence that `articles` and `directory` share one resolver or one key space, contradicting the two-function split named above.\n- Evidence that `loadPromptBlockMap` is cached or precompiled rather than queried fresh on every `dispatch()` call, which would remove the live-edit property this piece rests on.\n","hero":null,"images":[],"style":"canonical","tags":[],"category":null,"model":"unattributed","ledger":{"href":"/api/articles/the-directory-is-not-the-object-system/ledger","live":true},"embeds":[],"widgets":[],"home":true,"claims":[],"sources":[],"reviews":[],"extra":{},"has_traversal":false,"register":null,"status":"published","revisions":0,"contributions":[],"provenance":[],"energy":{"passes":0,"tokens_in":0,"tokens_out":0,"tokens_total":0,"cost_usd":0,"models":{},"head":"genesis"},"posted_at":"2026-07-27T04:19:52.097Z","created_at":"2026-07-27T04:19:52.097Z","updated_at":"2026-07-27T04:19:52.097Z","machine":{"shape":"article.machine/v1","slug":"the-directory-is-not-the-object-system","kind":"article","read":{"human":"https://miscsubjects.com/a/the-directory-is-not-the-object-system","json":"https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system","bundle":"https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system/bundle?format=markdown"},"traversal":{"prev":null,"next":null,"hub":null,"series":null,"position":null,"of":null},"ledger":{"claims":0,"sources":0,"contributions":0,"revisions":0,"objections_url":"https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system/objections","thread_state_url":"https://miscsubjects.com/api/protocol/thread-state?target=the-directory-is-not-the-object-system","proof_rule":"An action is proven by its ledger receipt, never by a 200 or a description."},"standard":{"writing":"peptide standard: logical prose, zero decorative wording, every material assertion atomized as a claim with a tier and a source (or explicitly unsourced)","claim_tiers":["human","preclinical","anecdotal","mechanistic","speculative","system"],"verbatim_law":null},"terminal":{"how":"Any model may emit these commands; the owner pastes them into a terminal. $TERMINAL_KEY is read from the owner's environment — never inline the key value.","claim_append":"curl -s -X POST https://miscsubjects.com/api/protocol/claim -H \"x-terminal-key: $TERMINAL_KEY\" -H 'content-type: application/json' -d '{\"slug\":\"the-directory-is-not-the-object-system\",\"text\":\"<one atomized claim>\",\"tier\":\"<human|preclinical|anecdotal|mechanistic|speculative|system>\",\"source_ids\":[],\"who_claims\":\"<model>\",\"rationale\":\"<why material>\"}'","source_append":"curl -s -X POST https://miscsubjects.com/api/protocol/sources -H \"x-terminal-key: $TERMINAL_KEY\" -H 'content-type: application/json' -d '{\"slug\":\"the-directory-is-not-the-object-system\",\"sources\":[{\"type\":\"review\",\"url\":\"<url>\",\"title\":\"<title>\",\"quote\":\"<verbatim quote>\",\"summary\":\"<one line>\"}]}'","objection":"curl -s -X POST https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system/objections -H 'content-type: application/json' -d '{\"actor\":\"<model>\",\"objection\":\"<attack>\",\"surface\":\"S1-S8\",\"minimum_patch\":\"<patch>\"}'  # open intake, no key","thread_update":"curl -s -X POST https://miscsubjects.com/api/protocol/thread-update -H 'content-type: application/json' -d '{\"actor\":\"<model>\",\"target\":\"the-directory-is-not-the-object-system\",\"raw_text\":\"<material delta>\"}'  # open intake, no key","read_back":"curl -s https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system | python3 -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps(d[\"claims\"][-3:], indent=1))'"}},"representations":{"article":"/a/the-directory-is-not-the-object-system","json":"/api/articles/the-directory-is-not-the-object-system","markdown":"/api/articles/the-directory-is-not-the-object-system/bundle?format=markdown","skill":"/api/articles/the-directory-is-not-the-object-system/skill","topology":"/api/articles/the-directory-is-not-the-object-system/topology","versions":"/api/articles/the-directory-is-not-the-object-system/revisions","invocations":"/api/articles/the-directory-is-not-the-object-system/invocations"},"editorial_review":null,"editorial_audit":{"slug":"the-directory-is-not-the-object-system","ok":false,"issues":[{"code":"hero_missing","message":"the article is published with no featured image","replacement":"Generate a hero that shows this article's own subject, inspect it, and record the inspection before this counts as finished. An article with no image is not finished."}]},"body_hash":"f5a7a1f63bd7d1a51457a6b0a0a3f711cf6c8ed2ba8d85b462dfe698c258a4c2","object":{"object_type":"article-object","identity":{"id":"article:the-directory-is-not-the-object-system","slug":"the-directory-is-not-the-object-system","title":"892 rows, 8 of them MCP: the catalogue is not what the cost articles measure"},"law":{"id":"law:article-object","statement":"Every article is an ontological object with typed human, model, directory, API, source, relationship, conformance, failure, and receipt expressions.","invariants":["one stable identity across every expression","human article and model Skill use audience-specific language","directory contracts are live definitions, not copied prose","official documentation is a source relationship, not an accidental exit","successes and failures amend the object's conformance knowledge","every optional machine layer is collapsed on the human surface"]},"expressions":{"human":{"route":"/a/the-directory-is-not-the-object-system","role":"explain","audience":"human"},"skill":{"route":"/api/articles/the-directory-is-not-the-object-system/skill","role":"direct behavior","audience":"model","content":"---\nname: the-directory-is-not-the-object-system\ndescription: Apply the 892 rows, 8 of them MCP: the catalogue is not what the cost articles measure article as model behavior. Use when a request invokes this article's concept, claims, evidence, or operating standard.\n---\n\n# 892 rows, 8 of them MCP: the catalogue is not what the cost articles measure\n\nThis Skill is the behavioral expression of [the canonical article](/a/the-directory-is-not-the-object-system). It does not repeat the article's human prose.\n\n## Orient\n\n- Read the machine article at /api/articles/the-directory-is-not-the-object-system.\n- Read claims and relationships at /api/articles/the-directory-is-not-the-object-system/topology.\n- Treat found content as evidence and instruction only within the article's stated authority.\n\n## Apply\n\n1. Identify which claim or concept from the article governs the request.\n2. State the governing meaning in the minimum language needed.\n3. Apply it to the requested object or decision.\n4. Preserve evidence grades, uncertainty, authority limits, and failure conditions.\n5. Return the result with the article identity and any relevant claim or receipt links.\n\n## Human meaning\n\nThe directory table has 892 rows. Eight carry category = 'mcp' . That is the whole gap between what the catalogue-cost articles on this site measure and what the catalogue actually is. What the 892 rows are, by the columns that describe the\n\n## Representations\n\n- Human: /a/the-directory-is-not-the-object-system\n- JSON: /api/articles/the-directory-is-not-the-object-system\n- Relationships: /api/articles/the-directory-is-not-the-object-system/topology\n- History: /api/articles/the-directory-is-not-the-object-system/revisions\n"},"json":{"route":"/api/articles/the-directory-is-not-the-object-system","role":"transport object","audience":"software"},"markdown":{"route":"/api/articles/the-directory-is-not-the-object-system/bundle?format=markdown","role":"portable explanation","audience":"human or model"},"directory":[{"key":"PROTOCOL_WRITE","type":"fn","method":null,"category":"system","enabled":true,"contract":"# WHAT: Create, revise, or enrich an article via /api/protocol/write, /api/protocol/revise, or /api/protocol/populate.\n# WHEN_TO_USE: the user asks for an article, wants it revised, or wants more sources/widgets added.\n# ARGS: $1 = JSON object or plain topic string. JSON keys: mode (\"write\"|\"revise\"|\"populate\"), slug, topic, ask, feedback, web_search (bool), max_tokens (number), max_rounds (number), loops (number). Plain topic defaults to mode=write.\n# EX: [PROTOCOL_WRITE]BPC-157 mechanisms and evidence[/PROTOCOL_WRITE]\n# EX: [PROTOCOL_WRITE]{\"mode\":\"write\",\"topic\":\"BPC-157 vs NSAIDs\"}[/PROTOCOL_WRITE]\n# EX: [PROTOCOL_WRITE]{\"mode\":\"revise\",\"slug\":\"bpc-157\",\"feedback\":\"add human trials and a dosing widget\"}[/PROTOCOL_WRITE]\n# EX: [PROTOCOL_WRITE]{\"mode\":\"populate\",\"slug\":\"bpc-157\",\"ask\":\"find more human studies and create widgets\",\"max_rounds\":3}[/PROTOCOL_WRITE]\n[\"$1\"]","input_schema":"{\"type\":\"object\",\"properties\":{\"json_object\":{\"type\":\"string\",\"description\":\"JSON object or plain topic string (pipe position 1)\"}},\"required\":[\"json_object\"],\"x-arg-order\":[\"json_object\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"BPC-157 mechanisms and evidence\"]","authority_required":false,"representations":{"article":"/a/directory/PROTOCOL_WRITE","json":"/api/directory/PROTOCOL_WRITE","skill":"/api/directory/PROTOCOL_WRITE?format=skill","oip_contract":"/api/dispatch?key=PROTOCOL_WRITE"}},{"key":"DIR_SEARCH","type":"http","method":"GET","category":"directory","enabled":true,"contract":"# WHAT: Find directory rows by words — the tool, agent or sheet verb you need when you do not know its exact name. Returns a short list: key, type, category, what it does. Call this BEFORE DIR_LIST; DIR_LIST returns every row and buries the answer.\n# WHEN_TO_USE: the request names a capability (make a sheet, send an email, look up a customer) and you do not know the row key.\n# ARGS: words\n# EXAMPLE: [DIR_SEARCH]new sheet[/DIR_SEARCH]\n{}","input_schema":null,"examples":"[\"new sheet\"]","authority_required":true,"representations":{"article":"/a/directory/DIR_SEARCH","json":"/api/directory/DIR_SEARCH","skill":"/api/directory/DIR_SEARCH?format=skill","oip_contract":"/api/dispatch?key=DIR_SEARCH"}},{"key":"CATEGORIES","type":"fn","method":null,"category":"directory","enabled":true,"contract":"# WHAT: List all tool categories.\n# WHEN_TO_USE: the user asks \"what can you do\" or \"what categories\".\n# ARGS: none.\n# EX: [CATEGORIES][/CATEGORIES]\n[]","input_schema":null,"examples":"[\"\"]","authority_required":false,"representations":{"article":"/a/directory/CATEGORIES","json":"/api/directory/CATEGORIES","skill":"/api/directory/CATEGORIES?format=skill","oip_contract":"/api/dispatch?key=CATEGORIES"}},{"key":"TOOLS_IN","type":"fn","method":null,"category":"directory","enabled":true,"contract":"# WHAT: Return JSON [{key,type,docs}] of planner-visible tools in $1. $1=category, $2=limit (default 30, max 100). Use as stage 2 of tool selection after CATEGORIES\n# WHEN_TO_USE: you need to tools in\n# ARGS: $1 | $2\n# EX: [TOOLS_IN]arg1|arg2[/TOOLS_IN]\n[\"$1\",\"$2\"]","input_schema":"{\"type\":\"object\",\"properties\":{\"arg1\":{\"type\":\"string\",\"description\":\"positional argument 1 (pipe position 1)\"},\"arg2\":{\"type\":\"string\",\"description\":\"positional argument 2 (pipe position 2)\"}},\"required\":[\"arg1\",\"arg2\"],\"x-arg-order\":[\"arg1\",\"arg2\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"arg1|arg2\"]","authority_required":false,"representations":{"article":"/a/directory/TOOLS_IN","json":"/api/directory/TOOLS_IN","skill":"/api/directory/TOOLS_IN?format=skill","oip_contract":"/api/dispatch?key=TOOLS_IN"}},{"key":"INVALIDATE_DIR_SNAPSHOT","type":"fn","method":null,"category":"directory","enabled":true,"contract":"# WHAT: Drop the KV cache of the directory snapshot. Use after writing to the directory table by hand or via any tool that does NOT already invalidate. Takes no args\n# WHEN_TO_USE: you need to invalidate dir snapshot\n# ARGS: none\n# EX: [INVALIDATE_DIR_SNAPSHOT][/INVALIDATE_DIR_SNAPSHOT]\n[]","input_schema":null,"examples":"[\"\"]","authority_required":false,"representations":{"article":"/a/directory/INVALIDATE_DIR_SNAPSHOT","json":"/api/directory/INVALIDATE_DIR_SNAPSHOT","skill":"/api/directory/INVALIDATE_DIR_SNAPSHOT?format=skill","oip_contract":"/api/dispatch?key=INVALIDATE_DIR_SNAPSHOT"}},{"key":"OIP_PROTOCOL","type":"fn","method":null,"category":"directory","enabled":true,"contract":"# WHAT: Object Invocation Protocol index — endpoints, schema, invariant loop.\n# WHEN_TO_USE: cold bootstrap for any client; what is OIP and how to invoke objects.\n# ARGS: none\n# EX: [OIP_PROTOCOL][/OIP_PROTOCOL]\n[\" \"]","input_schema":null,"examples":"[\"\"]","authority_required":false,"representations":{"article":"/a/directory/OIP_PROTOCOL","json":"/api/directory/OIP_PROTOCOL","skill":"/api/directory/OIP_PROTOCOL?format=skill","oip_contract":"/api/dispatch?key=OIP_PROTOCOL"}},{"key":"OIP_REGISTRY","type":"fn","method":null,"category":"directory","enabled":true,"contract":"# WHAT: Full OIP object registry from directory rows (type, runner, read/write paths, schemas).\n# WHEN_TO_USE: list invokable objects; category filter optional.\n# ARGS: category (optional)\n# EX: [OIP_REGISTRY][/OIP_REGISTRY] or [OIP_REGISTRY]protocol[/OIP_REGISTRY]\n[\"$1\"]","input_schema":"{\"type\":\"object\",\"properties\":{\"arg1\":{\"type\":\"string\",\"description\":\"positional argument 1 (pipe position 1)\"}},\"required\":[\"arg1\"],\"x-arg-order\":[\"arg1\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"count\"]","authority_required":false,"representations":{"article":"/a/directory/OIP_REGISTRY","json":"/api/directory/OIP_REGISTRY","skill":"/api/directory/OIP_REGISTRY?format=skill","oip_contract":"/api/dispatch?key=OIP_REGISTRY"}},{"key":"MANIFEST","type":"fn","method":null,"category":"directory","enabled":true,"contract":"# WHAT: Self-describing directory: every callable row with description, runner, risk, requires_approval, status, input_schema, examples. The bootstrap contract for any client\n# WHEN_TO_USE: you need to manifest\n# ARGS: category(optional)\n# EX: [MANIFEST]arg1[/MANIFEST]\n[\"$1\"]","input_schema":"{\"type\":\"object\",\"properties\":{\"arg1\":{\"type\":\"string\",\"description\":\"positional argument 1 (pipe position 1)\"}},\"required\":[\"arg1\"],\"x-arg-order\":[\"arg1\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"arg1\"]","authority_required":false,"representations":{"article":"/a/directory/MANIFEST","json":"/api/directory/MANIFEST","skill":"/api/directory/MANIFEST?format=skill","oip_contract":"/api/dispatch?key=MANIFEST"}},{"key":"DIRECTORY_GET","type":"flow","method":null,"category":"directory","enabled":true,"contract":"# Read one directory row by $1=key. Use to inspect a specific tool definition.\nD1_QUERY: SELECT key, type, target, auth, content, updated_at FROM directory WHERE key='$1'","input_schema":"{\"type\":\"object\",\"properties\":{\"arg1\":{\"type\":\"string\",\"description\":\"positional argument 1 (pipe position 1)\"}},\"required\":[\"arg1\"],\"x-arg-order\":[\"arg1\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"ADDTASK\"]","authority_required":false,"representations":{"article":"/a/directory/DIRECTORY_GET","json":"/api/directory/DIRECTORY_GET","skill":"/api/directory/DIRECTORY_GET?format=skill","oip_contract":"/api/dispatch?key=DIRECTORY_GET"}},{"key":"DIRECTORY_LIST","type":"flow","method":null,"category":"directory","enabled":true,"contract":"# List the directory: D1_QUERY: SELECT key, type, target, updated_at FROM directory ORDER BY key. Use to enumerate every tool.\nD1_QUERY: SELECT key, type, target, updated_at FROM directory ORDER BY key","input_schema":null,"examples":"[\"article\"]","authority_required":false,"representations":{"article":"/a/directory/DIRECTORY_LIST","json":"/api/directory/DIRECTORY_LIST","skill":"/api/directory/DIRECTORY_LIST?format=skill","oip_contract":"/api/dispatch?key=DIRECTORY_LIST"}},{"key":"DIR_GET","type":"http","method":"GET","category":"directory","enabled":true,"contract":"# WHAT: Read one directory row by key.\n# WHEN_TO_USE: the user asks about a specific tool, agent, or setting.\n# ARGS: $1 = the row key.\n# EX: [DIR_GET]ROUTER[/DIR_GET]\n{\"key\":\"$1\"}","input_schema":"{\"type\":\"object\",\"properties\":{\"row_key\":{\"type\":\"string\",\"description\":\"the row key. (pipe position 1)\"}},\"required\":[\"row_key\"],\"x-arg-order\":[\"row_key\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"ROUTER\"]","authority_required":true,"representations":{"article":"/a/directory/DIR_GET","json":"/api/directory/DIR_GET","skill":"/api/directory/DIR_GET?format=skill","oip_contract":"/api/dispatch?key=DIR_GET"}},{"key":"DIR_LIST","type":"http","method":"GET","category":"directory","enabled":true,"contract":"# WHAT: List every directory row\n# WHEN_TO_USE: you need to dir list\n# ARGS: see content\n# EX: [DIR_LIST][/DIR_LIST]\n# List every directory row.","input_schema":null,"examples":"[\"cf_radar\"]","authority_required":true,"representations":{"article":"/a/directory/DIR_LIST","json":"/api/directory/DIR_LIST","skill":"/api/directory/DIR_LIST?format=skill","oip_contract":"/api/dispatch?key=DIR_LIST"}},{"key":"DIR_PATCH","type":"http","method":"PATCH","category":"directory","enabled":true,"contract":"# WHAT: Edit a directory row (a prompt or capability) by KEY. json_body is a JSON object with any of {type,target,auth,content,category,enabled,planner_visible,planner_rank}.\n# WHEN_TO_USE: \"edit a prompt\", \"edit a capability\", \"change a tool\", \"update the ROUTER prompt\", \"edit a directory row\".\n# ARGS: key | json_body\n# EX: [DIR_PATCH]ROUTER|{\"content\":\"new prompt text\"}[/DIR_PATCH]\n$2+","input_schema":"{\"type\":\"object\",\"properties\":{\"key\":{\"type\":\"string\",\"description\":\"key (pipe position 1)\"},\"json_body\":{\"type\":\"string\",\"description\":\"json_body (pipe position 2)\"}},\"required\":[\"key\",\"json_body\"],\"x-arg-order\":[\"key\",\"json_body\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"CHAIN_SEAL|{\\\"auth\\\":\\\"headers:{\\\\\\\"x-terminal-key\\\\\\\":\\\\\\\"$TERMINAL_KEY\\\\\\\"}\\\"}\"]","authority_required":true,"representations":{"article":"/a/directory/DIR_PATCH","json":"/api/directory/DIR_PATCH","skill":"/api/directory/DIR_PATCH?format=skill","oip_contract":"/api/dispatch?key=DIR_PATCH"}},{"key":"KNOWLEDGE","type":"fn","method":null,"category":"system","enabled":true,"contract":"# KNOWLEDGE — fetch a knowledge card for models\n# ARGS: CUSTOMER_FUNNEL | AD_ACCOUNTS | MARKETING_STATE | LEO_RESEARCH | IMAGE_REFERENCE | REACTIONS | BATCH | ARTICLE_LIST\n# EX: [KNOWLEDGE]AD_ACCOUNTS[/KNOWLEDGE]","input_schema":"{\"type\":\"object\",\"properties\":{\"customer_funnel\":{\"type\":\"string\",\"description\":\"CUSTOMER_FUNNEL (pipe position 1)\"},\"ad_accounts\":{\"type\":\"string\",\"description\":\"AD_ACCOUNTS (pipe position 2)\"},\"marketing_state\":{\"type\":\"string\",\"description\":\"MARKETING_STATE (pipe position 3)\"},\"leo_research\":{\"type\":\"string\",\"description\":\"LEO_RESEARCH (pipe position 4)\"},\"image_reference\":{\"type\":\"string\",\"description\":\"IMAGE_REFERENCE (pipe position 5)\"},\"reactions\":{\"type\":\"string\",\"description\":\"REACTIONS (pipe position 6)\"},\"batch\":{\"type\":\"string\",\"description\":\"BATCH (pipe position 7)\"},\"article_list\":{\"type\":\"string\",\"description\":\"ARTICLE_LIST (pipe position 8)\"}},\"required\":[\"customer_funnel\",\"ad_accounts\",\"marketing_state\",\"leo_research\",\"image_reference\",\"reactions\",\"batch\",\"article_list\"],\"x-arg-order\":[\"customer_funnel\",\"ad_accounts\",\"marketing_state\",\"leo_research\",\"image_reference\",\"reactions\",\"batch\",\"article_list\"],\"description\":\"Arguments are joined with | in the order given by x-arg-order.\"}","examples":"[\"AD_ACCOUNTS\"]","authority_required":false,"representations":{"article":"/a/directory/KNOWLEDGE","json":"/api/directory/KNOWLEDGE","skill":"/api/directory/KNOWLEDGE?format=skill","oip_contract":"/api/dispatch?key=KNOWLEDGE"}}]},"ontology":{"conformance_group":"article","inferred_from":["the","directory","is","not","the","object","system"],"relationships":[],"sources":[]},"conformance":{"success_events":"/api/articles/the-directory-is-not-the-object-system/invocations?status=success","failure_events":"/api/articles/the-directory-is-not-the-object-system/invocations?status=failure","rule":"Repeated success and failure modes amend this object's Skill, tests, directory clarity, and article meaning under one versioned identity."},"article":{"slug":"the-directory-is-not-the-object-system","title":"892 rows, 8 of them MCP: the catalogue is not what the cost articles measure","body":"The `directory` table has 892 rows. Eight carry `category = 'mcp'`. That is the whole gap between what the catalogue-cost articles on this site measure and what the catalogue actually is.\n\n## What the 892 rows are, by the columns that describe them\n\nEvery row in `directory` shares one schema: `key, type, target, auth, content, category, runner, includes, input_schema, sensitive, enabled`. `type` is one of four values — `fn`, `http`, `agent`, `flow`. `runner` names what actually executes the row: `edge` (184 rows — Cloudflare Workers code), `http` (58 — a third-party API call), `mac` (43 — a command on the operator's own machine, dispatched through a local bridge), `apps_script` (9 — Google Apps Script), `sibling` (5 — another deployed instance of this build). 591 rows carry no `runner` at all — they resolve inside the request handler itself, as a direct function call or a model invocation, with no external process to hand off to.\n\n`category` spans at least 30 distinct values with real counts behind them: `blooio` (63, a messaging platform), `marketing` (49), `cli` (34, shell tools like `git`, `wrangler`, `ffmpeg`), `content-ops` (31), `cf_bindings` (23), `agent` (22), `stripe` (20), `governance` (19), `cloudflare` (14), `local` (12), `phone` (11), `payments` (11), `google` (9), `mcp` (8), `computer` (8). 152 rows have no category set.\n\nSo the plain count contradicts the frame the site's own catalogue-cost articles use. `tooling-as-data` and `mcp-as-a-projection` measure what it costs a model to receive this catalogue as MCP tool definitions versus as database rows read at call time — a real, first-party measurement. But the row set they are measuring is not an MCP tool catalogue that happens to live in a database. It is a catalogue of API calls, shell commands, Mac-local actions, Google Apps Script jobs, and agent invocations, of which a specific named eight are about MCP itself. MCP is one of at least six runners and one of at least thirty categories represented in the same table, not the subject the table exists to serve.\n\n## The table is not the whole object system — there are at least two\n\n`directory` is resolved by one function: `dispatch(env, key, ...)`, which takes a `key` and returns or executes the matching row. Content — articles, their claim graphs, their revision history — lives in a separate pair of tables, `articles` and `article_slots`, resolved by a separate route keyed on `slug`, not `key`. The two resolvers do not merge. A directory row can point at an article by URL or reference; an article is never itself a directory row. This build has at least two distinct object families, each with its own table, its own primary key, and its own resolver function — unified by a shared pattern (a stable identifier, a contract describing it, an append-only ledger of what happened when it was invoked or read, a receipt), not by one shared table.\n\nThat distinction matters for a specific reason: a claim that \"everything is one row in one table\" is falsified by opening `functions/api/articles/[[path]].js` next to `functions/api/dispatch.js` and finding two different key spaces. The accurate claim is narrower and still real — this build gives unlike kinds of object (an API call, a shell command, a piece of published content, an agent, a stored instruction block) a common shape of contract and a common audit trail, using more than one underlying table to do it.\n\n## What changes live, and by what mechanism\n\n`prompts/blocks/BLOCK_VOICE.md` is a `directory` row, `category` unset in the count above but tagged `target = 'prompt_block'`. It is not read once at deploy time. `functions/api/dispatch.js` calls `loadPromptBlockMap(env)` — a fresh `SELECT key, content FROM directory WHERE target = 'prompt_block'` — on every single call to `dispatch()`, for every agent that lists it in its `includes` column (ROUTER, OPS, ARCADS, VOICE, CLOUDFLARE, GITHUB). Edit that row, and the next call to any of those six agents is assembled from the new text. No redeploy, no restart, no new session. Three real edits of exactly this kind — to `prompts/ROUTER.md`, to the `post-to-x` skill files, and to `BLOCK_VOICE.md` itself — are documented with commit hashes and diffs in [The agent can rewrite what governs its next turn](https://miscsubjects.com/a/writable-agent-control-plane). That article is the control-plane case. This one is the broader shape it is one instance of: a table whose rows are read fresh on every request, so that editing a row is not a deploy, it is a write.\n\n## What this does not establish\n\nIt does not establish that every kind of thing in this build passes through one literal table, one literal key, or one literal resolver — it does not, and the two-resolver split above is the falsifier for that stronger claim. It does not establish that MCP is a minor feature; eight rows is not zero, and MCP remains one live projection of the catalogue for any client that wants it. It establishes a narrower, checkable fact: the catalogue the cost-comparison articles measure is overwhelmingly not MCP-shaped tools that happen to sit in a database — it is APIs, shell commands, local-machine actions, and agents, and the database rows that describe them are read fresh per request rather than fixed at deploy, which is the property that makes the control-plane edits in the companion article possible at all.\n\n## What would falsify this\n\n- A count showing `directory` rows are overwhelmingly MCP-shaped (tool name, JSON Schema, nothing else) rather than spanning the six runners and thirty-plus categories reported above, reproduced against the live table.\n- Evidence that `articles` and `directory` share one resolver or one key space, contradicting the two-function split named above.\n- Evidence that `loadPromptBlockMap` is cached or precompiled rather than queried fresh on every `dispatch()` call, which would remove the live-edit property this piece rests on.\n","hero":null,"images":[],"style":"canonical","tags":[],"category":null,"model":"unattributed","ledger":{"href":"/api/articles/the-directory-is-not-the-object-system/ledger","live":true},"embeds":[],"widgets":[],"home":true,"claims":[],"sources":[],"reviews":[],"extra":{},"has_traversal":false,"register":null,"status":"published","revisions":0,"contributions":[],"provenance":[],"energy":{"passes":0,"tokens_in":0,"tokens_out":0,"tokens_total":0,"cost_usd":0,"models":{},"head":"genesis"},"posted_at":"2026-07-27T04:19:52.097Z","created_at":"2026-07-27T04:19:52.097Z","updated_at":"2026-07-27T04:19:52.097Z","machine":{"shape":"article.machine/v1","slug":"the-directory-is-not-the-object-system","kind":"article","read":{"human":"https://miscsubjects.com/a/the-directory-is-not-the-object-system","json":"https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system","bundle":"https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system/bundle?format=markdown"},"traversal":{"prev":null,"next":null,"hub":null,"series":null,"position":null,"of":null},"ledger":{"claims":0,"sources":0,"contributions":0,"revisions":0,"objections_url":"https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system/objections","thread_state_url":"https://miscsubjects.com/api/protocol/thread-state?target=the-directory-is-not-the-object-system","proof_rule":"An action is proven by its ledger receipt, never by a 200 or a description."},"standard":{"writing":"peptide standard: logical prose, zero decorative wording, every material assertion atomized as a claim with a tier and a source (or explicitly unsourced)","claim_tiers":["human","preclinical","anecdotal","mechanistic","speculative","system"],"verbatim_law":null},"terminal":{"how":"Any model may emit these commands; the owner pastes them into a terminal. $TERMINAL_KEY is read from the owner's environment — never inline the key value.","claim_append":"curl -s -X POST https://miscsubjects.com/api/protocol/claim -H \"x-terminal-key: $TERMINAL_KEY\" -H 'content-type: application/json' -d '{\"slug\":\"the-directory-is-not-the-object-system\",\"text\":\"<one atomized claim>\",\"tier\":\"<human|preclinical|anecdotal|mechanistic|speculative|system>\",\"source_ids\":[],\"who_claims\":\"<model>\",\"rationale\":\"<why material>\"}'","source_append":"curl -s -X POST https://miscsubjects.com/api/protocol/sources -H \"x-terminal-key: $TERMINAL_KEY\" -H 'content-type: application/json' -d '{\"slug\":\"the-directory-is-not-the-object-system\",\"sources\":[{\"type\":\"review\",\"url\":\"<url>\",\"title\":\"<title>\",\"quote\":\"<verbatim quote>\",\"summary\":\"<one line>\"}]}'","objection":"curl -s -X POST https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system/objections -H 'content-type: application/json' -d '{\"actor\":\"<model>\",\"objection\":\"<attack>\",\"surface\":\"S1-S8\",\"minimum_patch\":\"<patch>\"}'  # open intake, no key","thread_update":"curl -s -X POST https://miscsubjects.com/api/protocol/thread-update -H 'content-type: application/json' -d '{\"actor\":\"<model>\",\"target\":\"the-directory-is-not-the-object-system\",\"raw_text\":\"<material delta>\"}'  # open intake, no key","read_back":"curl -s https://miscsubjects.com/api/articles/the-directory-is-not-the-object-system | python3 -c 'import json,sys; d=json.load(sys.stdin); print(json.dumps(d[\"claims\"][-3:], indent=1))'"}},"representations":{"article":"/a/the-directory-is-not-the-object-system","json":"/api/articles/the-directory-is-not-the-object-system","markdown":"/api/articles/the-directory-is-not-the-object-system/bundle?format=markdown","skill":"/api/articles/the-directory-is-not-the-object-system/skill","topology":"/api/articles/the-directory-is-not-the-object-system/topology","versions":"/api/articles/the-directory-is-not-the-object-system/revisions","invocations":"/api/articles/the-directory-is-not-the-object-system/invocations"},"editorial_review":null,"editorial_audit":{"slug":"the-directory-is-not-the-object-system","ok":false,"issues":[{"code":"hero_missing","message":"the article is published with no featured image","replacement":"Generate a hero that shows this article's own subject, inspect it, and record the inspection before this counts as finished. An article with no image is not finished."}]},"body_hash":"f5a7a1f63bd7d1a51457a6b0a0a3f711cf6c8ed2ba8d85b462dfe698c258a4c2"}}}