Skip to content

docs(rules): collapse docs into .rules, gate PRs, auto-version - #197

Open
echobt wants to merge 2 commits into
mainfrom
cursor/repo-discipline-overhaul-a8b2
Open

docs(rules): collapse docs into .rules, gate PRs, auto-version#197
echobt wants to merge 2 commits into
mainfrom
cursor/repo-discipline-overhaul-a8b2

Conversation

@echobt

@echobt echobt commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Repo-discipline overhaul. The human docs/ site is gone; what is left is three
surfaces with clear owners:

Surface Audience
README.md the only human-facing document
AGENTS.md agent / operator contract, now headed by "read .rules/ first"
.rules/ the enforceable rules an agent must read before opening or readying a PR

Nothing normative was dropped. Everything a gate pins was relocated to
.rules/contracts/ and the gates were repointed in the same commit.

Why

Stale prose was accumulating faster than anyone read it: 23 markdown articles
plus an evidence/ and spikes/ tree, with commands that no longer existed
(the deleted docs/OPERATOR_SECURITY.md told operators to run
cargo run -p xtask -- agent-challenge-check, a subcommand that has not existed
for a long time). Meanwhile the things that actually must not rot — the frozen
byte contracts, the local gate list, the naming freeze — had no machine check
tying them to reality. This PR inverts that: fewer documents, and the ones that
remain are gated.

Deleted vs relocated

Relocated (gate-pinned or normative, nothing lost):

