Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .devcontainer/skills/codespace-persistent-symlinks/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines +67 to +87

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Unresolved conflict markers remain

When this skill is read or validated, the committed Git conflict markers expose unresolved merge metadata around the new guidance, leaving the intended document state ambiguous and causing checks that reject conflict markers to fail.

Suggested change
<<<<<<< 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
- **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.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .devcontainer/skills/codespace-persistent-symlinks/SKILL.md
Line: 67-87

Comment:
**Unresolved conflict markers remain**

When this skill is read or validated, the committed Git conflict markers expose unresolved merge metadata around the new guidance, leaving the intended document state ambiguous and causing checks that reject conflict markers to fail.

```suggestion
- **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.
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.


## Sync note (wiki)
- `persistent-memory-proposal.md` — reference/proposal doc vs this procedural skill.
Expand Down
14 changes: 14 additions & 0 deletions .devcontainer/skills/github-codespace/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading