{"slug": "org-rules-and-project-rules-need-different-homes", "title": "Org rules and project rules need different homes", "summary": "Keystone, a new project-harnessing tool, introduces a file-tree-based boundary to separate project-specific rules from organization-wide policies, preventing the \"Level 3\" organizational rules from collapsing into \"Level 2\" project rules. The system splits a repository's harness into a project-owned `corpus/` and `guides/` directory, and a separate `policies/` directory where each policy is installed into its own namespace and locked against local edits. This structural separation, enforced by the installer and a per-file hash lockfile, ensures that a policy's rules remain distinct from a team's local project configurations.", "body_md": "I have three repos that all want the same TODO hygiene rules. The first one got them after a review where I caught a `TODO: fix this`\n\nwith no owner. The second one picked them up by copying `CLAUDE.md`\n\nfrom the first. The third one is where I noticed I was opening the second project's `CLAUDE.md`\n\nto copy it a third time.\n\nThat is the exact failure Level 3 is supposed to prevent.\n\nThe taxonomy is easy enough to write down. Level 2 is the project harness; Level 3 is the organization harness. The hard part is the split inside the repo. If both kinds of rule end up in the same files, the boundary collapses every time someone edits anything. Keystone draws the line in the file tree itself.\n\nA Keystone harness has two halves.\n\nThe project half is `harness/corpus/`\n\nand `harness/guides/`\n\n. The team owns it. They edit it freely. It is the reasoning and the rules that describe *this codebase*: which test runner, which lint config, which idioms, which domain constraints.\n\nThe org half is `harness/policies/`\n\n. Each policy is its own namespace, owned by whoever published it. Policies arrive through `keystone init --policy <ref>`\n\nand update through `keystone policy update <name>`\n\n. Local edits inside a policy namespace block the next update unless `--force`\n\nis passed.\n\n```\nharness/\n├── corpus/              # project reasoning (Level 2)\n├── guides/              # project rules (Level 2)\n├── policies/            # Level 3\n│   ├── universal/       # ships with the binary\n│   └── tacoda/          # installed via --policy\n├── sensors/\n├── adapters/\n├── learning/\n└── archive/\n```\n\nTwo things make the boundary stick. First, every policy writes only inside its own subtree; the installer enforces that. Second, the lockfile records per-file hashes, so the update flow can tell whether a policy file has been edited locally. The structure is what keeps a Level 3 rule from quietly becoming a Level 2 rule.\n\nSensors deliberately do not live inside a policy. Sensors describe project tooling (lint, type-check, test). A policy can declare *what* must be checked; the project decides *how*. That is the right cut: principles distribute, commands do not.\n\nThe shape is easier to see in a real one. [tacoda-policy](https://github.com/tacoda/tacoda-policy) is the example repo I use to test the layer end-to-end. It carries my personal preferences around documentation and TODOs, and it installs as a policy named `tacoda`\n\n.\n\nThe repo is small on purpose:\n\n```\ntacoda-policy/\n├── keystone-policy.yaml\n├── README.md\n└── policy/\n    └── harness/policies/tacoda/\n        ├── corpus/\n        │   ├── documentation.md\n        │   └── todos.md\n        └── guides/\n            ├── documentation.md\n            └── todos.md\n```\n\nThe manifest is short. Name, version, description:\n\n```\nname: tacoda\nversion: 0.1.0\ndescription: |\n  Example policy for tacoda projects. Layers on top of the keystone universal\n  baseline with personal/team preferences around documentation conciseness\n  and TODO hygiene.\n```\n\nThe `policy/`\n\ndirectory mirrors how the content lands inside a consumer's harness. The installer rejects anything outside the policy's own namespace (`policy/harness/policies/tacoda/`\n\n), so this repo cannot accidentally drop files into a consumer's project tree. That guarantee is what makes \"trust this policy enough to install it\" a smaller ask than \"trust this script enough to run it.\"\n\n`--policy`\n\ndoes to your project\nRun `keystone init`\n\nin a fresh repo with the policy flag:\n\n```\nkeystone init --policy git+https://github.com/tacoda/tacoda-policy.git#v0.1.0\n```\n\nYou get the full harness, plus the policy dropped into its namespace:\n\n```\nharness/policies/tacoda/\n├── corpus/\n│   ├── documentation.md\n│   └── todos.md\n└── guides/\n    ├── documentation.md\n    └── todos.md\n```\n\nSame shape as the project layer, scoped to `tacoda/`\n\n. Two pairs. Each pair is a corpus file (the reasoning) and a guide file (the rules). Guides are ambient: the agent loads them every turn. Corpus is on-demand: the agent reaches a corpus file by following the forward-link in the paired guide when it needs the *why*.\n\nHere is the documentation guide that lands in the project, trimmed to the golden rules:\n\n```\n## GOLDEN RULES\n\n- **Apply the Hemingway test to every sentence.** Each sentence must change\n  what the reader does. If a sentence can be deleted without losing\n  instruction or context, delete it.\n- **Default to no comment.** Add one only when the *why* is non-obvious.\n- **Lead with the why.** Documentation explains motivation and non-obvious\n  behavior. Well-named identifiers explain *what*; comments explain *why*.\n```\n\nThe corpus file holds the long-form reasoning: where the Hemingway test comes from, what gets cut, what stays, why bad docs are worse than no docs. The agent only pays for those tokens when it reaches for them.\n\nThat split matters for the same reason it matters at the project layer. Guides are the cheapest tokens you can spend; corpus is on-demand context that earns its keep when the agent has to make a judgment call.\n\nA policy is a git repo with two things at its root. The manifest:\n\n```\nname: my-org\nversion: 0.1.0\ndescription: |\n  Org-wide engineering standards: vendor list, license rules, release gates.\n```\n\nAnd a `policy/`\n\ndirectory that mirrors the consumer layout:\n\n```\nmy-policy-repo/\n├── keystone-policy.yaml\n├── README.md\n└── policy/\n    └── harness/policies/my-org/\n        ├── corpus/\n        │   ├── vendors.md\n        │   └── licensing.md\n        └── guides/\n            ├── vendors.md\n            └── licensing.md\n```\n\nThe `name`\n\nin the manifest is the namespace. Every file under `policy/`\n\nmust live inside `policy/harness/policies/my-org/`\n\n; anything outside is rejected at install time. The README and the manifest sit at the repo root for humans, not consumers, and the installer ignores them.\n\nA guide file in the policy looks the same as a project guide. Short, ambient, full of rules. The bottom line points at the corpus:\n\n```\n# Vendors — rules\n\nThe rules from [`corpus/vendors.md`](../corpus/vendors.md).\nLoaded ambient; enforced by the [drift sensor](../../../../sensors/drift.md).\n\n## GOLDEN RULES\n\n- Approved cloud vendors: AWS, GCP, Cloudflare. Anything else needs review.\n- Storage of customer data outside the approved list is a release blocker.\n\n---\n\nTraces to: [`corpus/vendors.md`](../corpus/vendors.md).\n```\n\nThe corpus file is where the reasoning lives: why this vendor list, what the review process looks like, the contractual constraints that drove it. Same shape as project corpus. Same load behavior.\n\nThe interesting part of Level 3 is not the install. It is what happens the second time.\n\nEach installed policy is pinned in `harness/.keystone.lock`\n\n:\n\n```\npolicies:\n  tacoda:\n    source_ref: \"git+https://github.com/tacoda/tacoda-policy.git#v0.1.0\"\n    resolved_sha: \"abc1234...\"\n    policy_version: \"0.1.0\"\n    keystone_version: \"0.9.0\"\n    files:\n      \"harness/policies/tacoda/guides/documentation.md\": \"sha256:...\"\n      \"harness/policies/tacoda/guides/todos.md\": \"sha256:...\"\n      \"harness/policies/tacoda/corpus/documentation.md\": \"sha256:...\"\n      \"harness/policies/tacoda/corpus/todos.md\": \"sha256:...\"\n```\n\nBump to a new ref:\n\n```\nkeystone policy update tacoda '#v0.2.0'\n```\n\nOr re-resolve the current ref (useful when tracking `#main`\n\n):\n\n```\nkeystone policy update tacoda\n```\n\nThe hashes are the safety net. If a file inside the policy namespace has been edited locally since install, the update refuses to overwrite it. You either revert the local edit or pass `--force`\n\nand accept the loss. That refusal is what makes \"policies are not project-authored\" a real constraint, not a convention.\n\nIf a project genuinely needs to soften or extend a policy rule, the right move is at the project layer. Add a project guide under `harness/guides/`\n\nthat traces to the policy file by path and records the deviation:\n\n```\n# Documentation — project deviation\n\nThis project relaxes\n[`policies/tacoda/guides/documentation.md`](../policies/tacoda/guides/documentation.md):\nmulti-paragraph docstrings are permitted on public API surfaces because the\ndocs site is generated from them.\n```\n\nThe policy stays unmodified. The deviation lives where future readers will look. The lockfile keeps updating cleanly.\n\nThe deviation pattern works for most rules. It does not work for the rules a project is not allowed to relax. A vendor list pinned by legal is not a suggestion. A license rule that gates a release is not a starting point for negotiation.\n\nThat is what `strict`\n\nis for. The flag lives in the policy manifest and defaults to `false`\n\n:\n\n```\nname: my-org\nversion: 0.2.0\nstrict: true\ndescription: |\n  Org-wide engineering standards. Strict: project deviations do not apply.\n```\n\nA strict policy changes two things about how its guides reach the agent.\n\nFirst, load order. Project guides under `harness/guides/`\n\nnormally load before policy guides, so a later project guide can sit on top of a policy rule and the agent reads the project's relaxation last. A strict policy reverses that: its guides load last and have the final word on any rule it covers.\n\nSecond, authority. The drift sensor reads `strict: true`\n\nand marks the policy's rules as non-overridable in the loaded context. A project-layer deviation guide that traces back to a strict policy file is treated as a violation, not a softening. The agent will not quietly apply it.\n\nFile-level behavior is unchanged. Local edits to a strict policy file still block updates the same way; `--force`\n\nstill works the same way. Strict is not about file ownership; it is about precedence at agent runtime.\n\nUse it sparingly. Most rules deserve the deviation door because most rules have edge cases worth respecting. Strict is for the rules whose edge cases have already been argued and lost: compliance, licensing, security posture. The flag exists so the policy author can name those rules as different in kind, not just different in topic.\n\nA strict policy is a promise to the rest of the org. Defaulting to `false`\n\nkeeps that promise rare enough to mean something.\n\nThe argument against splitting Level 2 and Level 3 is that it is one more concept to hold. The argument for it is that the wrong layer is the wrong owner, and the wrong owner is how rules rot.\n\nA \"use Vitest, not Jest\" rule belongs to one project. A \"every TODO names an owner\" rule belongs to me across every project I touch. If both end up in the same `CLAUDE.md`\n\n, the next person to edit it has to guess which rules can travel and which cannot. They will guess wrong, and the file will drift further every quarter.\n\nKeystone makes the answer structural. Project rules go in `harness/guides/`\n\n. Org rules go in `harness/policies/<name>/guides/`\n\n. The lockfile keeps the org rules in sync. The namespace rule keeps a policy from escaping its lane. The drift sensor enforces both layers the same way at agent runtime, because the agent does not care where a rule came from; only the humans editing the files do.\n\nThat is the rule worth naming: a harness is not just a place to put rules. It is a place to put rules *where the right person can edit them*. Level 3 is the layer that question gets answered at.\n\nThe example repo is [tacoda-policy](https://github.com/tacoda/tacoda-policy). The harness installer is [keystone](https://github.com/tacoda/keystone). The thing I keep returning to: the cost of a good split is one extra directory. The cost of no split is a file you stop trusting.", "url": "https://wpnews.pro/news/org-rules-and-project-rules-need-different-homes", "canonical_source": "https://dev.to/tacoda/org-rules-and-project-rules-need-different-homes-4n0h", "published_at": "2026-06-04 19:09:51+00:00", "updated_at": "2026-06-04 19:43:18.178165+00:00", "lang": "en", "topics": ["ai-tools", "ai-infrastructure"], "entities": ["Keystone"], "alternates": {"html": "https://wpnews.pro/news/org-rules-and-project-rules-need-different-homes", "markdown": "https://wpnews.pro/news/org-rules-and-project-rules-need-different-homes.md", "text": "https://wpnews.pro/news/org-rules-and-project-rules-need-different-homes.txt", "jsonld": "https://wpnews.pro/news/org-rules-and-project-rules-need-different-homes.jsonld"}}