Every repo updates its vendored policy files with one command, script/update-policy #162

Open
opened 2026-11-07 06:36:27 +01:00 by clawbot · 2 comments
Collaborator

sneak, on sneak/rtnetmon#17 (comment), 7 November, on re-vendoring the canonical policy files:

i think each repo should have a scripts/update-policy that fetches them from their known urls on gitea and then adds/commits them and pushes, that way updating a repo is a single command.

Definition of done:

  • The template repositories carry script/update-policy. The repos use script/, the scripts-to-rule-them-all directory, so it goes there.
    • It fetches every canonical file the repo vendors from its known URL on git.eeqj.de/sneak/prompts, at the commit given, or at main when none is given.
    • It writes the files into place, then git adds them by name and commits them, naming the prompts commit.
    • It pushes, failing loudly on any fetch or push error.
  • The list of vendored files lives in one place in the script, and REPO_POLICIES.md says how a repo updates its policy files: with this one command.
  • The Makefile gains an update-policy target that runs it.
  • make check passes. Each repo picks it up at its next standards update. The template repositories get it in their own issues.

Model: opus-5-5

sneak, on https://git.eeqj.de/sneak/rtnetmon/issues/17#issuecomment-170394, 7 November, on re-vendoring the canonical policy files: > i think each repo should have a scripts/update-policy that fetches them from their known urls on gitea and then adds/commits them and pushes, that way updating a repo is a single command. **Definition of done:** - The template repositories carry `script/update-policy`. The repos use `script/`, the scripts-to-rule-them-all directory, so it goes there. - It fetches every canonical file the repo vendors from its known URL on `git.eeqj.de/sneak/prompts`, at the commit given, or at `main` when none is given. - It writes the files into place, then `git add`s them by name and commits them, naming the `prompts` commit. - It pushes, failing loudly on any fetch or push error. - The list of vendored files lives in one place in the script, and `REPO_POLICIES.md` says how a repo updates its policy files: with this one command. - The `Makefile` gains an `update-policy` target that runs it. - `make check` passes. Each repo picks it up at its next standards update. The template repositories get it in their own issues. Model: opus-5-5
clawbot self-assigned this 2026-11-07 06:36:27 +01:00
Author
Collaborator

Plan, for the worker. One PR into next, adding the model script/update-policy here. The template repositories get their own issues once it lands.

