Skip to content

Move the pin out of .agents/ - #41

Merged
sehkone merged 1 commit into
mainfrom
sehkone/issue-40
Aug 11, 2026
Merged

Move the pin out of .agents/#41
sehkone merged 1 commit into
mainfrom
sehkone/issue-40

Conversation

@sehkone

@sehkone sehkone commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Moves the pin from .agents/instructions.toml to .agent-instructions.toml at the repository root, behind a compatibility window, and fixes two staging bugs the move exposed.

The name

.agents/ is generic in a namespace where every tool marks its own — .claude/, .cursor/, .gemini/. That leaves it open to a later tool claiming it, and open to being read as tool output and dropped into a .gitignore; five of the thirteen consuming repositories already ignore .claude/, so the habit is here. The directory held exactly one file with no second one planned. .agent-instructions.toml names this system, and a single file has no directory anyone can ignore wholesale.

Not a flag day

Both reusable workflows run these scripts from @main while each repository still carries whatever path its last apply wrote, so switching the path outright would turn every repository red at once until each merged the move.

Instead, pin_file.py reads the old path where that is the only one present, and every write puts the pin on the new path and deletes the old file (and the directory, if it was alone in it). The apply writes the pin on every release it delivers, so a consumer migrates inside the pull request it was getting anyway — nothing to do in any of the thirteen. The fallback comes out in its own release once none is left.

Two bugs the tests found

Neither is new; the move is what made them reachable.

  • Both drivers staged with git commit -a, which covers modifications to tracked files and not a new path. Delivering to a repository that had to gain a file — the moved pin, or any pin at all in a repository being onboarded — would have pushed the rewritten blocks with no pin beside them, and the drift check would then have failed on a file it could not read. Both now git add -A. In apply.yml that is safe because the two checkouts are removed first, which the comment there now says is load-bearing rather than tidiness.
  • sync.sh decided "already current" with git diff --quiet, which is blind to untracked files — so it would have reported the repository that needed the run as needing nothing. It now asks git status --porcelain.

No tag for this

The changelog entries sit under [Unreleased]. This changes no block and no repos.json entry, so check_release_surface.sh would refuse a tag for it — correctly, by its own reasoning that scripts and workflows reach consumers from @main rather than from a release. The move takes effect for every repository on its next scheduled apply, and the entries fold into whatever release is cut next. That release is MINOR by the version scheme's interface clause, whatever else it carries.

Verification

  • scripts/test_pin_file.py is new (18 checks) and covers both paths, a write that migrates, a directory left alone because something else is in it, a repository holding both files, and one holding neither. CI runs it.
  • test_apply_blocks.py gains an end-to-end migration case; test_sync.py's consumer fixture is deliberately still on the old path, so the fan-out is proved to carry both halves — the new file added and the old one deleted — through real git.
  • All six script tests, lint_blocks.py, and markdownlint pass.

Closes #40

`.agents/` is a generic name in a namespace where every tool marks its
own -- `.claude/`, `.cursor/`, `.gemini/`. That left it open to a later
tool claiming it, and open to being read as tool output and dropped into
a `.gitignore`; five of the thirteen consuming repositories already
ignore `.claude/`, so the habit is here. The directory held one file
with no second one planned, so it was structure buying nothing while
carrying both risks. `.agent-instructions.toml` names this system, and
a single file has no directory anyone can ignore wholesale.

The move cannot be a flag day. Both reusable workflows run these
scripts from `@main` while each repository still carries whatever path
its last apply wrote, so a hard switch would turn every repository red
at once. The reader takes the old path where that is the only one
present, and every write moves the repository onto the new one and
deletes the old -- which makes the apply the migration, with nothing
for anyone in a consumer to do. The fallback comes out once none is
left.

Writing the tests for that turned up a bug older than this change.
Both drivers staged with `commit -a`, which covers modifications to
tracked files and not a new path: delivering to a repository that had
to gain a file -- the moved pin, or any pin at all in one being
onboarded -- would have pushed rewritten blocks with no pin beside
them, and the drift check would then have failed on a file it could
not read. `sync.sh` decided "already current" with `diff --quiet`,
blind to the same case, and would have skipped exactly the repository
that needed the run.

The changelog entries sit under `[Unreleased]` rather than a version:
this changes no block and no roster entry, so the release-surface
guard would refuse a tag for it, correctly. The move reaches consumers
through `@main` on their next scheduled apply, and the entries fold
into whatever release is cut next.

Closes #40
@sehkone
sehkone merged commit f101c84 into main Aug 11, 2026
1 check passed
@sehkone
sehkone deleted the sehkone/issue-40 branch August 11, 2026 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move the pin out of .agents/

1 participant