@jaybeeuu/agent-cortex 1.41.1 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/style-versioning/SKILL.md +73 -2
- package/.github/workflows/ci.yml +52 -32
- package/AGENTS.md +23 -2
- package/CHANGELOG.md +189 -0
- package/README.md +125 -73
- package/agents/README.md +17 -4
- package/agents/ralph-plan/agent.md +7 -3
- package/agents/ralph-plan.agent.md +7 -3
- package/bin/agent-cortex.mjs +48 -30
- package/bin/installers/pi.mjs +885 -237
- package/claude-extras/scripts/statusline-command.sh +0 -0
- package/docs/claude-hooks.md +5 -4
- package/docs/commit-signing.md +231 -0
- package/docs/ideas/ban-content-assertion-tests.md +3 -1
- package/docs/ideas/dedicated-review-tests-skill.md +71 -0
- package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md +10 -1
- package/docs/ideas/extension-manifests.md +5 -0
- package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +71 -0
- package/docs/research/disable-model-invocation.md +103 -0
- package/docs/research/skill-design-research.md +2 -2
- package/docs/skills/skill-anatomy.md +5 -1
- package/docs/technical-direction/harness-config.md +25 -1
- package/docs/technical-direction/migration-execution-labels.md +17 -9
- package/extensions/agent-modes/discover.test.ts +19 -0
- package/extensions/agent-modes/discover.ts +25 -3
- package/extensions/session-start/README.md +38 -0
- package/extensions/session-start/index.test.ts +122 -0
- package/extensions/session-start/index.ts +27 -0
- package/extensions/session-start/package.json +19 -0
- package/extensions/session-start/tsconfig.json +12 -0
- package/extensions/subagent/README.md +1 -1
- package/extensions/subagent/agents.test.ts +176 -0
- package/extensions/subagent/agents.ts +102 -11
- package/extensions/subagent/index.ts +2 -1
- package/extensions/subagent/package.json +1 -1
- package/lib/cli.mjs +35 -9
- package/package.json +10 -6
- package/pi/settings.json +1 -7
- package/plugin.json +1 -1
- package/pnpm-workspace.yaml +6 -0
- package/scripts/check-changeset.mjs +42 -0
- package/scripts/install-instructions.sh +0 -0
- package/scripts/lib/release-gates.mjs +61 -0
- package/scripts/lib/verify-worker-tree.mjs +107 -0
- package/scripts/resolve-publish-command.mjs +17 -0
- package/scripts/sync-plugin-version.sh +0 -0
- package/skills/engineering/grill-with-docs/SKILL.md +3 -2
- package/skills/engineering/improve-codebase-architecture/REFERENCE.md +5 -0
- package/skills/engineering/improve-codebase-architecture/SKILL.md +2 -1
- package/skills/planning/create-task/SKILL.md +8 -3
- package/skills/planning/create-task/scripts/create-chores.ts +4 -1
- package/skills/planning/prd-to-tasks/REFERENCE.md +2 -2
- package/skills/planning/prd-to-tasks/SKILL.md +9 -4
- package/skills/planning/request-refactor-plan/FORMAT.md +5 -0
- package/skills/planning/request-refactor-plan/SKILL.md +3 -2
- package/skills/planning/spec-to-tickets/REFERENCE.md +82 -0
- package/skills/planning/spec-to-tickets/SKILL.md +143 -0
- package/skills/planning/write-a-prd/FORMAT.md +6 -0
- package/skills/planning/write-a-prd/SKILL.md +9 -6
- package/skills/planning/write-a-ticket/EXAMPLES.md +133 -0
- package/skills/planning/write-a-ticket/SKILL.md +77 -59
- package/skills/productivity/bd-tool/SKILL.md +27 -2
- package/skills/productivity/grill-me/SKILL.md +11 -0
- package/skills/review/review-security/scripts/install-gitleaks.sh +0 -0
- package/skills/workflow/git-workflow/SKILL.md +35 -1
- package/skills/workflow/plan/SKILL.md +20 -8
- package/skills/workflow/ralph/REFERENCE.md +20 -2
- package/skills/workflow/ralph/SKILL.md +4 -1
- package/skills/workflow/run-pipeline-stage/SKILL.md +17 -5
- package/skills/workflow/run-pipeline-stage/playbooks/code.md +2 -0
- package/skills/workflow/run-pipeline-stage/playbooks/document.md +3 -0
- package/skills/workflow/run-pipeline-stage/playbooks/fix.md +2 -0
- package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +11 -0
- package/skills/workflow/using-agent-skills/SKILL.md +1 -0
- package/test/cli.test.mjs +26 -29
- package/test/create-chores.test.mjs +12 -0
- package/test/fake-bd.test.mjs +72 -0
- package/test/helpers/fake-bd.mjs +26 -6
- package/test/helpers/fake-pi.mjs +132 -0
- package/test/pi-installer.test.mjs +345 -286
- package/test/pi-register.test.mjs +342 -0
- package/test/pi-sweep.test.mjs +619 -0
- package/test/release-gates.test.mjs +190 -0
- package/test/verify-worker-tree.test.mjs +120 -0
- package/token-map.README.md +7 -6
- package/token-map.json +6 -5
- package/extensions/agent-guardrails/node_modules/.bin/pi +0 -21
- package/extensions/agent-guardrails/node_modules/.bin/tsc +0 -21
- package/extensions/agent-guardrails/node_modules/.bin/tsserver +0 -21
- package/extensions/agent-guardrails/node_modules/.bin/tsx +0 -21
- package/extensions/agent-modes/node_modules/.bin/pi +0 -21
- package/extensions/agent-modes/node_modules/.bin/tsc +0 -21
- package/extensions/agent-modes/node_modules/.bin/tsserver +0 -21
- package/extensions/agent-modes/node_modules/.bin/tsx +0 -21
- package/extensions/session-start.ts +0 -44
- package/extensions/skill-stats/node_modules/.bin/pi +0 -21
- package/extensions/skill-stats/node_modules/.bin/tsc +0 -21
- package/extensions/skill-stats/node_modules/.bin/tsserver +0 -21
- package/extensions/skill-stats/node_modules/.bin/tsx +0 -21
- package/extensions/subagent/node_modules/.bin/pi +0 -21
- package/extensions/subagent/node_modules/.bin/pi-ai +0 -21
- package/extensions/subagent/node_modules/.bin/tsc +0 -21
- package/extensions/subagent/node_modules/.bin/tsserver +0 -21
- package/extensions/subagent/node_modules/.bin/tsx +0 -21
- package/lib/pi-packages.mjs +0 -169
- package/skills/planning/create-task/scripts/node_modules/.bin/tsc +0 -21
- package/skills/planning/create-task/scripts/node_modules/.bin/tsserver +0 -21
- package/skills/planning/create-task/scripts/node_modules/.bin/tsx +0 -21
- package/skills/productivity/validate-agent-dir/scripts/node_modules/.bin/tsc +0 -21
- package/skills/productivity/validate-agent-dir/scripts/node_modules/.bin/tsserver +0 -21
- package/skills/productivity/validate-agent-dir/scripts/node_modules/.bin/tsx +0 -21
- package/skills/workflow/run-pipeline-stage/scripts/node_modules/.bin/tsc +0 -21
- package/skills/workflow/run-pipeline-stage/scripts/node_modules/.bin/tsserver +0 -21
- package/skills/workflow/run-pipeline-stage/scripts/node_modules/.bin/tsx +0 -21
- package/test/pi-packages.test.mjs +0 -295
|
File without changes
|
package/docs/claude-hooks.md
CHANGED
|
@@ -14,7 +14,7 @@ UI surface. Each decision below is grounded in the Claude Code hooks reference.
|
|
|
14
14
|
|
|
15
15
|
| pi extension | Claude port | Decision |
|
|
16
16
|
|---|---|---|
|
|
17
|
-
| `session-start
|
|
17
|
+
| `session-start/` | `SessionStart` hook commands | **Port** (extended) |
|
|
18
18
|
| `auto-name.ts` | — | **Reject** — built-in |
|
|
19
19
|
| `agent-guardrails/` | — | **Reject** — pi-only (no system-prompt hook) |
|
|
20
20
|
| `notify/` | `Notification` hook + `scripts/notify.mjs` | **Port** |
|
|
@@ -22,10 +22,11 @@ UI surface. Each decision below is grounded in the Claude Code hooks reference.
|
|
|
22
22
|
| `subagent/` | — | **Reject** — native |
|
|
23
23
|
| `agent-modes/` | — | **Reject** — no equivalent |
|
|
24
24
|
|
|
25
|
-
## `session-start
|
|
25
|
+
## `session-start/` → SessionStart (port)
|
|
26
26
|
|
|
27
|
-
pi injects
|
|
28
|
-
|
|
27
|
+
pi injects the project context files (AGENTS.md, `docs/user-preferences.md`)
|
|
28
|
+
into every session; it lists no skills, since pi's system prompt already names
|
|
29
|
+
every skill with its `SKILL.md` path. Claude Code already loads
|
|
29
30
|
`AGENTS.md` natively and the existing SessionStart hook nudge ("Load AGENTS.md
|
|
30
31
|
and active beads context…") plus the style-skill policy (PR #57) cover the
|
|
31
32
|
context side. This bead closes the remaining gap: a skill-policy command listing
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Commit signing
|
|
2
|
+
|
|
3
|
+
GitHub has refused merges here with **"Merging is blocked — Commits must have verified
|
|
4
|
+
signatures"**. The instinctive reading — "agents don't sign, so of course" — is wrong:
|
|
5
|
+
agent and human commits on this repo are GPG-signed and verified. The unsigned commits
|
|
6
|
+
are the ones `github-actions[bot]` writes, and only because `GITHUB_TOKEN` cannot hold a
|
|
7
|
+
signing key. This note records what is actually signed, what the API says about
|
|
8
|
+
enforcement, and the release policy that follows.
|
|
9
|
+
|
|
10
|
+
## What is signed, and what is not
|
|
11
|
+
|
|
12
|
+
The agent environment signs automatically. Global git config has `commit.gpgsign=true`
|
|
13
|
+
and the secret key `DF657A88675E4AF8F7D65192A8F2E11DE960BE54` (Josh Bickley-Wallace,
|
|
14
|
+
the `noreply` address) is present, so every commit an agent makes is signed without any
|
|
15
|
+
per-commit step. Verified against the API:
|
|
16
|
+
|
|
17
|
+
| Commit | Author | `verification` |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `63f3bef` (PR #181 head) | jaybeeuu | `verified=true reason=valid` |
|
|
20
|
+
| `7f99e4c` (PR #182 head) | jaybeeuu | `verified=true reason=valid` |
|
|
21
|
+
| `9443f55` (PR #168 head) | github-actions[bot] | `verified=false reason=unsigned` |
|
|
22
|
+
|
|
23
|
+
`changesets/action` commits as `github-actions[bot]` using `secrets.GITHUB_TOKEN`, and
|
|
24
|
+
GitHub does not sign commits made with a token. That is a property of the token, not a
|
|
25
|
+
missing configuration step — no amount of workflow YAML changes it.
|
|
26
|
+
|
|
27
|
+
Landed history looks uniformly `valid` for a different reason: the commit the merge creates
|
|
28
|
+
is signed by GitHub. `dd347471b1`, the commit that landed PR #161 ("chore: version
|
|
29
|
+
packages", authored by `github-actions[bot]`), has `committer=GitHub` and
|
|
30
|
+
`verification.verified=true reason=valid`. The bot's unsigned branch commit never reached
|
|
31
|
+
`main`; the squash commit GitHub created did, and GitHub signed it.
|
|
32
|
+
|
|
33
|
+
That is what this repository's history proves, and it is all it proves. It does **not**
|
|
34
|
+
prove that a squash merge escapes an *enforced* signature rule.
|
|
35
|
+
|
|
36
|
+
## Squash does not bypass an enforced signature rule
|
|
37
|
+
|
|
38
|
+
The landing commit being GitHub-signed does not exempt the pull request from the check:
|
|
39
|
+
a ruleset that requires signatures inspects the head-branch commits too. GitHub's ruleset
|
|
40
|
+
reference, ["Require signed commits"](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#require-signed-commits)
|
|
41
|
+
(quoted verbatim, checked 2026-10-27):
|
|
42
|
+
|
|
43
|
+
> When GitHub evaluates whether a pull request can be merged, it creates a test merge commit
|
|
44
|
+
> whose parents are the latest commit on the base branch and the pull request's head commit.
|
|
45
|
+
> GitHub checks the commits introduced by this test merge, including commits from the head
|
|
46
|
+
> branch. As a result, unsigned commits on the head branch can block a squash merge, even
|
|
47
|
+
> though GitHub would sign the final squash commit. This restriction can also apply to the
|
|
48
|
+
> author of the pull request.
|
|
49
|
+
|
|
50
|
+
and the remedy it documents:
|
|
51
|
+
|
|
52
|
+
> To merge a blocked pull request, rewrite and sign the unsigned commits on the head branch,
|
|
53
|
+
> or ask someone with permission to bypass the applicable protections to merge the pull
|
|
54
|
+
> request.
|
|
55
|
+
|
|
56
|
+
So "squash it and let GitHub re-sign" is not a way *around* the check — it is only the reason
|
|
57
|
+
landed history reads `valid` when no signature rule is in force. If a signature rule is
|
|
58
|
+
enforced, the remedy is a signed commit, not a different merge method.
|
|
59
|
+
|
|
60
|
+
## What the ruleset API shows — and what it cannot
|
|
61
|
+
|
|
62
|
+
No `required_signatures` rule is visible to the tokens available here, at any level.
|
|
63
|
+
Read-only probes:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
$ gh api repos/jaybeeuu/agent-cortex/rules/branches/main --jq '[.[].type]'
|
|
67
|
+
["deletion","non_fast_forward","required_linear_history",
|
|
68
|
+
"required_status_checks","pull_request"]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Every effective rule on `main` comes from `ruleset_id 22101709` with
|
|
72
|
+
`ruleset_source_type: Repository`. That is evidence rather than silence, because the endpoint
|
|
73
|
+
is not repository-scoped by construction: it is documented to return rules "regardless of the
|
|
74
|
+
level at which they are configured (e.g. repository or organization)", and its own response
|
|
75
|
+
schema includes a `ruleset_source_type: "Organization"` example ([REST reference, "Get rules for a branch"](https://docs.github.com/en/rest/repos/rules#get-rules-for-a-branch), checked
|
|
76
|
+
2026-10-27). There is no `required_signatures` rule in it, and its `pull_request` parameters
|
|
77
|
+
allow `["merge","squash","rebase"]`. The other read paths agree:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
$ gh api repos/jaybeeuu/agent-cortex/branches/main/protection
|
|
81
|
+
{"message":"Branch not protected", ... "status":"404"}
|
|
82
|
+
|
|
83
|
+
$ gh api orgs/jaybeeuu/rulesets
|
|
84
|
+
{"message":"Not Found", ... "status":"404"}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Two explanations remain. The branch-rule read above weighs heavily against the first, without
|
|
88
|
+
formally eliminating it:
|
|
89
|
+
|
|
90
|
+
1. **An organization-level ruleset enforces signatures.** This is the weaker of the two now:
|
|
91
|
+
the applied-rule read covers every level and shows no organization-sourced rule, so this
|
|
92
|
+
survives only on an undocumented possibility that the endpoint filters by caller
|
|
93
|
+
visibility. Org ruleset *definitions* do separately require organization administration
|
|
94
|
+
read, which the current token does not hold (scopes: `gist, read:org, repo, workflow`), so
|
|
95
|
+
a `404` on `orgs/jaybeeuu/rulesets` is inconclusive — it may mean "none exist" or "you may
|
|
96
|
+
not see them". Note that the ruleset's `bypass_actors` is empty and
|
|
97
|
+
`current_user_can_bypass` is `"never"`, so repository admin does **not** bypass it.
|
|
98
|
+
2. **The UI message was stale** — shown while a signature rule was active, before ruleset
|
|
99
|
+
`22101709` was last updated (2026-09-13).
|
|
100
|
+
|
|
101
|
+
Closing this out needs a merge attempt (a mutation) or org-admin access: see *The enforcing
|
|
102
|
+
rule: still open (AC1)* and the human follow-ups below.
|
|
103
|
+
|
|
104
|
+
One adjacent rule is worth knowing, though it cannot fire here. Ruleset `22101709` sets
|
|
105
|
+
`require_extra_approval_for_unattributed_changes: true`, which adds one approval when a pull
|
|
106
|
+
request is an unattributed Copilot pull request — but GitHub documents that the setting "has
|
|
107
|
+
no effect if the ruleset requires zero approvals" ([available rules for rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets#additional-approval-for-unattributed-copilot-pull-requests),
|
|
108
|
+
checked 2026-10-27), and this ruleset sets `required_approving_review_count: 0`. A blocked
|
|
109
|
+
merge box here is the missing `statusCheckRollup` on a Version Packages PR or a missing
|
|
110
|
+
code-owner review, not this setting.
|
|
111
|
+
|
|
112
|
+
## Policy: land bot-authored PRs by squash merge
|
|
113
|
+
|
|
114
|
+
Adopted: **Option A — no signing key in CI.** So long as no signature rule is enforced, no
|
|
115
|
+
unsigned commit is required to land a release: the merge produces a commit GitHub signs, so
|
|
116
|
+
the only requirement is the merge method.
|
|
117
|
+
|
|
118
|
+
Squash-merge Version Packages PRs (`gh pr merge <n> --squash`). GitHub rewrites the bot's
|
|
119
|
+
unsigned branch commit into a single commit that it signs as committer, which is exactly
|
|
120
|
+
what `dd347471b1` demonstrates. Squash is the only path that lands a GitHub-signed commit:
|
|
121
|
+
`allow_merge_commit` is `false` in the repository merge settings, so a true merge commit is
|
|
122
|
+
impossible, and `required_linear_history` on `main` means a pull request "must use a squash
|
|
123
|
+
merge or a rebase merge". The ruleset's `allowed_merge_methods`
|
|
124
|
+
(`["merge","squash","rebase"]`) leaves both open — its `merge` entry is already dead because
|
|
125
|
+
the repository disables merge commits. Of those two, only squash produces a commit GitHub
|
|
126
|
+
creates and signs: rebase-and-merge is documented to add the head-branch commits "without
|
|
127
|
+
commit signature verification", because the commit it creates is modified and GitHub "can't
|
|
128
|
+
therefore sign it as a generic system user" ([about merge methods](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github),
|
|
129
|
+
checked 2026-10-27). For a `github-actions[bot]` head commit that means an unsigned commit on
|
|
130
|
+
`main`, so rebase is not an acceptable path here even though the settings permit it.
|
|
131
|
+
|
|
132
|
+
Note the limit of this remedy: squash re-signs the landing commit, it does not bypass an
|
|
133
|
+
enforced signature rule (see above). It works here because no such rule is currently
|
|
134
|
+
enforced against this repository.
|
|
135
|
+
|
|
136
|
+
Consequence: the release automation stays fully automated and no signing key enters CI —
|
|
137
|
+
provided no signature rule is enforced. See the contingency below.
|
|
138
|
+
|
|
139
|
+
### Contingency: the enforcing rule turns out to be real at organization level
|
|
140
|
+
|
|
141
|
+
The policy above holds only while a squash merge is permitted. If the merge probe or an org
|
|
142
|
+
admin confirms an organization-level `required_signatures` rule, Option A's premise fails:
|
|
143
|
+
GitHub would then refuse the squash merge as well, because it validates the pull request's
|
|
144
|
+
head commits through the test merge. In that case:
|
|
145
|
+
|
|
146
|
+
1. Do not keep re-attempting the squash merge, and do not treat a bypass as the workaround —
|
|
147
|
+
a bypass is a human permission decision, not a release path.
|
|
148
|
+
2. The release path must produce signed commits, which means Option B (import a key into the
|
|
149
|
+
release job) or having a key-holding actor sign the release commit. That change must land
|
|
150
|
+
with the access audit and rotation procedure Option B requires.
|
|
151
|
+
3. Until then, releasing is a human step performed with bypass permission, recorded as a
|
|
152
|
+
HITL note on the bead.
|
|
153
|
+
|
|
154
|
+
The applied-rule read returns no organization-sourced rule, but org ruleset definitions stay
|
|
155
|
+
unreadable from a repository-scoped token, so re-check the read before assuming the absence
|
|
156
|
+
persists.
|
|
157
|
+
|
|
158
|
+
### Option B, rejected as the default
|
|
159
|
+
|
|
160
|
+
Importing a GPG key into the release job (`GPG_PRIVATE_KEY` + `GPG_PASSPHRASE` secrets and
|
|
161
|
+
a `git commit --amend -S` step) would make the *branch* commit signed too. It is rejected as
|
|
162
|
+
the default because, while no signature rule is enforced, it buys nothing the squash merge
|
|
163
|
+
does not already give — the branch commit is discarded on merge — while placing a
|
|
164
|
+
long-lived private key in repository secrets. That trade-off inverts if a signature rule is
|
|
165
|
+
confirmed enforced: Option B then becomes necessary (see the contingency above). Either way,
|
|
166
|
+
if it is revisited the same change must carry an access audit (who and what can read the
|
|
167
|
+
secret) and a rotation procedure (key expiry, re-issue, revocation). Neither exists today,
|
|
168
|
+
and adding the key without them is not acceptable.
|
|
169
|
+
|
|
170
|
+
## When the signature check fires
|
|
171
|
+
|
|
172
|
+
| Situation | Remedy |
|
|
173
|
+
|---|---|
|
|
174
|
+
| Bot-authored PR blocked on signatures, rule **confirmed** enforced | A squash merge will not help — GitHub checks head-branch commits through its test merge. Rewrite the branch so its commits are signed (`git rebase --exec 'git commit --amend -S --no-edit'` or an amend plus force-push), then merge; otherwise a person with bypass permission merges it. |
|
|
175
|
+
| Bot-authored PR blocked, `rules/branches/main` lists no `required_signatures` rule | The block is most likely not signatures. Read the merge box first: missing required status checks (an empty `statusCheckRollup` on a Version Packages PR is the common case) or a missing code-owner review fully explain `mergeStateStatus=BLOCKED`. |
|
|
176
|
+
| An agent commit is reported unsigned | Check `git config --get commit.gpgsign` and `gpg --list-secret-keys`; re-sign with `git commit --amend -S --no-edit` and force-push the branch. |
|
|
177
|
+
| The block persists with no visible cause | Read `gh api repos/<owner>/<repo>/rules/branches/<branch>`. That endpoint covers every level, so no `required_signatures` entry means no active signature rule applies as far as this read can see — if the block still looks like signatures, have an org admin confirm the org rulesets rather than guessing. |
|
|
178
|
+
|
|
179
|
+
## The enforcing rule: still open (AC1)
|
|
180
|
+
|
|
181
|
+
The parent bead's first acceptance criterion — "Enforcing rule identified, or the UI message
|
|
182
|
+
shown to be stale — with the merge API's error text quoted either way" — is **open**. No
|
|
183
|
+
merge API error text exists yet, because obtaining it requires a merge attempt, which is a
|
|
184
|
+
mutation and therefore a human step. Read-only evidence narrows the question sharply but
|
|
185
|
+
does not close it:
|
|
186
|
+
|
|
187
|
+
1. **No repository-level signature rule was blocking on 2026-10-13.** PR #161's head
|
|
188
|
+
`fe7ef84` is `verification.verified=false reason=unsigned`, and the PR was squash-merged
|
|
189
|
+
at `2026-10-13T21:46:06Z` — after ruleset `22101709`'s last update
|
|
190
|
+
(`2026-09-13T21:11:23.985+01:00`, i.e. `2026-09-13T20:11:23Z`). An unsigned head landed
|
|
191
|
+
after the ruleset's last edit, so neither that ruleset nor anything older in it enforced
|
|
192
|
+
signatures then.
|
|
193
|
+
2. **PR #168's current block needs no signature rule to explain it.**
|
|
194
|
+
`gh pr view 168 --json state,mergeable,mergeStateStatus,statusCheckRollup,reviews` returns
|
|
195
|
+
`state=OPEN`, `mergeable=MERGEABLE`, `mergeStateStatus=BLOCKED`,
|
|
196
|
+
`statusCheckRollup=[]`, `reviews=[]`. All five required checks (`Test`, `Lint`,
|
|
197
|
+
`Claude plugin materialiser check`, `Changeset check`, `Setup`) are unreported, and
|
|
198
|
+
`require_code_owner_review` is on with no reviews. `required_status_checks` plus the
|
|
199
|
+
missing code-owner review fully account for `BLOCKED`.
|
|
200
|
+
3. **The applied-rule read comes back clean, including at organization level.**
|
|
201
|
+
`rules/branches/{branch}` is documented to return every active rule "regardless of the
|
|
202
|
+
level at which they are configured (e.g. repository or organization)", so it is the read
|
|
203
|
+
that *would* surface an organization-level rule. The live read returns five rules, all
|
|
204
|
+
`ruleset_source_type: Repository` from `ruleset_id 22101709`, and none of them is
|
|
205
|
+
`required_signatures`. On the documented contract that is positive evidence that no
|
|
206
|
+
organization-level signature rule is applied to `main` today, not an unreadable gap. The
|
|
207
|
+
honest residual is narrower: whether this endpoint filters by caller visibility is
|
|
208
|
+
undocumented, and org ruleset *definitions* stay unreadable with the current token —
|
|
209
|
+
`gh api orgs/jaybeeuu/rulesets` returns `{"message":"Not Found", ... "status":"404"}` and
|
|
210
|
+
`gh api orgs/jaybeeuu` adds `gh: This API operation needs the "admin:org" scope`. So "no
|
|
211
|
+
org rule is applied" is read; "no org ruleset exists" is not.
|
|
212
|
+
|
|
213
|
+
Status: **open, pending a human merge probe or org-admin inspection** (see below). The read
|
|
214
|
+
above narrows the question but cannot close AC1, which turns on the merge API's own error
|
|
215
|
+
text; the merge probe supplies that.
|
|
216
|
+
|
|
217
|
+
## Human-only follow-ups
|
|
218
|
+
|
|
219
|
+
These need repository or organization settings and cannot be done by an agent:
|
|
220
|
+
|
|
221
|
+
- **Merge probe — closes AC1.** Run `gh pr merge 168 --squash` (or
|
|
222
|
+
`PUT /repos/jaybeeuu/agent-cortex/pulls/168/merge`) and record the verbatim error text
|
|
223
|
+
here. A signature error confirms an invisible rule and triggers the contingency above; a
|
|
224
|
+
status-check error confirms the message was stale and closes the criterion as
|
|
225
|
+
"UI message stale".
|
|
226
|
+
- **Inspect org rulesets.** Open `https://github.com/organizations/jaybeeuu/settings/rules`
|
|
227
|
+
and confirm whether a ruleset targets `jaybeeuu/agent-cortex` with "Require signed
|
|
228
|
+
commits". Record the answer here.
|
|
229
|
+
- **Confirm the merge method.** If squash-merge is the documented path, consider removing
|
|
230
|
+
`rebase` from `allowed_merge_methods` so a rebase merge cannot add an unsigned bot
|
|
231
|
+
commit to `main`.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Idea: ban-content-assertion-tests
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
|
-
|
|
4
|
+
Filed as epic `agnt-ctx-h9gt` (2026-10-06) — awaiting `prd-to-tasks`. Slice 1 (the
|
|
5
|
+
`style-tests` ban) shipped earlier in `daa77c8` (PR #143); this epic covers the review-gate
|
|
6
|
+
enforcement and the skill sweep.
|
|
5
7
|
|
|
6
8
|
## Created
|
|
7
9
|
2026-08-30
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Idea: Dedicated review-tests skill
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
Backlog idea (not implementation-ready) — priority P2 (moderate), timing: follows `agnt-ctx-h9gt`
|
|
5
|
+
|
|
6
|
+
## Created
|
|
7
|
+
2026-10-06
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
Test review has no home of its own in the ralph pipeline. The review stage invokes
|
|
11
|
+
`review-security` for a dedicated security pass, then falls back to `style-code` and
|
|
12
|
+
`style-tests` for everything else. `style-tests` is a *writing* skill — it states conventions
|
|
13
|
+
before tests are authored — so a reviewer reading it has to invert authoring guidance into
|
|
14
|
+
review findings. The result is that test defects are caught by whatever the reviewer happens to
|
|
15
|
+
notice rather than by an explicit checklist, and each new class of defect (the content-assertion
|
|
16
|
+
ban being the first) has to be bolted onto the review template individually.
|
|
17
|
+
|
|
18
|
+
## Who benefits
|
|
19
|
+
- **The author**, who stops triaging test defects that a structured review should have caught.
|
|
20
|
+
- **Ralph stage runners**, who get an explicit finding checklist instead of inferring one from a
|
|
21
|
+
writing-conventions skill.
|
|
22
|
+
- **Future skill authors**, who get one place to add a test-review rule rather than editing the
|
|
23
|
+
review template, the review playbook, and `style-tests` in lockstep.
|
|
24
|
+
|
|
25
|
+
## Proposed outcome
|
|
26
|
+
A `review-tests` skill — a peer to `review-security` — that specifies what a reviewer checks in
|
|
27
|
+
a test suite: assertion quality (does each assertion prove the behaviour under test),
|
|
28
|
+
mock discipline (boundaries only, never internals), test-data construction (vital data inline,
|
|
29
|
+
fresh per test, no shared mutable fixtures), determinism (no sleeps, no real clocks, every async
|
|
30
|
+
interaction awaited), and coverage gaps against the task's stated behaviours.
|
|
31
|
+
|
|
32
|
+
Broad scope, narrow use: the skill is generic test-review guidance, invoked as a stage step by
|
|
33
|
+
the ralph review playbook (and available to a human reviewer or a `git-workflow` PR review).
|
|
34
|
+
Once it exists, the content-assertion check added by `agnt-ctx-h9gt` becomes one row inside it
|
|
35
|
+
rather than a standing instruction in the review template.
|
|
36
|
+
|
|
37
|
+
## Validity check
|
|
38
|
+
- Evidence we already have: the review stage already delegates to skills for every other
|
|
39
|
+
concern (`review-security` for security, `style-code` for code shape, `style-documentation`
|
|
40
|
+
for docs) — test review is the gap in an otherwise uniform pattern. The content-assertion
|
|
41
|
+
ban was bolted onto the review template precisely because no skill owned test review.
|
|
42
|
+
- Riskiest assumption: that a *review* checklist is meaningfully different from `style-tests`
|
|
43
|
+
read critically. If a reviewer can derive the findings from the existing authoring skill with
|
|
44
|
+
no loss, this becomes a second statement of the same rules — exactly the two-homes problem
|
|
45
|
+
`agnt-ctx-h9gt` avoids by keeping `style-tests` canonical.
|
|
46
|
+
- What would invalidate this idea: if `agnt-ctx-h9gt`'s review-gate change turns out to be
|
|
47
|
+
sufficient — if the review stage, with the content-assertion check in hand, stops missing
|
|
48
|
+
test defects — then the dedicated skill earns nothing and should be dropped.
|
|
49
|
+
|
|
50
|
+
## Constraints
|
|
51
|
+
- `style-tests` stays the canonical statement of test conventions; `review-tests` must cite it
|
|
52
|
+
and add only the reviewer's framing, or the two will drift.
|
|
53
|
+
- Must not duplicate `review-security`'s ground or re-run the test suite (that is the verify
|
|
54
|
+
stage's job).
|
|
55
|
+
- Invoked from the review playbook, so it must be cheap to load — no expansion of the review
|
|
56
|
+
stage's token budget beyond one skill read.
|
|
57
|
+
- Follows `agnt-ctx-h9gt`; the content-assertion rule must not be restated in a second place
|
|
58
|
+
until this skill exists to hold it.
|
|
59
|
+
|
|
60
|
+
## Next validation step
|
|
61
|
+
After `agnt-ctx-h9gt` has run through the pipeline at least once, collect the test-related
|
|
62
|
+
findings its review stage actually produces across a few PRs. If reviewers keep requesting
|
|
63
|
+
changes on test grounds that the template does not name, that list is the skill's first
|
|
64
|
+
checklist and the idea is confirmed; if the template covers them, drop the idea.
|
|
65
|
+
|
|
66
|
+
## Notes
|
|
67
|
+
Floated by the author on 2026-10-06 while scoping `agnt-ctx-h9gt`. Stance locked in the
|
|
68
|
+
interview: broad scope (generic test review, not a pipeline-specific gate), used in the ralph
|
|
69
|
+
pipeline, priority P2 with the trigger being `agnt-ctx-h9gt`'s real-world review findings.
|
|
70
|
+
Deliberately kept as an idea rather than folded into `agnt-ctx-h9gt` so it passes the same
|
|
71
|
+
validity check as every other backlog entry.
|
package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md
CHANGED
|
@@ -30,4 +30,13 @@ The author. Main-branch history becomes verifiably authentic — every commit at
|
|
|
30
30
|
Determine how the changesets commit gets signed in CI on this repo — cheapest prototype: scratch repo (or the version branch) exercising the signing path end-to-end without touching `main`'s rule, then evaluate the rule change on `main`.
|
|
31
31
|
|
|
32
32
|
## Notes
|
|
33
|
-
Recorded 2026-09-02. Backlog capture only — no active work planned; revisit after the install-manager epic (pi/claude/copilot) settles. Adjacent to `docs/ideas/unified-ci-pipeline.md` (CI/release restructure).
|
|
33
|
+
Recorded 2026-09-02. Backlog capture only — no active work planned; revisit after the install-manager epic (pi/claude/copilot) settles. Adjacent to `docs/ideas/unified-ci-pipeline.md` (CI/release restructure).
|
|
34
|
+
|
|
35
|
+
Updated 2026-10-28: `docs/commit-signing.md` records the investigation and the decided policy.
|
|
36
|
+
The applied-rule read shows no `required_signatures` rule on `main` at repository or
|
|
37
|
+
organization level (org ruleset *definitions* stay unreadable with a repository-scoped token),
|
|
38
|
+
and Version Packages PRs land by squash merge, whose landing commit GitHub signs — so releases
|
|
39
|
+
stay automated with no key in CI, and the CI signing key this idea points at is rejected as the
|
|
40
|
+
default. That rejection does not settle the idea: GitHub checks head-branch commits through its
|
|
41
|
+
test merge, so enabling enforcement would still require the signed CI commit, exactly as
|
|
42
|
+
`Next validation step` describes.
|
|
@@ -7,6 +7,11 @@ harness's native dependency fields plus committed settings templates. See the de
|
|
|
7
7
|
prune TUI was rejected (see "Prune rejected") and the proposed declared-vs-installed diff was
|
|
8
8
|
dropped — `agent-cortex install <harness>` reconciles instead.
|
|
9
9
|
|
|
10
|
+
The mechanism recorded under "What shipped" has since been removed (2026-10-24,
|
|
11
|
+
`agnt-ctx-7kru.1`): `pi.packages`, `lib/pi-packages.mjs` and `--no-provision` are gone, and the
|
|
12
|
+
required pi packages now travel inside the staged package at `~/.agent-cortex/pi` instead of
|
|
13
|
+
being provisioned into pi's user scope.
|
|
14
|
+
|
|
10
15
|
## Created
|
|
11
16
|
2026-08-25
|
|
12
17
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Idea: Unify the ticket and task decomposition workflows
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
Backlog idea (not implementation-ready)
|
|
5
|
+
|
|
6
|
+
## Created
|
|
7
|
+
2026-10-13
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
The planning skills assume a fixed split between tickets and tasks, and implement
|
|
11
|
+
decomposition in three places that do not agree:
|
|
12
|
+
|
|
13
|
+
- `prd-to-tasks` slices a PRD into epics and task beads, then expands each task through
|
|
14
|
+
`create-task` into pipeline chore beads for ralph.
|
|
15
|
+
- `spec-to-tickets` slices a spec into a ticket map, drafts bodies, and creates tickets in
|
|
16
|
+
a tracker (Jira, GitLab, GitHub, or beads).
|
|
17
|
+
- `plan` Phase 2 re-implements the slicing logic inline rather than delegating.
|
|
18
|
+
|
|
19
|
+
There is no model for a ticket that itself needs breaking into tasks, and no single place
|
|
20
|
+
that owns decomposition. Which skill to use depends on the tracker rather than on the work.
|
|
21
|
+
|
|
22
|
+
## Who benefits
|
|
23
|
+
The author, and any agent running the planning skills. One decomposition path replaces
|
|
24
|
+
three overlapping ones, and a ticket in any tracker can be created and then broken into
|
|
25
|
+
tasks without switching skills.
|
|
26
|
+
|
|
27
|
+
## Proposed outcome
|
|
28
|
+
A single coherent model in which a ticket — in any tracker, including beads — can be
|
|
29
|
+
created and then decomposed into tasks, with the tracker acting as an adapter rather than
|
|
30
|
+
defining a separate skill. The exact shape is deliberately undecided; this record captures
|
|
31
|
+
the problem, not a design.
|
|
32
|
+
|
|
33
|
+
## Validity check
|
|
34
|
+
- Evidence we already have: three implementations of spec-to-units slicing (`plan` Phase 2
|
|
35
|
+
inline, `prd-to-tasks`, `spec-to-tickets`); `prd-to-tasks` has eight dependents plus a
|
|
36
|
+
generated agent file; the only substantive difference between the two decomposition
|
|
37
|
+
skills is the creation contract — `create-task` expands AFK tasks into ralph's chore
|
|
38
|
+
tree, while `spec-to-tickets` uses a generic tracker adapter.
|
|
39
|
+
- Riskiest assumption: not yet identified — this needs a thinking-through pass. Candidates
|
|
40
|
+
to test: (a) the ticket/task split can be unified without losing ralph's execution
|
|
41
|
+
contract; (b) the refactor is affordable given its blast radius; (c) the duplication is
|
|
42
|
+
causing enough harm to justify it at all.
|
|
43
|
+
- What would invalidate this idea: if ralph's requirements — chore-tree expansion via
|
|
44
|
+
`create-chores.ts`/`pipeline.json`, epic branches, AFK/HITL classification — cannot be
|
|
45
|
+
expressed as a tracker adapter behind one slicing skill, then the split is load-bearing
|
|
46
|
+
and should stay. It would also be invalidated if the duplication never produces concrete
|
|
47
|
+
drift.
|
|
48
|
+
|
|
49
|
+
## Constraints
|
|
50
|
+
- Ralph's execution contract is fixed and must keep working: chore expansion, the epic PR
|
|
51
|
+
flow, and AFK/HITL classification.
|
|
52
|
+
- Open beads `agnt-ctx-s5xd.4` and `agnt-ctx-s5xd.4.4` are already rewriting
|
|
53
|
+
`prd-to-tasks` and `plan`'s tagging for the `execution:` label model. Any refactor has to
|
|
54
|
+
land after that epic or it will collide.
|
|
55
|
+
- Skills target ~150 lines, so a unified decomposition skill would need its tracker
|
|
56
|
+
adapters and formats split into support files.
|
|
57
|
+
|
|
58
|
+
## Next validation step
|
|
59
|
+
Once the s5xd two-axis epic lands, enumerate exactly what `create-task` and ralph require
|
|
60
|
+
from a decomposition — classification, chore tree, epic hierarchy, labels — and test
|
|
61
|
+
whether each can be expressed as a tracker adapter behind one slicing skill. That is the
|
|
62
|
+
cheapest step that would firm up or kill the idea.
|
|
63
|
+
|
|
64
|
+
## Notes
|
|
65
|
+
- The open question at the heart of it: are "ticket" and "task" the same thing at different
|
|
66
|
+
granularities, or genuinely different things? Related: is a ticket a ralph task, or
|
|
67
|
+
something a ralph task is created from?
|
|
68
|
+
- Priority P3 by the author's call — it blocks other planning work rather than being
|
|
69
|
+
polish.
|
|
70
|
+
- Filed during the `write-a-ticket` / `spec-to-tickets` work (bead `agnt-ctx-vgzj`), where
|
|
71
|
+
the overlap first became concrete.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# `disable-model-invocation` across harnesses
|
|
2
|
+
|
|
3
|
+
Decision record for the frontmatter field this repo uses to keep rare or destructive
|
|
4
|
+
skills out of automatic model routing (bead `agnt-ctx-yf24`).
|
|
5
|
+
|
|
6
|
+
**Verdict:** rely on it for pi and Claude Code. Do not rely on it in Copilot CLI as
|
|
7
|
+
"invoke-only" — there it means "unreachable through the model-facing skill tool".
|
|
8
|
+
|
|
9
|
+
## What the field does
|
|
10
|
+
|
|
11
|
+
`disable-model-invocation: true` removes a skill from the list the model is offered.
|
|
12
|
+
The user can still invoke it explicitly. It does not summarise, rewrite, or
|
|
13
|
+
otherwise change how the body loads, which is what `docs/skills/skill-anatomy.md`
|
|
14
|
+
previously implied.
|
|
15
|
+
|
|
16
|
+
## Preservation and honouring
|
|
17
|
+
|
|
18
|
+
| Harness | Field survives materialisation | Loader honours it | Evidence |
|
|
19
|
+
| --- | --- | --- | --- |
|
|
20
|
+
| pi 1.4.0 | Yes — byte-identical copy | Yes — hidden from the prompt, `/skill:name` still works | `bin/installers/pi.mjs:182-204`, `scripts/lib/compose-agent.mjs:69-95`; `dist/core/skills.js:262` (parse) and `:279` (filter); `docs/skills.md:53` |
|
|
21
|
+
| Claude Code 2.1.294 | Yes — byte-identical copy | Yes — Claude cannot invoke it, `/skill-name` still works | `bin/installers/claude.mjs:160-201`, same token helper; [Claude Code skills docs](https://code.claude.com/docs/en/skills) ("Control who invokes a skill") |
|
|
22
|
+
| Copilot CLI (1.0.55 locally, 1.0.80/1.0.83 upstream) | N/A — no copy; `plugin.json` `"skills": "skills/"` serves the repo tree in place | Auto-invocation suppressed, but explicit model invocation fails; `/skill-name` works | `plugin.json:12`; [github/copilot-cli#4438](https://github.com/github/copilot-cli/issues/4438) (open, retested 1.0.83) |
|
|
23
|
+
|
|
24
|
+
Both materialisers copy `SKILL.md` as text and rewrite only `{{TOOL:...}}` /
|
|
25
|
+
`{{PATH:...}}` tokens, so frontmatter keys they do not know pass through untouched —
|
|
26
|
+
nothing re-serialises YAML. Verified by installing all three harnesses into
|
|
27
|
+
`/var/tmp/dmi-check` and diffing `skills/productivity/teach/SKILL.md` (the repo's
|
|
28
|
+
only current user of the field): both copies are byte-identical to the source.
|
|
29
|
+
`claude plugin validate /var/tmp/dmi-check/claude/skills` passes, i.e. Claude Code's
|
|
30
|
+
own validator accepts the field rather than warning about it.
|
|
31
|
+
|
|
32
|
+
pi was probed against the materialised tree with its own loader: 32 skills loaded,
|
|
33
|
+
31 advertised, `teach` parsed with `disableModelInvocation: true` and absent from
|
|
34
|
+
`formatSkillsForPrompt` output.
|
|
35
|
+
|
|
36
|
+
## Per-harness detail
|
|
37
|
+
|
|
38
|
+
**pi.** Documented and implemented. `docs/skills.md:53`: "Set
|
|
39
|
+
`disable-model-invocation: true` in frontmatter when a skill should be available only
|
|
40
|
+
through its explicit command", with the frontmatter table listing it as "Hide the
|
|
41
|
+
skill from automatic model selection".
|
|
42
|
+
|
|
43
|
+
**Claude Code.** Documented, and the docs are explicit about the enforcement: "Claude
|
|
44
|
+
can't invoke the skill on its own … If Claude tries anyway, Claude Code blocks the
|
|
45
|
+
call and instructs it not to reproduce the deploy steps another way", and it "removes
|
|
46
|
+
the skill from Claude's context entirely".
|
|
47
|
+
|
|
48
|
+
Two Claude-specific caveats:
|
|
49
|
+
|
|
50
|
+
- The field is a Claude Code extension, not part of the
|
|
51
|
+
[Agent Skills spec](https://agentskills.io/specification), whose six fields
|
|
52
|
+
(`name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools`)
|
|
53
|
+
are otherwise exhaustive. Claude Code ignores unknown fields, but packing or
|
|
54
|
+
uploading a skill to claude.ai (or through the Skills API) "fails with a hard error
|
|
55
|
+
instead of ignoring the field". Our plugin path is unaffected; a skill we ever
|
|
56
|
+
publish to claude.ai must drop the field.
|
|
57
|
+
- `skillOverrides` does not apply to plugin skills, and our install is a plugin. The
|
|
58
|
+
frontmatter field itself still applies there — only that settings-based alternative
|
|
59
|
+
is unavailable.
|
|
60
|
+
|
|
61
|
+
**Copilot CLI.** The field is not in GitHub's skill documentation, which lists only
|
|
62
|
+
`name`, `description`, `license`, and `allowed-tools`. In practice the CLI filters
|
|
63
|
+
flagged skills out of the `skill()` tool's resolution list, so the model cannot call
|
|
64
|
+
them even when the user names one: `Skill not found`. Only the interactive
|
|
65
|
+
`/skill-name` slash command reaches a flagged skill, and `-p` mode has no slash path.
|
|
66
|
+
Upstream issue #4438 is open.
|
|
67
|
+
|
|
68
|
+
Local probing was not possible: the installed CLI is 1.0.55 (no `copilot skill`
|
|
69
|
+
subcommand), and prompt runs are refused by this machine's org policy. The upstream
|
|
70
|
+
report is the evidence for Copilot, tested on 1.0.80 and 1.0.83 — newer than 1.0.55,
|
|
71
|
+
so this may differ locally, in either direction.
|
|
72
|
+
|
|
73
|
+
## Options for "explicit invocation only", evaluated
|
|
74
|
+
|
|
75
|
+
| Option | Portable? | Enforced? | Verdict |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| `disable-model-invocation: true` | pi + Claude Code yes; Copilot suppresses but breaks tool-based invocation | Yes on pi/Claude | **Recommended** where suppressing auto-routing is the point and the explicit path is a human typing `/name` |
|
|
78
|
+
| Naming convention (e.g. `manual-*`) | Yes | No — no harness reads names | Rejected: a human signal we already get from the body |
|
|
79
|
+
| `metadata:` block | Yes (spec-legal) | No — pi and Claude read top-level keys only, Copilot undefined | Rejected: documentation that looks like enforcement |
|
|
80
|
+
| Keep such skills out of `skills/` | Yes | Yes, by not shipping the skill | Rejected: gives up the per-harness install entirely |
|
|
81
|
+
|
|
82
|
+
## Recommendation
|
|
83
|
+
|
|
84
|
+
Use the field when the danger is fuzzy automatic matching and the intended explicit
|
|
85
|
+
path is a human typing `/skill-name`: that is the case for a migration skill whose
|
|
86
|
+
`--apply` renames labels workspace-wide. Accept, and document, that on Copilot CLI it
|
|
87
|
+
also blocks model-mediated invocation, including `-p` runs — if a workflow needs
|
|
88
|
+
non-interactive access to such a skill, do not set the field and instead disable the
|
|
89
|
+
skill in that user's Copilot config (`copilot skill disable <name>`, or the `/skills`
|
|
90
|
+
toggle), which is harness-native and per-user.
|
|
91
|
+
|
|
92
|
+
## Reproducing
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
node bin/agent-cortex.mjs install claude --output /var/tmp/dmi-check/claude
|
|
96
|
+
node bin/agent-cortex.mjs install pi --output /var/tmp/dmi-check/pi
|
|
97
|
+
node bin/agent-cortex.mjs install copilot --output /var/tmp/dmi-check/copilot
|
|
98
|
+
diff skills/productivity/teach/SKILL.md /var/tmp/dmi-check/claude/skills/teach/SKILL.md
|
|
99
|
+
diff skills/productivity/teach/SKILL.md /var/tmp/dmi-check/pi/skills/productivity/teach/SKILL.md
|
|
100
|
+
claude plugin validate /var/tmp/dmi-check/claude/skills
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The Copilot run writes only composed agent files — there is no skill copy to inspect.
|
|
@@ -35,7 +35,7 @@ The headline finding: **agent-cortex skills are well-structured but systematical
|
|
|
35
35
|
| Cross-skill references | Explicit inline calls: "run `/grill-with-docs`" | Implicit — no inline cross-refs | agent-cortex weaker |
|
|
36
36
|
| Shared vocabulary file | `CONTEXT.md` at repo root; skills told to read it | None | Missing in agent-cortex |
|
|
37
37
|
| Skill manifest | Flat JSON array of skill paths | Same | ✅ Aligned |
|
|
38
|
-
| `disable-model-invocation` | Used for pure prompt-injection skills |
|
|
38
|
+
| `disable-model-invocation` | Used for pure prompt-injection skills | Used by `teach`; semantics now documented in `docs/skills/skill-anatomy.md` | Field adopted; rationale corrected |
|
|
39
39
|
| Missing SKILL.md | 0 | 1 (`prd-to-epics`) | Bug in agent-cortex |
|
|
40
40
|
|
|
41
41
|
### 2.2 Tone and Voice
|
|
@@ -251,7 +251,7 @@ These are patterns present in `mattpocock/skills` that have no equivalent here a
|
|
|
251
251
|
|
|
252
252
|
2. **Philosophy sections in skills** — `tdd` doesn't just describe TDD, it argues *why* horizontal slicing is wrong. This bakes intent into the skill so the agent handles novel cases correctly (backed by CoT rationale evidence).
|
|
253
253
|
|
|
254
|
-
3. **`disable-model-invocation: true`** —
|
|
254
|
+
3. **`disable-model-invocation: true`** — hides a skill from automatic model routing so only an explicit `/skill-name` invocation reaches it. See `docs/research/disable-model-invocation.md` for per-harness behaviour and caveats.
|
|
255
255
|
|
|
256
256
|
4. **Composability by design** — skills reference each other by slash-command inline. This keeps each skill shorter and creates a network of reusable primitives rather than monolithic blobs.
|
|
257
257
|
|
|
@@ -11,7 +11,11 @@ Required fields:
|
|
|
11
11
|
|
|
12
12
|
Optional fields:
|
|
13
13
|
- `argument-hint`: input prompt shown to users at invocation.
|
|
14
|
-
- `disable-model-invocation`:
|
|
14
|
+
- `disable-model-invocation`: hides the skill from automatic model routing; explicit
|
|
15
|
+
`/skill-name` invocation still works. Set it when the danger is a fuzzy description
|
|
16
|
+
match, e.g. a skill whose steps are destructive. Preserved and honoured by pi and
|
|
17
|
+
Claude Code; Copilot CLI suppresses auto-routing but then cannot reach the skill
|
|
18
|
+
through its model-facing tool. See `docs/research/disable-model-invocation.md`.
|
|
15
19
|
|
|
16
20
|
## Description format rules
|
|
17
21
|
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Technical Direction: Harness config and third-party extensions
|
|
2
2
|
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
**Partly superseded (2026-10-24) by the staged-package model** (`agnt-ctx-7kru`). Two premises
|
|
6
|
+
below no longer hold:
|
|
7
|
+
|
|
8
|
+
- **The pi half landed without bundling.** `agent-cortex install pi` stages a self-contained
|
|
9
|
+
package at `~/.agent-cortex/pi` and copies the required third-party packages — resolved
|
|
10
|
+
through Node's own resolution — into that tree's `node_modules/`, instead of declaring
|
|
11
|
+
`bundledDependencies` in the published tarball. pi loads a local directory and resolves no
|
|
12
|
+
npm packages itself, so a tarball's `node_modules/` reached nobody; bundling also forced a
|
|
13
|
+
repo-wide `node-linker=hoisted`, surrendering pnpm's isolated resolution for the workspace.
|
|
14
|
+
- **pi's own settings are no longer installer output.** The installer writes nothing into
|
|
15
|
+
`~/.pi/agent`; it registers the staged package by driving pi's own `pi install` /
|
|
16
|
+
`pi remove` commands, which own `settings.json` → `packages[]`. `pi/settings.json` and
|
|
17
|
+
`pi/keybindings.json` are reference templates. Registration's invariant is **one
|
|
18
|
+
agent-cortex source**: a source pointing at a raw agent-cortex checkout is removed first,
|
|
19
|
+
and one that survives `pi remove` fails the run rather than leave two sources configured
|
|
20
|
+
that both load.
|
|
21
|
+
|
|
22
|
+
`pi.packages` and `lib/pi-packages.mjs` are deleted, so the bespoke-pi-mechanism problem this
|
|
23
|
+
memo was written to settle is closed. The Claude and Copilot analysis stands.
|
|
24
|
+
|
|
3
25
|
## Problem and target outcome
|
|
4
26
|
|
|
5
27
|
- **What we are solving.** agent-cortex ships agents and skills to three harnesses (pi, Claude
|
|
@@ -155,7 +177,9 @@ pi extension loads from `node_modules/` and an optional one is materialised from
|
|
|
155
177
|
`extraKnownMarketplaces`).
|
|
156
178
|
- GitHub Copilot CLI, *Plugin reference* — https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference
|
|
157
179
|
and *Configuration directory* — https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-config-dir-reference
|
|
158
|
-
- Code evidence
|
|
180
|
+
- Code evidence (as of 2026-09 — `pi.packages` and `lib/pi-packages.mjs` were removed in
|
|
181
|
+
`agnt-ctx-7kru.1`, see Status): `package.json` (`pi.packages`), `lib/pi-packages.mjs` (main's
|
|
182
|
+
provisioner);
|
|
159
183
|
`pi.extensions.json`, `claude.extensions.json`, `lib/extension-manifest.mjs` (epic F5, `1e0e970`);
|
|
160
184
|
`bin/installers/pi.mjs` settings materialisation (epic F3, `afab2c6`);
|
|
161
185
|
`docs/ideas/extension-manifests.md` (the originating idea).
|