docs(memory): the talk-deploy permission problem never existed

Vuong asked me to find and fix the harness issue blocking tts-dev from deploying
talk. There was no harness issue, and no issue of any kind.

/opt/docker/compose on nh3-dev is root:docker 2775, agent sessions run as lkraven,
and lkraven is in the docker group. A mkdir settles it in one second and nobody ran
one for nine days. There is also no tts-dev OS account, so the group request had no
referent.

It held together because a stale persistent-memory row supplied a plausible
mechanism and the operator's routing instruction - 'give it to infra' - was read as
corroboration of a capability limit. Those are different claims and only one was
ever stated: a routing preference explains where work went, never whether it could
have gone elsewhere. A contradicting ls -la was on screen in the same session and
was dropped. I then repeated the claim to the operator as fact in a deploy report,
which put a second name behind it.

Then I did the same thing one layer up. Finding no OS problem and no deny rule, I
inferred an auto-mode classifier refusal because the shape fit, and committed a
settings.json into tts-dev's repo on that inference. Their mkdir showed the path
writes with no refusal at all, so the hypothesis was wrong and the commit is
reverted. I had spent the night writing up this failure class and still built a fix
for a layer nobody had shown me failing.

That commit also claimed a doc correction it did not contain: the edit and the
commit were chained in one invocation, the edit's anchor assertion failed because
the target text had already been fixed, and the commit ran regardless. Amended
before reverting. Never chain an edit and its commit in one invocation.

The rule worth keeping is that 'I can't do X' from any source is a hypothesis until
someone runs the command and pastes the error, and that 'there is no error text,
because there was no error' is a possible answer.
This commit is contained in:
vh
2026-09-15 09:23:57 -07:00
parent af8d6df387
commit f4320ff57e
2 changed files with 49 additions and 0 deletions
@@ -64,6 +64,53 @@ edit silently left the live tool behind, so the first "fixed" test ran the OLD c
Caught it; the next person could read stale output as proof a correct fix failed and
revert it. Now a symlink. **Check what you are running, not what you edited.**
## ⚠ The sibling failure: a claim nobody ever measured
The nine above are broken instruments. This one is *no instrument at all*, and it cost
more than any of them on 2026-09-15.
**The talk-deploy "permission problem" never existed.** tts-dev's `docs/infrastructure.md`
and a stale `persistent-memory.md` row said `/opt/docker/compose` on nh3-dev was not
project-writable. It is `root:docker 2775`, agent sessions run as `lkraven`, and
`lkraven` is in the `docker` group — a `mkdir` proves it in one second. **Nobody ran one
for nine days.** There is no `tts-dev` OS account either, so "add tts-dev to the docker
group" had no referent at all.
How it held together:
1. A **stale memory row** (`root:root`) supplied a plausible mechanism.
2. The operator's **routing instruction** ("give it to infra") was read as
*corroboration of a capability limit*. ⭐ **Those are different claims and only one
was ever stated** — a routing preference explains where work went, never whether it
could have gone elsewhere.
3. ⚠ A **contradicting `ls -la` was on screen in the same session** and was noted, then
dropped.
4. **I repeated it to the operator as fact** in a deploy report ("the durable fix is a
group rather than a relay"), which put a second agent's name behind it.
⚠⚠ **And then I did it again, one layer up.** Told to fix the harness issue, I found no
OS problem and no deny rule, inferred the **auto-mode classifier** must be refusing it
(the shape fit — I had been refused twice that night on the same box), and **committed a
`.claude/settings.json` to someone else's repo on that inference.** tts-dev's `mkdir`
then showed their session writes the path with no refusal at all. Reverted. I had spent
the night writing up this exact failure class and still built a fix for a layer nobody
had shown me failing.
⚠ The commit that carried it also **overclaimed a doc correction that never happened**:
I chained the edit and the commit in one invocation, the edit's anchor assertion failed
because the target text was already gone, and the commit ran anyway. **Never chain an
edit and its commit in one invocation** — a failed edit still produces a commit message
asserting it.
⭐ **The rule: "I can't do X" from any source — a doc, a peer, a memory row — is a
hypothesis until someone runs the command and pastes the error.** Ask for the error text
before designing around it. "There is no error text, because there was no error" is a
possible answer, and it was the right one here.
⭐ **Distinguish the layer before fixing it.** A shell `Permission denied` is a Unix
problem; a refusal naming permission rules or auto-mode is a harness one. Different
fixes, and neither applies when nothing failed.
## Related
`2026-09-15-talk-v10-deploy.md` (#2, and the gate built for it),