diff --git a/.github/workflows/validate-plugins.yml b/.github/workflows/validate-plugins.yml
index 83015b433..acfe5bbb9 100644
--- a/.github/workflows/validate-plugins.yml
+++ b/.github/workflows/validate-plugins.yml
@@ -6,6 +6,7 @@ on:
- ".cursor-plugin/marketplace.json"
- ".claude-plugin/marketplace.json"
- "**/plugin.json"
+ - ".agents/plugins/marketplace.json"
- "schemas/**"
- "pstack/**"
- "harness/**"
@@ -20,7 +21,7 @@ jobs:
- uses: actions/setup-node@v4
with:
- node-version: 22
+ node-version: ">=24.22 <25"
- name: Install dependencies
run: npm install --no-save ajv ajv-formats fast-check@4.5.3
@@ -28,8 +29,17 @@ jobs:
- name: Validate plugin definitions
run: node scripts/validate-plugins.mjs
+ - name: Check LStack Codex packaging
+ run: node scripts/configure-lstack-codex.mjs --check
+
- name: Check generated pstack harness trees
run: node scripts/generate-pstack-harness-trees.mjs --check
+ - name: Test LStack conversation mode hooks
+ run: python3 -m unittest discover -s pstack/hooks/tests
+
+ - name: Test Codex history and worktree audit
+ run: node --test scripts/test/*.test.mjs
+
- name: Test pstack skill scripts
run: node --disable-warning=ExperimentalWarning --test pstack/skills/*/scripts/test/*.test.ts
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 000000000..749ad186e
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,9 @@
+# Maintaining LStack
+
+LStack forks `cursor/plugins` pstack. When updating this fork, fetch `upstream/main` and compare pstack changes against the revisions in `pstack/docs/harness/upstream.json`. Import relevant changes and update that record. Changes to unrelated plugins do not require an import.
+
+The Codex adapter and history helpers incorporate unmerged upstream PR #1143. Fetch its current head when updating those features, review the diff, and record the imported commit. Do not describe the PR as an official release before it merges.
+
+Preserve the role settings in the user's `pstack-models.md`, explicit-request-only Astra use, Korean writing guidance, conversation mode hooks, and bundled `deslop`, `control-cli`, and `control-ui`. Keep the Codex native manifest so hooks remain usable. Generated Claude files must be regenerated rather than edited directly.
+
+Use Node 24.22+ in the 24.x line or Node 26.10+ for compressed-history checks. Run Codex packaging checks, generated-tree checks, hook tests, the Codex history tests, and relevant pstack script tests after changes. These instructions do not authorize delegation.
diff --git a/README.lstack.md b/README.lstack.md
index e3a3e249d..c60677cb9 100644
--- a/README.lstack.md
+++ b/README.lstack.md
@@ -5,11 +5,11 @@
## 설치
```bash
-codex plugin marketplace add LifeMash-hq/LStack
+codex plugin marketplace add LifeMash-app/LStack
codex plugin add pstack@lifemash
```
-설치 후 새 Codex 대화에서 스킬을 직접 호출합니다. 자동 실행 훅은 설치하지 않습니다. 원본 스킬 참조를 유지하기 위해 플러그인 식별자는 `pstack`, 표시 이름은 LStack을 사용합니다.
+설치 후 새 Codex 대화에서 스킬을 직접 호출합니다. 원본 스킬 참조를 유지하기 위해 플러그인 식별자는 `pstack`, 표시 이름은 LStack을 사용합니다.
```text
$pstack:poteto-mode 이 작업의 관련 코드와 호출 순서를 조사해줘. 파일은 수정하지 마.
@@ -17,6 +17,24 @@ $pstack:poteto-mode 이 작업의 관련 코드와 호출 순서를 조사해줘
동일한 이름의 기존 스킬이 있으면 스킬 선택 목록에서 LStack의 항목을 선택합니다.
+## 대화별 Poteto 모드 유지
+
+**한 번 켜면 현재 대화에서 스킬 이름을 반복해서 입력하지 않아도 됩니다.** 기본 상태는 꺼짐입니다. 로컬 Codex에서 플러그인 훅을 사용하며, 최초 사용과 훅 정의 변경 시 `/hooks`에서 내용을 검토하고 신뢰해야 합니다.
+
+| 동작 | 입력 |
+| --- | --- |
+| 켜기 | `poteto 모드 켜줘` |
+| 끄기 | `poteto 모드 꺼줘` |
+| 상태 확인 | `poteto 모드 상태` |
+
+입력의 첫 줄을 위 문구로 작성합니다. 다음 줄부터 작업을 적으면 모드 변경과 작업 요청을 함께 처리합니다. 영어 입력은 `poteto mode on`, `poteto mode off`, `poteto mode status`를 사용합니다.
+
+같은 대화를 재개하거나 압축해도 상태를 유지합니다. 새 대화, 대화 분기, `/clear` 후에는 꺼짐으로 시작합니다. 기존 `$pstack:poteto-mode 작업` 호출은 해당 요청에만 적용됩니다.
+
+훅은 매 요청에 짧은 스킬 참조만 전달하고, 모델 호출이나 대화 기록 저장을 하지 않습니다. 모델과 권한 설정은 유지합니다. 클라우드에서 대화를 실행하는 환경은 로컬 플러그인 훅을 지원하지 않으므로 요청마다 스킬을 직접 호출합니다. [Codex 훅 지원 범위](https://learn.chatgpt.com/docs/hooks)
+
+Codex CLI 0.166.0에서는 표준 Agent Plugins 형식의 훅을 로더가 제외합니다. LStack은 훅을 지원하는 `.codex-plugin/plugin.json`으로 설치합니다. Claude용 배포본을 생성하는 공통 매니페스트는 `pstack/plugin.template.json`에 보관합니다.
+
## 모델
| 작업 | 모델 | 추론 강도 |
@@ -25,13 +43,39 @@ $pstack:poteto-mode 이 작업의 관련 코드와 호출 순서를 조사해줘
| 설계와 독립 리뷰, 어려운 디버깅 | GPT-6.1 Sol | high |
| 명시적으로 요청한 특정 판단 | GPT-6 Astra | low |
-Astra는 자동으로 호출하지 않습니다. 메인 대화의 모델 설정은 실행할 때 결정합니다. 플러그인은 메인 모델을 변경하지 않습니다. 역할별 설정과 도구 연결은 [Codex 호환 지침](pstack/docs/harness/codex.md)에 있습니다.
+Astra는 자동으로 호출하지 않습니다. 메인 대화의 모델 설정은 실행할 때 결정하며, 플러그인은 메인 모델을 변경하지 않습니다.
+
+역할별 설정은 `$CODEX_HOME/pstack-models.md`에서 읽으며 기본 위치는 `~/.codex/pstack-models.md`입니다. 파일이 없으면 [LifeMash 기본 설정](pstack/docs/harness/codex/pstack-models.md)을 복사합니다. 기존 파일은 유지하고, `$pstack:setup-pstack`으로 사용 가능한 모델과 추론 강도를 확인한 뒤 변경합니다. `모델@추론강도`를 쓰며 `auto`와 `inherit-parent`는 대화의 설정을 따릅니다. 자세한 연결은 [Codex 호환 지침](pstack/docs/harness/codex.md)에 있습니다.
+
+## 과거 대화와 워크트리 확인
+
+**`recall`, `reflect`, 작업 인계는 현재 작업 폴더의 Codex 기록을 조회합니다.** 활성 기록과 보관된 기록을 함께 찾고, 하위 에이전트 기록은 필요할 때 포함합니다. 다른 작업 폴더의 대화 본문은 읽지 않습니다. 워크트리 감사는 최근 작업 기록이 있으면 삭제 가능한 항목에서 제외하며, 직접 삭제하지 않습니다.
+
+```bash
+node pstack/docs/harness/codex/sessions.mjs --cwd "$PWD"
+node pstack/docs/harness/codex/worktree-audit.mjs "$PWD"
+```
+
+압축 기록에는 Node 24.22 이상의 24.x 버전 또는 26.10 이상이 필요합니다. 기본 Node가 오래됐다면 위 명령의 `node`를 `npm exec --yes --package=node@24.22.1 -- node`로 바꿔 실행합니다. 시스템 Node를 변경하지 않습니다.
+
+## pstack 업데이트 반영
+
+**pstack의 변경은 원본 저장소에서 가져오고, Codex 기능은 PR #1143의 변경도 확인합니다.** 반영 기준 커밋은 [원본 기록](pstack/docs/harness/upstream.json)에 있습니다. PR #1143은 아직 병합 전이며, LStack은 해당 구현을 가져와 사용합니다. 모델 설정과 Astra 제한, 한국어 작성 규칙, 대화 모드, 추가 세 스킬은 유지합니다.
+
+```bash
+git fetch upstream main
+git fetch upstream refs/pull/1143/head:refs/remotes/upstream/pr-1143
+```
+
+이전 반영 커밋부터의 pstack 변경을 비교해 적용한 뒤 아래 검증을 실행하고 원본 기록을 갱신합니다. 업데이트 확인은 유지보수 시 실행하며 자동 예약 작업을 설치하지 않습니다.
## 로컬 개발
```bash
node scripts/configure-lstack-codex.mjs --check
node scripts/generate-pstack-harness-trees.mjs --check
+python3 -m unittest discover -s pstack/hooks/tests
+node --test scripts/test/*.test.mjs
codex plugin marketplace add "$PWD"
codex plugin add pstack@lifemash
```
diff --git a/harness/pstack/README.md b/harness/pstack/README.md
index 07e17d8a9..40d5a6283 100644
--- a/harness/pstack/README.md
+++ b/harness/pstack/README.md
@@ -1,6 +1,6 @@
# pstack harness tree
-This folder is generated from `pstack/skills`, `pstack/agents`, `pstack/docs/guide`, `pstack/docs/harness/claude-code.md`, `pstack/README.md`, `pstack/LICENSE`, and `pstack/plugin.json`. Do not edit it by hand.
+This folder is generated from `pstack/skills`, `pstack/agents`, `pstack/docs/guide`, `pstack/docs/harness/claude-code.md`, `pstack/README.md`, `pstack/LICENSE`, and `pstack/plugin.template.json`. Do not edit it by hand.
Cursor uses `pstack/` directly, and Claude Code installs `claude-code/`. The tree leaves out the rest of `pstack/`, such as `pstack/automations` and `pstack/assets`. A relative link to a pstack file that the tree leaves out points at that file on GitHub `main` instead.
diff --git a/harness/pstack/claude-code/.claude-plugin/plugin.json b/harness/pstack/claude-code/.claude-plugin/plugin.json
index 5f7548ee3..7df458381 100644
--- a/harness/pstack/claude-code/.claude-plugin/plugin.json
+++ b/harness/pstack/claude-code/.claude-plugin/plugin.json
@@ -1,7 +1,7 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "pstack",
- "version": "0.15.36-lstack.1",
+ "version": "0.15.36-lstack.3",
"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.",
"author": {
"name": "Lauren Tan"
diff --git a/harness/pstack/claude-code/docs/guide/01-setup.md b/harness/pstack/claude-code/docs/guide/01-setup.md
index 2c2ef3413..d1e7f0bea 100644
--- a/harness/pstack/claude-code/docs/guide/01-setup.md
+++ b/harness/pstack/claude-code/docs/guide/01-setup.md
@@ -14,6 +14,17 @@ Cursor confirms the plugin is installed.
In Claude Code, run `/plugin marketplace add cursor/plugins`, then `/plugin install pstack@cursor-plugins`. Claude Code prefixes plugin commands, so each command in this guide takes a `pstack:` prefix there, such as `/pstack:setup-pstack`, which writes its model rule to `~/.claude/rules/pstack-models.md`. The [Claude Code adapter](../harness/claude-code.md) covers the other differences.
+For Codex, run these commands in a terminal:
+
+```sh
+codex plugin marketplace add LifeMash-app/LStack
+codex plugin add pstack@lifemash
+```
+
+Start a new Codex chat and run `$pstack:setup-pstack`. Then start a task with `$pstack:poteto-mode` and your goal. Codex reads model choices from `$CODEX_HOME/pstack-models.md`, which defaults to `~/.codex/pstack-models.md`.
+
+The rest of this guide uses Cursor command names and paths. In Codex, use `$pstack:name` and the paths in the [Codex adapter](https://github.com/cursor/plugins/blob/main/pstack/docs/harness/codex.md). Unconfigured roles inherit the chat's model and effort. A budget change does not override inherited choices. Setup offers only models and effort levels the host supports.
+
## Pick your models
Run:
diff --git a/harness/pstack/claude-code/plugin.json b/harness/pstack/claude-code/plugin.json
index 5f7548ee3..7df458381 100644
--- a/harness/pstack/claude-code/plugin.json
+++ b/harness/pstack/claude-code/plugin.json
@@ -1,7 +1,7 @@
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "pstack",
- "version": "0.15.36-lstack.1",
+ "version": "0.15.36-lstack.3",
"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.",
"author": {
"name": "Lauren Tan"
diff --git a/harness/pstack/claude-code/skills/poteto-help/SKILL.md b/harness/pstack/claude-code/skills/poteto-help/SKILL.md
index eb0be95dc..7fdfd46df 100644
--- a/harness/pstack/claude-code/skills/poteto-help/SKILL.md
+++ b/harness/pstack/claude-code/skills/poteto-help/SKILL.md
@@ -10,7 +10,7 @@ In Claude Code, read [the Claude Code adapter](../../docs/harness/claude-code.md
Answer the user's question about pstack, hand them a prompt they can send, and link the file the answer came from. For a help question, don't start the work. The user asked how, and a pstack run spends real tokens, so let them send the prompt.
-A message that asks for work, such as "use pstack to fix this bug", is not a help question. Read [`poteto-mode`](../poteto-mode/SKILL.md), do the work under it, and mention once that a Custom Mode keeps it on.
+A message that asks for work, such as "use pstack to fix this bug", is not a help question. Read [`poteto-mode`](../poteto-mode/SKILL.md) and do the work under it. In Cursor, mention once that a Custom Mode keeps it on.
This file maps questions to the skills and guide pages that hold the answers. Those files own the details. Read the file you route to before you quote it, and trust it when it disagrees with this map. The links here point into the installed plugin, which the user may not be able to open, so give the user the file's public copy: `https://github.com/cursor/plugins/blob/main/pstack/` followed by its path.
@@ -37,7 +37,7 @@ When the model rule is missing and it matters, ask whether the user wants to pic
## Get set up
-1. Install with `/add-plugin pstack` in chat, or from Customize in the sidebar.
+1. Use the installation steps for the user's host in [guide page 1](../../docs/guide/01-setup.md).
2. Run [`/setup-pstack`](../setup-pstack/SKILL.md). It asks for a reasoning budget, maps a model to each role, and writes a rule. The rule applies to new chats. Then it offers once each to generate a verification skill and a formal verification skill for the project, unless the project already has one.
3. Start a real task with `/poteto-mode`, a goal, and a check that can pass or fail.
@@ -45,15 +45,17 @@ Installing changes nothing until the user invokes a skill. Only `/setup-pstack`
If cost is the worry, say where the tokens go and how to spend fewer. pstack spends extra tokens on subagents and review panels. Rerun `/setup-pstack` and pick a smaller budget or cheaper models. A role set to `auto` or `inherit-parent` runs on the chat's model, which saves tokens when the chat runs on Auto or a cheaper model. A shorter panel list runs fewer subagents, one for each entry. Save `/poteto-mode` for work that needs rigor.
-pstack is built for Cursor, and it also installs in Claude Code with `/plugin marketplace add cursor/plugins`, then `/plugin install pstack@cursor-plugins`. There, each command takes a `pstack:` prefix, such as `/pstack:poteto-mode`. The [Claude Code adapter](../../docs/harness/claude-code.md) maps the Cursor names, and a step that needs a Cursor-only feature, such as Bugbot or Automations, is skipped with a one-line note.
+pstack supports Cursor, Claude Code, and Codex. In Claude Code, each command takes a `pstack:` prefix, such as `/pstack:poteto-mode`. The [Claude Code adapter](../../docs/harness/claude-code.md) maps the Cursor names.
-Other tools can read the skills, because they use the Agent Skills format. But most workflow skills, including `/poteto-mode`, `/how`, `/why`, and `/teach`, spawn Cursor subagents with per-role models, and Custom Modes and `/loop` are Cursor features, so those parts may not work there.
+In Codex, select the installed pstack skill or use `$pstack:name`, such as `$pstack:poteto-mode`. Read the [Codex adapter](https://github.com/cursor/plugins/blob/main/pstack/docs/harness/codex.md) for tools, model choices, and history. Use the skill for one request, or say `poteto 모드 켜줘` to keep LStack routing on for this conversation. Say `poteto 모드 꺼줘` to turn it off. Cursor Custom Modes and `/loop` do not apply in Codex.
+
+For a step that needs a Cursor-only feature, follow the host adapter's skip rule and report the missing check. Other tools can read the Agent Skills files, but need their own mappings for tools and subagents.
## Start a task with `/poteto-mode`
`/poteto-mode` matches the task to a playbook, copies the playbook's steps into the todo list, and runs the other skills as the steps need them. A step it skips stays in the list as `skip: `. A good prompt states the goal and how to tell it's done. It doesn't list skills, because a hand-written sequence tends to drop or reorder steps the playbook would keep. Read [`references/prompting.md`](references/prompting.md) before you help word one. [Guide page 2](../../docs/guide/02-poteto-mode.md) has examples.
-Whether `/poteto-mode` stays on depends on how the user starts it:
+In Cursor, whether `/poteto-mode` stays on depends on how the user starts it:
- Enter on `/poteto-mode` attaches the skill to one message. It fades as the chat moves on.
- Option+Enter on Mac or Alt+Enter on Windows, or Use as Mode from the skill entry, makes it a Custom Mode. It stays in context every turn until the user exits the mode, and it stays out of casual turns.
diff --git a/harness/pstack/claude-code/skills/poteto-mode/SKILL.md b/harness/pstack/claude-code/skills/poteto-mode/SKILL.md
index 3fb1e551f..d10b27209 100644
--- a/harness/pstack/claude-code/skills/poteto-mode/SKILL.md
+++ b/harness/pstack/claude-code/skills/poteto-mode/SKILL.md
@@ -107,10 +107,10 @@ You own every subagent's work. Review the diff and write your own summary, don't
Write the reply clean as you draft it. A cleanup pass after drafting does not remove these patterns.
-- **Short declarative sentences.** One thought per sentence, ended with a period.
+- **English prose.** Use short declarative sentences, one thought per sentence, ended with a period. For Korean, follow [the Korean writing rules](references/korean-writing.md) for sentence and paragraph structure instead.
- **No long-dash character anywhere.** Write a file-list bullet as a sentence ("`main.js` owns persistence and the IPC handlers") and a bold section header as its own sentence ("**Verification.** End to end via CDP").
- **A colon as a mid-sentence connector is also out** (unslop rule 14). A colon before a list is fine.
-- **Terse is not an excuse to drop content.** Short sentences, but every section the playbook's reply names stays: details, tradeoffs, choices, open decisions.
+- **Terse is not an excuse to drop content.** Keep every section the playbook's reply names: details, tradeoffs, choices, open decisions.
- **Frame impact for the consumer and the maintainer.** Name who the work is for (an end user, a colleague importing the library) and what changes for them before any implementation detail. Then what the next engineer who owns this code inherits. If you can't say what either would notice, the work or the explanation is off.
- **Never fabricate a link, citation, or transcript reference.** Link only artifacts you produced or read this session.
- **Every claim carries its evidence or its label in the same sentence.** Measured, inferred, or guess. A prediction or an unseen cause is a guess. Never hand the human a check you could run.
diff --git a/harness/pstack/claude-code/skills/poteto-mode/references/korean-writing.md b/harness/pstack/claude-code/skills/poteto-mode/references/korean-writing.md
new file mode 100644
index 000000000..88b03105b
--- /dev/null
+++ b/harness/pstack/claude-code/skills/poteto-mode/references/korean-writing.md
@@ -0,0 +1,14 @@
+# 한국어 답변과 문서 작성
+
+한국어에서는 이 지침을 영어의 문장 길이, 연결 방식, 목록 형식 규칙보다 우선합니다. 목표는 문장을 짧게 만드는 것이 아니라 주장과 근거를 분명하게 전달하는 것입니다.
+
+- 이유, 조건, 대조, 결과로 연결된 내용은 연결 어미로 잇고, 서로 독립된 사실은 문장을 나눕니다. 길이나 단어 수만으로 문장을 끊지 않습니다.
+- 한 문장의 연결 어미는 둘 정도를 기준으로 삼습니다. 셋 이상 이어져 읽기 어려우면 관계가 가장 약한 지점에서 나누며, 개수만 맞추려고 자연스러운 문장을 쪼개지 않습니다.
+- 문단 첫 문장에 요지를 두고 뒤에서 근거를 설명하며, 한 문단에는 주제 하나만 둡니다.
+- 같은 종결 어미가 반복되면 내용의 관계에 맞춰 문장 구조를 조정합니다. 반복을 피하려고 주어나 동의어를 억지로 덧붙이지 않습니다.
+- 생략한 주어나 지시어 때문에 대상을 다시 찾아야 한다면 구체적인 이름을 씁니다. 대상이 분명할 때는 같은 주어를 매번 반복하지 않습니다.
+- 목록과 표는 같은 기준으로 비교할 수 있는 병렬 항목에 씁니다. 인과나 순서를 설명하는 내용을 글머리표로 잘게 나누지 않습니다.
+- 긴 대시와 문장 중간의 연결용 콜론을 쓰지 않고, 주장에는 근거나 측정, 추정, 추측의 구분을 같은 문장에 붙입니다. 판단은 명확하게 쓰되 실제 불확실성을 숨기지는 않습니다.
+- 짧게 쓰려고 필요한 세부 사항, 장단점, 남은 결정을 빼지 않습니다.
+
+문장 예시에서 "린트가 이미 이 경우를 막습니다. 그래서 이 주석은 불필요합니다."는 "린트가 이미 이 경우를 막으므로 이 주석은 불필요합니다."로 잇습니다.
diff --git a/harness/pstack/claude-code/skills/technical-writing/SKILL.md b/harness/pstack/claude-code/skills/technical-writing/SKILL.md
index 903d7d6d2..afeef3d1c 100644
--- a/harness/pstack/claude-code/skills/technical-writing/SKILL.md
+++ b/harness/pstack/claude-code/skills/technical-writing/SKILL.md
@@ -10,6 +10,8 @@ In Claude Code, read [the Claude Code adapter](../../docs/harness/claude-code.md
Write so a tired engineer understands on the first read. Apply all four layers.
+For Korean prose, [the Korean writing rules](../poteto-mode/references/korean-writing.md) take precedence over the English sentence-length, connective, and list-format rules below.
+
Three rules sit above the layers:
- **Cut every word that does no work.** If the sentence survives without a word, the word goes. "In order to" is "to". "It is important to note that" is nothing.
diff --git a/harness/pstack/claude-code/skills/unslop/SKILL.md b/harness/pstack/claude-code/skills/unslop/SKILL.md
index 97f5b6412..d075aa4e0 100644
--- a/harness/pstack/claude-code/skills/unslop/SKILL.md
+++ b/harness/pstack/claude-code/skills/unslop/SKILL.md
@@ -54,7 +54,7 @@ Rule numbers are stable ids that other skills cite. A removed rule leaves a gap.
### Plain speech
27. **Say what it does, not how it feels.** "the database stays close at hand", "SQL you can read", "types that follow your schema" name a feeling. The fix names the mechanism or a number: "`.toSQL()` returns the exact string sent to the database", "a column rename fails the build". Ask what the sentence tells the reader to do or know, then write that. If you can't restate it as a concrete instruction, fact, or number, cut it. One more check: if the sentence could appear unchanged in another project's docs, it says nothing about this one. Cut it.
-28. **Shorten or split dense sentences.** If the reader has to backtrack to parse a sentence, break it in two or drop clauses. One idea per sentence.
+28. **Shorten or split dense sentences.** If the reader has to backtrack to parse a sentence, break it in two or drop clauses. One idea per sentence. For Korean, apply [the Korean writing rules](../poteto-mode/references/korean-writing.md) instead of mechanically splitting connected ideas.
29. **Active voice.** Prefer it. Catch "is/are/was/were + past participle" and name the actor: "queries are validated" becomes "the compiler validates queries", "the file is parsed by the loader" becomes "the loader parses the file". Passive is fine only when the actor is unknown or genuinely doesn't matter.
30. **Cut adverbs, or use a stronger verb.** "runs quickly" becomes "is fast" or the number, and "significantly improves" becomes the measured delta. An adverb propping up a weak verb means the verb is wrong.
31. **Prefer the plain word.** "utilize" and "leverage" become "use", "facilitate" becomes "help", "numerous" becomes "many", "in the event that" becomes "if". The fancier synonym is rarely clearer.
diff --git a/pstack/.codex-plugin/plugin.json b/pstack/.codex-plugin/plugin.json
index 943a5c155..a54c97a62 100644
--- a/pstack/.codex-plugin/plugin.json
+++ b/pstack/.codex-plugin/plugin.json
@@ -1,12 +1,13 @@
{
"name": "pstack",
- "version": "0.15.36-lstack.1",
+ "version": "0.15.36-lstack.3",
"description": "LifeMashStack. Upstream pstack workflows adapted for Codex.",
"author": { "name": "LifeMash" },
- "homepage": "https://github.com/LifeMash-hq/LStack",
- "repository": "https://github.com/LifeMash-hq/LStack",
+ "homepage": "https://github.com/LifeMash-app/LStack",
+ "repository": "https://github.com/LifeMash-app/LStack",
"license": "MIT",
"skills": "./skills/",
+ "hooks": "./hooks/hooks.json",
"interface": {
"displayName": "LStack (LifeMashStack)",
"shortDescription": "pstack engineering workflows for Codex",
diff --git a/pstack/.cursor-plugin/plugin.json b/pstack/.cursor-plugin/plugin.json
index 810749dd9..81884d637 100644
--- a/pstack/.cursor-plugin/plugin.json
+++ b/pstack/.cursor-plugin/plugin.json
@@ -1,7 +1,7 @@
{
"name": "pstack",
"displayName": "pstack",
- "version": "0.15.36-lstack.1",
+ "version": "0.15.36-lstack.2",
"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.",
"author": {
"name": "Lauren Tan"
diff --git a/pstack/docs/guide/01-setup.md b/pstack/docs/guide/01-setup.md
index 2c2ef3413..2bae61904 100644
--- a/pstack/docs/guide/01-setup.md
+++ b/pstack/docs/guide/01-setup.md
@@ -14,6 +14,17 @@ Cursor confirms the plugin is installed.
In Claude Code, run `/plugin marketplace add cursor/plugins`, then `/plugin install pstack@cursor-plugins`. Claude Code prefixes plugin commands, so each command in this guide takes a `pstack:` prefix there, such as `/pstack:setup-pstack`, which writes its model rule to `~/.claude/rules/pstack-models.md`. The [Claude Code adapter](../harness/claude-code.md) covers the other differences.
+For Codex, run these commands in a terminal:
+
+```sh
+codex plugin marketplace add LifeMash-app/LStack
+codex plugin add pstack@lifemash
+```
+
+Start a new Codex chat and run `$pstack:setup-pstack`. Then start a task with `$pstack:poteto-mode` and your goal. Codex reads model choices from `$CODEX_HOME/pstack-models.md`, which defaults to `~/.codex/pstack-models.md`.
+
+The rest of this guide uses Cursor command names and paths. In Codex, use `$pstack:name` and the paths in the [Codex adapter](../harness/codex.md). Unconfigured roles inherit the chat's model and effort. A budget change does not override inherited choices. Setup offers only models and effort levels the host supports.
+
## Pick your models
Run:
diff --git a/pstack/docs/harness/codex.md b/pstack/docs/harness/codex.md
index f78511b3c..c5c45bffd 100644
--- a/pstack/docs/harness/codex.md
+++ b/pstack/docs/harness/codex.md
@@ -1,53 +1,135 @@
# LStack in Codex
-Read once per task. These mappings replace Cursor-specific instructions in the bundled skills and their references. Keep the playbook steps. `` is this plugin's root, two directories above this file.
+pstack skills use Cursor names. In Codex, read this file once per session. Apply these mappings wherever a skill or its references use those names. `` is the installed folder that contains `skills/` and `docs/`. Use the tools and argument schemas exposed in the current session. Clients can expose different tools.
-## Tools
+## Tools and invocation
-| Upstream name | Codex operation |
+| Cursor | Codex |
| --- | --- |
-| `Read`, `Grep`, `Glob`, `Bash`, file edits | Available file and shell tools. Search with `rg`; edit with the patch tool. |
-| `AskQuestion` | Available user-input tool, or a question in the conversation. |
-| Todolist, `TodoWrite` | Available plan tool, or a short tracked list when absent. |
-| `/name`, the **name** skill | Read `/skills//SKILL.md`. User invocation is `$pstack:name`. |
-| `Task`, `generalPurpose` | Available native agent spawn tool. Use only its actual schema. |
-| `poteto-agent`, `comment-sicko` | Pass the corresponding `/agents/.md` instructions and absolute skill paths to a native agent. Do not assume a custom agent type is registered. |
-| `run_in_background`, `resume`, `file_attachments` | Native agents run asynchronously. Use native wait/message/resume operations when supported; put file paths in the brief. |
-| `readonly: true` | Give a read-only brief. This does not create a separate sandbox. |
-| `environment: "cloud"`, `cloud_base_branch` | A separate local worktree at the specified base. Create it before spawning and give its absolute path to the agent. |
+| `Task` | The available `spawn_agent` tool. It may be in a `collaboration` namespace. |
+| `AskQuestion` | Use the available structured question tool. `request_user_input_async` allows independent work while the answer is pending. Use `request_user_input` only in modes that expose it. Otherwise ask in your reply. |
+| Open a todolist | Use `update_plan` when exposed. Otherwise keep the playbook checklist in the conversation and update it at each phase. A goal is not a todo list. |
+| Run another pstack skill (`/name` or "the **name** skill") | Read `/skills//SKILL.md` directly and follow it. Most pstack skills intentionally stay out of implicit discovery. When addressing the user, tell them to select the installed pstack skill in the composer or invoke it with `$pstack:name`, not a Cursor slash command. |
+| `Read`, `Grep`, `Glob`, `Bash` | Use the session's file and shell tools. Use `rg` for searches. |
+| `create-skill`, `deslop`, `control-cli`, `control-ui` | Use the corresponding installed skill or native tool when available. `deslop`, `control-cli`, and `control-ui` are bundled at `/skills//SKILL.md`. `create-skill` maps to the installed `skill-creator` skill. Run CLI checks through the shell. Drive UI with the exposed browser or computer tools. Clean up code directly when there is no matching skill. Report any required live check that cannot run. |
-Repository instructions govern delegation. Without authorization or agent tools, carry out the same investigation, implementation, and review steps sequentially yourself and report that independent review did not run. Do not bypass this fallback through a second Codex CLI or an external model API. Parallel writers need separate worktrees or disjoint file ownership.
+The package generates `agents/openai.yaml` from each skill's `disable-model-invocation` flag. Explicit selection loads the skill. Read sibling skills by their packaged paths, even when they are absent from the automatic catalog. Explicit `poteto-mode` invocation applies to the current request. LStack also supports conversation persistence through the hooks described below. Cursor Custom Modes do not apply in Codex.
-## Models
+When creating or updating a skill, including `automate-me`'s `-mode`, translate its invocation policy too. In that skill's `agents/openai.yaml`, set `policy.allow_implicit_invocation` to the inverse of `disable-model-invocation`. Preserve other existing fields. Frontmatter alone does not express Codex's documented invocation policy. For an explicit-only mode, write:
-Replace all upstream role defaults, model pools, budget ladders, and model-family fallback rules with these settings. Do not read or write `pstack-models.mdc` in Codex.
+```yaml
+policy:
+ allow_implicit_invocation: false
+```
+
+## Subagents
+
+| Cursor | Codex |
+| --- | --- |
+| `subagent_type: generalPurpose` | Use the default general-purpose agent. Omit Cursor's `subagent_type`. |
+| `poteto-agent` | Spawn a delegate whose brief includes the absolute paths to this adapter and `/skills/poteto-mode/SKILL.md`, and tells it to read both before working. These plugin Markdown files do not register a Codex agent type. |
+| `comment-sicko` | Spawn a reviewer with the scoped diff and the absolute paths to this adapter and `/agents/comment-sicko.md`. |
+| `readonly: true` | Give a read-only brief and verify the working tree afterward. A brief does not change permissions. Retain the session's sandbox and approval controls. |
+| `readonly: false` | Use the normal delegate with the parent's permissions. |
+| `environment: "cloud"`, `environment: "local"` | Codex delegates share the filesystem. Give concurrent writers separate worktrees or disjoint output directories. Omit the Cursor fields. |
+| `cloud_base_branch` | Put the exact starting branch or commit and the worktree path in the delegate's brief. |
+| `run_in_background: true` | Omit. Spawned agents already run alongside the parent. |
+| `resume` | Use `followup_task` or `resume_agent` when offered. Preserve the skill's restrictions on reusing a delegate. |
+| `file_attachments` | Put absolute file paths in the brief. |
+
+Use the returned agent identifier with the session's send, wait, and follow-up tools. `wait_agent` can report mailbox updates. Read the delivered messages to get the answer. A timeout is not completion. Use `close_agent` only when it exists. After a capacity error, wait for existing work. Do not retry with a different model. On hosts without a close tool, completion does not necessarily free a slot.
-| Role | Model | Reasoning effort |
-| --- | --- | --- |
-| Ordinary exploration, implementation, synthesis, prose | `gpt-6.1-sol` | `medium` |
-| Architecture, independent review, difficult debugging | `gpt-6.1-sol` | `high` |
-| One specific judgment explicitly requested from Astra | `gpt-6-astra` | `low` |
+When selecting another model or effort requires a fresh context, use the spawn tool's fresh-context option (`fork_turns: "none"` on hosts that expose it) and supply the task, paths, and relevant constraints explicitly. Full-history forks may inherit model and effort and reject overrides.
-Astra is never an automatic fallback, panel member, or cross-judge. An authorized Astra consultation receives only the question and necessary code/evidence, defaults to one call, and does not delegate or retry automatically. Sol handles follow-up implementation.
+Current Codex releases enable subagents by default. Local clients can disable them with `agents.enabled = false`. If no spawn tool is available, report that limitation. Independent tasks can run sequentially, but a required independent review remains unverified until another agent or reviewer performs it. Do not count the parent's own second pass as independent review.
+
+Repository instructions govern delegation. Without authorization, perform the same steps sequentially and report that independent review did not run. Do not bypass this through another Codex CLI or external model API.
+
+## Models and effort
+
+| Cursor | Codex |
+| --- | --- |
+| `pstack-models.mdc`, `~/.cursor/rules/pstack-models.mdc` | Read `$CODEX_HOME/pstack-models.md` (default `~/.codex/pstack-models.md`) when a skill selects models. Codex does not automatically load this file. |
+| An unconfigured `claude-*`, `grok-*`, or `gpt-*` default | Inherit the parent. A Cursor model slug is not evidence that Codex can run it. |
+| `auto` or `inherit-parent` | Omit model and effort overrides. Each panel entry represents one independent agent. |
+| A configured Codex model | Pass it only if the current spawn tool and available model inventory support it. |
+| `@` | Pass the model and supported `reasoning_effort` separately. |
-Use actual spawn model/effort settings or a configured custom agent. Do not encode reasoning effort in the model name or claim that prose changes the running model. When changing a child's model, use a fresh context if required by the spawn tool and supply a self-contained brief. If the requested settings are unavailable, inherit the parent, report the actual fallback, and do not probe other expensive models. The main chat retains its launch settings; the plugin cannot change them.
+Keep role names identical to `setup-pstack`. For a bare model name, preserve the session effort when the host exposes and accepts it. Otherwise explain that the host chooses the effort. An optional `default effort` row applies to real model entries without an `@effort` suffix. A value of `session` means the parent's effort. Keep configured Codex model names. If the host rejects a model, report the rejection. Use a confirmed available model only under the workflow's fallback rule. Otherwise inherit the parent and disclose the substitution.
-For `arena`, `architect`, and `interrogate`, keep the requested perspectives using Sol at the role's effort. This is independent same-model review, not multi-model review. Arena's different-family judge is skipped unless the user explicitly requests Astra. A sequential pass is not an independent review.
+Repeated models provide independent reviewers, but not model diversity. GPT models belong to the same family for Arena's cross-judge rule. When no different-family model is available, follow Arena's documented skip path and report the missing cross-judge. Another provider's CLI needs separate access and authorization.
-## Paths and capabilities
+### LifeMash defaults and Astra limit
-Use the installed `` paths instead of searching `~/.cursor/plugins/`. Codex plugin metadata is `/.codex-plugin/plugin.json`. Project skill paths are `.agents/skills/`; project instructions are `AGENTS.md`. Do not write Cursor or Claude configuration from Codex.
+The [initial model sheet](codex/pstack-models.md) preserves LifeMash's current choices. When installing for LifeMash and the user has not created a sheet, copy it to `$CODEX_HOME/pstack-models.md`. Preserve an existing sheet. Read it when selecting delegates; this file does not change the main chat's running model or effort.
-For history, use a supported session-history tool scoped to the current project, or user-supplied transcripts. Do not guess Cursor transcript paths in Codex.
+Astra is only for one specific judgment explicitly requested by the user. It is never an automatic fallback, panel member, or cross-judge, even if a sheet lists it. An authorized consultation defaults to one call at `low`, receives only necessary evidence, and does not delegate or retry automatically. Sol performs follow-up implementation. If the model is unavailable, inherit the parent and report the actual fallback; do not probe expensive alternatives.
-For built-in PR actions, use the available forge connector or CLI. Existing Bugbot comments can be read as ordinary PR reviews. Cursor cloud control, automations, and Cursor-specific script commands are unavailable. Skip an optional step with a reason; if required evidence depends on it, report the missing capability rather than claiming completion. A long-running request does not create a background monitor by itself.
+### setup-pstack
-`deslop`, `control-cli`, and `control-ui` are bundled in `/skills/`. Read those local skills when a playbook references them, including references naming `cursor-team-kit`. They are instructions, not installed runtimes; use available terminal/browser tools or the project's existing harness. Report a missing capability when it prevents verification. Cursor's built-in `create-skill` maps to the available `skill-creator` skill.
+Follow the skill's steps with these substitutions:
-## setup-pstack
+- **Detect:** inventory the models and effort levels the current spawn tool accepts. If no reliable inventory is exposed, offer `inherit-parent` and `auto`. Ask for model choices only when needed. Do not persist guessed slugs.
+- **Load:** read the Codex sheet above, not a Cursor rule. Use its existing role values and budget as the starting point. Preserve its `default effort` setting when present.
+- **Defaults:** map each unconfigured role to `inherit-parent`. Keep the number of entries in default panels. Explain that inherited entries follow the session's model and effort, so changing the budget does not override those entries.
+- **Budget and confirm:** show every role, model, effort, and panel size before writing. For a real model, store `@` when an effort is chosen. Offer only supported levels and keep an inheritance choice for effort.
+- **Write:** write the confirmed rows and budget to the Codex sheet, with no Cursor frontmatter. Change only that file. Do not put model preferences in `AGENTS.md`, `CLAUDE.md`, or `config.toml`.
+- **Confirm:** the next model-selecting pstack skill reads the sheet. Continue the optional verification-skill offers using the Codex paths below.
-In Codex, report the current model/effort when observable and explain the role settings above, then stop. Do not follow the Cursor setup steps or install hooks. To start a chat with the baseline settings, the user can run:
+## Paths and history
-```bash
-codex --model gpt-6.1-sol -c 'model_reasoning_effort="medium"'
+| Cursor | Codex |
+| --- | --- |
+| `.cursor/skills/`, `~/.cursor/skills/` | `.agents/skills/`, `~/.agents/skills/` for project and personal skills. |
+| `~/.cursor/plugins/`, `.cursor-plugin/plugin.json` | Use the installed `` path supplied by the skill catalog. The generated package has `plugin.json` and a `.codex-plugin/plugin.json` compatibility manifest. |
+| `.cursor/rules/`, always-applied rules | Project or personal `AGENTS.md`. The separate model sheet above is the exception. |
+| `https://github.com/cursor/plugins/blob/main/pstack/` | Read `/` when packaged. Give the public URL to the user when they need a link. |
+| `~/.cursor/projects//agent-transcripts/` | Use a history tool scoped to the requested chat when available. For local rollouts, use the helper below to select this workspace's sessions before reading their contents. |
+
+For compressed history, use Node 24.22 or a later 24.x release, or Node 26.10 or newer. Check `node --version` first. If the default runtime is older, run these helpers with `npm exec --yes --package=node@24.22.1 -- node