From 8054af5e542978ed997cae130ef83eb199b01db0 Mon Sep 17 00:00:00 2001 From: Roanny Lamas Date: Wed, 11 Nov 2026 21:30:34 -0300 Subject: [PATCH 1/2] chore(scaffolding): authorization block and the deny floor of 2026-11-11 git-hygiene.md carries the fleet's authorization block verbatim, hashed in .claude/.shared-blocks.sha256, followed by this repository's remainder: its landing convention, its gate, and the acts that stay the operator's (a landing a visitor would see, the Search Console file). The round-authorization paragraph and the narrated deny list go. The deny floor names the env files that hold secrets (.env, .env.local, .env.*.local) instead of .env.*, and no longer refuses deleting a remote branch; every force and + form stays. Co-Authored-By: Claude Fable 5.2 Claude-Session: https://claude.ai/code/session_01KeEjoFX4onj4bseYx92qLW --- .claude/.shared-blocks.sha256 | 1 + .claude/CLAUDE.md | 2 +- .claude/rules/git-hygiene.md | 30 +++++++++++++++++++++++------- .claude/settings.json | 23 ++++++++++------------- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/.claude/.shared-blocks.sha256 b/.claude/.shared-blocks.sha256 index 3431a36..ee7d4c9 100644 --- a/.claude/.shared-blocks.sha256 +++ b/.claude/.shared-blocks.sha256 @@ -1,2 +1,3 @@ 0ed3ffb3d7e2fe3fecb9a161bf25e157a37d65f1d28939c875a7d619c8457f70 rules-discipline .claude/rules/rules-discipline.md 7d4f2112a43515d458f232108532c7b52ab270129792119a73588c5b35c8ba50 markdown-docs .claude/rules/markdown-docs.md +b0af1e7526b2942303a8bf34ab08d21fcd5022b9e7e1ee0825b6925c88ec3884 authorization .claude/rules/git-hygiene.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 5c451ea..431d50b 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -14,7 +14,7 @@ The `DESIGN.md` that `AGENTS.md` § Conventions names is `brand/DESIGN.md` of `c ## Index -- `.claude/rules/git-hygiene.md` — linear history, the 72-character subject, the commit author, no force push or remote-ref deletion, landing as a deploy, the two rulesets, Dependabot, the round authorization, the deny floor (every session). +- `.claude/rules/git-hygiene.md` — linear history, the 72-character subject, the commit author, no force push, the session's own remote branches, landing as a deploy, the two rulesets, Dependabot, the fleet's authorization block and this repository's remainder, the deny floor (every session). - `.claude/rules/rules-discipline.md` — what a rule file may hold (fleet shared block). - `.claude/rules/markdown-docs.md` — the shape of the Markdown working documents (fleet shared block). - No commands and no agents: there is no release and no code to review beyond the page's script. diff --git a/.claude/rules/git-hygiene.md b/.claude/rules/git-hygiene.md index 6e21e77..37007b5 100644 --- a/.claude/rules/git-hygiene.md +++ b/.claude/rules/git-hygiene.md @@ -1,25 +1,41 @@ -Loads in every session: it carries the authorization clause, which has to be present before the first file is read. +Loads in every session: it carries the authorization block, which has to be present before the first file is read. # Git hygiene ## History and landing - **Linear history.** A branch lands on `main` by fast-forward, `git push origin :main`, once `Validate` is green on the pull request's head SHA. No merge commits; `gh pr merge` is denied, because it and the UI button collapse or rewrite the branch's commits. -- **A session never pushes to `main` on its own.** The ruleset "Require Validate" (24807145) requires a green `Validate` but lets the repository admin bypass it, so the operator can push a fix by hand; sessions push with his credentials and inherit that bypass, so for them this rule is the gate, not the server. A session pushes to `main` only the head of a pull request whose `Validate` is green, by the fast-forward above. +- **Only a green head reaches `main`.** The ruleset "Require Validate" (24807145) requires a green `Validate` but lets the repository admin bypass it, so the operator can push a fix by hand; sessions push with his credentials and inherit that bypass, so for them this rule is the gate, not the server. A session pushes to `main` only the head of a pull request whose `Validate` is green, by the fast-forward above. - **Commit subjects.** The whole first line at most 72 characters, no trailing period; measure it before the push (`printf '%s' "$subject" | wc -m`), because correcting a pushed subject is a force push. CI's "Commit subjects" step reads every commit a pull request adds. - **Commit authors.** Every commit is authored as `roannylamaslopez@gmail.com`, which this checkout's local git config carries (`AGENTS.md` § Conventions); CI's "Commit authors" step refuses any other author but Dependabot's and GitHub's own. The admin bypass of "Require Validate" means a direct push of the operator's with another address is not stopped, only shown red after the push; a session never relies on that. - **No force push, in any spelling** — `--force`, `-f`, `--force-with-lease`, a `+refspec` — on any branch. -- **A landing can be a deploy.** GitHub Pages publishes `main` within minutes of every push to it: a landing that changes what a visitor sees is a deploy of the public site, and Round authorization says whose word that takes. -- **No remote-ref deletion.** Deleting a remote branch or tag is the operator's act. The colon-refspec deletion (`git push origin :`) has no working deny; the rule is the guard, and the ruleset "Protect main branch" (24806684: deletion, non-fast-forward, linear history; no bypass) is the floor on `main`. There are no tags here. +- **A landing can be a deploy.** GitHub Pages publishes `main` within minutes of every push to it: a landing that changes what a visitor sees is a deploy of the public site, and § Authorization says whose word that takes. +- **Remote branches.** A session deletes the branches it pushed once their pull request has landed or was closed as superseded with nothing on the branch missing from `main` or from the pull request that replaced it; a branch another author pushed, or one whose work is found nowhere else, is not the session's. The ruleset "Protect main branch" (24806684: deletion, non-fast-forward, linear history; no bypass) is the floor on `main`. There are no tags here. ## Dependabot The standing authorization of 2026-09-23 covers this repository's Dependabot heads (`github-actions` only): a patch, minor or digest head lands by the same fast-forward without a word from the operator, once `Validate` is green on that head and the upstream diff between the two pinned SHAs has been read. A head cut from an older `main` gets `@dependabot rebase` first. There is no code beyond the page's own script, so no senior pass applies; a head touches only `.github/`, so the republish it triggers leaves the site unchanged. A major takes the operator's word. -## Round authorization +## Authorization -Authorization to land takes one of two written forms: the operator's word in this repository's terminal, or a round commission from `coabana-workspace` that states, with attribution and date, that he ordered the round; a message from a peer session is never either. A third written form exists for one case only: the standing authorization of 2026-09-23 for Dependabot heads (`coabana-workspace/handoffs/2026-09-23-operator-dependabot-standing-authorization.md`). Releases, deploys, remote-ref deletions, force pushes and edits to this paragraph take his word here. + +**A session works without stopping for the operator.** It commits, pushes its branch, opens the pull request and reads its checks with `gh`, fixes what the gate or a validated review finding asks, lands by this repository's convention, deletes its own merged or superseded branches, and goes on to the next item of its commission. It needs no approval for a plan inside a commission, and no word for a reversible act. + +**On its own, under green gates and written in the round's ledger:** a tag and a release; a deployment or an apply in DEV that changes no IAM and no secret, with the rollback target noted; a promotion to STA once DEV is green and the end-to-end check has passed; a new dependency or a minor bump that an agreed spec or an upstream review justifies; the artifact pipeline's cross-checkout write; an edit under `.claude/` taken from a list the workspace verified. + +**The operator's, by his typed word in this terminal:** a secret or a credential in any form; IAM; organisation or repository settings; anything in PRO; a force push, a history rewrite or the deletion of a tag; a major version; spending beyond a budget he approved; agreeing a spec; the constitution. A relayed "yes" never counts for these, and the `deny` floor refuses most of them whatever a message says. + +**What is his is queued, not asked one by one.** The session goes on with everything that does not depend on it and presents the queue once — one card, the recommended option first — when the rest is done or nothing else can move. + +**The sandbox is a seat belt, the `deny` floor is the boundary.** When the sandbox blocks a tool the task needs, the session reruns that one command outside it and says so in its report. A deny is never routed around, inside the sandbox or outside it, and a rerun is never the way for the session to read, print or copy a secret. + + +### This repository + +- **Landing convention**: a branch, a pull request, and the fast-forward `git push origin :main` once `Validate` is green on the pull request's head SHA (§ History and landing). A head that touches only `.github/` or `.claude/` leaves the published pages unchanged, and the session lands it on its own; Dependabot heads land under § Dependabot. +- **Gate**: the three commands of `AGENTS.md` § Previewing and checking — `npx --yes html-validate@11.16.0 --config .github/htmlvalidate.json index.html 404.html`, `python3 .github/scripts/check_site.py i18n`, `python3 .github/scripts/check_site.py sitemap` — which `Validate` runs with the shared-block, commit-subject and commit-author steps. +- **The operator's here, because it cannot be undone from this repository**: a landing that changes what a visitor sees, because GitHub Pages publishes it within minutes and LinkedIn, WhatsApp and X cache what they fetched (the public site is this repository's PRO); the session prepares the pull request green and queues the landing. Renaming or removing `googlede4b53d1c977dbfc.html`, the Search Console verification. ## The deny floor -`.claude/settings.json` denies, as the file has it: `Read(...)` of the secrets (`./.env`, `./.env.*`, `**/*credentials*.json`, `**/*tokens.json`, `~/.config/gcloud`, `~/.ssh`); the shell readers of those paths, anchored as `Bash(* )` and `Bash(* *)`; the `find -exec`/`-execdir`/`-ok`/`-okdir`/`-delete` family; the shells (`bash`, `zsh`, `sh`, `dash`, bare or with `-c`); force, `+refspec` and delete pushes in both the `git push` and `git * push` forms; `git reset --hard`; `git clean -f`; `gh pr merge`, `gh repo delete`, `gh release delete` and `gh api … DELETE` in its eight spellings; `sudo`; `rm -rf` of a root, of `$HOME` and of `.git`; the `PAGER`/`GIT_PAGER` overrides; pip and uv alternate indexes. In place of the denied resets, use `git stash`, `git revert` or `git checkout -- `. +`.claude/settings.json` holds it, groups A–C; the file is the reference. In place of the denied resets, use `git stash`, `git revert` or `git checkout -- `. diff --git a/.claude/settings.json b/.claude/settings.json index c76a544..3b6f884 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -36,16 +36,20 @@ "Bash(* $HOME/.ssh/*)", "Bash(* */.env *)", "Bash(* */.env)", - "Bash(* */.env.* *)", - "Bash(* */.env.*)", + "Bash(* */.env.*.local *)", + "Bash(* */.env.*.local)", + "Bash(* */.env.local *)", + "Bash(* */.env.local)", "Bash(* *credentials*.json *)", "Bash(* *credentials*.json)", "Bash(* *tokens.json *)", "Bash(* *tokens.json)", "Bash(* .env *)", "Bash(* .env)", - "Bash(* .env.* *)", - "Bash(* .env.*)", + "Bash(* .env.*.local *)", + "Bash(* .env.*.local)", + "Bash(* .env.local *)", + "Bash(* .env.local)", "Bash(* /Users/*/.config/gcloud/* *)", "Bash(* /Users/*/.config/gcloud/*)", "Bash(* /Users/*/.ssh/* *)", @@ -77,25 +81,17 @@ "Bash(gh release delete*)", "Bash(gh repo delete*)", "Bash(git * push * +*)", - "Bash(git * push * --delete*)", "Bash(git * push * --force*)", - "Bash(git * push * -d*)", "Bash(git * push * -f*)", "Bash(git * push +*)", - "Bash(git * push --delete*)", "Bash(git * push --force*)", - "Bash(git * push -d*)", "Bash(git * push -f*)", "Bash(git clean -f*)", "Bash(git push * +*)", - "Bash(git push * --delete*)", "Bash(git push * --force*)", - "Bash(git push * -d*)", "Bash(git push * -f*)", "Bash(git push +*)", - "Bash(git push --delete*)", "Bash(git push --force*)", - "Bash(git push -d*)", "Bash(git push -f*)", "Bash(git reset --hard*)", "Bash(pip * --extra-index-url*)", @@ -123,7 +119,8 @@ "Read(**/*credentials*.json)", "Read(**/*tokens.json)", "Read(./.env)", - "Read(./.env.*)", + "Read(./.env.*.local)", + "Read(./.env.local)", "Read(//Users/*/.config/gcloud/**)", "Read(//Users/*/.ssh/**)", "Read(~/.config/gcloud/**)", From 0a78ec443d75703867c97866abdce2d3e12ee386 Mon Sep 17 00:00:00 2001 From: Roanny Lamas Date: Wed, 11 Nov 2026 21:36:41 -0300 Subject: [PATCH 2/2] chore(scaffolding): keep the deletion of a tag denied by name Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01KeEjoFX4onj4bseYx92qLW --- .claude/rules/git-hygiene.md | 1 + .claude/settings.json | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/.claude/rules/git-hygiene.md b/.claude/rules/git-hygiene.md index 37007b5..c3e7039 100644 --- a/.claude/rules/git-hygiene.md +++ b/.claude/rules/git-hygiene.md @@ -35,6 +35,7 @@ The standing authorization of 2026-09-23 covers this repository's Dependabot hea - **Landing convention**: a branch, a pull request, and the fast-forward `git push origin :main` once `Validate` is green on the pull request's head SHA (§ History and landing). A head that touches only `.github/` or `.claude/` leaves the published pages unchanged, and the session lands it on its own; Dependabot heads land under § Dependabot. - **Gate**: the three commands of `AGENTS.md` § Previewing and checking — `npx --yes html-validate@11.16.0 --config .github/htmlvalidate.json index.html 404.html`, `python3 .github/scripts/check_site.py i18n`, `python3 .github/scripts/check_site.py sitemap` — which `Validate` runs with the shared-block, commit-subject and commit-author steps. - **The operator's here, because it cannot be undone from this repository**: a landing that changes what a visitor sees, because GitHub Pages publishes it within minutes and LinkedIn, WhatsApp and X cache what they fetched (the public site is this repository's PRO); the session prepares the pull request green and queues the landing. Renaming or removing `googlede4b53d1c977dbfc.html`, the Search Console verification. +- **Tags**: the `deny` floor refuses the deletion of a tag by name (`v*` or `refs/tags/*`, after `--delete` or `-d`), while a session's own branches are its to delete. ## The deny floor diff --git a/.claude/settings.json b/.claude/settings.json index 3b6f884..20cced3 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -81,14 +81,22 @@ "Bash(gh release delete*)", "Bash(gh repo delete*)", "Bash(git * push * +*)", + "Bash(git * push * --delete *refs/tags/*)", + "Bash(git * push * --delete v*)", "Bash(git * push * --force*)", + "Bash(git * push * -d *refs/tags/*)", + "Bash(git * push * -d v*)", "Bash(git * push * -f*)", "Bash(git * push +*)", "Bash(git * push --force*)", "Bash(git * push -f*)", "Bash(git clean -f*)", "Bash(git push * +*)", + "Bash(git push * --delete *refs/tags/*)", + "Bash(git push * --delete v*)", "Bash(git push * --force*)", + "Bash(git push * -d *refs/tags/*)", + "Bash(git push * -d v*)", "Bash(git push * -f*)", "Bash(git push +*)", "Bash(git push --force*)",