Skip to content
Merged
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
1 change: 1 addition & 0 deletions .agents/skills/verify-open-pstack/features/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Run the parent skill's Launch and Doctor first. Use one fresh scratch store per

- [Installation and discovery](installation.md): marketplace installation, reload, skill discovery in both parents.
- [Model setup](setup.md): selected-provider checks, confirmation, persistence, native probes.
- [Startup routing](startup-routing.md): bundled SessionStart hook registration, opt-in trust, and shared routing text.
- [Engineering workflows](workflows.md): invoking poteto-mode and direct focused skills.
- [Routing policy](routing.md): inspecting a saved role through the CLI and observing parent-owned dispatch.
- [Worker ownership and continuation](worker-contract.md): enforced capabilities, parent Git operations, handoffs and bounded recovery.
Expand Down
41 changes: 41 additions & 0 deletions .agents/skills/verify-open-pstack/features/startup-routing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Startup routing

The plugin bundles a `SessionStart` hook for each parent. Claude Code loads it through `hooks/hooks.json`; Codex loads `hooks/codex-hooks.json` through the manifest's explicit `hooks` entry and skips it until the user trusts the exact hook definition in `/hooks`.

## Sub-features

- `startup-descriptor`: each host's registration selects the right sources and routes to the shared emitter.
- `startup-emission`: the shipped command prints the exact shared routing text on stdout.
- `startup-opt-in`: Codex routing is inactive until the hook is trusted; disabling a trusted hook turns it off.
- `startup-routing-only`: a routing-only setup request changes no model bytes.

## How to get to it (user POV)

Install the plugin, open `/hooks` in Codex CLI, review the pstack `SessionStart` entry, and trust it to opt in; disable the same entry to opt out. `pstack:setup-pstack` offers this as an independent optional choice on a Codex parent.

## Driving it with the parent apps and shell

Preconditions: Launch and Doctor passed. `python3 tests/test-session-start.py` covers the packaged contract in CI: it executes the real `command` strings from both descriptors through `run-hook.cmd` and asserts the exact emitted text, matcher coverage, manifest override, repeated emission, and that model files and preference state remain unchanged.

```bash
capture session-start-tests python3 "$VERIFY_REPO/tests/test-session-start.py"
```

For the installed candidate, use a dedicated Codex profile and the [installation](installation.md) candidate-identity steps first. Inspect its global and project instructions, custom developer instructions, and other hooks. Remove any standing Pstack routing mandate from this dedicated fixture before testing. Keep any model-only configuration needed to preserve the assigned providers and spending policy. Record those instruction sources with the evidence; do not paste the hook instruction into the user prompt or fixture instructions.

Use a plain request such as "Add a --format json option to this report command and cover both output formats." Seed a small local command for the task. Observe the actual installed skill read or invocation, not only a final claim that Pstack was used. Compare fresh tasks with the hook untrusted, trusted and enabled, and disabled. Keep every other instruction source identical.

- **Contract listing (works unauthenticated):** in the dedicated Codex profile, confirm the pstack `SessionStart` entry resolves to the plugin's `hooks/codex-hooks.json` and reports untrusted state. A listed `enabled` flag alongside an untrusted status means inactive until trusted, not running.
- **Injection and routing (needs an authenticated parent):** trust the hook in `/hooks`, start a fresh root task, and observe the delivered developer context and the parent's actual `pstack:poteto-mode` skill selection for a non-trivial engineering request. Exercise a pure question and a trivial edit (stay lightweight), an explicit "skip poteto-mode" instruction (overrides), and `resume`, `clear`, and `compact` re-delivery. Disable the hook and confirm a fresh task no longer routes while `$pstack:poteto-mode` still works by name.
- **Claude regression:** install the same candidate in a dedicated Claude Code profile and confirm `startup`, `clear`, and `compact` still inject the shared text and a non-trivial request still selects `pstack:poteto-mode`.
- **Model-file invariance:** snapshot `~/.codex/pstack-models.md` and the `pstack:models` block in `~/.codex/AGENTS.md` before and after enabling, disabling, and a routing-only setup request; expect byte-identical files and no probes.

## Gotchas

- Trust is recorded against the exact hook definition hash; a changed descriptor or command marks the hook for review again. Do not treat a previously trusted install as proof for the current candidate.
- The hook has no persistent session cache: `compact` (including mid-turn auto-compaction) must re-deliver the text.
- `--dangerously-bypass-hook-trust` runs untrusted hooks for one invocation; it is a deliberate bypass, not normal opt-in evidence.
- `commandWindows` is a documented schema field, but Windows execution of the packaged command is unverified until exercised on a real Windows host; record it separately.
- The dedicated Codex test profile may lack authentication. Contract listing and local emission still count; skill selection, context injection, and override behavior then remain unverified and the pull request stays a draft.

