Repository navigation
feat(pstack): guard the T3 port with a drift check and an intent table - #4
Conversation
Add scripts/check-t3-port.mjs, which fails when Cursor wording comes back into pstack/skills or a T3 anchor goes missing, and names the fix. A PENDING list holds the drift that later sync PRs remove, and fails once an entry has nothing left to match. FORK.md gains a "T3 port intent" table that says what the fork changes and why, plus the sync steps. FORK-SYNC-LOG.md lists all 29 upstream pstack commits since 11713c6 with a planned decision each. poteto-mode's Subagents section gets a Speed rule. Grok and GPT may run fast freely. Claude fast mode needs the operator's approval in the session, for one named task only. setup-pstack never writes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e55a05be32
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (pending >= 0) usedPending.add(pending); | ||
| else fail(`${file}:${i + 1}`, rule.id, rule.fix); |
There was a problem hiding this comment.
Limit pending exemptions to the known violations
When a file has a matching PENDING entry, every occurrence of that rule in the file is accepted, rather than only the pre-existing violation. During the upcoming sync, adding another forbidden command such as gt submit to playbooks/orchestrate.md still produces T3 port check clean, so the guard misses exactly the new drift it is intended to catch. Record expected lines or match counts and fail when additional occurrences appear.
Useful? React with 👍 / 👎.
| const root = mkdtempSync(join(tmpdir(), "t3-port-")); | ||
| cpSync(join(repo, "pstack"), join(root, "pstack"), { |
There was a problem hiding this comment.
Every regression test creates a complete temporary copy of pstack but never removes it. A single invocation currently leaves eight roughly 4 MB directories under /tmp, so repeated local runs or runs on persistent workers continually consume disk space. Track the created roots and remove them in test teardown.
Useful? React with 👍 / 👎.
The Speed rule now says a Claude fast-mode approval covers only the work the operator names, not retries, replacement agents, reviewers, verifiers, the lead's own chat or later sessions, and that it ends with that work. The drift check counts PENDING matches exactly, so new drift in a pending file fails. It now catches Cursor's environment, run_in_background, readonly and ~/.cursor/plugins wording and structured Claude targets with fastMode true. It reads YAML block descriptions, requires the named-only sentence at the end, and accepts disable-model-invocation: false. FORK.md names the auto and inherit-parent target exception and the four auto-load skills. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The structured-target check now finds the object around each claudeAgent provider and looks for fastMode true inside it, in any key order, with single or double quotes, or as T3's list of {id, value} options. Prose after the object no longer counts. Plain YAML descriptions that continue on the next line parse again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 58e54b1b76
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // A structured T3 target can span lines and list its keys in any order, so these run | ||
| // over the whole object that holds each claudeAgent provider. | ||
| const CLAUDE_PROVIDER = /["']?providerInstanceId["']?\s*:\s*["']claudeAgent["']/g; | ||
| const FAST_ON = /["']?fastMode["']?\s*[:=]\s*true\b|["']id["']\s*:\s*["']fastMode["']\s*,\s*["']value["']\s*:\s*true\b/; |
There was a problem hiding this comment.
Match list-form fast options regardless of key order
When a valid list-form option serializes its members as {"value": true, "id": "fastMode"}, this regex misses it: the first alternative expects fastMode to be followed by : or =, while the second hard-codes id before value. Consequently, a structured Claude target with fast mode enabled can still produce T3 port check clean solely because JSON object members were reordered; parse the option object or accept either member order.
Useful? React with 👍 / 👎.
…simple Two rounds of parser fixes kept missing target shapes. A census found no structured targets in the fork's skills or upstream's, and 21 compact role lines, which the existing rule covers. So the object parser goes. A line naming claudeAgent as the provider now fails if fastMode appears within 8 lines, whatever the value, key order or comments. Skill examples never need to show Claude fast mode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f78e11d77b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| const root = resolve(process.argv[2] ?? join(dirname(fileURLToPath(import.meta.url)), "..")); | ||
| const SCANNED = ["pstack/skills", "pstack/agents"]; | ||
| const TEXT = /\.(md|mjs|js|ts|sh|json|tsv)$/; |
There was a problem hiding this comment.
Scan extensionless source files for port drift
The extension allowlist silently excludes the existing source file pstack/skills/poteto-mode/scripts/watch-pr/watch-pr. During an upstream sync, adding a banned construct such as origin/main to that executable still produces T3 port check clean, so the new guard does not cover all installed source under its advertised scan roots. Include extensionless text executables or determine text files by content rather than this suffix list.
Useful? React with 👍 / 👎.
* test(orch): pin that frontier set refuses a trunk checkout resolveFrontier already throws a UserError when HEAD is the trunk, so `orch frontier set` can no longer overwrite a valid frontier with an empty one. Nothing tested it. The new test saves a frontier, checks out main, asserts the UserError, and asserts frontier.json is byte-for-byte unchanged. It fails when the guard is removed. Fixes #6 (comment) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(check-t3-port): scan extensionless text files and clean up test trees The extension allowlist skipped extensionless executables such as scripts/watch-pr/watch-pr, so drift planted there passed. The walker now also scans an extensionless file when its first 8 KB hold no NUL byte. New tests plant origin/main in watch-pr and show an extensionless binary is skipped. Each test fails against the matching broken walker. copyTree(t) now registers t.after cleanup right after creating its temp root, and every caller passes t, so runs no longer leave t3-port-* copies of the tree in the temp dir. Fixes #4 (comment) Fixes #4 (comment) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(pstack): compare the whole PR patch before reusing a verdict Shipping step 3 compared `git patch-id` at the verdict SHA with the head. Hashing a commit only covers the tip, so a rebase that changed an earlier commit of a multi-commit PR could keep an old verdict for code no verifier saw. A verdict now records the head it verified and that head's merge base with the PR's base branch, taken at verification time. Reuse compares `git diff <saved-merge-base> <verdict-head> | git patch-id --stable` with the same diff from the current merge base to the current head. The saved merge base is never recomputed, because a restack moves it. The build-equivalence exception for test, doc and lint changes stays. Shipping step 3 owns the rule. autopilot-full, autopilot-stack and multi-phase-plan point to it. Fixes #6 (comment) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(pstack): place /ketchup choices above the list and restore /swarm's N step /ketchup said to show a choice after the action list, but also that the html_render page, where a drawn choice goes, shows above the reply. It now says to show each choice above the list, either under the screenshots that already show its options or on the published page, with the action item ending "see the page above". Upstream's 99743e9 cut /swarm's step 3, so a bare "swarm this" left N undefined while Phase B still spawns all N workers. The step is back, and FORK-SYNC-LOG.md records it as a fork fix on top of 99743e9. Fixes #7 (comment) Fixes #7 (comment) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(pstack): compare verdict patches with whitespace kept git patch-id --stable strips whitespace, so a rebase that only dedents Python or changes YAML nesting kept the same ID and carried an old verdict to untested behavior. --verbatim keeps whitespace. Checked in a scratch repo: --stable gave the same ID for a dedent that changed behavior, --verbatim gave different IDs. Fixes #9 (comment) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Why
Upstream pstack is 8 versions ahead, and 50 files changed on both sides. Before porting anything, the fork needs a written statement of what it changes for T3 and why, plus a check that catches upstream's Cursor wording when it slips back in.
What changed
scripts/check-t3-port.mjsfails on Cursor terms (Task,-fastmodel names,~/.cursor/rules, hidden skills,origin/main, ClaudefastMode=true) and on missing T3 anchors. Each failure names the fix.FORK.mdgets a "T3 port intent" table and sync steps.FORK-SYNC-LOG.mdlists all 29 upstream commits with a planned decision each.Scope
Blast Radius
The skill text changes are the Speed rule, one setup-pstack paragraph, and one default in multi-phase-plan. Every other change is a maintenance file outside
pstack/skills, which the install doesn't copy.Verification
node scripts/check-t3-port.mjsis clean on this branch and reports 177 problems on upstream'spstack/tree.node --test scripts/check-t3-port.test.mjspasses 9 of 9: the branch passes, and each of 8 planted regressions fails with its rule id.🤖 Generated with Claude Code
Note
Low Risk
Mostly docs and CI-style lint on skill copy; limited runtime impact except new agent rules for Claude fast mode and one playbook default string.
Overview
Adds T3 port guardrails before the fork catches up to upstream pstack (0.15.17→0.15.25).
FORK.mdgains a T3 port intent table (subagents, roles, speed, trunk, install, etc.) and numbered sync steps;FORK-SYNC-LOG.mdlogs 29 upstream commits with planned take/adapt/skip and target follow-up PRs. No upstream behavior is ported in this PR (first of four).scripts/check-t3-port.mjsscanspstack/skillsandpstack/agentsfor Cursor drift (Task,-fastslugs,origin/main, hidden skills, Graphite, ClaudefastMode=truedefaults, etc.), required T3 anchor strings, and named-only skill descriptions; failures name the fix. APENDINGallowlist tolerates known drift until sync PRs B/C land, and stale entries fail the check.check-t3-port.test.mjsasserts the repo passes and eight planted regressions fail with the right rule id.Skill text changes:
poteto-modedocuments Speed (Grok/GPT fast OK; ClaudefastModeonly on explicit per-task operator approval in-session).setup-pstackrefuses to write Claude fast mode on role lines.multi-phase-planupdates the default swarm workers model to the T3 role-line form (cursor/grok-4.7 … fastMode=true).Reviewed by Cursor Bugbot for commit e55a05b. Configure here.