-
Notifications
You must be signed in to change notification settings - Fork 0
plan: probe verdict + the rules Stack B must obey #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c341141
84d4045
23941e6
f177948
2be937d
8fd3fe6
d36c1dc
3b4ada0
5bc74b3
bba368d
c22703a
8d24a3b
7e13b3e
8c6576f
2a03442
678eab8
c6d5afe
54ec34d
4211cf3
74276d3
99fdbd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,10 +5,11 @@ | |
| # Deterministic layer under the ystack-main-gate ruleset — defense in depth, | ||
| # and the only enforcement in clones where no ruleset exists. | ||
| # | ||
| # Deliberately NOT blocked: scripts/merge-pr.sh — the v1 in-session merge | ||
| # harness keeps its own safety checks (SHA pinning, required-checks gate, | ||
| # REVIEW_REQUIRED refusal). Raw merge commands are blocked; the harness or a | ||
| # human is the only merge path. | ||
| # The merge helper is blocked too. It was exempt while the manager could | ||
| # merge in-session; that permission is retired, so the exemption became a | ||
| # bypass — in a clone with no ruleset, or under an account that can merge, | ||
| # an agent could have merged through it. scripts/merge-pr.sh is now the | ||
| # operator's own tool, run by a human, never by an agent. | ||
|
|
||
| input=$(cat) | ||
| cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty') | ||
|
|
@@ -22,9 +23,13 @@ if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+push[^|;&]*[[:space:]:+](refs/h | |
| exit 2 | ||
| fi | ||
|
|
||
| # Raw merge commands — merging is the human gate (or scripts/merge-pr.sh). | ||
| # Every merge path — merging is the operator's, always. | ||
| if printf '%s' "$cmd" | grep -Eq 'gh[[:space:]]+pr[[:space:]]+merge'; then | ||
| echo "Blocked by ystack guard: agents never merge PRs. A human merges at the gate (or use scripts/merge-pr.sh in-session)." >&2 | ||
| echo "Blocked by ystack guard: agents never merge PRs. The operator merges at the gate." >&2 | ||
| exit 2 | ||
| fi | ||
| if printf '%s' "$cmd" | grep -Eq 'merge-pr\.sh'; then | ||
| echo "Blocked by ystack guard: merge-pr.sh is the operator's own tool. Apply merge-ready and hand the PR over." >&2 | ||
| exit 2 | ||
|
Comment on lines
+31
to
33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the normal installed path, AGENTS.md reference: AGENTS.md:L65-L68 Useful? React with 👍 / 👎. |
||
| fi | ||
| if printf '%s' "$cmd" | grep -Eq 'gh[[:space:]]+api[[:space:]][^|;&]*pulls/[0-9]+/merge'; then | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| # Working in this repo — for every agent | ||
|
|
||
| ystack is a control plane for an autonomous coding team, and it is its own | ||
| target repo: agents here are improving the team itself. | ||
|
|
||
| **This file is the single source of working rules.** Every agent reads it, | ||
| whatever vendor — Codex and most tools look for `AGENTS.md`, Claude Code | ||
| reads `CLAUDE.md`, which imports this file. One file, no drift. | ||
|
|
||
| Companions: **`REVIEW.md`** is how work is reviewed here (passes, Important | ||
| vs nit, how disagreements end). **`work/<slug>/`** holds the artifact chain — | ||
| `intent.md` → `spec.md` → `plan.md`. If you are implementing, your brief is | ||
| that slug's plan; it is written so someone who never saw the conversation can | ||
| build from it. | ||
|
|
||
| Two goals drive the backlog: | ||
| 1. **Reusable by anyone** — a clean, parameterized, well-documented product others can adopt. | ||
| 2. **Full backup** — everything needed to reconstruct the team if the live setup is lost. | ||
|
|
||
| ## What lives here | ||
| - `manager/CLAUDE.md` — yshifu's role (the manager persona). | ||
| - `routines/*.md` — the coder's baseline instructions yshifu reads to brief a spawned | ||
| coder subagent (`coder.md` / `coder-revision.md`) plus the per-task `brief.md`. | ||
| - `reviewer/codex-review.md` — the doc for the Codex reviewer harness (`scripts/codex-review.sh`). | ||
| - `templates/*` — drop-in files for target repos. | ||
| - `scripts/*.sh` — the shipped tooling: `install.sh` (generates the `/yshifu` command), | ||
| `setup-target-repo.sh` (bootstraps a target repo's loop labels), and `codex-review.sh` | ||
| (runs the Codex reviewer against a PR). | ||
|
|
||
| ## Stack & commands | ||
| - Markdown + shell. The setup/reviewer tooling lives in `scripts/*.sh`; validators are | ||
| still to come. | ||
| - CI: `.github/workflows/ci.yml` (structure check + shellcheck). **CI must stay green — | ||
| it is the hard merge gate.** Add real tests as code lands. | ||
| - **Shellcheck is pinned to `0.11.0`** (the `SHELLCHECK_VERSION` constant in | ||
| `ci.yml` is the single source of truth). CI downloads that exact static release and | ||
| verifies its release-asset SHA-256 and version before linting, so a runner-image bump | ||
| or changed download can't silently drift it. **Lint locally against 0.11.0** — not | ||
| whatever your local install happens to be — with `shellcheck -x -S style` over | ||
| `find . -name '*.sh' -not -path './.git/*'`; another shellcheck version can report | ||
| different findings/codes (e.g. SC2317 vs SC2329) and disagree with CI. Grab the pinned | ||
| binary from the shellcheck GitHub releases if your local version differs. | ||
| - The **structure check** reads `ci/required-files.txt` — the manifest of every | ||
| restore-critical file — and fails if any listed path is missing (and if a listed | ||
| `scripts/*.sh` isn't executable). This is what makes the full-backup goal enforceable: | ||
| delete a load-bearing file and CI goes red. **Add new restore-critical files to the | ||
| manifest** so the guarantee keeps holding. | ||
|
|
||
| ## PR rules (enforced by coder + reviewer) | ||
| - **One concern per PR.** Soft size budget ~300–400 net lines; split if bigger. | ||
| - Every PR links its issue (`Closes #<n>`) and keeps README/docs in sync with any change. | ||
| - **Plain language, always** (operator rule, 2026-08-26): every artifact | ||
| (intent/spec/plan), PR title/description, and review comment is written for a | ||
| tired human. Short sentences. Everyday words. No jargon where a plain word | ||
| works. If two phrasings say the same thing, use the shorter one. | ||
|
|
||
| ## CRITICAL — self-modification safety | ||
| - The live setup runs from **generated/synced artifacts, not from these files directly.** | ||
| Editing a prompt or doc here is a *proposal*; it only takes effect once synced: the live | ||
| `/yshifu` command is regenerated by re-running **`scripts/install.sh`**, and the coder | ||
| instructions in `routines/coder.md` / `routines/coder-revision.md` take effect when | ||
| **yshifu reads them to brief a spawned coder subagent** (there are no UI-pasted routines). | ||
| Merging a prompt change does NOT change live behavior until synced — call this out in the | ||
| PR description when a prompt changes. | ||
| - **Never weaken the safety rails without explicit human sign-off:** reviewer stays | ||
| read-only / comments-only; **merging is the operator's, always** — the in-session | ||
| auto-merge v1 allowed was retired when the branch ruleset landed, and no agent has a | ||
| merge path any more; the rounds cap and `needs-human` escalation stay | ||
|
Comment on lines
+66
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Compliance] Fresh evidence in this revision is that the new canonical rule forbids every agent merge, but the live sources were not synced: AGENTS.md reference: AGENTS.md:L58-L64 Useful? React with 👍 / 👎.
Comment on lines
+65
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Compliance] This new never-merge rule leaves AGENTS.md reference: AGENTS.md:L65-L68 Useful? React with 👍 / 👎.
Comment on lines
+65
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Security] In clones without branch protection, or when the session account can merge, the new claim that agents have no merge path is false: AGENTS.md reference: AGENTS.md:L65-L68 Useful? React with 👍 / 👎.
Comment on lines
+65
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
[Compliance] In the final tree, shipped guidance still contradicts this new rule: AGENTS.md reference: AGENTS.md:L49-L55 Useful? React with 👍 / 👎. |
||
| intact. yshifu never writes code/opens PRs and **never self-approves acting alone** — a | ||
| user-directed issue is gated by the user's approval of the drafted spec (the one-liner is the | ||
| request, not the go), a proactive issue by the passed yshifu⇄Codex manager-debate consensus | ||
| (for *proactive* work the user's gate is at the north-star altitude; user-directed issues | ||
| still need the user's spec approval). | ||
|
|
||
| ## v2 artifact chain (work/) | ||
| - One initiative = one dir: `work/<slug>/` holding `intent.md` → `spec.md` → `plan.md`. | ||
| Each artifact lands via its own PR and the operator's merge IS the gate: G1 accepts | ||
| the intent, G2 approves the spec, G3 approves the implementation PR (which carries | ||
| `plan.md` + code + tests). Details: `work/README.md`; review policy: `REVIEW.md`. | ||
| - Skills: `/intent-draft`, `/spec-draft`, `/plan-draft` hold the templates and stage rules. | ||
| - **Hash discipline:** `spec.md` frontmatter records `intent-blob` (`git hash-object` of | ||
| the intent it was drafted from); `plan.md` records `spec-blob`. On mismatch with main's | ||
| current upstream file, label the PR `stale` and stop — never build on a moved artifact. | ||
| - **Stage rules (autonomous lane):** the spec stage writes only `work/<slug>/spec.md`; | ||
| the implement stage never touches `intent.md`/`spec.md`; unattended agents never write | ||
| the **constitution paths** — `.github/**`, `.claude/**`, `AGENTS.md` (this file), | ||
| `CLAUDE.md`, `REVIEW.md` — such changes land as patches under `proposals/` that the | ||
| operator applies. That is the same list `REVIEW.md` uses; the two must always match, so | ||
| a change to one is a change to both. Operator-driven sessions are exempt; Phase 3 hooks | ||
| enforce this mechanically via `YSTACK_STAGE`. | ||
| - Deterministic branches: `ystack/intent/<slug>`, `ystack/spec/<slug>`, | ||
| `ystack/impl/<slug>` — re-runs update the existing PR, never open a second. | ||
|
|
||
| ## Reusability goal | ||
| - No hardcoded personal values (usernames, repo names) in shipped templates — keep the | ||
| reusable path parameterized. Personal config stays out of it. | ||
|
|
||
| ## The rules that bite | ||
|
|
||
| - **Never merge.** Opening a PR ends an agent's authority; the operator | ||
| merges. Pushing to `main` is refused server-side anyway. | ||
| - **Prove it.** Run the checks the plan names, paste the output, and say | ||
| which commit you ran them on. Old proof on a new commit is stale. | ||
| - **Old names are gone.** The project and its manager were renamed; | ||
| `scripts/check-rename.sh` fails CI if either old name survives in a tracked | ||
| file. A line documenting real back-compat must carry the word "legacy" — | ||
| that is how the gate tells intent from leftovers. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,83 +1,9 @@ | ||
| # ystack — conventions for the coding agents | ||
|
|
||
| This is the **control-plane repo for an autonomous coding team, and it is its own | ||
| target repo** — agents working here are improving the team itself. Two goals drive | ||
| the backlog: | ||
| 1. **Reusable by anyone** — a clean, parameterized, well-documented product others can adopt. | ||
| 2. **Full backup** — everything needed to reconstruct the team if the live setup is lost. | ||
| The working rules live in **[`AGENTS.md`](AGENTS.md)** so every agent reads the | ||
| same thing, whatever vendor. Open that file — this one only imports it so | ||
| Claude Code loads the same text: | ||
|
|
||
| ## What lives here | ||
| - `manager/CLAUDE.md` — yshifu's role (the manager persona). | ||
| - `routines/*.md` — the coder's baseline instructions yshifu reads to brief a spawned | ||
| coder subagent (`coder.md` / `coder-revision.md`) plus the per-task `brief.md`. | ||
| - `reviewer/codex-review.md` — the doc for the Codex reviewer harness (`scripts/codex-review.sh`). | ||
| - `templates/*` — drop-in files for target repos. | ||
| - `scripts/*.sh` — the shipped tooling: `install.sh` (generates the `/yshifu` command), | ||
| `setup-target-repo.sh` (bootstraps a target repo's loop labels), and `codex-review.sh` | ||
| (runs the Codex reviewer against a PR). | ||
| @AGENTS.md | ||
|
|
||
| ## Stack & commands | ||
| - Markdown + shell. The setup/reviewer tooling lives in `scripts/*.sh`; validators are | ||
| still to come. | ||
| - CI: `.github/workflows/ci.yml` (structure check + shellcheck). **CI must stay green — | ||
| it is the hard merge gate.** Add real tests as code lands. | ||
| - **Shellcheck is pinned to `0.11.0`** (the `SHELLCHECK_VERSION` constant in | ||
| `ci.yml` is the single source of truth). CI downloads that exact static release and | ||
| verifies its release-asset SHA-256 and version before linting, so a runner-image bump | ||
| or changed download can't silently drift it. **Lint locally against 0.11.0** — not | ||
| whatever your local install happens to be — with `shellcheck -x -S style` over | ||
| `find . -name '*.sh' -not -path './.git/*'`; another shellcheck version can report | ||
| different findings/codes (e.g. SC2317 vs SC2329) and disagree with CI. Grab the pinned | ||
| binary from the shellcheck GitHub releases if your local version differs. | ||
| - The **structure check** reads `ci/required-files.txt` — the manifest of every | ||
| restore-critical file — and fails if any listed path is missing (and if a listed | ||
| `scripts/*.sh` isn't executable). This is what makes the full-backup goal enforceable: | ||
| delete a load-bearing file and CI goes red. **Add new restore-critical files to the | ||
| manifest** so the guarantee keeps holding. | ||
|
|
||
| ## PR rules (enforced by coder + reviewer) | ||
| - **One concern per PR.** Soft size budget ~300–400 net lines; split if bigger. | ||
| - Every PR links its issue (`Closes #<n>`) and keeps README/docs in sync with any change. | ||
| - **Plain language, always** (operator rule, 2026-08-26): every artifact | ||
| (intent/spec/plan), PR title/description, and review comment is written for a | ||
| tired human. Short sentences. Everyday words. No jargon where a plain word | ||
| works. If two phrasings say the same thing, use the shorter one. | ||
|
|
||
| ## CRITICAL — self-modification safety | ||
| - The live setup runs from **generated/synced artifacts, not from these files directly.** | ||
| Editing a prompt or doc here is a *proposal*; it only takes effect once synced: the live | ||
| `/yshifu` command is regenerated by re-running **`scripts/install.sh`**, and the coder | ||
| instructions in `routines/coder.md` / `routines/coder-revision.md` take effect when | ||
| **yshifu reads them to brief a spawned coder subagent** (there are no UI-pasted routines). | ||
| Merging a prompt change does NOT change live behavior until synced — call this out in the | ||
| PR description when a prompt changes. | ||
| - **Never weaken the safety rails without explicit human sign-off:** reviewer stays | ||
| read-only / comments-only; merge stays gated (yshifu may merge only CI-green + Codex-clean | ||
| + low-risk PRs under standing authorization, and must bring safety-rail / north-star / | ||
| ambiguous / high-risk PRs to the human); the rounds cap and `needs-human` escalation stay | ||
| intact. yshifu never writes code/opens PRs and **never self-approves acting alone** — a | ||
| user-directed issue is gated by the user's approval of the drafted spec (the one-liner is the | ||
| request, not the go), a proactive issue by the passed yshifu⇄Codex manager-debate consensus | ||
| (for *proactive* work the user's gate is at the north-star altitude; user-directed issues | ||
| still need the user's spec approval). | ||
|
|
||
| ## v2 artifact chain (work/) | ||
| - One initiative = one dir: `work/<slug>/` holding `intent.md` → `spec.md` → `plan.md`. | ||
| Each artifact lands via its own PR and the operator's merge IS the gate: G1 accepts | ||
| the intent, G2 approves the spec, G3 approves the implementation PR (which carries | ||
| `plan.md` + code + tests). Details: `work/README.md`; review policy: `REVIEW.md`. | ||
| - Skills: `/intent-draft`, `/spec-draft`, `/plan-draft` hold the templates and stage rules. | ||
| - **Hash discipline:** `spec.md` frontmatter records `intent-blob` (`git hash-object` of | ||
| the intent it was drafted from); `plan.md` records `spec-blob`. On mismatch with main's | ||
| current upstream file, label the PR `stale` and stop — never build on a moved artifact. | ||
| - **Stage rules (autonomous lane):** the spec stage writes only `work/<slug>/spec.md`; | ||
| the implement stage never touches `intent.md`/`spec.md`; unattended agents never write | ||
| `.github/**` or `.claude/**` — such changes land as patches under `proposals/` that the | ||
| operator applies. Operator-driven sessions are exempt; Phase 3 hooks enforce this | ||
| mechanically via `YSTACK_STAGE`. | ||
| - Deterministic branches: `ystack/intent/<slug>`, `ystack/spec/<slug>`, | ||
| `ystack/impl/<slug>` — re-runs update the existing PR, never open a second. | ||
|
|
||
| ## Reusability goal | ||
| - No hardcoded personal values (usernames, repo names) in shipped templates — keep the | ||
| reusable path parameterized. Personal config stays out of it. | ||
| Nothing else belongs here. Put changes in `AGENTS.md`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern blocks every Bash command that merely mentions the file, not just commands that run it. For example,
cat scripts/merge-pr.sh,git diff -- scripts/merge-pr.sh, andshellcheck scripts/merge-pr.shall exit 2, so an agent cannot inspect or directly verify the helper during legitimate work. Narrow the match to command-position execution while still enforcing the rule that agents never merge.AGENTS.md reference: AGENTS.md:L100-L101
Useful? React with 👍 / 👎.