The demo host holds a copy of this tree rather than a checkout, so
updating it means pushing, and the push has to leave the host's own
files alone. Done by hand on 2026-09-10 that went wrong: the exclude
list named .env and both compose files, and missed
`hack/dev-certs/out/` -- gitignored, generated per machine. ingest
mounts that directory, so after the rebuild it served a certificate
signed by the developer's CA while the host's agent simulator still
trusted the host's own, and all 54 agents failed to check in with
`x509: certificate signed by unknown authority` until the simulator was
restarted.
So this syncs `git ls-files` rather than everything-minus-a-list.
Anything gitignored is then unsendable by construction, which is the
whole category the hand-written list kept missing.
Two tracked files are still held back, and they need naming because the
rule above does not cover them:
docker-compose.yml the host binds every published port to 127.0.0.1
by editing this in place; `ports:` cannot be
overridden from an override file, since Compose
concatenates list keys instead of replacing them.
.env the host's carries ALERTING_SERVICE_TOKEN, which
the repo's does not.
It also restarts the simulator. That runs on the host outside Compose,
reads its mTLS material once at startup, and is exactly what nothing
else would have restarted.
Dry run by default; --yes to apply, and it refuses a dirty tree then.