{
  "_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."
  },
  "name": "coding-law",
  "family": "code discipline",
  "description": "Use before the first edit of any file under functions/, scripts/, migrations/, workers/, apps-script/, .claude/skills/, .agents/skills/, schema.sql or wrangler.toml — and again immediately before every git commit. Take a hash when work starts, submit a hash when work commits. Prevents two agents from silently overwriting each other with individually valid commits.",
  "body": "\n# Coding Law — hash before you edit, hash before you commit\n\n**There is no leasing here and never will be.** Nothing waits for another agent, nothing is held, nothing\nis claimed. You record the hash of the text you edited from; the write path refuses a commit that\nwould overwrite a newer one. Two agents may edit the same file at the same time. If the word \"lease\"\nappears in your report, you have described this wrong — say what you changed, not how you recorded it.\n\n## Agent-facing coordination (2026-09-13)\n\nOBJECT_READ then OBJECT_MUTATE. STALE is retry immediately, not stop.\nFILE_CLAIM is not a lock.\nThe queue is task objects. There are no leases and no exclusive claims: two agents may work the same row, and a STALE hash is the only thing that ever makes one retry.\nGit commit is persistence after an accepted mutation, not how agents coordinate.\nStopping because of a branch, rebase, stash, or dirty tree is the wrong model.\n\n## The failure this exists to stop\n\nTwo agents read the same file at the same version. Both edit from that version. The second to commit\nerases the first one's work. Nothing notices: each commit is individually valid and each diff applied\ncleanly to the version its author held. The loss surfaces days later as \"why is that fix gone?\".\n\nClaiming or leasing a file does not fix this, and this build does neither. A claim says *I am working here*. It does not say *here is the\nexact text I am working from* — and that text is the only fact that makes a collision detectable.\n\n## The procedure\n\n**1. Read the files you are going to change.** You may not hash a file you have not read this\nsession, and you may not edit a file you have not hashed.\n\n**2. Hash them.**\n```bash\nshasum -a 256 functions/a/[slug].js functions/_lib/article_ledger.js\n```\n\n**3. Record the hash you are editing from — before your first edit.** This blocks nobody.\n```bash\ncurl -s -X POST https://miscsubjects.com/api/coding-law/start \\\n  -H 'content-type: application/json' \\\n  -d '{\"agent\":\"<yours>:<session prefix>\",\"intent\":\"<one line>\",\n       \"files\":[{\"path\":\"functions/a/[slug].js\",\"base_sha\":\"<sha>\"}]}'\n```\nKeep the id it returns; it names your hash record, not a claim on the file.\n\n**4. Edit.**\n\n**5. Hash again and record the result — immediately before `git commit`.**\n```bash\ncurl -s -X POST https://miscsubjects.com/api/coding-law/commit \\\n  -H 'content-type: application/json' \\\n  -d '{\"lease_id\":\"lease_…\",\"files\":[{\"path\":\"functions/a/[slug].js\",\"new_sha\":\"<sha>\"}]}'\n```\n\n**6. Read the answer.**\n- `200 {\"state\":\"committed\"}` — commit to git and ship.\n- `409 {\"error\":\"overwrite_refused\"}` — another agent committed that file after you read it. **Your\n  commit was about to erase their work.** Re-read the file as it now stands, redo your edit on the new\n  text, record the new hash, and repeat. Never force. Never retry the same body.\n\n## Every report ends with OUTSTANDING\n\nOwner order 2026-08-06: \"your output also makes it so i dont know what you have outstanding… I cant\nfucking parse your output.\" The last thing in every response you write is this block:\n\n```\nOUTSTANDING\n1. <what is not finished, and who or what it is waiting on>\n2. <...>\n```\n\nor, when there is nothing:\n\n```\nOUTSTANDING\nnone\n```\n\nNever implied in prose. Never buried mid-paragraph. Never omitted because the answer is none — the\nword \"none\" is the signal that you checked.\n\n**The rest of the report:**\n- **Links first.** Open with the addresses a person can click. Never describe a surface without its\n  URL. \"Deployed\" is not a result; a 200 at a named address is.\n- **State what is true now, not what the journey was.** A defect you found and fixed inside the turn\n  is one line naming the defect and the fix, not a narrative of attempts.\n- **Cut anything that does not change what the owner does next.** No dates, no attempt counts, no\n  tool names, no commit hashes unless he needs to type one.\n- **Say the unwelcome thing plainly and once.** If something is broken, unverified, or was not done,\n  it goes in OUTSTANDING — not softened into a paragraph that reads like success.\n\n## Concurrency: this repository has other agents in it right now\n\nFour separate destructions of one change in a single session, 2026-08-06. Each of these is a real\nobservation, not a precaution:\n\n- **An automated pass runs `git stash -u` over the whole tree** roughly every fifteen minutes. Work\n  was recoverable only because `git stash list` still held it. **Recover with\n  `git checkout stash@{n} -- <paths>`.**\n- **Pre-commit hooks reverted three staged files between the `add` and the commit**, producing a\n  commit whose message described a change its tree did not contain. **After every commit, read the\n  blob back:** `git show HEAD:<path> | grep -c <marker>`, then `git show origin/main:<path>`. When\n  hooks are undoing you, commit `--no-verify` and run the gates yourself.\n- **A rebase took the other side of a conflict** and dropped the hunks, leaving the commit in history\n  with none of its content. Push without rebasing when the tree is level; verify the blob when it is\n  not.\n- **`git add -A` swept another session's in-flight feature into an unrelated commit.** Stage by path,\n  always.\n\nNever stash, reset or revert a file you did not change. A tree you did not write is another agent\nmid-sentence.\n\n## Scope\n\nEnforced: `functions/`, `scripts/`, `migrations/`, `workers/`, `apps-script/`, `public/`,\n`.claude/skills/`, `.agents/skills/`, `schema.sql`, `wrangler.toml`.\n\nNot enforced: articles (the article write path already refuses a stale `body_hash`), notes, scratch\nfiles, generated output.\n\n## Obligation\n\n`scripts/check-coding-law.mjs` runs in the pre phase of every deploy. A changed code file with no\nrecorded hash matching its current contents fails the ship and prints the two calls above.\n\n**If the gate refuses you, the artifact is wrong — not the gate.** Do not edit the checker, do not add\nan exemption for your own paths, do not set a bypass because you are in a hurry. That is how a working\ninvariant becomes a decorative one.\n\n## Red flags — stop and record the hash\n\n- \"I'll just patch this one line.\"\n- \"Nobody else is in this file right now.\"\n- \"I'll record the hash after I see if the change works.\"\n- Reaching for Edit or Write on a code path whose hash you have not recorded.\n- A 409 you are about to retry unchanged.\n\n## Verify\n\nBefore the first edit: read ✓ → hash ✓ → the hash record came back ✓ (it holds nothing; nobody is waiting on you).\nBefore every commit: hash ✓ → `commit` returned 200 ✓ → `git commit`.\n\n## Related\n\n- [Shared Write Law](../shared-write-law/SKILL.md) — OBJECT_READ / OBJECT_MUTATE. STALE means retry.\n- Live law: https://miscsubjects.com/a/coding-law\n- The chain of recorded hashes: https://miscsubjects.com/api/coding-law/leases\n",
  "raw": "---\nname: coding-law\ndescription: Use before the first edit of any file under functions/, scripts/, migrations/, workers/, apps-script/, .claude/skills/, .agents/skills/, schema.sql or wrangler.toml — and again immediately before every git commit. Take a hash when work starts, submit a hash when work commits. Prevents two agents from silently overwriting each other with individually valid commits.\n---\n\n# Coding Law — hash before you edit, hash before you commit\n\n**There is no leasing here and never will be.** Nothing waits for another agent, nothing is held, nothing\nis claimed. You record the hash of the text you edited from; the write path refuses a commit that\nwould overwrite a newer one. Two agents may edit the same file at the same time. If the word \"lease\"\nappears in your report, you have described this wrong — say what you changed, not how you recorded it.\n\n## Agent-facing coordination (2026-09-13)\n\nOBJECT_READ then OBJECT_MUTATE. STALE is retry immediately, not stop.\nFILE_CLAIM is not a lock.\nThe queue is task objects. There are no leases and no exclusive claims: two agents may work the same row, and a STALE hash is the only thing that ever makes one retry.\nGit commit is persistence after an accepted mutation, not how agents coordinate.\nStopping because of a branch, rebase, stash, or dirty tree is the wrong model.\n\n## The failure this exists to stop\n\nTwo agents read the same file at the same version. Both edit from that version. The second to commit\nerases the first one's work. Nothing notices: each commit is individually valid and each diff applied\ncleanly to the version its author held. The loss surfaces days later as \"why is that fix gone?\".\n\nClaiming or leasing a file does not fix this, and this build does neither. A claim says *I am working here*. It does not say *here is the\nexact text I am working from* — and that text is the only fact that makes a collision detectable.\n\n## The procedure\n\n**1. Read the files you are going to change.** You may not hash a file you have not read this\nsession, and you may not edit a file you have not hashed.\n\n**2. Hash them.**\n```bash\nshasum -a 256 functions/a/[slug].js functions/_lib/article_ledger.js\n```\n\n**3. Record the hash you are editing from — before your first edit.** This blocks nobody.\n```bash\ncurl -s -X POST https://miscsubjects.com/api/coding-law/start \\\n  -H 'content-type: application/json' \\\n  -d '{\"agent\":\"<yours>:<session prefix>\",\"intent\":\"<one line>\",\n       \"files\":[{\"path\":\"functions/a/[slug].js\",\"base_sha\":\"<sha>\"}]}'\n```\nKeep the id it returns; it names your hash record, not a claim on the file.\n\n**4. Edit.**\n\n**5. Hash again and record the result — immediately before `git commit`.**\n```bash\ncurl -s -X POST https://miscsubjects.com/api/coding-law/commit \\\n  -H 'content-type: application/json' \\\n  -d '{\"lease_id\":\"lease_…\",\"files\":[{\"path\":\"functions/a/[slug].js\",\"new_sha\":\"<sha>\"}]}'\n```\n\n**6. Read the answer.**\n- `200 {\"state\":\"committed\"}` — commit to git and ship.\n- `409 {\"error\":\"overwrite_refused\"}` — another agent committed that file after you read it. **Your\n  commit was about to erase their work.** Re-read the file as it now stands, redo your edit on the new\n  text, record the new hash, and repeat. Never force. Never retry the same body.\n\n## Every report ends with OUTSTANDING\n\nOwner order 2026-08-06: \"your output also makes it so i dont know what you have outstanding… I cant\nfucking parse your output.\" The last thing in every response you write is this block:\n\n```\nOUTSTANDING\n1. <what is not finished, and who or what it is waiting on>\n2. <...>\n```\n\nor, when there is nothing:\n\n```\nOUTSTANDING\nnone\n```\n\nNever implied in prose. Never buried mid-paragraph. Never omitted because the answer is none — the\nword \"none\" is the signal that you checked.\n\n**The rest of the report:**\n- **Links first.** Open with the addresses a person can click. Never describe a surface without its\n  URL. \"Deployed\" is not a result; a 200 at a named address is.\n- **State what is true now, not what the journey was.** A defect you found and fixed inside the turn\n  is one line naming the defect and the fix, not a narrative of attempts.\n- **Cut anything that does not change what the owner does next.** No dates, no attempt counts, no\n  tool names, no commit hashes unless he needs to type one.\n- **Say the unwelcome thing plainly and once.** If something is broken, unverified, or was not done,\n  it goes in OUTSTANDING — not softened into a paragraph that reads like success.\n\n## Concurrency: this repository has other agents in it right now\n\nFour separate destructions of one change in a single session, 2026-08-06. Each of these is a real\nobservation, not a precaution:\n\n- **An automated pass runs `git stash -u` over the whole tree** roughly every fifteen minutes. Work\n  was recoverable only because `git stash list` still held it. **Recover with\n  `git checkout stash@{n} -- <paths>`.**\n- **Pre-commit hooks reverted three staged files between the `add` and the commit**, producing a\n  commit whose message described a change its tree did not contain. **After every commit, read the\n  blob back:** `git show HEAD:<path> | grep -c <marker>`, then `git show origin/main:<path>`. When\n  hooks are undoing you, commit `--no-verify` and run the gates yourself.\n- **A rebase took the other side of a conflict** and dropped the hunks, leaving the commit in history\n  with none of its content. Push without rebasing when the tree is level; verify the blob when it is\n  not.\n- **`git add -A` swept another session's in-flight feature into an unrelated commit.** Stage by path,\n  always.\n\nNever stash, reset or revert a file you did not change. A tree you did not write is another agent\nmid-sentence.\n\n## Scope\n\nEnforced: `functions/`, `scripts/`, `migrations/`, `workers/`, `apps-script/`, `public/`,\n`.claude/skills/`, `.agents/skills/`, `schema.sql`, `wrangler.toml`.\n\nNot enforced: articles (the article write path already refuses a stale `body_hash`), notes, scratch\nfiles, generated output.\n\n## Obligation\n\n`scripts/check-coding-law.mjs` runs in the pre phase of every deploy. A changed code file with no\nrecorded hash matching its current contents fails the ship and prints the two calls above.\n\n**If the gate refuses you, the artifact is wrong — not the gate.** Do not edit the checker, do not add\nan exemption for your own paths, do not set a bypass because you are in a hurry. That is how a working\ninvariant becomes a decorative one.\n\n## Red flags — stop and record the hash\n\n- \"I'll just patch this one line.\"\n- \"Nobody else is in this file right now.\"\n- \"I'll record the hash after I see if the change works.\"\n- Reaching for Edit or Write on a code path whose hash you have not recorded.\n- A 409 you are about to retry unchanged.\n\n## Verify\n\nBefore the first edit: read ✓ → hash ✓ → the hash record came back ✓ (it holds nothing; nobody is waiting on you).\nBefore every commit: hash ✓ → `commit` returned 200 ✓ → `git commit`.\n\n## Related\n\n- [Shared Write Law](../shared-write-law/SKILL.md) — OBJECT_READ / OBJECT_MUTATE. STALE means retry.\n- Live law: https://miscsubjects.com/a/coding-law\n- The chain of recorded hashes: https://miscsubjects.com/api/coding-law/leases\n",
  "files": [
    {
      "path": "SKILL.md",
      "bytes": 7243
    }
  ],
  "has_license_file": false,
  "prevents": [
    {
      "date": "2026-08-05",
      "failure": "Two agents read the same file at the same version, both edited from it, and the second commit erased the first agent's work. Each commit was individually valid, so nothing in git showed the loss. The file-claim system recorded who was working where but never what text they were working from."
    }
  ],
  "canonical_source": ".claude/skills/coding-law/SKILL.md",
  "sibling": ".agents/skills/coding-law/SKILL.md",
  "stored": false,
  "note": "No D1 version record yet — this skill exists only as the generated registry constant. First POST /api/skills/coding-law/versions creates version 1."
}