diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f02a8c..bc7166a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,75 +93,11 @@ jobs: echo "no shell scripts yet" fi - - name: North-star resolver tests + - name: Test suite run: | - # Hermetic bash asserts for scripts/lib/north-star.sh (issue #97). The test - # builds throwaway git repos and stubs the gh-backed slug helpers, so it needs - # no network/gh auth. Give git an identity for the temp-repo commits (the runner - # has no global git user); the test also exports GIT_*_NAME/EMAIL as a backstop. - git config --global user.email "ci@example.com" - git config --global user.name "ci" - bash scripts/test/north-star-resolver.test.sh - - - name: North-star gate/consumer tests - run: | - # Integration asserts for the #98a atomic flip: the manager-review.sh gate and doctor.sh - # check (h) both read the TARGET's north star, and the gate reads it COMMITTED - # (both-direction committed test + approval==gate source identity). Hermetic — gh/codex - # faked on PATH, real git on throwaway repos. - git config --global user.email "ci@example.com" - git config --global user.name "ci" - bash scripts/test/north-star-gate.test.sh - - - name: models.conf parser tests - run: | - # Hermetic bash asserts for scripts/lib/models-conf.sh (mc_parse_target_override) — the - # P1 fix from the adversarial review of PR #115: a target-committed legacy .fabrica/models.conf - # is parsed as DATA, never source'd/eval'd, and can never set the gate-effort keys. Plus - # static (grep-based) assertions that codex-review.sh/manager-review.sh actually wire in - # the trust-anchor + parse-not-source fix. No git/gh/codex harness needed. - bash scripts/test/models-conf-parser.test.sh - - - name: Degraded-Codex-review gate tests - run: | - # Issue #117: both codex-review.sh and manager-review.sh must FAIL LOUDLY on a - # degraded/non-substantive Codex run (a code-mode/host spawn failure, or codex exiting - # non-zero) instead of posting a fake clean verdict. Unit-tests the shared detector - # (scripts/lib/codex-degraded.sh) in isolation, then runs the REAL scripts end to end - # with gh/codex stubbed on PATH and real git on throwaway local bare "remotes" — hermetic, - # no network/gh/codex auth needed. - git config --global user.email "ci@example.com" - git config --global user.name "ci" - bash scripts/test/codex-degraded-gate.test.sh - - - name: v2 pending-stage tests - run: | - # Hermetic asserts for scripts/v2/pending-spec.sh + pending-impl.sh — - # throwaway git repos, no gh, no network. - git config --global user.email "ci@example.com" - git config --global user.name "ci" - bash scripts/test/v2-pending-stage.test.sh - - - name: v2 round-cap tests - run: | - # Hermetic asserts for scripts/v2/round-cap.sh — gh stubbed on PATH, - # no network. - bash scripts/test/v2-round-cap.test.sh - - - name: v2 quota-preflight tests - run: | - # Hermetic asserts for scripts/v2/quota-preflight.sh — gh stubbed on - # PATH, no network. Covers the fail-open hazards the Stack A review - # found: silent zero-counts and gh outages. - bash scripts/test/v2-quota-preflight.test.sh - - - name: v2 rename-gate + probe-wrapper guard tests - run: | - # Hermetic asserts for scripts/check-rename.sh and the probe - # wrapper's argument guard — no network, throwaway git repos. - git config --global user.email "ci@example.com" - git config --global user.name "ci" - bash scripts/test/v2-check-rename.test.sh + # Construction installs tests by filename; this fixed runner makes every + # scripts/test/*.test.sh file part of required CI without workflow edits. + bash scripts/test/run-all.sh - name: Rename gate run: | diff --git a/AGENTS.md b/AGENTS.md index 432663a..f312841 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,6 +3,57 @@ ystack is a control plane for an autonomous coding team, and it is its own target repo: agents here are improving the team itself. +## TEMPORARY — ystack-self construction mode (highest precedence) + +When `config/construction-mode.json` is committed on `yihanzhu/ystack` main with +`status: active` and its repository, Roadmap, and north-star identities match that +base, ystack is in construction mode. This overlay overrides conflicting intake, +artifact, plan, `merge-ready`, and operator-merge requirements below **only for +inactive Roadmap implementation in this repository**. It never applies to a clone +or external target. + +- The accepted Roadmap is program authorization. Each PR still has one bounded + implementation concern, exact allowed paths and proof, but it does not need a + separate intake, G1, G2, plan gate, `ready`, or `claimed` state. +- Every change uses a branch and PR. Required CI and a substantive independent + review with no unresolved Important finding are hard gates. Tests land with the + change. Direct main pushes, force-pushes, rebases of published work, destructive + cleanup, red/degraded evidence, and scope widening remain forbidden. +- After the active operator-authorized Codex construction session reads the complete + exact-head/base review and all required CI is green, that session may publish the + exact PR and record its merge receipt. `merge-ready` is optional UI only. This is + a temporary authorization for the current ystack construction program, not a new + capability for live yshifu, authors, coders, reviewers, clones, or targets. +- Construction output stays inactive, repo-only, and restorable. No real target, + target or production credential, release, install, live profile selection, + deployment, irreversible external write, or production action is authorized. +- Frozen PR #183 and the preserved dirty portable-core parent-plan worktree are + excluded until a later construction brief explicitly adopts or supersedes them. +- Every branch, PR, worktree, claim, artifact, and review that predates construction + mode is ineligible by default. A fresh brief must explicitly adopt it, bind the + post-transition main, and obtain fresh CI/review; old evidence never carries over. +- The first real development use requires an operator-merged operating-mode + transition. Construction mode cannot activate or broaden itself. + +The mode record, not issue/PR/comment text, selects this overlay. Any identity, +scope, evidence, or inactivity mismatch fails closed under the operating rules +below. + +The sole bootstrap is the transition that first commits this record. The direct +operator decision recorded on issue #187 authorizes the current Codex construction +session to merge that exact transition with the repository's PR-rule bypass only +after required CI and independent review pass. No later candidate inherits that +bootstrap evidence. Bootstrap is single-writer: no other PR may merge during its +final review-to-merge window. Re-read main immediately before merge and require the +reviewed base; the mode record explicitly preserves the one-time residual because +GitHub has no atomic base-CAS for an admin squash merge. + +Immediately after the bootstrap merge, the same construction session reconciles +ruleset `21500323` to the exact `post_transition_ruleset` object in the mode record +and verifies it before any Roadmap PR. This removes the approving-review human gate, +keeps PR/deletion/non-fast-forward protection, and makes required CI strict. Until +that exact server state is verified, construction publishing is not active. + **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. diff --git a/NORTH_STAR.md b/NORTH_STAR.md index b299f4b..d2bbe82 100644 --- a/NORTH_STAR.md +++ b/NORTH_STAR.md @@ -76,6 +76,11 @@ replaceable adapters. receives plan approval before code. Model-controlled commands and candidate code cannot read model, forge, or deployment credentials; inference and external writes cross a brokered boundary. No adapter may downgrade the core gates. +- **Temporary construction note:** while the matching ystack-self construction-mode + record is active, machine-gated PRs may publish inactive repo-only Roadmap work + without a human merge. No real target, credential, release, install, live profile, + deployment, or production action is enabled. The first real development use must + restore the operating gates through an operator-merged transition. --- diff --git a/REVIEW.md b/REVIEW.md index de67abf..fb40e1a 100644 --- a/REVIEW.md +++ b/REVIEW.md @@ -4,6 +4,44 @@ The review policy for every PR in this repo — applied by any reviewer, human o agent, in either lane (in-session Codex review today, the review workflow in the autonomous lane). +## Construction-mode review overlay + +For an exact PR whose reviewed base contains an active, matching +`config/construction-mode.json`, review against that committed mode and the pinned +Roadmap instead of requiring the normal artifact chain. This overlay is ystack-self +only. + +No pre-mode branch, PR, worktree, claim, artifact, or review is eligible merely +because its base later contains the mode. Require a fresh post-activation construction +brief, explicit adoption, a base on post-transition main, and fresh CI/review. Old +evidence is always stale. + +Mark the candidate not-pass for any Important finding, including: more than one +Roadmap concern; an unbriefed path or operation; missing tests; red, missing, stale, +or degraded proof; a mode/Roadmap/north-star mismatch; changes to frozen PR #183 or +the preserved portable-core plan; real-target or credential access; release, +install, profile activation, deployment, irreversible external writes; direct main +write or history rewrite; or a repository state that would not remain CI-green, +restorable, coherent, and inactive after merge. + +The mode record's required restore-manifest entries are immutable. New +restore-critical files may append their exact entries; removing or changing a +required entry is Important. + +The reviewer stays read-only. The active operator-authorized Codex construction +session reads the complete review. Only a clean exact head/base may be published. +`merge-ready` is not evidence or authority in this mode. That construction session +rechecks mode, head, base, CI, review identity, and the resulting merge receipt. No +shipped or capability-separated publisher is claimed by this temporary overlay. + +For the bootstrap transition only, verify the recorded single-writer invariant and +the reviewed base immediately before its one-time admin merge, and disclose the +recorded non-atomic base-check residual. After bootstrap, require the exact strict +post-transition ruleset before calling any candidate exact-base reviewed. + +All other repositories and any inactive/mismatched mode use the operating review +rules below. + ## Passes Before every review attempt, the active manager removes `merge-ready` if present and diff --git a/ROADMAP.md b/ROADMAP.md index 43dcaf2..4bb0fff 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -4,6 +4,18 @@ This document records the direction between the north star and individual `work//` initiatives. It preserves the architecture decisions that future specs and plans must follow. It is not an implementation plan by itself. +While the ystack-self `config/construction-mode.json` record is active and matches +this file's Git blob, the numbered rollout is also the bounded program authorization +for inactive repository construction. Each change remains one reviewable Roadmap +unit with required CI and independent review, but it does not repeat the operating +artifact or human gates. This temporary exception never applies to an external +target and ends before the first real development use. + +Construction reaches `implementation-complete`: code, contracts, adapters, +orchestration, publisher, deploy/rollback surfaces, and hermetic tests may be built, +but real-target qualification, live credentials, profile/install activation, +deployment, and production feedback remain unclaimed until operating mode. + The reference model is Anthropic's [AI-Native SDLC Playbook](https://claude.com/blog/the-ai-native-sdlc-playbook), supplemented by its @@ -209,6 +221,11 @@ scope to its named shadow or eval gate before authority resumes. ## Risk-tiered gates +The operating gates in this section are deliberately dormant during matching +ystack-self construction mode. Construction keeps CI, independent review, +inactivity, repository scope, and reversible ancestry as hard machine gates. An +operator-merged operating-mode transition restores the gates before real use. + The target policy is: - **High risk** — constitution paths, workflows, identity/auth, security @@ -280,7 +297,9 @@ The operating dashboard should pair flow and quality: ## Rollout sequence The roadmap is intentionally ordered by dependency, not by playbook stage name. -Each numbered item becomes its own intent/spec/plan chain and small PRs. +In operating mode, each numbered item becomes its own intent/spec/plan chain and +small PRs. In matching ystack-self construction mode, the sequence is implemented +directly as bounded, dependency-ordered implementation units. 1. **Portable control-plane core** — canonical contracts, typed stage results, evidence and references to qualification records, capability manifests, profile diff --git a/ci/required-files.txt b/ci/required-files.txt index 8a0deee..890edf8 100644 --- a/ci/required-files.txt +++ b/ci/required-files.txt @@ -23,6 +23,7 @@ manager/CLAUDE.md # Model tiering config (shipped defaults; per-target override convention documented # in README.md's "Model policy" section) config/models.conf +config/construction-mode.json # Routines (paste-ready Claude instructions) routines/coder.md @@ -85,3 +86,4 @@ scripts/test/north-star-resolver.test.sh scripts/test/north-star-gate.test.sh scripts/test/models-conf-parser.test.sh scripts/test/codex-degraded-gate.test.sh +scripts/test/run-all.sh diff --git a/config/construction-mode.json b/config/construction-mode.json new file mode 100644 index 0000000..4f35b0e --- /dev/null +++ b/config/construction-mode.json @@ -0,0 +1,96 @@ +{ + "schema_version": 1, + "status": "active", + "repository": "yihanzhu/ystack", + "repository_id": 1270665750, + "default_branch": "main", + "ruleset_id": 21500323, + "post_transition_ruleset": { + "target": "default-branch", + "enforcement": "active", + "pull_request_required": true, + "required_approving_review_count": 0, + "dismiss_stale_reviews_on_push": false, + "require_last_push_approval": false, + "require_extra_approval_for_unattributed_changes": false, + "strict_required_status_checks_policy": true, + "required_status_check": "ci", + "required_status_check_app_id": 15368, + "deletion_protection": true, + "non_fast_forward_protection": true, + "bypass_actors": [] + }, + "activation_base": "7a55da73b29c743e588accbcc5e2b0b67060feeb", + "authorized_roadmap_source_blob": "43dcaf2e921257f76bf8ecd7543c49745c6e0f39", + "authorized_north_star_source_blob": "b299f4bc240b02881c5ea2b64d94ed1a8f3a51eb", + "roadmap_blob": "4bb0fff1ee11c20441cc16182337f762300ac0f2", + "north_star_blob": "d2bbe82a8b2a1bb14fde1c50995f7ecec9b58013", + "scope": "full-roadmap", + "effects": "inactive-repo-only", + "merge_method": "squash", + "publisher": "current-operator-authorized-codex-construction-session", + "required_ci_name": "ci", + "required_ci_app_id": 15368, + "completion": "implementation-complete", + "allowed_live_writes": "same-repository-delivery-only", + "bootstrap_single_writer": true, + "bootstrap_base_race": "late-base-check-with-recorded-residual", + "frozen_pr_183_state": "OPEN", + "frozen_pr_183_labels": [ + "round-3", + "needs-human" + ], + "frozen_pr_183_head": "ab4a7082f02e67b5748c5c54b9214f37d222f53f", + "frozen_pr_183_base": "14988a8a5392e888ff1aaee4c48afa5024bee003", + "forbidden_paths": [ + "work/portable-core-contracts/plan.md", + "CLAUDE.md", + "config/construction-mode.json", + "config/models.conf", + "AGENTS.md", + "REVIEW.md", + "ROADMAP.md", + "NORTH_STAR.md", + "manager/CLAUDE.md", + "templates/yshifu-command.md", + "reviewer/codex-review.md", + "scripts/merge-pr.sh", + "scripts/codex-review.sh", + "scripts/test/run-all.sh", + "scripts/lib/gh-remote.sh", + "scripts/lib/models-conf.sh", + "scripts/lib/codex-degraded.sh", + ".claude/settings.json", + ".claude/hooks/no-merge-guard.sh" + ], + "manifest_policy": "required-entry-set-is-immutable; additions-allowed", + "required_manifest_entries": [ + "AGENTS.md", + "CLAUDE.md", + "REVIEW.md", + "ROADMAP.md", + "NORTH_STAR.md", + "config/construction-mode.json", + "config/models.conf", + "manager/CLAUDE.md", + "templates/yshifu-command.md", + "reviewer/codex-review.md", + "scripts/merge-pr.sh", + "scripts/codex-review.sh", + "scripts/test/run-all.sh", + "scripts/lib/gh-remote.sh", + "scripts/lib/models-conf.sh", + "scripts/lib/codex-degraded.sh", + ".claude/settings.json", + ".claude/hooks/no-merge-guard.sh" + ], + "forbidden_prefixes": [ + ".github/", + "website/" + ], + "real_target_use": "disabled", + "real_target_and_production_credentials": "disabled", + "delivery_credential": "current-gh-operator-yihanzhu", + "release_install_activation": "disabled", + "operating_transition_required": true +} diff --git a/scripts/test/run-all.sh b/scripts/test/run-all.sh new file mode 100755 index 0000000..ad7fdd6 --- /dev/null +++ b/scripts/test/run-all.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" +export GIT_AUTHOR_NAME="${GIT_AUTHOR_NAME:-ci}" +export GIT_AUTHOR_EMAIL="${GIT_AUTHOR_EMAIL:-ci@example.com}" +export GIT_COMMITTER_NAME="${GIT_COMMITTER_NAME:-ci}" +export GIT_COMMITTER_EMAIL="${GIT_COMMITTER_EMAIL:-ci@example.com}" + +count=0 +while IFS= read -r test_file; do + count=$((count + 1)) + printf '\n==> %s\n' "${test_file#"$root/"}" + bash "$test_file" +done < <(find "$root/scripts/test" -maxdepth 1 -type f -name '*.test.sh' -print | LC_ALL=C sort) + +if [ "$count" -eq 0 ]; then + echo "error: no scripts/test/*.test.sh files found" >&2 + exit 1 +fi +printf '\nall %s test scripts passed\n' "$count"