docs(guides): slice 1 identities round 3, revoke before rm

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-04 22:14:10 -05:00
co-authored by Claude Opus 5.5
parent ee82aa5e4f
commit 98814a67d2
2 changed files with 19 additions and 11 deletions
+1
View File
@@ -488,3 +488,4 @@ are never rewritten or removed; corrections are new entries.
2026-10-05T02:58:34Z | Sage (T3 Claude Code, thread 1ef1e4f8) | slice 1 SR runbook, S5 rulings | docs/guides/slice-1-identities.md drafted for Darkwing's review (row 35); lead decision 56 accepts Dewey's Q1-Q5; Rocko started row 37 2026-10-05T02:58:34Z | Sage (T3 Claude Code, thread 1ef1e4f8) | slice 1 SR runbook, S5 rulings | docs/guides/slice-1-identities.md drafted for Darkwing's review (row 35); lead decision 56 accepts Dewey's Q1-Q5; Rocko started row 37
2026-10-05T03:03:02Z | Sage (T3 Claude Code, thread 1ef1e4f8) | schema v3a | Darkwing's v3a (29daa482) rerun matched on Node 26; lead decision 57; row 37 note 2026-10-05T03:03:02Z | Sage (T3 Claude Code, thread 1ef1e4f8) | schema v3a | Darkwing's v3a (29daa482) rerun matched on Node 26; lead decision 57; row 37 note
2026-10-05T03:10:32Z | Sage (T3 Claude Code, thread 1ef1e4f8) | row 35 SR round 2 | guide revised per Darkwing's round 1 (comment 26709): mint error path, jq strings, read -rs Gitea tokens, business-prefixed bot names; PRD 0.4 REQ-CRED-1 naming; lead decision 58 2026-10-05T03:10:32Z | Sage (T3 Claude Code, thread 1ef1e4f8) | row 35 SR round 2 | guide revised per Darkwing's round 1 (comment 26709): mint error path, jq strings, read -rs Gitea tokens, business-prefixed bot names; PRD 0.4 REQ-CRED-1 naming; lead decision 58
2026-10-05T03:14:10Z | Sage (T3 Claude Code, thread 1ef1e4f8) | row 35 SR round 3 | Darkwing's round 2 (comment 26712): revoke before rm in rotation; optional items taken (.new then mv, one-role loop, api silent-failure note, botId placeholder)
+18 -11
View File
@@ -92,8 +92,9 @@ password, so this part uses the web UI.
done done
``` ```
`read` and `printf` are shell builtins, so the value never reaches For one role, as in a rotation, name only that role: `for r in coder;
`ps` or the history. Don't use an editor, which can leave a swap or do ...`. `read` and `printf` are shell builtins, so the value never
reaches `ps` or the history. Don't use an editor, which can leave a swap or
backup copy behind. backup copy behind.
5. Log out of each bot account. Record today's date as each Gitea 5. Log out of each bot account. Record today's date as each Gitea
token's `rotateBy` base. Section 5 has the rotation schedule. token's `rotateBy` base. Section 5 has the rotation schedule.
@@ -194,7 +195,9 @@ for r in pm cto coder reviewer sync; do
done done
``` ```
Note the five ids. Bot usernames must start with `bot-`, and this guide Note the five ids. Each call prints one line. A missing line means the
call failed, because `api` uses `curl -sf`, which prints nothing on an
HTTP error. Bot usernames must start with `bot-`, and this guide
uses `bot-<business>-<role>` so two businesses on one instance don't uses `bot-<business>-<role>` so two businesses on one instance don't
collide. collide.
@@ -242,9 +245,10 @@ mint() { # mint ROLE BOT_ID SCOPES_FILE
curl -s --fail-with-body -H @"$S/vikunja-owner.hdr" -H 'Content-Type: application/json' \ curl -s --fail-with-body -H @"$S/vikunja-owner.hdr" -H 'Content-Type: application/json' \
-X POST "$VK/api/v2/tokens" --data-binary @- -o "$resp" || -X POST "$VK/api/v2/tokens" --data-binary @- -o "$resp" ||
{ jq -c '{code, message}' "$resp"; rm -f "$resp"; return 1; } { jq -c '{code, message}' "$resp"; rm -f "$resp"; return 1; }
jq -je '.token | strings' "$resp" > "$S/$r-vikunja.token" && jq -je '.token | strings' "$resp" > "$S/$r-vikunja.token.new" &&
mv "$S/$r-vikunja.token.new" "$S/$r-vikunja.token" &&
jq -c '{id, owner_id, expires_at, starts_tk: (.token | startswith("tk_"))}' "$resp" jq -c '{id, owner_id, expires_at, starts_tk: (.token | startswith("tk_"))}' "$resp"
rm -f "$resp" rm -f "$resp" "$S/$r-vikunja.token.new"
} }
mint pm <pm id> "$S/scopes-pm.json" mint pm <pm id> "$S/scopes-pm.json"
mint cto <cto id> "$S/scopes-worker.json" mint cto <cto id> "$S/scopes-worker.json"
@@ -257,8 +261,9 @@ Check that each line shows `starts_tk: true` and the `expires_at` you
set. Vikunja accepts a past expiry without complaint, so read it. On an set. Vikunja accepts a past expiry without complaint, so read it. On an
error, `mint` prints the response's `code` and `message`, which carry no error, `mint` prints the response's `code` and `message`, which carry no
token. Code 14002 means a scope name is wrong. Fix the scope file and token. Code 14002 means a scope name is wrong. Fix the scope file and
mint again. If the response has no `token` field, `mint` writes nothing mint again. If the response has no `token` field, `mint` stops and
usable and stops; delete the empty file before you retry. leaves any existing token file as it was, so a bad mint during rotation
doesn't empty the live file.
## 4. Check and clean up ## 4. Check and clean up
@@ -276,7 +281,8 @@ passing for all nine, closes row SR's gate.
The business file (`~/.config/mosaic-dev/businesses/mosaic-stack.json`, The business file (`~/.config/mosaic-dev/businesses/mosaic-stack.json`,
row S1) references each file by absolute path, and never holds a value. row S1) references each file by absolute path, and never holds a value.
One role's entry looks like this. Row S1's validator has the final One role's entry looks like this. Row S1's validator has the final
shape. shape. `botId` 0 is a placeholder for the id you noted in section 3, and
S1 refuses 0.
```json ```json
"coder": { "definition": "coder", "coder": { "definition": "coder",
@@ -294,9 +300,10 @@ role. The stack never writes this file.
- **Vikunja**, before `expires`: in a new shell, rerun section 0, the - **Vikunja**, before `expires`: in a new shell, rerun section 0, the
owner login in section 2, and the `api` and `mint` definitions in owner login in section 2, and the `api` and `mint` definitions in
section 3. Mint a new token for the same bot, update `expires` in the section 3. Mint a new token for the same bot, update `expires` in the
business file, restart the broker, and finish with section 4's business file, and restart the broker. Revoke the old token while the
`rm -f`. Then revoke the old token: owner header still exists:
`api -X DELETE "$VK/api/v2/tokens/<old id>"`. The broker refuses to `api -X DELETE "$VK/api/v2/tokens/<old id>"`. Then finish with section
4's `rm -f`, which deletes the header. The broker refuses to
start with a token past its `expires`, and it treats any 401 as a start with a token past its `expires`, and it treats any 401 as a
refusal, never a retry. refusal, never a retry.
- **Gitea**, every 90 days or at once if a token may have leaked: log in - **Gitea**, every 90 days or at once if a token may have leaked: log in