Disabling a hook cannot retract context already delivered to an open chat. Test opt-out in a fresh chat and test a direct user override separately. Record unavailable lifecycle actions as unverified instead of substituting synthetic event input.
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"name": "pstack",
"source": "./plugins/pstack",
"description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence.",
"version": "1.9.1",
"version": "1.10.0",
"author": {
"name": "Lauren Tan (original)"
},
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
run: bun run typecheck
- name: Test fork maintenance
run: python3 tests/test-fork-maintenance.py
- name: Test session-start hook
run: python3 tests/test-session-start.py
- name: Check documentation
run: |
python3 tests/test-check-docs.py
Expand Down
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Add or keep a public document only when it answers a question readers ask repeat
| Bug reports and contribution checks | `CONTRIBUTING.md` |
| Install-source policy | this file (the `main` paragraph above) |
| Skill purpose and invocation | each packaged `SKILL.md`; README lists common entry points |
| Session-start routing behavior | `plugins/pstack/hooks/session-start-context.md` and each host's hook descriptor in `plugins/pstack/hooks/` |
| Codex startup-routing setup choice | `plugins/pstack/skills/setup-pstack/SKILL.md` (`## Codex startup routing`) |
| Reproducible verification | `.agents/skills/verify-open-pstack/` and `tests/` |

`python3 scripts/check-docs.py` checks that the README provider table matches the runner IDs, that relative links and heading anchors resolve, that the public documentation inventory stays within its approved scope, and that the current `CHANGELOG.md` entry and pinned upstream README agree with the package version and Cursor baseline. Passing proves structure, not that all prose is current.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ This file records what each version of the Open Pstack package changed. Versions

Entries describe package versions. Published release checkpoints have tag links; installation follows `main` unless pinned. Validation belongs to the linked pull requests. Older reports remain available through immutable links.

## 1.10.0 adds opt-in Codex startup routing

