decisions: SKILLS.md is the skills contract (#7)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4upF5LVwmPDDqrhdUfnXh
This commit is contained in:
1 parent
372ce5c0a0
commit
679f74c9b0
1 file changed
+1
@@ -38,3 +38,4 @@ Format: date · decision · why. Add at the bottom. Never edit an old entry; sup
|
||||
- 2026-10-14 · **Correction: the temporary admin tokens were not revoked when this log said.** The `ANTHROPIC_API_KEY` entry says the token used to set the secret was "revoked within minutes"; it wasn't. `gitea admin user` has no command that deletes a token, and the call meant to do it failed without anyone seeing an error. Four short-lived `teahubxyz` tokens (for the user-level secret and variables, Time's repo variables, and the push that made PRs go out as `time`) stayed valid for 11 to 65 minutes, were never printed, and were deleted from the database by 20:23 UTC (`access_token` ids 22, 23, 24, 26). The only token on prod now is `time`'s own (`TIME_TOKEN`). From now on a temporary token is deleted with `sqlite3` on the Fly box, and the deletion is checked by listing the table before anyone writes "revoked". Why: this log is how the next agent knows which credentials exist.
|
||||
- 2026-10-14 · **Every write Time makes, except comments and commit statuses, goes out as `time`.** Widens the entry above, which covered only opening and merging PRs. Gitea 1.24 also refuses the Actions identity label edits (removing a label is a 500); that crashed `promote_next` after time#50 merged and stalled the queue. `gh()` now sends every non-GET call with `TIME_TOKEN` except comments and statuses, which stay with `gitea-actions` because Time's beats are that author's comments. The `time` user never counts as trusted, mention replies ignore it, and `astra.yml` gets the token too (time `c2055e8`). Three more temporary admin tokens were used this evening, to read job logs and push the fix; each was deleted by id and the table checked (ids 27, 28, 29). Also found: Gitea's label events carry no label name, so labelling a card `ready` doesn't wake the heartbeat; promoted cards wait for the hourly tick. Why: one identity that can actually do the factory's writes, and the Actions identity kept for the two things it reliably does.
|
||||
- 2026-10-14 · **The factory runs without the operator: Astra is on, and a steward merges engine PRs.** The operator delegated merging and admin to Claude and approved both explicitly. Astra (`astra.yml`, daily at 13:13 UTC, one Opus call) now labels its picks `queued` instead of `ready`, so they line up behind the existing queue and `promote_next` runs one card at a time (time `97b7667`). Engine PRs (anything under `.github/`) still never merge themselves: Time marks them needs-human, and the **Teahub steward**, a scheduled Claude session (cloud, every 6 hours at :47 past 01, 07, 13 and 19 UTC, automatic approval), reads each one, answers the reviewer, and merges it only if CI is green, it does what its card's DONE line says, it touches no workflows, secrets or deploy, and it doesn't weaken the spend governor or the protected-path rule. The steward also works open andons (never by raising a cap or changing `TIME_MODE`) and repairs a failed heartbeat. Its admin tokens follow the rule above: minted on the Fly box, deleted by id, table checked. Tonight time#54 and time#56 were merged that way and `TIME_ASTRA` was set (tokens 30, 31, 34, all deleted); tokens 32 and 33 belonged to another session and were already gone when checked. Why: the operator doesn't want to be the merge gate, and the engine still shouldn't change without someone reading the diff.
|
||||
- 2026-10-14 · **SKILLS.md is the skills contract**, the third root file beside `AGENTS.md` (how to move here) and `DESIGN.md` (what good looks like): routes (task → one to three skills, named by path), a ledger (upstream ref and tree, version, what each skill writes) and belts (⬜ admitted, 🟩 katas beat no-skill on a named seat, ⬛ grown from our traces, 💤 retired once a seat no longer needs it). Skills are never left to auto-trigger, and no model decides which skill to load. `.agents/skills/README.md` now points to it and AGENTS.md has the move. (The first skills README said Claude Code reads `.agents/skills/`; it reads `.claude/skills/` only.) Why: the Oct 14 skills research — unaided triggering fires about half the time, generic skills often add nothing on strong models, and the trust that holds comes from gates (evals, pinned refs, sandboxes), not prose. Time's seats are plain API calls, so routing has to live in a file every seat can read (#7).
|
||||
Reference in new issue
Block a user