script/update-policy [commit]: POSIX sh, shaped like its siblings in script/, using only curl and git.

  1. Stop when script/projectname prints prompts: this repo is the source, and its root REPO_POLICIES.md is a symlink into prompts/.
  2. The commit is the argument, or else main resolved to a hash with git ls-remote. Fetch everything at that hash, from https://git.eeqj.de/sneak/prompts/raw/commit/<hash>/<path>.
  3. The list of vendored files, one per line at the top of the script, is the only place files are named: .dockerignore, .editorconfig, .gitea/workflows/check.yml, .gitignore, .golangci.yml, .prettierrc, and every prompts/*.md file. A prompts/NAME.md lands at NAME.md, or at docs/NAME.md where the repo keeps it there. A listed file the repo does not carry is skipped, so the script stays byte-identical across repos.
  4. Fetch everything into a temp directory first. A failed fetch, or a carried file with uncommitted changes, stops the script before anything is written.
  5. A repo's own entries survive, as the policy already requires of a re-vendor:
    • .gitignore, .editorconfig, .dockerignore: the last line of the fetched file ends the canonical part. What follows that line in the local file is kept, after the fetched content. A local file without that line stops the script, naming the file and saying to put the repo's own entries below that comment. .dockerignore has no such comment yet: add one at its end, worded as in .gitignore.
    • .golangci.yml: entries in the deny list of the test-support rule whose - pkg: line is not in the fetched file are added to the fetched deny list, in their order. A fetched file with no such list stops the script.
  6. Write the files and git add each by name. If nothing changed, say so and exit 0 with no commit. Otherwise commit only those paths, naming the full prompts hash in the message, then git push origin HEAD. Any failure exits non-zero.

Also:

  • Makefile: an update-policy target, listed in .PHONY.
  • prompts/REPO_POLICIES.md: a repo updates its policy files with this one command, and what the script keeps. Add it where the document talks about re-vendoring and keep the change small: #159 rewrites that file, and whichever lands second rebases.
  • The script list in README.md and both checklists. prompts/EXISTING_REPO_CHECKLIST.md also says that before the first use the repo's own entries go below that comment.

Test on throwaway clones with a local bare repository as origin, never a real remote: own entries kept in all four files, files the repo does not carry skipped, nothing changed, a bad commit hash stops with nothing written, a push failure exits non-zero.

Disclosure for the PR: the commit the script makes has no Model: line, since no model writes it.

make fmt, make check.

Model: opus-5-5

**Plan, for the worker.** One PR into `next`, adding the model `script/update-policy` here. The template repositories get their own issues once it lands. `script/update-policy [commit]`: POSIX `sh`, shaped like its siblings in `script/`, using only `curl` and `git`. 1. Stop when `script/projectname` prints `prompts`: this repo is the source, and its root `REPO_POLICIES.md` is a symlink into `prompts/`. 2. The commit is the argument, or else `main` resolved to a hash with `git ls-remote`. Fetch everything at that hash, from `https://git.eeqj.de/sneak/prompts/raw/commit/<hash>/<path>`. 3. The list of vendored files, one per line at the top of the script, is the only place files are named: `.dockerignore`, `.editorconfig`, `.gitea/workflows/check.yml`, `.gitignore`, `.golangci.yml`, `.prettierrc`, and every `prompts/*.md` file. A `prompts/NAME.md` lands at `NAME.md`, or at `docs/NAME.md` where the repo keeps it there. A listed file the repo does not carry is skipped, so the script stays byte-identical across repos. 4. Fetch everything into a temp directory first. A failed fetch, or a carried file with uncommitted changes, stops the script before anything is written. 5. A repo's own entries survive, as the policy already requires of a re-vendor: - `.gitignore`, `.editorconfig`, `.dockerignore`: the last line of the fetched file ends the canonical part. What follows that line in the local file is kept, after the fetched content. A local file without that line stops the script, naming the file and saying to put the repo's own entries below that comment. `.dockerignore` has no such comment yet: add one at its end, worded as in `.gitignore`. - `.golangci.yml`: entries in the `deny` list of the `test-support` rule whose `- pkg:` line is not in the fetched file are added to the fetched `deny` list, in their order. A fetched file with no such list stops the script. 6. Write the files and `git add` each by name. If nothing changed, say so and exit 0 with no commit. Otherwise commit only those paths, naming the full `prompts` hash in the message, then `git push origin HEAD`. Any failure exits non-zero. Also: - `Makefile`: an `update-policy` target, listed in `.PHONY`. - `prompts/REPO_POLICIES.md`: a repo updates its policy files with this one command, and what the script keeps. Add it where the document talks about re-vendoring and keep the change small: https://git.eeqj.de/sneak/prompts/pulls/159 rewrites that file, and whichever lands second rebases. - The script list in `README.md` and both checklists. `prompts/EXISTING_REPO_CHECKLIST.md` also says that before the first use the repo's own entries go below that comment. Test on throwaway clones with a local bare repository as `origin`, never a real remote: own entries kept in all four files, files the repo does not carry skipped, nothing changed, a bad commit hash stops with nothing written, a push failure exits non-zero. Disclosure for the PR: the commit the script makes has no `Model:` line, since no model writes it. `make fmt`, `make check`. Model: opus-5-5
Author
Collaborator

Built as planned in #164; choices and disclosures are in its body.

Model: opus-5-5

Built as planned in https://git.eeqj.de/sneak/prompts/pulls/164; choices and disclosures are in its body. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/prompts#162