changelog: an Unreleased section for a rule that was already there
Records the two skill commits ahead of tomorrow's build, and states the finding that shaped them: the "a negative result is usually your own filter" rule was already baked, already symlinked in at every container start, and already survived every recreate — then was violated five times by a session that had it available. The gap was activation, not persistence, which is why the cross-cutting form went into the always-appended AGENTS block instead of into a skill that only loads when a task description matches. Also notes what the entry's own subject implies for the reader: neither change reaches a running container until the image is rebuilt AND the container recreated, since ~/.agents/skills and the global AGENTS.md both live in the image rather than in a volume or a mount.
This commit is contained in:
@@ -11,6 +11,74 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
**Two vendored skills changed, and one of the changes is a correction rather than
|
||||||
|
an addition.** Nothing about the image's behaviour moves; this is entirely about
|
||||||
|
what the next agent reads before it acts.
|
||||||
|
|
||||||
|
**`pi-devbox-environment` §2 had a rule that was half wrong, and the wrong half
|
||||||
|
cost five findings in one session.** The section "A negative result is usually
|
||||||
|
your own filter" closed with *"a positive result needs no such scepticism — it
|
||||||
|
carries its own evidence."* That sentence is false. A positive result is evidence
|
||||||
|
about the question your command *actually posed*, which may not be the question
|
||||||
|
you meant — and the failure is invisible precisely because the command succeeded.
|
||||||
|
Three measured instances, all from 2026-08-29, all filed as fact before being
|
||||||
|
caught: an SSH handshake that succeeded and greeted the agent as `joakimp` while
|
||||||
|
it believed it was probing `gitea.egl.lan` (a `Host gitea*` block had rewritten
|
||||||
|
`HostName`, so it authenticated to the wrong Gitea instance); a `401` that was a
|
||||||
|
genuine answer from an issuer which had never minted the credential being tested;
|
||||||
|
and a "regression" produced by diffing `ssh -G` output against a `2222` that the
|
||||||
|
agent's own earlier `-p 2222` flag had supplied. The section now carries a
|
||||||
|
counterpart, *"…and a positive result only proves what you actually asked"*, plus
|
||||||
|
the three false-negative rows that session added (a palace scan that queried
|
||||||
|
`embedding_metadata` while documents live in `embedding_fulltext_search_content`;
|
||||||
|
a token declared dead on a 401 from the wrong issuer; a host declared unreachable
|
||||||
|
after trying two of its three open ports, with the port written in an environment
|
||||||
|
variable the agent already held).
|
||||||
|
|
||||||
|
**The cross-cutting form of that rule went into `pi-global-AGENTS.append.md`, not
|
||||||
|
into the skill — deliberately, and this is the whole point of the change.** The
|
||||||
|
rule *already existed* in the baked skill, authored by an earlier session,
|
||||||
|
symlinked into `~/.agents/skills/` at every container start. It survived every
|
||||||
|
recreate, was available for the entire session that broke it, and was violated
|
||||||
|
five times anyway. So the gap was never persistence; it was **activation**.
|
||||||
|
A reasoning rule that only loads when a task description happens to match it
|
||||||
|
cannot fire on the occasions that need it, because "I am about to state something
|
||||||
|
false" is not a recognisable task type. The always-appended block is read by every
|
||||||
|
agent in every container without being asked for, which is the only property that
|
||||||
|
matters here. Writing a sixth document restating the rule would have felt like
|
||||||
|
progress and changed nothing.
|
||||||
|
|
||||||
|
**New baked skill: `credential-incident-response`.** Authored here, so the baked
|
||||||
|
copy is canonical and it is *not* listed in `skillset-owned.txt`. It carries the
|
||||||
|
*facts* a two-day credential incident produced, on the theory that facts transfer
|
||||||
|
between sessions where exhortations do not: probe the issuing provider **first**
|
||||||
|
(11 of 13 "exposed" credentials in that sweep turned out to be already dead at the
|
||||||
|
provider — five HTTP requests would have established it, and nobody asked);
|
||||||
|
`sha256[:8]` fingerprints as leak-free credential identity; the `403`-vs-`401`
|
||||||
|
trap that scoped tokens introduce into liveness probes, where a live token looks
|
||||||
|
revoked on `/api/v1/user`; **revocation beats deletion** for anything already
|
||||||
|
replicated, because deletion is best-effort over an unbounded copy set (FTS shadow
|
||||||
|
rows, per-host feed inboxes, sqlite free pages, mesh replicas, backups) while
|
||||||
|
revocation invalidates copies nobody enumerated; the three places a secret hides
|
||||||
|
in a Chroma palace, in coverage order; deriving least-privilege scopes from
|
||||||
|
*measured* consumers; and the exposures rotation does not fix (cleartext channels,
|
||||||
|
git history, agent-authored drawers).
|
||||||
|
|
||||||
|
**Three smoke assertions extended** so a rebuild cannot silently drop the new
|
||||||
|
skill: baked-file existence, resolves-to-the-baked-tree, and reported as `baked`
|
||||||
|
by `pi-devbox-version`. Skill directories are picked up by a glob in
|
||||||
|
`entrypoint-user.sh`, so no registration was needed — verified rather than
|
||||||
|
assumed, since an enumerated list would have left the skill inert, which would
|
||||||
|
have been a fitting way for *this* skill to fail.
|
||||||
|
|
||||||
|
Neither change reaches a running container until the image is rebuilt **and** the
|
||||||
|
container recreated: `~/.agents/skills/` and the global `AGENTS.md` both live in
|
||||||
|
the image, not in a volume or a mount.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v1.8.11 — 2026-08-27
|
## v1.8.11 — 2026-08-27
|
||||||
|
|
||||||
**Shell state that the writable layer eats on every recreate now gets rebuilt at
|
**Shell state that the writable layer eats on every recreate now gets rebuilt at
|
||||||
|
|||||||
Reference in New Issue
Block a user