Repository navigation
feat(pstack): update Codex port to upstream 0.15.10 - #2
Conversation
Port the reviewed workflows and principles through 4e5b1cf, adapt runtime integrations to Codex, and configure Sol, Luna, and Astra routes. Add plan validation, installation checks, and CI while preserving existing user configuration.
There was a problem hiding this comment.
🔍 Failed installs leave a mixed skill set
The final audit runs after replacements and configuration writes. If copying or validation fails, backups exist but the installer leaves the partially replaced catalog active. Consider staging and checking the full catalog before replacing installed skills.
(Refers to this code)
Was this helpful? React with 👍 or 👎 to provide feedback.
| 4. **Prepare only the bottom PR.** Fetch current trunk. Rebase the lowest verified branch onto the exact trunk tip when needed, push it, and retarget only that PR to trunk with `origin pr edit <pr> --base <trunk>` or `gh pr edit <pr> --base <trunk>`. Re-run step 3 after the push. Do not retarget, arm, or merge descendants yet. | ||
| 5. **Land one PR at a time.** If the bottom PR is mergeable now, squash it with `origin pr merge <pr> --squash` or `gh pr merge <pr> --squash`. If requirements are still running and the user asked for merge-when-ready, arm only that PR with `origin pr merge <pr> --squash --auto` or `gh pr merge <pr> --squash --auto`. Origin's `--auto` is Origin merge-when-ready. GitHub's `--auto` is GitHub auto-merge. Wait for that PR to merge before preparing the next one. | ||
| 6. **Do not read GitHub `autoMergeRequest` as stack readiness.** At most it says GitHub auto-merge was requested for one GitHub PR. It does not prove Origin merge-when-ready is armed, that a descendant is queued, that a patch verdict is current, or that the contiguous stack is safe. Confirm the active forge's state for the current bottom PR, and say that the state is unknown if the active forge cannot report it. | ||
| 7. **Recompute after every merge.** Fetch trunk, confirm the merged SHA is present, drop the merged PR from the frozen bottom-to-top list, and inspect the new bottom PR's base, head, checks, and patch-id. A host may retarget a child automatically, but do not assume it did. Repeat steps 3 through 6 for that one PR. Independent work stays outside this chain and ships on its own. |
There was a problem hiding this comment.
🔴 Squashed PR stops stack shipping
After a squash merge, Shipping looks for the PR head SHA on trunk. Squashing creates a different commit, so a successful merge fails confirmation and stops the remaining stack.
Learn more
The Shipping playbook lands PRs with --squash. A squash commit contains the PR's changes but has a new SHA, so the former branch head does not become an ancestor of trunk. The subsequent confirmation in step 7 therefore rejects a successful merge and prevents the next PR from being processed.
Example: PR #11 has head abc123. gh pr merge 11 --squash reports success and creates trunk commit def456. Fetching trunk shows def456 but not abc123; step 7 cannot confirm the merge and never prepares PR #12.
Recommended fix: Confirm the forge reports the PR merged and verify its reported squash merge commit is on fetched trunk. Keep the branch head SHA for verdict matching before merging, not for ancestry checks after squashing.
Was this helpful? React with 👍 or 👎 to provide feedback.
| ### Opening a PR | ||
|
|
||
| Check this gate at the end of every change playbook. Open or update a PR only when the user requested publication, the active task explicitly includes it, or an established repository workflow already placed the work on a PR branch. Otherwise stop after local verification and report that the changes are ready. A request to build or fix does not by itself authorize a PR, push, or external review action. | ||
| Invoked at the end of every other playbook. |
There was a problem hiding this comment.
🟡 Unrequested PR publication on code changes
For a private code-change request, Opening a PR no longer checks publication authority. Feature invokes it unconditionally, so the workflow can publish a PR outside the user's scope.
Learn more
The Feature playbook invokes Opening a PR after building a change. Previously this playbook checked whether the user requested publication or an established workflow authorized it. The new opening sentence removes that check, while runtime policy still limits publication to authorized tasks.
Example: A user asks Codex to change a local formatter and show the result, without requesting a PR. Feature reaches Opening a PR and publishes a ready PR instead of handing back the local change.
Recommended fix: Restore a publication gate at the start of Opening a PR. Return the local result without creating or pushing a PR when no request or active workflow authorizes publication.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const lanes = boxes(live.lines).map((b) => ({ ...b, m: b.text.match(/^Lane (\d+)\. /) })); | ||
| const numbers = lanes.filter((b) => b.m).map((b) => Number(b.m[1])).sort((a, b) => a - b); | ||
| if (laneSpec) { | ||
| const count = Number(laneSpec[1]); | ||
| if (numbers.length !== count || numbers.some((number, i) => number !== i + 1)) fail(live.n, `${pr.title}: lanes are [${numbers.join(",")}], expected 1 to ${count}`); | ||
| } | ||
| for (const lane of lanes) { | ||
| if (!lane.m) fail(lane.n, `${pr.title}: live box is not a lane`); | ||
| else if (!/Save `[^`]+`/.test(lane.text)) fail(lane.n, `${pr.title}: lane ${lane.m[1]} names no evidence receipt`); | ||
| else if (!lane.text.includes("Pass when")) fail(lane.n, `${pr.title}: lane ${lane.m[1]} has no pass predicate`); |
There was a problem hiding this comment.
🟡 Plans pass without trunk regression checks
When Lane 1 tests only the PR head, check-plan still accepts it if numbering and receipts match. The required trunk comparison never runs, leaving regressions outside the verified plan.
Learn more
The plan template requires a regression lane against trunk. The checker parses only the lane number, Save receipt, and Pass when text. A plan can replace the trunk comparison with another head-only scenario and still pass validation.
Example: A one-lane plan says Lane 1. Run the CLI at the PR head. Save \head.txt`. Pass when it exits 0.` The checker reports zero problems, even though no trunk scenario or regression comparison is planned.
Recommended fix: Require the regression lane to specify both trunk and head and describe the same scenario on each. Add a negative test for a head-only Lane 1; keep the validation aligned with the template's exception when trunk lacks the feature.
Was this helpful? React with 👍 or 👎 to provide feedback.
| if (/^```/.test(text)) fence = !fence; | ||
| lines.push({ n, text, code: fence }); |
There was a problem hiding this comment.
🔍 Four-backtick examples confuse plan parsing
The template uses four-backtick fences, but check-plan recognizes only three-backtick fences. A quoted template can supply headings that the checker treats as live plan sections. Check fence handling before relying on this checker for plans with examples.
Was this helpful? React with 👍 or 👎 to provide feedback.
| **Just do it.** Use any MCP tool. Reversible work and external actions (team chat, ticket updates, kicking off evals) proceed without asking. | ||
|
|
||
| **Always pause** when completion needs new authority or an irreversible action outside the permission already given: force-pushes to shared branches, deploys, data deletion, or external messages. | ||
| **Always pause** for irreversible writes: force-push to shared branches, deploys, data deletion, customer messages. |
There was a problem hiding this comment.
Why
The Codex port was 25 pstack commits behind upstream. This brings its workflows and principles to pstack 0.15.10 while keeping execution native to Codex.
What changed
Scope
Covers the reviewed upstream changes through 4e5b1cf. The port record lists every commit and adaptation. Grok Bot UI and Cursor-only integration remain excluded. Existing global skills and user configuration are unchanged by this PR.
Tradeoffs
The plan checker uses a stated positive lane count and screenshots or terminal receipts instead of requiring ten cloud lanes. The balanced model setup uses Sol for sustained work, Luna for focused tasks, and Astra for demanding judgment.
Verification
GitHub validation passed on the final revision, including all 25 packaging tests and the watcher test and typecheck suites.