Skip to content
Draft
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
2 changes: 0 additions & 2 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
/src/server/management-auth.ts @lidge-jun @Ingwannu

# Governance and security policy
/AGENTS.md @lidge-jun @Ingwannu
**/AGENTS.md @lidge-jun @Ingwannu
/MAINTAINERS.md @lidge-jun @Ingwannu
/SECURITY.md @lidge-jun @Ingwannu

Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# * Full cross-platform (macOS/Windows) CI runs ONLY via manual
# workflow_dispatch and on push to main/preview (release lines).
# * NEVER add a dev push trigger or pull_request runs for macOS/Windows jobs.
# PRs that change this policy will be closed. See AGENTS.md "CI policy".
# PRs that change this policy will be closed. See CONTRIBUTING.md "CI policy".
# ============================================================================
name: Cross-platform CI

Expand All @@ -15,8 +15,8 @@ on:
pull_request: {}
# No base-branch filter on purpose. GitHub matches `branches:` against the
# BASE ref, so `[main, dev]` silently excluded stacked child PRs — whose
# base is another open PR's head branch, an intentional review workflow per
# AGENTS.md that `enforce-target` already exempts from the wrong-base gate.
# base is another open PR's head branch, a stacked review workflow that
# `enforce-target` already exempts from the wrong-base gate.
# The #951-#955 stack merged with `enforce-target`, `label`, and
# `react-doctor` as its only check-runs: no test job ever queued for 24
# changed files under `src/`.
Expand Down Expand Up @@ -359,8 +359,8 @@ jobs:
# the only place CI runs `bun run structure:check`. The aggregate
# then reported success over nothing. #4999, a pure doc split, is the
# live example; it stayed invisible for so long because
# `structure/AGENTS.md` makes a `structure/` edit almost always
# arrive beside a `src/` one, which the `ci` filter does match.
# `structure/` edits usually arrived beside `src/` changes,
# which the `ci` filter does match.
#
# The job this feeds runs the gate alone rather than widening `ci`,
# so a prose edit still does not start the cross-platform matrix.
Expand Down
8 changes: 3 additions & 5 deletions AGENTS_INSTALL.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Agent rules for installing and running opencodex
# User consent when installing and running opencodex

This file is for an agent **installing, starting, or operating** opencodex on a
user's machine. It is not about contributing to this repository — that is
[`AGENTS.md`](./AGENTS.md), and nothing here concerns you if you are only
reading or changing this codebase.
This guide describes the consent boundary for an agent **installing, starting,
or operating** opencodex on a user's machine.

There is one rule, and it exists because `ocx start` can print a question that
an agent is capable of answering and must not.
Expand Down
5 changes: 1 addition & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ the reasoning.
Rebase pull requests are welcome: bringing a stale branch onto the current head
is normal contribution. Note the source commits in the description.

Agent-facing repository and review rules live in [`AGENTS.md`](./AGENTS.md).

For local development commands, architecture notes, and release workflow details, use the hosted
contributing guide above instead of duplicating instructions here.

Expand Down Expand Up @@ -76,8 +74,7 @@ The suite uses Bun 1.4.3 (`testRunnerBun`) while the shipped runtime is 1.4.2.
Run `bun run test` before review readiness. If the full local suite is too costly
for the task or available resources, run at least focused regression tests for
the changed behavior. Document the reason, commands, results, and remaining
coverage in the PR. Follow [AGENTS.md](./AGENTS.md#commands) for the complete
validation policy; required CI must pass on the current PR head before merge.
coverage in the PR. Required CI must pass on the current PR head before merge.
`bun run prepush` remains an optional comprehensive local check.

```sh
Expand Down
2 changes: 1 addition & 1 deletion MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ when a maintainer steps down.
it can check itself: the branch must be on the latest `dev` commit or at
most 10 commits behind it, and Codex/CodeRabbit findings must be resolved.
The local-validation box follows the full-suite default and documented resource
exception in [AGENTS.md](./AGENTS.md#commands); focused regression tests remain
exception in [CONTRIBUTING.md](./CONTRIBUTING.md#local-validation-and-hooks); focused regression tests remain
mandatory under that exception. It is an author attestation only — fork
contributors cannot start repository CI; a maintainer has to — so the gate
never disproves it;
Expand Down
2 changes: 1 addition & 1 deletion scripts/bump-dev-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ if (import.meta.main) {
// each file's version line, because a full JSON or TOML round-trip would reformat the file
// and turn a one-line bump into an unreviewable diff. It computes every rewrite before
// writing, so a missing or unrecognisable desktop source fails with nothing changed, and
// it replaces each file atomically, per scripts/AGENTS.md: package metadata is exactly the
// it replaces each file atomically: package metadata is exactly the
// class of file whose partial write corrupts a checkout. This script is also the
// documented manual recovery path, so it can run on a developer machine where an interrupt
// or a full disk mid-write would otherwise leave a truncated package.json.
Expand Down
4 changes: 2 additions & 2 deletions scripts/release-version-sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ export function versionSourceMismatches(root: string, expected: string): string[
* Rewrite every source to `version` and return the paths whose bytes changed.
*
* Every rewrite is computed before anything is written, so an unlocatable source leaves the
* whole set untouched. Each file is then replaced atomically (sibling temp file, rename), per
* scripts/AGENTS.md. Temp files are all written before the first rename, so a write failure
* whole set untouched. Each file is then replaced atomically (sibling temp file, rename).
* Temp files are all written before the first rename, so a write failure
* such as a full disk or a read-only directory also leaves every original intact.
*
* @throws on a malformed version or any source whose version cannot be located.
Expand Down
2 changes: 1 addition & 1 deletion scripts/setup-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@ if (failures.length > 0) {
process.exitCode = 1;
}

console.log("Run validation explicitly before review; see AGENTS.md for test scope.");
console.log("Run validation explicitly before review; see CONTRIBUTING.md for test scope.");
6 changes: 2 additions & 4 deletions scripts/structure-ssot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ export type Manifest = {
};

const GENERATED_DOCS = ["INDEX.md"];
const RULE_DOCS = ["AGENTS.md"];
/**
* Roots that stay checked even after they are deleted. Deriving the root set from the tree alone
* means a reference becomes INVISIBLE exactly when the directory disappears, which is the moment
Expand Down Expand Up @@ -224,9 +223,8 @@ export function renderIndex(manifest: Manifest): string {
lines.push("");
lines.push(
"Generated from " + BT + "structure/manifest.json" + BT + " by " + BT + "bun run structure:index" + BT + ". Do not edit by hand; " +
BT + "bun run structure:check" + BT + " fails when this file and the manifest disagree. The rules for changing anything",
BT + "bun run structure:check" + BT + " fails when this file and the manifest disagree.",
);
lines.push("in this folder are in [" + BT + "AGENTS.md" + BT + "](AGENTS.md).");
lines.push("");
lines.push("## Reading order");
for (const tier of manifest.tiers) {
Expand Down Expand Up @@ -328,7 +326,7 @@ export function runStructureChecks(repoRoot: string): string[] {
else for (const entry of readdirSync(repoRoot, { withFileTypes: true })) rootEntries.add(entry.name);

const present = listMarkdown(structureDir, structureDir);
const sotOnDisk = present.filter((p) => !p.startsWith("decisions/") && !GENERATED_DOCS.includes(p) && !RULE_DOCS.includes(p));
const sotOnDisk = present.filter((p) => !p.startsWith("decisions/") && !GENERATED_DOCS.includes(p));
const declared = manifest.docs.map((d) => d.path);

// 1. doc map parity
Expand Down
2 changes: 1 addition & 1 deletion scripts/test-layout/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface VerifyReport {
*/
export const SWEEP_ROOTS = [
"tests", "scripts", ".github", "src", "gui/src", "gui/tests", "bin", "docs", "docs-site", "structure", "skills",
"AGENTS.md", "AGENTS_INSTALL.md", "MAINTAINERS.md", "CONTRIBUTING.md", "README.md", "CREDITS.md",
"AGENTS_INSTALL.md", "MAINTAINERS.md", "CONTRIBUTING.md", "README.md", "CREDITS.md",
"bunfig.toml", "package.json", ".gitignore", ".npmignore",
];
// dist/ is a build output (gitignored) and is rebuilt from src; it is deliberately not swept.
Expand Down
2 changes: 1 addition & 1 deletion skills/ocx/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ integration controls and diagnostics have different transports and limits. A sha
API prefix does not prove that every dashboard action has a CLI equivalent.

This skill is for **operating** a proxy. `AGENTS_INSTALL.md` covers installation
and operating consent; the repository `AGENTS.md` covers code changes.
and operating consent; `CONTRIBUTING.md` covers code changes.

## Find the task offline

Expand Down
2 changes: 1 addition & 1 deletion src/clients/config-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* - **No secret is ever serialized.** Configs carry only the client's documented env
* reference (`{env:VAR}` for OpenCode, `$VAR` for Pi); the real admission key travels
* through the environment. AGENTS.md treats token serialization as a release blocker.
* through the environment. Never serialize the token into exported configuration.
* - **No metadata is guessed.** A model with no authoritative context window ships
* without context/output fields, and the client applies its own defaults. Pi's `cost`
* is omitted entirely rather than zero-filled, because zeros would assert "free",
Expand Down
2 changes: 1 addition & 1 deletion src/quota/reset-observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Kept behind a lazy import from both quota subsystems: src/codex/quota.ts and
* src/providers/quota.ts are both statically reachable from
* src/server/responses/core.ts, so a static edge here would load this module, its config
* resolution, and its sink registry into every install — the failure AGENTS.md documents for
* resolution, and its sink registry into every install — the earlier failure in
* Compatibility Lab, where a six-hop chain pulled ~69 modules onto the core path.
*
* Never throws. A detection or delivery failure must not break the quota write that
Expand Down
2 changes: 1 addition & 1 deletion src/server/gui-freshness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { join } from "node:path";
/**
* Whether the served dashboard bundle predates the sources it was built from.
*
* The dashboard is a build artifact: `AGENTS.md` records that `gui/` is served from `gui/dist`,
* The dashboard is a build artifact: `gui/` is served from `gui/dist`,
* so a checkout that moves forward without `bun run build:gui` keeps serving the previous bundle.
* Nothing fails when that happens. The proxy answers, the page loads, and every feature added since
* the last build is simply absent — which reads as the feature being broken rather than unbuilt.
Expand Down
2 changes: 1 addition & 1 deletion src/server/management/anthropic-reset-grant-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* POST /api/anthropic/reset-grants/consume spend one grant
*
* Spending uses the user's own subscription benefit, so the POST requires the
* dashboard session principal (AGENTS.md, "User-consent actions"); the admin token
* dashboard session principal to enforce user consent; the admin token
* alone is refused. Responses carry fixed codes and fixed messages only: no
* upstream body, exception text, token, organization id, or email. Nothing here
* logs. Lazy-loaded by `handleAnthropicResetGrantRoutesOnDemand` in
Expand Down
4 changes: 2 additions & 2 deletions src/server/management/codex-prompt-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ export async function handleCodexPromptRoutes(ctx: ManagementContext): Promise<R
// this proxy at all. So this is not a technical barrier against a determined local
// agent. What it removes is the CASUAL path — an agent that would have PUT here
// because the endpoint existed and the token was lying in `~/.opencodex` — and it
// makes the refusal legible instead of silent. The real boundary is normative and
// lives in AGENTS.md.
// makes the refusal legible instead of silent. Explicit user consent remains
// necessary whichever mechanism is used to change their prompt configuration.
//
// Reads stay open to the admin token: describing the prompt stack changes nothing,
// and the dashboard's own cold load needs it.
Expand Down
2 changes: 1 addition & 1 deletion src/server/management/sidebar-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function hasBrowserSessionEvidence(ctx: ManagementContext): boolean {
// because both hold every local credential. So this endpoint is not a technical
// barrier against a determined local agent — it removes the CASUAL path (an agent
// that would have POSTed here because the endpoint existed) and makes the refusal
// legible. The actual boundary is normative and lives in AGENTS.md: an agent must
// legible. The consent boundary is documented in AGENTS_INSTALL.md: an agent must
// not spend the user's identity, whichever mechanism is at hand.

export async function handleSidebarRoutes(ctx: ManagementContext): Promise<Response | null> {
Expand Down
3 changes: 1 addition & 2 deletions structure/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ This folder is the maintainer source of truth for the current system shape. Publ
belong in `docs-site/`. Development work is recorded in `devlog/` units — `_plan/` while open,
`_fin/` once closed.

Generated from `structure/manifest.json` by `bun run structure:index`. Do not edit by hand; `bun run structure:check` fails when this file and the manifest disagree. The rules for changing anything
in this folder are in [`AGENTS.md`](AGENTS.md).
Generated from `structure/manifest.json` by `bun run structure:index`. Do not edit by hand; `bun run structure:check` fails when this file and the manifest disagree.

## Reading order

Expand Down
8 changes: 3 additions & 5 deletions structure/ops/docs-and-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ The account reference documents the [Orca source-owned import](../codex-home.md#
Its local-only command is declared in `src/cli/capabilities.ts`, and the generated skill surface
lists its required source/registry paths and preview/apply flags. The index and domain chapters follow the [CLI reference generation contract](../cli-management.md#generated-operating-reference).

Local validation follows [the contributor test policy](../../AGENTS.md#commands): run the
Local validation follows [the contributor test policy](../../CONTRIBUTING.md#local-validation-and-hooks): run the
suite by default, with a documented resource exception requiring focused regression tests.
`scripts/setup-hooks.ts` retires only an exact match for the old managed pre-push and
post-merge shims; custom hooks are preserved. Required current-head CI and
Expand Down Expand Up @@ -285,13 +285,11 @@ image committed anywhere else is caught by review, not by a gate.

Cross-cutting structure contracts are maintained by editing `structure/manifest.json`, the authority
statement, and any dependent whose local explanation changes. Regenerate `structure/INDEX.md` with
the owning command and require the structure check in hosted CI. The
[structure rules](../AGENTS.md#the-source-to-doc-map) retain review of every document mapped to a
changed source area even when no text edit is needed.
the owning command and require the structure check in hosted CI.

## Branch and devlog policy

[`AGENTS.md`](../../AGENTS.md) and [`MAINTAINERS.md`](../../MAINTAINERS.md) are authoritative; this section
[`MAINTAINERS.md`](../../MAINTAINERS.md) is authoritative; this section
exists so the repository-shape source of truth does not omit the shape of its own history.

- `dev` is the single integration branch and the target for ordinary pull requests. `main` moves only
Expand Down
3 changes: 1 addition & 2 deletions structure/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,7 @@ guards. The workflow contract and process bounds live in

`structure/manifest.json` declares both source-review coverage and cross-cutting contract authority.
`scripts/structure-ssot.ts` validates that topology, and generated `structure/INDEX.md` publishes it.
The [structure rules](AGENTS.md#the-source-to-doc-map) define when review requires a content edit;
contract authority never reduces the source map's many-to-many review fan-out.
Contract authority never reduces the source map's many-to-many coverage.

Two invariants are stated here without a binding, and `grace.unboundInvariants` in
[`manifest.json`](manifest.json) carries the reason for each. They are true statements about the system;
Expand Down
2 changes: 1 addition & 1 deletion tests/ci-workflows/bump-dev-version.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ describe("dev version bump rule", () => {
// package.json is package metadata, so a partial write corrupts a checkout and this
// script is also the documented manual recovery path - it runs on developer machines
// where an interrupt or a full disk mid-write would strand an unusable file.
// scripts/AGENTS.md requires atomic replacement for exactly this class of file.
// Package metadata must be replaced atomically to avoid partial writes.
const path = tempPackageJson("2.36.0");
const dir = dirname(path);
const proc = runCli("2.36.0", path);
Expand Down
4 changes: 2 additions & 2 deletions tests/ci-workflows/ci-structure-gate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { repoPath } from "../helpers/repo-root";
* `structure/**`. On #4999, a pure doc split, every expensive leg reported
* `skipped` and the aggregate `ci` check reported success over nothing (#5001).
*
* It hid for so long because `structure/AGENTS.md` makes a `structure/` edit
* almost always arrive beside a `src/` one, which the `ci` filter does match.
* It hid for so long because `structure/` edits usually arrived beside
* `src/` changes, which the `ci` filter does match.
* Only a pure doc change exposes it, and it took a doc reaching its size budget
* to produce one.
*/
Expand Down
4 changes: 2 additions & 2 deletions tests/ci-workflows/docs-provider-preset-counts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
* zh-TW — and every quickstart including the English one — still said 94 (78 key-based). Nothing
* failed, because both numbers read as plausible and no check compared them to the registry.
*
* AGENTS.md calls this class out directly: prefer deriving a count from the thing it describes
* over restating it. The counts here are derived from PROVIDER_REGISTRY, so the next preset that
* Derive a count from the thing it describes instead of restating it.
* The counts here are derived from PROVIDER_REGISTRY, so the next preset that
* lands fails this test in every locale at once instead of drifting.
*
* Each page is anchored by a locale-specific fragment rather than a number, so a reworded
Expand Down
2 changes: 1 addition & 1 deletion tests/ci-workflows/docs-readme-memory-inventory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* time. Review does not catch this: an English diff of one number looks complete on its own,
* and the seven translations were copied from a source that was already stale.
*
* AGENTS.md calls this class out directly: derive a count from the thing it describes rather
* Derive a count from the thing it describes rather
* than restating it. The three numbers below are derived from the rosters the runtime actually
* registers, so the next store that lands fails this test in all eight pages at once instead of
* silently disagreeing with the proxy for months.
Expand Down
3 changes: 1 addition & 2 deletions tests/ci-workflows/structure-ssot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ function scaffold(): string {
scratch.push(root);
write(root, "src/alpha/keep.ts", "export const keep = 1;\n");
write(root, "tests/alpha/alpha.test.ts", "// Holds INV-A-01\nexport {};\n");
// The generated index names the sibling documentation roots and links the rules file, so a
// The generated index names the sibling documentation roots, so a
// scaffold without them fails on the index rather than on the rule under test.
for (const root_dir of ["docs", "docs-site", "devlog"]) write(root, root_dir + "/.gitkeep", "");
write(root, "structure/AGENTS.md", "# Rules\n");
const manifest: Manifest = {
version: 2,
sizeBudgetLines: 600,
Expand Down
2 changes: 1 addition & 1 deletion tests/codex-integration/gpt6-native-rows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* GPT-6 Sol, Luna and Astra Minor native rows.
*
* Held in its own file because tests/codex-integration/codex-catalog.test.ts sits at its
* file-size ratchet cap (see AGENTS.md, "The file-size ratchet has almost no headroom").
* file-size ratchet cap recorded in tests/fixtures/file-size-baseline.json.
*
* Evidence: the authenticated roster probe of 2026-09-23
* (`chatgpt.com/backend-api/codex/models?client_version=0.155.0`, main account), pinned verbatim
Expand Down
Loading
Loading