docs: the instructions block is a snapshot from session start
Validate Helm Charts / Detect changed charts (pull_request) Successful in 2s
Validate Helm Charts / Build ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }} (pull_request) Skipped
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Skipped
Validate Helm Charts / Install-test (pull_request) Skipped
Validate Helm Charts / Resource quantities (pull_request) Successful in 8s

The first wording said the project-instructions block "is read from the
spawning session's working directory", which suggests that pulling in
that directory fixes it. It does not. The block is a snapshot taken when
the spawning session started, and nothing re-reads it afterwards.

Measured: a session whose working directory had been fast-forwarded to
the tip immediately before, and verified as up to date, still handed the
next agent a block from before Gitea #47 — while that agent's own
worktree was identical to origin/main (0 0). A current checkout and
stale instructions at the same moment.

Hence the two consequences that actually hold: the directory must be
current before the session starts, and an agent checks a rule against
the file in its own worktree and the diff against origin/main, because
the first cannot be enforced from inside an agent and the second can.
This commit was merged in pull request #58.
This commit is contained in:
jklein committed 2026-09-27 23:05:06 +00:00
1 parent 56bed94064
commit 61e28a1459
1 file changed
+1 -1
+1 -1
View File
@@ -58,7 +58,7 @@ Everything runs on the Gitea instance JLab-Git: issues, pull requests, CI and Re
- **`tea`, not `gh`.** Work happens in a **Coder workspace, and it has no `op`** — that is the normal case here, not a broken environment, so do not wait for the 1Password CLI or propose installing it. Call `tea` directly; it carries the workspace's stored login and opens PRs and issues under the **bot account**, which is accepted. Say so in the report when something is authored that way. (`op plugin run -- tea`, the older instruction, applies only where `op` actually exists.)
- **The remote is `origin`, and it points at Gitea** (`ssh://git@git.jk-dev.de:30022/jlab-cluster/helm-charts.git`). The checkout has exactly that one, and so does every worktree cut from it, so a bare `git push` goes to the leading copy; the github.com mirror is fed by Gitea itself and is never pushed to by hand. A clone elsewhere may carry the mirror as a second remote named `github` — wherever more than one exists, say which one you mean.
- **Cut every worktree from a freshly fetched `origin/main`.** `git fetch origin main` first, then branch from `origin/main` — never from the local `main` ref, and never assume the shared checkout is current: both can be many merges behind. The staleness is invisible where it matters most, because the project-instructions block a subagent receives is read from the **spawning** session's working directory, so an outdated worktree hands every agent rules that were corrected two PRs ago. Measured on 2026-09-27: an agent reported a contradiction in this file that had been fixed two PRs earlier, quoting the stale copy as binding. For the same reason, check a diff against `origin/main`, never against `main`.
- **Cut every worktree from a freshly fetched `origin/main`.** `git fetch origin main` first, then branch from `origin/main` — never from the local `main` ref, and never assume the shared checkout is current: both can be many merges behind. The staleness is invisible where it matters most, and it outlives the fix: the project-instructions block a subagent receives is a **snapshot** of the spawning session's working directory, taken when **that session started** — not a live read. Fetching mid-session does not refresh it, so the file on disk can be correct while every agent started from then on is still handed the superseded rules. Measured on 2026-09-27: an agent whose own worktree was identical to `origin/main` (`git rev-list --left-right --count origin/main...HEAD` returned `0 0`) received a block from before Gitea #47 and reported a contradiction in this file that two PRs had already fixed, quoting the stale copy as binding. Two consequences, and only these two help: the spawning session's directory must be current **before** the session starts, and an agent checks a rule against the **file in its own worktree** plus a diff against `origin/main` — never against `main`, and never against its own context block, because the first consequence cannot be enforced from inside an agent and the second can.
- **Branch protection with a signature requirement is active**, and signatures verify on Gitea. A commit that is not signed does not reach `main` — check before opening a PR, do not discover it at merge time.
- **No merge queue.** Gitea has none, and its place is taken by **auto-merge on green checks**: the PR is armed once and merges itself when the required check passes **and the required review exists** — both are active on `main`, so an armed PR without a review sits there instead of merging. Rule 7 above is unchanged — the user merges, and an agent never merges its own PR or arms auto-merge on it.
- **A required check per chart is not possible.** Gitea runs a whole matrix as one job under one status context, so the install-test reports once for all charts. What is required on `main` is `validate-charts`, as that single context; per chart is the part that cannot be had. Relevant whenever branch protection is touched.