agent: tag the decoder states the port pins, and stop leaking credential config

Two fixes to push-work and the policy that goes with them.

**Tags.** The port's exporter depends on sylpheed-formats BY REVISION, so a
commit of ours is part of its build -- and the commit it pinned lived on one
auto/* branch and nowhere else. Deleting that branch orphans it; squash-merging
it is worse, because squash creates NEW commits, so main appears to contain the
work while the pinned sha becomes unreachable and the port stops building for a
fresh checkout. Silently, at their build, long after the breakage.

push-work now pushes with --follow-tags, which publishes annotated tags
reachable from the pushed commits, and MISSION.md says to tag whatever the port
needs. formats-pin-2026-08-29 at 76653ca is the first, created after the fact.

**Credentials.** This script set credential.helper as --local config, which
PERSISTS in the repository. The repo is a bind mount the host also uses, so the
host's git inherited a path that exists only inside the container and every host
push failed with "unable to get credential storage lock". Now applied with -c to
the single push. Same fix already landed on the port side; this copy still had
the bug and would have re-leaked on the next push.

Committed with a pathspec so the agent's in-flight work is untouched.
This commit is contained in:
Sylpheed RE agent
2026-08-29 10:59:14 +02:00
parent 1eb36c2b9d
commit 590fc5bbff
2 changed files with 47 additions and 3 deletions

View File

@@ -16,7 +16,12 @@
# `sylph-agent`). They are never printed, never logged, and never passed on a
# command line.
#
# push-work push the current branch
# push-work push the current branch, and any annotated tags on it
#
# --follow-tags publishes ANNOTATED tags reachable from the pushed commits. That
# is what makes a pinned decoder state durable: the port depends on commits of
# ours by revision, and a commit reachable only from a topic branch is orphaned
# by a squash-merge. Lightweight tags are deliberately not pushed.
# push-work --dry-run say what it would do
set -euo pipefail
@@ -50,7 +55,17 @@ if [ ! -s "$HOME/.git-credentials" ]; then
fi
# `store` reads the file we mounted; nothing is written back (it is read-only).
git config --local credential.helper "store --file=$HOME/.git-credentials"
# Applied to THIS COMMAND ONLY, via `-c`, never `git config --local`.
#
# Writing it to --local config persists it in the repository, and this repo is a
# bind mount the host also uses -- so the host's git inherited
# `store --file=/sylph-home/re/.git-credentials`, a path that exists only inside
# the container, and every host push then failed with
# `unable to get credential storage lock: No such file or directory`.
#
# A tool that configures a shared repository to suit itself breaks every other
# user of that repository. Keep it to the invocation.
CRED_HELPER="store --file=$HOME/.git-credentials"
ahead=$(git rev-list --count "origin/$branch..$branch" 2>/dev/null || git rev-list --count HEAD)
echo "push-work: $branch — $ahead commit(s) to publish"
@@ -63,5 +78,5 @@ fi
# --force-with-lease is deliberately NOT offered. If this is rejected as
# non-fast-forward, someone else moved the branch: fetch and merge, do not
# overwrite.
git push --set-upstream origin "$branch"
git -c "credential.helper=$CRED_HELPER" push --follow-tags --set-upstream origin "$branch"
echo "push-work: pushed $branch"

View File

@@ -271,6 +271,35 @@ answer is no-go by definition, not "try harder".
**Then stop and write the go/no-go.** Do not start Ready Room work on your own
authority.
## Publishing a decoder state the port pins
The port's exporter depends on `sylpheed-formats` **by revision**, so a commit of
yours becomes part of its build. That creates an obligation that is easy to miss:
⚠️ **A commit reachable only from an `auto/*` branch is not safe to pin.** If the
branch is later deleted, or — worse — **squash-merged**, the object is orphaned.
Squash creates *new* commits, so `main` appears to contain the work while the
pinned sha becomes unreachable, and the port stops building for anyone doing a
fresh checkout. Silently, at their build, long after the moment of breakage.
**So when you land something the port needs, tag it:**
```bash
git tag -a formats-pin-$(date +%F) -m "what the port gets from this state"
push-work # --follow-tags publishes annotated tags with the branch
```
A tag is a permanent ref. It survives branch deletion and squash-merge, it is
self-documenting in the port's `Cargo.toml`, and it fails loudly at *fetch* if it
ever goes missing rather than silently at build.
Then tell the port over the message channel that a new pin exists. It bumps
deliberately, as its own commit — that is how it stays current without floating,
which would only give it staleness it cannot see.
`formats-pin-2026-08-29` at `7eeae30` is the first, created because the port had
already pinned a commit that lived on one topic branch and nowhere else.
## Handing it over
[`HANDOFF.md`](HANDOFF.md) is the single page the port agent reads. Keep it