Cursor baseline: [0.15.5](https://github.com/cursor/plugins/tree/12d587dfb20741cafc376c42c696c5f6e2a64487/pstack). [Issue #88](https://github.com/arjitj2/open-pstack/issues/88).

Codex can route engineering requests into Pstack through an optional plugin hook, enabled through its native `/hooks` trust controls. Startup, resume, clear, and compaction reuse the shared routing instruction. A routing-only setup request leaves model assignments and spending permissions unchanged.

## 1.9.1 packages license texts and credits the Open Pstack port

Cursor baseline: [0.15.5](https://github.com/cursor/plugins/tree/12d587dfb20741cafc376c42c696c5f6e2a64487/pstack). [Issue #82](https://github.com/arjitj2/open-pstack/issues/82). Tag [v1.9.1](https://github.com/arjitj2/open-pstack/releases/tag/v1.9.1).
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ multi_agent = true

Start a new Codex task after installation so it can discover the new skills and setting.

Pstack also bundles an optional `SessionStart` hook that routes non-trivial engineering tasks into `pstack:poteto-mode` at session startup, resume, clear, and compaction. It is inactive until you review and trust it: open [`/hooks` in Codex CLI](https://developers.openai.com/codex/hooks), inspect the pstack `SessionStart` entry, and trust it to turn routing on. Disable the same entry to turn it off again. Leaving it untrusted keeps ordinary Codex behavior; `$pstack:poteto-mode` and the other skills still work by name.

## Get started

Configure model access, establish verification for your repository, then start a task.
Expand Down Expand Up @@ -142,7 +144,7 @@ $pstack:poteto-mode Add saved filters to search. Keep the design simple, verify

In this example, poteto-mode first examines the existing search implementation before deciding how to add saved filters. It settles how saved filters are stored before writing code, then implements the smallest complete version. It runs the feature the way a user would, reviews the result, and prepares the pull request.

The skill name is `poteto-mode`, spelled with an “e”. Claude Code also loads this distribution's startup instruction for non-trivial engineering work. In Codex, select the skill explicitly or add a standing instruction if you want it used by default. Model setup saves routing preferences; it does not install an always-on Codex workflow instruction.
The skill name is `poteto-mode`, spelled with an “e”. Claude Code loads this distribution's startup instruction for non-trivial engineering work. Codex delivers the same instruction once you trust the plugin's `SessionStart` hook in `/hooks` as described under [Install](#install); without that opt-in, select the skill explicitly. Model setup saves routing preferences; it never changes the hook's trust or enabled state.

Use the verification skill for each change. If you add or change a feature, update its entry in the feature map too. The other skills are there when poteto-mode needs them or when you want to call one directly.

Expand Down
4 changes: 2 additions & 2 deletions UPSTREAM.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This page records the current Cursor baseline and the maintainer procedure for r
| Path | `pstack/` |
| Commit | `12d587dfb20741cafc376c42c696c5f6e2a64487` |
| Upstream version | `0.15.5` |
| open-pstack version | `1.9.1` |
| open-pstack version | `1.10.0` |

The table records the packaged version on `main` and the Cursor content it incorporates, minus the exclusions below. Detecting or reviewing a newer Cursor commit does not advance this baseline. Cursor's version identifies the imported content. The open-pstack version identifies the cross-harness package, and its numbers are independent of Cursor and Eric's port.

Expand All @@ -29,7 +29,7 @@ Earlier exclusions include Cursor's Benny automation, tutorial and sticky-mode U

## Port adaptations

Both parent apps load the same `plugins/pstack/skills/` tree through their own plugin manifests. Claude Code also loads a SessionStart instruction that routes engineering tasks into `poteto-mode`. Codex users invoke the skill explicitly or add a standing instruction.
Both parent apps load the same `plugins/pstack/skills/` tree and `hooks/session-start-context.md`. Claude Code uses `hooks/hooks.json`; the Codex manifest selects `hooks/codex-hooks.json`. See [Codex installation](README.md#codex) for the optional routing and trust controls.

When incorporating Cursor content, translate harness primitives at the existing boundaries:

Expand Down
2 changes: 1 addition & 1 deletion plugins/pstack/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pstack",
"displayName": "pstack",
"version": "1.9.1",
"version": "1.10.0",
"description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. Ported from cursor/plugins/pstack for Claude Code and Codex.",
"author": {
"name": "Lauren Tan"
Expand Down
3 changes: 2 additions & 1 deletion plugins/pstack/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pstack",
"version": "1.9.1",
"version": "1.10.0",
"description": "if you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. Codex port of the Claude Code plugin; skills are shared, tool names resolve via skills/poteto-mode/references/codex-tools.md.",
"author": {
"name": "Lauren Tan"
Expand All @@ -18,6 +18,7 @@
"unslop"
],
"skills": "./skills/",
"hooks": "./hooks/codex-hooks.json",
"interface": {
"logo": "./assets/logo.png",
"displayName": "pstack",
Expand Down
18 changes: 18 additions & 0 deletions plugins/pstack/hooks/codex-hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"hooks": {
"SessionStart": [
{
"matcher": "^(startup|resume|clear|compact)$",
"hooks": [
{
"type": "command",
"command": "\"${PLUGIN_ROOT}/hooks/run-hook.cmd\" session-start",
"commandWindows": "\"%PLUGIN_ROOT%\\hooks\\run-hook.cmd\" session-start",
"async": false,
"statusMessage": "Loading pstack routing"
}
]
}
]
}
}
3 changes: 0 additions & 3 deletions plugins/pstack/hooks/session-start
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
#!/usr/bin/env bash
# SessionStart hook for the pstack plugin: prints the poteto-mode dispatch
# mandate to stdout, which Claude Code injects as session context directly.
# A missing context file fails the hook cleanly instead of injecting noise.

set -euo pipefail

Expand Down
6 changes: 3 additions & 3 deletions plugins/pstack/hooks/session-start-context.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<EXTREMELY_IMPORTANT>
You have pstack.

Before responding to any non-trivial engineering task — a feature, bug fix, refactor, debugging, performance work, or any multi-step code change — invoke the `pstack:poteto-mode` skill with the Skill tool and follow it. It is the default entry point and routes to the specific pstack skills from there. Pure questions and trivial one-line edits don't need it.
For non-trivial engineering work, invoke the `pstack:poteto-mode` skill through your host's skill-loading mechanism before proceeding and follow it. This includes features, bug fixes, refactors, debugging, performance work, and multi-step code changes. It is the default entry point and routes to the specific pstack skills from there. Pure questions and trivial one-line edits don't need it. If the appropriate Pstack workflow is already active, continue it instead of starting it again.

When the intent is already specific, enter directly: `pstack:tdd` (bug with a reproducible failure), `pstack:architect` (types and module shape before code that crosses a function boundary), `pstack:how` (how a subsystem works), `pstack:why` (why it was built this way), `pstack:arena` (N parallel attempts at one task), `pstack:interrogate` (multi-model diff review).

If you were dispatched as a subagent to execute a specific task, ignore this block — poteto-mode governs the orchestrating session, and it already shaped your dispatch.
If you were dispatched as a subagent to execute a specific task, ignore this block. Poteto-mode governs the orchestrating session, and it already shaped your dispatch.

User instructions (CLAUDE.md, AGENTS.md, direct requests) take precedence over this mandate. Other session-start mandates (such as superpowers) compose with it: their skill-check discipline stands, and poteto-mode is the implementation entry point they route to for non-trivial code work.
Direct user or project instructions take precedence over this mandate. Other session-start guidance (such as superpowers) composes with it: its skill-check discipline stands, and poteto-mode is the implementation entry point it routes to for non-trivial code work.
</EXTREMELY_IMPORTANT>
Loading
Loading