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
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.
Stop when script/projectname prints prompts: this repo is the source, and its root REPO_POLICIES.md is a symlink into prompts/.
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>.
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.
Fetch everything into a temp directory first. A failed fetch, or a carried file with uncommitted changes, stops the script before anything is written.
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.
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
sneak, on sneak/rtnetmon#17 (comment), 7 November, on re-vendoring the canonical policy files:
Definition of done:
script/update-policy. The repos usescript/, the scripts-to-rule-them-all directory, so it goes there.git.eeqj.de/sneak/prompts, at the commit given, or atmainwhen none is given.git adds them by name and commits them, naming thepromptscommit.REPO_POLICIES.mdsays how a repo updates its policy files: with this one command.Makefilegains anupdate-policytarget that runs it.make checkpasses. Each repo picks it up at its next standards update. The template repositories get it in their own issues.Model: opus-5-5
Plan, for the worker. One PR into
next, adding the modelscript/update-policyhere. The template repositories get their own issues once it lands.script/update-policy [commit]: POSIXsh, shaped like its siblings inscript/, using onlycurlandgit.script/projectnameprintsprompts: this repo is the source, and its rootREPO_POLICIES.mdis a symlink intoprompts/.mainresolved to a hash withgit ls-remote. Fetch everything at that hash, fromhttps://git.eeqj.de/sneak/prompts/raw/commit/<hash>/<path>..dockerignore,.editorconfig,.gitea/workflows/check.yml,.gitignore,.golangci.yml,.prettierrc, and everyprompts/*.mdfile. Aprompts/NAME.mdlands atNAME.md, or atdocs/NAME.mdwhere the repo keeps it there. A listed file the repo does not carry is skipped, so the script stays byte-identical across repos..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..dockerignorehas no such comment yet: add one at its end, worded as in.gitignore..golangci.yml: entries in thedenylist of thetest-supportrule whose- pkg:line is not in the fetched file are added to the fetcheddenylist, in their order. A fetched file with no such list stops the script.git addeach by name. If nothing changed, say so and exit 0 with no commit. Otherwise commit only those paths, naming the fullpromptshash in the message, thengit push origin HEAD. Any failure exits non-zero.Also:
Makefile: anupdate-policytarget, 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.README.mdand both checklists.prompts/EXISTING_REPO_CHECKLIST.mdalso 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
Built as planned in #164; choices and disclosures are in its body.
Model: opus-5-5