From To
docs/BUNDLE_SPEC.md, docs/BUNDLE_SPEC_CHECKLIST.md .rules/contracts/
docs/DESIGN_CHALLENGE.md, docs/DESIGN_CHALLENGE_CHECKLIST.md .rules/contracts/
docs/PRISM.md, docs/PRISM_RECIPE.md .rules/contracts/
docs/THREAT_MODEL.md (D19 pinned word-for-word) .rules/contracts/
docs/external-miner/** incl. examples/ .rules/contracts/external-miner/
docs/NAMING.md .rules/60-naming.md (promoted to a numbered rule)

Repointed to match: xtask spec-check, design-check, external-docs-check,
the four include_str! sites for the design baseline
(crates/design-challenge/src/corpus.rs, its two test files,
crates/design-sandbox/src/lib.rs), crates/prism-verda/tests/live_dense.rs,
and deploy/Dockerfile's COPY.

Deleted (human prose; recoverable from git history):

  • docs/ARCHITECTURE.md → condensed into README.md § Architecture (topology,
    one-epoch data flow, crate/process table).
  • docs/AGENTS.md, docs/COMPLETENESS.md, docs/GITHOOKS.md,
    docs/SITE_API.md → superseded by .rules/ and README.md.
  • docs/OPERATOR_SECURITY.md → the load-bearing assertions became
    .rules/20-pre-prod-local.md § 5 (digest pins, master-only gateway,
    evil-gateway absent, admin 401/403, trust-root verify, file modes,
    pg_dump before promote).
  • docs/runbooks/** (9 files) → the live operator surface is deploy/README.md
    • deploy/AGENTS.md + ./deploy/scripts/local-e2e.sh --help, which sit next
      to the scripts they drive. The local-before-prod path is now
      .rules/20-pre-prod-local.md.
  • docs/evidence/**, docs/spikes/** → non-normative history.
  • CONTRIBUTING.md, CODE_OF_CONDUCT.md, SUPPORT.md → prose duplicates of
    README.md and .rules/.

Kept at root, deliberately: LICENSE (Apache-2.0, unchanged),
CODEOWNERS, AGENTS.md (an agent contract, not a doc article), and
SECURITY.md — GitHub surfaces the security policy in its own UI and in the
private-vulnerability-reporting flow, so it is a platform integration point
rather than a docs/ article. Its two dangling links were repointed.

Two docs/ strings were left alone on purpose:
config/challenges.staging.toml carries a detached owner signature
(.sig) and editing a comment would invalidate it, and hashed artifacts
(crates/db/migrations/*.sql, crates/prism-recipe/anchors/v3.json) must not
change bytes for a comment tidy. .rules/10-maintenance.md and
.rules/60-naming.md say so, so the next agent does not "fix" them.

How an agent is supposed to use .rules/

  1. .cursor/rules/00-read-dot-rules.mdc (alwaysApply: true) and the first
    line of AGENTS.md both say: read .rules/ before touching anything.
  2. Read the seven numbered files in full — overview, maintenance,
    pre-prod-local, PR, agents, versioning, naming. They are short and
    imperative.
  3. Read the .rules/contracts/ file your change touches. Never weaken a pin to
    make a diff pass.
  4. Run every command in .rules/20-pre-prod-local.md locally. That file is
    machine-tied to CI: rules-check fails if ci.yml runs a cargo or
    bash deploy/ command the file does not list, so the "local gates" can never
    silently drift from the real ones.
  5. Bump the version, fill the attestation, self-check:
cargo run -p xtask -- rules-check
cargo run -p xtask -- version verify-bump --base origin/main
cargo run -p xtask -- pr-check --body-file /tmp/pr-body.md

rules-check also fails if docs/ comes back, if a .rules/ file goes
missing, if AGENTS.md/README.md stop pointing at the rules, if the PR
template drifts from the attestation pr-check enforces, or if any relative
markdown link in README.md, AGENTS.md, SECURITY.md, deploy/*.md, or
.rules/** points at a file that does not exist. It found one genuinely broken
pre-existing link on the first run (PRISM_RECIPE.md pointed at
prism_harness.py; the file is harness/main.py).

How versioning works

Single source of truth: [workspace.package] version in the root Cargo.toml.
All 89 members inherit it with version.workspace = true, and Cargo.lock is
rewritten from it. No VERSION file, no second packaging system.

Level is derived from Conventional Commit subjects on the branch: feat
minor, ! or BREAKING CHANGE: → major, everything else → patch. Zero-major
rule:
while the version is 0.y.z, a breaking change maps to minor, because
cargo treats 0.y as the compatibility unit — the repo does not promote itself
to 1.0.0 by accident.

cargo run -p xtask -- version                                # print
cargo run -p xtask -- version check                          # members inherit + lock in sync
cargo run -p xtask -- version bump                           # auto level from commits
cargo run -p xtask -- version bump --level minor             # or patch / major
cargo run -p xtask -- version verify-bump --base origin/main # the CI gate

Enforcement: pr-gate.yml runs version verify-bump on every PR and fails when
the version is unchanged versus the merge base, went backwards, or is a smaller
bump than the commits require. Narrow exemption for PRs that touch only
deploy/pins/, deploy/digests/, or metadata/ — machine-written pin
artifacts. ci.yml additionally runs version check on pushes, so a
hand-edited manifest or a stale lockfile fails there too.

Implementing this surfaced a real trap: crates/prism-pipeline was the one
crate pinning a literal version = "0.1.0" on an intra-workspace path
dependency, which made any bump unresolvable. Dropped, and version check now
fails on that pattern so it cannot return.

Releases stay as they were: annotated tags vX.Y.Z cut on main
(git tag -a v0.2.0 -m 'v0.2.0' && git push origin v0.2.0deploy-prod.yml).
No history was rewritten.

PR attestation gate

.github/PULL_REQUEST_TEMPLATE.md now carries four checkboxes, and
.github/workflows/pr-gate.yml enforces them on
opened | edited | reopened | synchronize | ready_for_review | converted_to_draft
so ticking a box or flipping a draft re-runs the gate. On a draft it reports
the open items without failing; the moment the PR is marked ready it must be
complete. The PR body arrives via an env var, never inline interpolation.

The phrases live in exactly one place (REQUIRED in xtask/src/pr_check.rs);
rules-check asserts the template still contains them, so a filled-in template
always passes.

Residual org settings I cannot flip from the repo

These need someone with admin on CortexLM/cortex:

  • Branch protection on main — require ci and pr-gate as required
    status checks, and require a PR before merge. This PR adds the checks; only
    org settings can make them blocking.
  • production environment reviewers for deploy-prod.yml.
  • Optionally, disable "squash and merge" commit-message rewriting that would
    drop Conventional Commit subjects, since version verify-bump reads them.

Risk

No product code paths changed. crates/design-challenge,
crates/design-sandbox, and crates/prism-verda changed only the path in
include_str! / a test fixture join — the embedded bytes are identical, so the
agentic-review corpus anchor is unchanged. deploy/Dockerfile copies the same
files from the new path. No incentive, scoring, consensus, BASE_*, or domain-tag
semantics were touched. No Relearn work and no Prism/Design product changes are
in this PR. Signed trust roots and hashed artifacts were deliberately not
edited. No secrets added.

Test plan

Run locally on this branch, exit status checked on each:

cargo fmt --all -- --check                                     ok
cargo clippy --workspace --all-targets -- -D warnings          ok  (whole workspace, 0 warnings)
cargo test --workspace                                         ok  (218 "test result: ok" blocks, 0 failures)
cargo deny check                                               ok  (advisories ok, bans ok, licenses ok, sources ok)
cargo run -p xtask -- loc-cap                                  ok
cargo run -p xtask -- consensus-lint                           ok  (4 listed consensus crates)
cargo run -p xtask -- spec-check                               ok  (.rules/contracts/BUNDLE_SPEC.md, 12 letter + 7 content pins)
cargo run -p xtask -- design-check                             ok  (.rules/contracts/DESIGN_CHALLENGE.md, 13 section + 62 content pins)
cargo run -p xtask -- external-docs-check                      ok  (protocol_version=1, D19 verbatim)
cargo run -p xtask -- rules-check                              ok  (7 rules files, 9 contracts, 4 attestations, links resolve)
cargo run -p xtask -- version check                            ok  (0.2.0, 89 members inherit, Cargo.lock in sync)
cargo run -p xtask -- version verify-bump --base origin/main   ok  (0.1.0 -> 0.2.0, minor bump, patch required)
cargo run -p xtask -- pr-check --body-file <this body>          ok  (4 attestations checked)

pr-check was also exercised negatively: an empty body, a body with no
checklist, and a body with unticked boxes each fail with a pointed message
naming the offending line, and --draft downgrades the same findings to a
notice instead of a failure.

CI on this PR is green and covers what this environment could not run (no Docker
daemon here):

fmt · clippy · test · deny · xtask     pass 4m42s
  xtask rules-check                    rules-check: OK (7 rules files, 9 contracts, 4 attestations, links resolve)
  xtask version check                  version check: OK (0.2.0, 89 members inherit, Cargo.lock in sync)
  compose matrix assertions            assert-compose-matrix: all checks passed
  clippy -p validator-bin --features dcap
prism harness smokes (cpu torch)       pass 1m33s
rules attestation · version bump       pass 58s
  xtask pr-check                       pr-check: OK (4 attestations checked)
  xtask version verify-bump            version verify-bump: OK 0.1.0 -> 0.2.0 (minor bump, patch required)

Still needs an operator machine, not CI: ./deploy/scripts/local-e2e.sh --smoke
and the challenge submission matrix in .rules/20-pre-prod-local.md § 3–4
(wallets + testnet egress). This branch changes no challenge behaviour, and the
design baseline fixtures it relocates are exercised by cargo test --workspace
(crates/design-challenge e2e_sim and cheat_fixtures,
crates/design-sandbox), which compile the moved agent.py / pyproject.toml
in via include_str!.

Rules attestation (required — pr-gate fails a ready PR without all four)

Tick only what you actually did. See .rules/30-pr.md.

  • I read all of .rules/ before opening this PR and before marking it ready
  • AGENTS.md, README.md and .rules/ are accurate for this change, or N/A with a reason below
  • Local pre-prod gates in .rules/20-pre-prod-local.md all passed
  • Version bumped per .rules/50-versioning.md

Version before → after: 0.1.0 → 0.2.0

N/A reasons: every gate in .rules/20-pre-prod-local.md § 1–2 passed locally,
and CI additionally confirmed assert-compose-matrix.sh green. The wallet- and
testnet-dependent § 3–4 items cannot run in this environment and are itemised
under Test plan rather than silently claimed.

Naming

I did not rename BASE_* environment variables, deployed host paths
(/opt/base, /run/base, …), GHCR baseintelligence/base package names, or
base-*-v1 cryptographic domain tags. docs/NAMING.md moved to
.rules/60-naming.md with its content intact and its status raised from
reference doc to numbered rule.

Open in Web Open in Cursor 

cursoragent and others added 2 commits August 29, 2026 08:14
Delete the human `docs/` site and make the repo strict about the three
surfaces that remain: `README.md` for humans, `AGENTS.md` for the agent /
operator contract, and `.rules/` for the enforceable rules every coding
agent must read before opening or readying a PR.

Gate-pinned normative content is relocated, not dropped:
`.rules/contracts/` now holds BUNDLE_SPEC, DESIGN_CHALLENGE (+ checklists),
PRISM, PRISM_RECIPE, THREAT_MODEL, and the miner-facing `external-miner/`
tree with its examples. `spec-check`, `design-check`, and
`external-docs-check` are repointed at the new paths, and the design
baseline `include_str!` sites plus `deploy/Dockerfile` follow the move.

New xtask gates keep this honest: `rules-check` fails if `docs/` returns, a
`.rules/` file goes missing, `AGENTS.md` / `README.md` stop pointing at the
rules, the PR template drifts from the attestation CI enforces, the local
gate list stops matching CI, or a markdown link dangles. `pr-check` fails a
ready PR whose body is missing the attestation. `version` owns the workspace
version end to end. `pr-gate.yml` runs the attestation and bump gates on
pull requests.

CONTRIBUTING, CODE_OF_CONDUCT, and SUPPORT were prose duplicates of the
README and `.rules/`; LICENSE, SECURITY.md, and CODEOWNERS stay at root.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
Single source of truth is `[workspace.package] version`; every member
inherits it and `Cargo.lock` is derived from it. Minor rather than patch:
this branch adds xtask subcommands and CI gates, and moves the documented
contract paths, so it is new behaviour for anyone driving the repo.

`prism-pipeline` was the one crate pinning a literal version on an
intra-workspace path dependency, which made any bump unresolvable. Dropped,
and `version check` now fails on that pattern so it cannot come back.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
@echobt
echobt marked this pull request as ready for review August 29, 2026 08:28
@greptile-apps

greptile-apps Bot commented Aug 29, 2026

Copy link
Copy Markdown

Too many files changed for review (147 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants