From 8cf1d0270e952c88b0013b64018b4d228fb580a0 Mon Sep 17 00:00:00 2001 From: pokemanricko Date: Fri, 21 Aug 2026 08:05:43 +0000 Subject: [PATCH] docs(skills): capture PR-editing + symlink-guard testing lessons - github-codespace: document REST PATCH fallback when 'gh pr edit' lacks read:project scope (device-code gho_ token works; ghu_ App token 403s) - codespace-persistent-symlinks: add test-stub-leak pitfall (never cp runtime stub back into tracked config; Greptile caught defaultProvider:'x' shipped this way) and 'name config dirs after the tool not the skill' guidance --- .../codespace-persistent-symlinks/SKILL.md | 21 +++++++++++++++++++ .../skills/github-codespace/SKILL.md | 14 +++++++++++++ 2 files changed, 35 insertions(+) diff --git a/.devcontainer/skills/codespace-persistent-symlinks/SKILL.md b/.devcontainer/skills/codespace-persistent-symlinks/SKILL.md index e55153d..e1da59f 100644 --- a/.devcontainer/skills/codespace-persistent-symlinks/SKILL.md +++ b/.devcontainer/skills/codespace-persistent-symlinks/SKILL.md @@ -64,6 +64,27 @@ self-check.sh). Run locally: ONLY the injected marker line (perl/grep), never tail-trim — you can truncate a real directive and the file shrinks unexpectedly (observed 1297B → 504B). - Verify the guard against ALL THREE cases, not just the happy path. +<<<<<<< Updated upstream +======= +- **Mixed-state runtime dirs need per-file symlinks, not whole-folder.** `~/.pi/agent/` + is the canonical case: symlink only `models.json`/`settings.json` into + `.devcontainer/pi-config/`; never symlink the whole dir (it drags in `auth.json`, + `sessions/`, locks). Add a `start-hermes.sh` guard to re-link past the tool's own + first-launch stub, and verify the guard replaces a plain stub with the symlink. +- **Test-stub leak: never `cp` from runtime back to tracked during guard testing.** When + simulating a rebuild, the runtime file (e.g. `~/.pi/agent/settings.json`) may contain + the tool's own stub (`defaultProvider: "x"`). If you `cp` it to the tracked location + (`.devcontainer/pi-config/settings.json`), you commit the stub instead of the intended + config. Instead: write the correct canonical content to the tracked file directly, then + verify the guard correctly relinks from tracked → runtime. The guard's job is + tracked→runtime; the test's job is to ensure tracked has the RIGHT content. (Observed: + Greptile caught `defaultProvider: "x"` shipped in a PR because a rebuild-sim had copied the + pi stub back into the tracked file.) +- **Name tracked config dirs after the tool, not the skill.** A folder named after the + installing skill (e.g. `firstmate/` holding pi's LM config) is misleading to reviewers and + drifts from the PR's actual purpose. Name it for what it holds (`pi-config/`), and keep the + PR title scoped to the real change (persisting pi config), not the skill install. +>>>>>>> Stashed changes ## Sync note (wiki) - `persistent-memory-proposal.md` — reference/proposal doc vs this procedural skill. diff --git a/.devcontainer/skills/github-codespace/SKILL.md b/.devcontainer/skills/github-codespace/SKILL.md index fb0f053..9eb5a97 100644 --- a/.devcontainer/skills/github-codespace/SKILL.md +++ b/.devcontainer/skills/github-codespace/SKILL.md @@ -422,6 +422,20 @@ Key principles: --- +### Editing PR title/body when `gh pr edit` lacks scope + +`gh pr edit` can fail with `your authentication token is missing required scopes [read:project]` — `repo` + `workflow` scopes are not enough on some orgs, and `gh auth refresh -s read:project` is interactive (won't complete unattended). Fallback: PATCH the PR directly via the REST API using the OAuth token `gh` already stored from the device-code flow: + +```bash +# Parse gh's stored OAuth token (gho_) from its hosts config +TOK=$(python3 -c "import re; print(re.search(r'oauth_token:\s*(\S+)', open('/home/codespace/.config/gh/hosts.yml').read()).group(1))") +curl -s -X PATCH "https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER" \ + -H "Authorization: token $TOK" -H "Accept: application/vnd.github+json" \ + -d '{"title":"new title","body":"new body"}' +``` + +The device-code `gho_` token has `repo` scope, so this works. Do NOT use the VS Code server App token (`ghu_`) for this — it returns 403 on PR PATCH (App-gated, pull-only on the origin repo). Apply the same pattern to set the body alone (`{"body": "..."}`) or title alone. + ## Public Repo API Access Without Auth For public repos, the GitHub REST API works without authentication for: