Skip to content
Merged
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: 1 addition & 1 deletion .claude/hooks/check-affected-pre-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# best-effort and also fires on any command holding $(), backticks or $VAR
# (https://code.claude.com/docs/en/hooks#bash-if-matching), so this script
# re-checks that a subcommand really is `git push` before it spends a run
# (docs/conventions/hook-precision/README.md, rule 2). A quoted or heredoc
# (docs/contracts/hook-precision/README.md, rule 2). A quoted or heredoc
# mention of "git push" is data, not a push.
#
# Stays quiet (exit 0) on: no real push; a push that only deletes remote refs,
Expand Down
10 changes: 5 additions & 5 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ updates:
- "patch"
# The harness-ops inventory's parser packages (acorn, eslint-scope). Nothing is
# vendored: the committed lockfile is what `npm ci` installs on first use
# (docs/conventions/on-demand-dependencies/), so a bump here is the release.
# (docs/contracts/on-demand-dependencies/), so a bump here is the release.
- package-ecosystem: npm
directory: /plugins/harness-ops/skills/inventory/scripts/js
labels:
Expand All @@ -143,7 +143,7 @@ updates:
- "patch"
# The harness-ops control-claude-code driver's terminal engine (@microsoft/tui-test).
# Nothing is vendored: the committed lockfile is what `npm ci` installs on first use
# (docs/conventions/on-demand-dependencies/), so a bump here is the release.
# (docs/contracts/on-demand-dependencies/), so a bump here is the release.
- package-ecosystem: npm
directory: /plugins/harness-ops/skills/control-claude-code/driver
labels:
Expand All @@ -162,7 +162,7 @@ updates:
- "patch"
# The testing check-visual-parity skill's pixelmatch and pngjs. Nothing is
# vendored: the committed lockfile is what `npm ci` installs on first use
# (docs/conventions/on-demand-dependencies/), so a bump here is the release.
# (docs/contracts/on-demand-dependencies/), so a bump here is the release.
- package-ecosystem: npm
directory: /plugins/testing/skills/check-visual-parity/scripts
labels:
Expand Down Expand Up @@ -267,7 +267,7 @@ updates:
- "patch"
# The animation plugin's hash-locked Python packages (numpy, opencv). Nothing is vendored:
# the SessionStart hook installs requirements.txt on demand
# (docs/conventions/on-demand-dependencies/), so a bump here is the release.
# (docs/contracts/on-demand-dependencies/), so a bump here is the release.
- package-ecosystem: pip
directory: /plugins/animation
labels:
Expand All @@ -286,7 +286,7 @@ updates:
- "patch"
# The explainer-video plugin's hash-locked Python packages (ManimCE). Nothing is vendored:
# the SessionStart hook installs requirements.txt on demand
# (docs/conventions/on-demand-dependencies/), so a bump here is the release.
# (docs/contracts/on-demand-dependencies/), so a bump here is the release.
- package-ecosystem: pip
directory: /plugins/explainer-video
labels:
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/plugin-eval/select-plugins.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ test("a change under a plugin's evals selects that plugin only", () => {
});

test("a change only under docs selects nothing", () => {
assert.deepEqual(selectPlugins(["docs/adr/0001-x.md", "docs/conventions/loop-lane/README.md"]), []);
assert.deepEqual(selectPlugins(["docs/adr/0001-x.md", "docs/contracts/loop-lane/README.md"]), []);
});

test("skills and agents select their plugin once, sorted", () => {
Expand Down
4 changes: 2 additions & 2 deletions .github/scripts/pr-merge/enable-auto-merge.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
// answers them all; a run whose verifier read did not come never narrows a
// person's comment that already names its reasons. The
// comment is the record; only a cause a person must clear
// (docs/conventions/loop-lane/README.md#when-work-stops-for-the-owner,
// (docs/contracts/loop-lane/README.md#when-work-stops-for-the-owner,
// with cost and trust holds kept: untrusted
// provenance or an untrusted spec, a security finding, a high path, a
// trusted-actor widening, a real charge or a listing too long to check, see
Expand Down Expand Up @@ -610,7 +610,7 @@ export function verifyHold(evidence, head) {
export const TRUST_REFUSALS = Object.freeze(["untrusted-provenance", "untrusted-provenance-removed-by-non-human", "issue-labels-unreadable"]);

// Who clears the refusal verifyHold reads in `evidence` at `head`
// (docs/conventions/loop-lane/README.md#when-work-stops-for-the-owner;
// (docs/contracts/loop-lane/README.md#when-work-stops-for-the-owner;
// cost and trust holds stay a person's): `person`
// for an issue link the trust hold refuses (TRUST_REFUSALS), a verifier
// refusal the gate marks `needsHuman` (babysit_verify_evidence NEEDS_HUMAN)
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/pr-merge/post-unarmed-status.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
// The status shows a hold the lanes own on the pull request, in place of the
// human-gated label (when a person is needed:
// docs/conventions/loop-lane/README.md#when-work-stops-for-the-owner). It is informational:
// docs/contracts/loop-lane/README.md#when-work-stops-for-the-owner). It is informational:
// its context is not `ci-status`, the only check the main ruleset requires,
// so it neither holds nor passes a merge. Each head's newest status in the
// context is read first, trusted only when the GitHub Actions bot posted it
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr-require-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1686,7 +1686,7 @@ jobs:
# whole hook entry whenever the key is unset (the declared userConfig
# `default` is unimplemented upstream — anthropics/claude-code#46477), so
# the hook never fires on a default install. The channel decision matrix
# (docs/conventions/hook-config-delivery/) rules argv out for hooks; this
# (docs/contracts/hook-config-delivery/) rules argv out for hooks; this
# gate pins the exact regression #1242 fixed.
- name: Check plugin hook configs for bare userConfig argv tokens
id: userconfig_argv
Expand Down Expand Up @@ -2264,7 +2264,7 @@ jobs:
- name: Verify generated shared-library copies match their canonical sources
if: needs.select-tests.outputs.run_tests == 'true'
run: scripts/sync-shared-copies.sh --check
# docs/conventions/prerequisites/: the gate validates every
# docs/contracts/prerequisites/: the gate validates every
# prerequisites.json and fails on an undeclared tool not listed in
# scripts/prerequisites-baseline.txt. Its suites run through the selector.
- name: Check plugin prerequisites are declared
Expand Down
2 changes: 1 addition & 1 deletion lefthook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# `lefthook install`, which also fetches the guardrails git hooks named in `remotes:` below; until
# then the .claude/settings.json pre-push row runs the check-affected check on a Claude Code
# session's pushes and says to install. Placement rules:
# docs/conventions/check-placement/README.md.
# docs/contracts/check-placement/README.md.
pre-push:
jobs:
# Runs .claude/hooks/check-affected-pre-push.sh as committed at the merge-base with
Expand Down
4 changes: 2 additions & 2 deletions scripts/check-declared-prerequisites.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// Three checks, all against scripts/prerequisites-baseline.txt, which lists
// today's gaps as `<plugin> <gap>` lines so main stays green:
// 1. Every plugins/*/prerequisites.json passes the schema in
// docs/conventions/prerequisites/, read through lib/prerequisites.mjs.
// docs/contracts/prerequisites/, read through lib/prerequisites.mjs.
// Gap `schema`: a file not yet in the schema's shape.
// 2. A plugin with a valid file carries the generated checker copies
// (lib/prerequisites.mjs, .sh, .ps1) registered in scripts/shared-copies.txt.
Expand Down Expand Up @@ -295,7 +295,7 @@ export function main(argv, out = { log: console.log, error: console.error }) {
}
if (findings.length) {
for (const f of findings) out.error(f);
out.error(`${findings.length} finding(s). Declare the tool per docs/conventions/prerequisites/README.md.`);
out.error(`${findings.length} finding(s). Declare the tool per docs/contracts/prerequisites/README.md.`);
return 1;
}
out.log(
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-detector-eval-coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
# runs to EOF, so that assertion alone passed while the gate was most broken.
#
# Adjacent and DIFFERENT: scripts/check-detector-findings-crosswalk.sh checks
# that each severity-crosswalk row in docs/conventions/detector-findings/ argues
# that each severity-crosswalk row in docs/contracts/detector-findings/ argues
# its disposition from a stated test. That is a judgment about a markdown table
# and says nothing about eval coverage.
# scripts/check-fleet-finding-test-coverage.sh is the same SHAPE one surface
Expand Down
6 changes: 3 additions & 3 deletions scripts/check-docs-naming.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ mk_repo() {
local dir
fixture_tree::build "$1" --sut "$SUT_SRC" --git || return 1
dir="${!1}"
mkdir -p "$dir/docs/conventions/standards" "$dir/docs/adr"
mkdir -p "$dir/docs/contracts/standards" "$dir/docs/adr"
printf 'seed\n' >"$dir/docs/README.md"
printf 'seed\n' >"$dir/docs/plugin-philosophy.md"
printf 'seed\n' >"$dir/docs/conventions/standards/README.md"
printf 'seed\n' >"$dir/docs/contracts/standards/README.md"
printf 'seed\n' >"$dir/docs/adr/0001-first.md"
git_test_config "$dir" add -A >/dev/null
git_test_config "$dir" commit -qm base
Expand Down Expand Up @@ -310,7 +310,7 @@ if [[ -n "$drift_ready" ]]; then
docs/NEW-FILE.md docs/a/snake_case.md docs/a/Mixed.md docs/a/foo..md
docs/a/foo.md. docs/a/foo... docs/a/noext docs/a/README.md.bak
docs/a/v1.2.schema.json docs/Foo.md docs/foo.md
docs/conventions/standards/readme.md docs/x/Readme.md
docs/contracts/standards/readme.md docs/x/Readme.md
docs/a/Bad_Name.PY "docs/x/caf"$'\303\251'".py" "docs/x/Caf"$'\303\251'".py"
"docs/New"$'\n'"line/foo.md" "docs/new"$'\n'"line/foo.md"
Top_Level.txt other/Bad_Name.json
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-docs-only-gate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# WHY. The heavy lanes short-circuit on a diff confined to the docs-only
# allowlist. That short-circuit is a fail-open shape by construction: getting it
# wrong makes a lane report success without running, which is exactly the
# false-green docs/conventions/liveness-assertion/ names. Consumers spell the
# false-green docs/contracts/liveness-assertion/ names. Consumers spell the
# gate as `steps.scope.outputs.docs_only != 'true'`, an INVERSE-polarity test
# of a string flag. A consumer that wrote `== 'false'` instead of `!= 'true'`
# would skip its lane whenever the detector emitted anything unexpected: the
Expand Down
4 changes: 2 additions & 2 deletions scripts/check-drive-root-litter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# `<current-drive>:\d\dir` and the consumer creates that whole phantom chain
# before writing. The residue is therefore always the same shape: `<drive>:\<x>\`
# where `<x>` is the single letter of the drive the author MEANT to write to.
# `docs/conventions/windows-path-emit/README.md` owns the rule that prevents it;
# `docs/contracts/windows-path-emit/README.md` owns the rule that prevents it;
# this script is that rule's detection net, for the runs that ignore it.
#
# Requiring the directory name to match a MOUNTED DRIVE is what keeps the
Expand Down Expand Up @@ -179,7 +179,7 @@ The litter is the cheap part. Whatever wrote it wrote to a path it did not
intend, so any run that produced it may have measured something other than what
it claims. Re-check the run's results before trusting them, then:

* fix the emitter - see docs/conventions/windows-path-emit/README.md, and
* fix the emitter - see docs/contracts/windows-path-emit/README.md, and
scripts/emit-windows-path.sh for the conversion itself;
* CHECK FOR A REGISTERED GIT WORKTREE BEFORE REMOVING ANYTHING. A phantom
tree can contain one: a `git worktree add` given an unconverted path
Expand Down
4 changes: 2 additions & 2 deletions scripts/check-hook-userconfig-argv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# closed not-planned), so an unset-but-defaulted ${user_config.*} argv token
# silently drops the ENTIRE hook entry instead of substituting. On a default
# install the hook never fires. The channel decision matrix
# (docs/conventions/hook-config-delivery/) rules argv out for hooks until
# (docs/contracts/hook-config-delivery/) rules argv out for hooks until
# upstream implements `default`; this gate pins that rule.
#
# Scope: hook configurations only — the default hooks/hooks.json, any
Expand Down Expand Up @@ -193,7 +193,7 @@ if ((errors > 0)); then
echo "A \${user_config.*} token in a plugin hook config silently drops the"
echo "whole hook entry whenever the key is unset (declared defaults are not"
echo "implemented upstream). Deliver the value per the channel decision"
echo "matrix instead: docs/conventions/hook-config-delivery/README.md."
echo "matrix instead: docs/contracts/hook-config-delivery/README.md."
} >&2
exit 1
fi
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-lane-coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# is not a gate: `managed-scope-sync` and `state-key-sync` shipped outside the
# aggregate for their whole lifetime (claude-code-plugins#2856), each advertised
# as a dedicated check in scripts/cross-plugin-source-registry.txt. That is the
# false-green shape docs/conventions/liveness-assertion/ names — green surface,
# false-green shape docs/contracts/liveness-assertion/ names — green surface,
# dead enforcement — with the added twist that the surface is the merge gate
# itself.
#
Expand Down
8 changes: 4 additions & 4 deletions scripts/check-loop-lane-floor-drift.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Exit: 0 every consumer matches the source, 1 drift or a stale registration,
# 2 usage or a prerequisite this gate cannot verify around.
#
# WHY. docs/conventions/loop-lane/README.md section 6 orders every consuming
# WHY. docs/contracts/loop-lane/README.md section 6 orders every consuming
# lane body to INLINE the floor, because an installed plugin cannot read a
# sibling plugin's files at runtime: the values have to be in the lane body or
# the lane cannot apply them. Inlining is therefore the design, not a defect,
Expand Down Expand Up @@ -43,7 +43,7 @@
# author does not add the entry, the six registered paths still agree, CI is
# green, and the next contract change strands that seventh copy. That is the
# same blindness that produced the drift this gate exists for, one level up,
# and it is the false-green shape docs/conventions/liveness-assertion/ names.
# and it is the false-green shape docs/contracts/liveness-assertion/ names.
#
# So before comparing anything, every TRACKED file is scanned for the floor's
# opening bullet and any carrier outside the registry FAILS. Discovery uses the
Expand Down Expand Up @@ -104,7 +104,7 @@
# adds the shape to the anchor here, in the same change.
#
# LIVENESS-ASSERTION CONVENTION, taxonomy row **Gate / classifier**
# (docs/conventions/liveness-assertion/README.md). That row requires the verdict
# (docs/contracts/liveness-assertion/README.md). That row requires the verdict
# to reflect the state actually read, and fail-closed on ambiguity rather than
# green on a misread signal. This gate satisfies it through the core contract's
# **fail loud** limb, not the agent-readable one: it blocks. Every input it
Expand Down Expand Up @@ -421,7 +421,7 @@ if ((errors != 0)); then

The rate-limit guard's operable floor is inlined on purpose: an installed
plugin cannot read a sibling plugin's files at runtime, so every consumer
carries its own copy (docs/conventions/loop-lane/README.md section 6). The
carries its own copy (docs/contracts/loop-lane/README.md section 6). The
values are DECIDED in one place only:

$SOURCE
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-loop-lane-floor-drift.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#
# The cases that earn their keep are the ones proving the gate goes RED. A
# drift check nobody has watched fail is the false-green shape
# docs/conventions/liveness-assertion/ names. So every failure class gets a case: exact
# docs/contracts/liveness-assertion/ names. So every failure class gets a case: exact
# drift, values drift, a consumer that stopped inlining the floor, a
# registration pointing at nothing, a COPY NOBODY REGISTERED, and the two ways
# the extractor could go blind and pass everything forever.
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-shell-portability.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# to prove the shipping config, not just the mechanism.
#
# Assertion scaffolding lives in scripts/lib/test-harness.sh — repo tooling,
# not a plugin library. See docs/conventions/shell-test-helpers/README.md.
# not a plugin library. See docs/contracts/shell-test-helpers/README.md.
# shellcheck disable=SC2016 # fixture bodies are literal shell content in single quotes; expansion is never wanted
set -uo pipefail

Expand Down
4 changes: 2 additions & 2 deletions scripts/check-silent-skips.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# A bare stderr write (`>&2`) is NOT a sanctioned visibility call: every site
# this gate inspects is, by construction, an exit-0 skip path, and per the
# official Claude Code hooks reference (re-fetched 2026-08-10,
# docs/conventions/hook-observability/) "Stderr from a hook that exits 0 goes
# docs/contracts/hook-observability/) "Stderr from a hook that exits 0 goes
# to the debug log only, never the transcript, and Claude never sees it" — so
# it reaches neither the user nor the agent on any path this gate inspects.
# A `>&2`-only notice on such a path is invisible regardless of intent.
Expand Down Expand Up @@ -204,7 +204,7 @@ if ((errors > 0)); then
echo "or carry a documented quiet classification:"
echo "'# silent-skip-ok: <reason>' at the site. A bare stderr write is"
echo "NOT sufficient — stderr on exit 0 is never shown to the user or"
echo "the agent (docs/conventions/hook-observability/)."
echo "the agent (docs/contracts/hook-observability/)."
echo
echo "A scripts/*.test.sh that cannot run an assertion must fail closed"
echo "(or annotate with '# silent-skip-ok: <reason>'), never score the"
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-skill-portability.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# bare-vs-guarded discrimination on live files, not only synthetic ones.
#
# Assertion scaffolding lives in scripts/lib/test-harness.sh — repo tooling,
# not a plugin library. See docs/conventions/shell-test-helpers/README.md.
# not a plugin library. See docs/contracts/shell-test-helpers/README.md.
# shellcheck disable=SC2016 # fixture bodies are literal skill content in single quotes; expansion is never wanted
set -uo pipefail

Expand Down
6 changes: 3 additions & 3 deletions scripts/check-upstream-drift.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# scripts/check-upstream-drift.sh --help
#
# The page forms (the git pin marker, row links, drift inputs, the `## Map`
# section and page status) are defined in docs/conventions/upstream-drift/
# section and page status) are defined in docs/contracts/upstream-drift/
# README.md, "Pinned git upstreams". In short: a page whose marker line reads
# **Last audited upstream state:** `<owner>/<repo>@<40-hex sha>` [under `<scope>/`]
# is checked; links to that repository outside `## Map` are drift inputs for any
Expand Down Expand Up @@ -350,7 +350,7 @@ for page in ${PAGES[@]+"${PAGES[@]}"}; do
parse_marker "$file"
case $? in
0) GIT_PAGES+=("$page") ;;
2) die "$page: marker line names a pin but does not match the git form (see docs/conventions/upstream-drift/README.md, \"Pinned git upstreams\")" ;;
2) die "$page: marker line names a pin but does not match the git form (see docs/contracts/upstream-drift/README.md, \"Pinned git upstreams\")" ;;
*) ((EXPLICIT)) && die "$page: no git pin marker" ;;
esac
done
Expand Down Expand Up @@ -493,7 +493,7 @@ fi

if ((drifted > 0)); then
printf '%s\n' "${FINDINGS[@]}" >&2
printf '%s: %d of %d page(s) show upstream drift; re-audit the rows named above (docs/conventions/upstream-drift/README.md, "Pinned git upstreams").\n' \
printf '%s: %d of %d page(s) show upstream drift; re-audit the rows named above (docs/contracts/upstream-drift/README.md, "Pinned git upstreams").\n' \
"$SELF" "$drifted" "${#GIT_PAGES[@]}" >&2
exit 1
fi
Expand Down
2 changes: 1 addition & 1 deletion scripts/emit-windows-path.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# Windows-native consumer - PowerShell, cmd, or a native interpreter such as
# Windows Python - the leading `/` anchors to the root of the CURRENT DRIVE, so
# the literal becomes `<current-drive>:\d\dir`. Nothing errors: the consumer
# happily creates the phantom tree and writes there. `docs/conventions/windows-path-emit/README.md` owns the rule
# happily creates the phantom tree and writes there. `docs/contracts/windows-path-emit/README.md` owns the rule
# this script implements, including the rule that ranks ABOVE it: prefer a path
# the native side computes itself from a working directory it already owns, and
# reach for this conversion only when an absolute path genuinely has to cross.
Expand Down
4 changes: 2 additions & 2 deletions scripts/gen-hook-event-registry.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
# (https://code.claude.com/docs/en/hooks, the lifecycle table under "Hook
# lifecycle"), and a hardcoded list drifts silently as events are added or
# renamed. Every registry entry is a four-part record per
# docs/conventions/upstream-drift (claim, basis, as-of date, recheck trigger),
# and per docs/conventions/native-references it states what the reference
# docs/contracts/upstream-drift (claim, basis, as-of date, recheck trigger),
# and per docs/contracts/native-references it states what the reference
# documented on the as-of date, never that the running binary fires the event.
#
# The log is a mod (plugins/harness-ops/hooks/register.ts; ADR 0065). It hooks
Expand Down
Loading
Loading