Skip to content

feat(harness): context map, @AGENTS.md single source, contexts rule, and commit-msg + anti-bypass hooks - #136

Merged
keli-wen merged 3 commits into
masterfrom
feat/harness-context-map-hooks
Jul 23, 2026
Merged

feat(harness): context map, @AGENTS.md single source, contexts rule, and commit-msg + anti-bypass hooks#136
keli-wen merged 3 commits into
masterfrom
feat/harness-context-map-hooks

Conversation

@keli-wen

@keli-wen keli-wen commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Bootstrap the agent-and-contributor harness: a path-scoped rule, two hooks (one git, one agent), and a design doc that explains how the pieces fit and how Claude Code and Codex stay aligned. This is the first implementation slice of the harness work; it adds no runtime/library behavior.

Rule — contexts authoring, surfaced just-in-time

  • .claude/rules/contexts-authoring.md is a path-scoped Claude Code rule (paths: contexts/**) that loads the contexts authoring standard when an agent edits a contexts/ page. It is thin and points at the canonical write-contexts.md rather than duplicating it. The structural rules themselves are already hard-enforced by tests/test_contexts.py; this rule just helps an agent get them right up front.
  • Codex is deliberately not given a parallel file: its .codex/rules/ are an execution-policy allowlist (not path-scoped instructions), and its closest instruction equivalent is a coarser nested AGENTS.md. The asymmetry is documented in the harness doc instead of worked around.

Git hook — commit message format

  • scripts/hooks/commit_msg_check.py, wired as a commit-msg stage in .pre-commit-config.yaml, rejects a non-English (CJK) or non-Conventional-Commit subject line. It is tool-agnostic: a human, Claude, or Codex all trigger it because git invokes it. scripts/pre-commit-setup.sh now installs the commit-msg hook type.

Agent hook — no verification bypass

  • scripts/hooks/pre_tool_use_no_bypass.py is a shared PreToolUse guard invoked from both .claude/settings.json and .codex/hooks.json. It denies a Bash git command that carries --no-verify, which would otherwise skip the commit-msg / pre-commit / pre-push checks. This is the one guarantee a git hook cannot self-enforce (that flag is what turns git hooks off), so it lives at the agent layer. It is a mechanical check only.

Doc

  • contexts/dev/harness-engineering.md documents the enforcement layers (CI is the only floor for external contributors; local git hooks and agent controls sit on top), the Claude-vs-Codex mechanism map (the word "rules" means different things on each side), the principle of aligning content by default and behavior (a shared hook) only for hard guarantees, and a canonical-source table. Registered in contexts/dev/README.md. It cites the Claude Code best-practices, Claude Code rules, and Codex hooks docs.

Context map and single-source agent instructions

  • contexts/CONTEXT_MAP.md is the navigation index for contexts/: a directory map with a one-line purpose per page, and a task-to-page route table. AGENTS.md points here as the first read, and it is registered in contexts/README.md.
  • AGENTS.md becomes the single source of repository instructions. CLAUDE.md is reduced to an @AGENTS.md import (plus a human-only HTML comment), so the two guides can no longer drift by hand; Claude Code expands the import at load. tests/test_contexts.py gains a _guide_text helper that inlines @path imports, so its literal-content assertions still hold for CLAUDE.md.

Anti-bypass guard: precise matching

The guard tokenizes the command with shlex, splits on shell operators, strips leading VAR=value and prefix words (env / command / sudo / ...), and denies only when --no-verify is a real argument token of a real git invocation. A command that merely mentions the flag inside a quoted string (a doc example, a grep, a commit message, a JSON test payload) keeps it inside one token and passes. It fails open on unbalanced quotes. Residual gap: shell indirection such as $VAR expansion or eval is not resolved, which is out of scope for a mechanical guard.

An earlier substring version denied any command that mentioned the flag; that false positive surfaced live while building this PR and is fixed in the second commit, with tests for the previously-blocked cases and a live confirmation that echoing the literal is no longer denied.

Not in this PR

  • CI PR-title lint: the server-side floor that enforces the commit convention for external contributors (local git hooks only fire for those who ran pre-commit install). Separate follow-up, noted in the harness doc.

Related Issue

Part of #134.

Verification

  • bash scripts/verify.sh passes: ruff format + ruff check + basedpyright + import-linter + pytest --cov (426 passed, 85.66% coverage).
  • Both hook scripts manually exercised: the commit-msg check exits 0 on a valid subject and 1 on CJK / non-conventional; the anti-bypass guard denies a git + no-verify command and passes everything else. Both also covered by tests/hooks/.
  • No live-network smoke test applies: this PR touches harness config, hook scripts, a rule, and a contexts page; it changes no public operation or source.

Checklist

  • The title uses English Conventional Commit format: type(scope): summary.
  • The related issue or design discussion is linked when applicable.
  • bash scripts/verify.sh passes.
  • Every applicable live-network component smoke test passes, or this PR states why none applies.
  • Public behavior has focused tests, an example, and documentation where applicable.
  • The PR is complete, small, and contains no unrelated changes.

…ness doc

Bootstrap the agent-and-contributor harness layer. Part of #134.

- .claude/rules/contexts-authoring.md: a path-scoped Claude Code rule
  (paths: contexts/**) that surfaces the contexts authoring standard
  just-in-time. It points at the canonical write-contexts.md instead of
  duplicating it. Codex has no per-file path-scoped instruction rule, so no
  parallel file is added; the asymmetry is documented, not worked around.
- commit-msg git hook (scripts/hooks/commit_msg_check.py + a commit-msg stage
  in .pre-commit-config.yaml): rejects a non-English (CJK) or
  non-Conventional-Commit subject line. Tool-agnostic, so it fires for a human,
  Claude, or Codex alike because git itself invokes it.
- anti-bypass agent hook (scripts/hooks/pre_tool_use_no_bypass.py, shared by
  .claude/settings.json and .codex/hooks.json): a PreToolUse deny when a Bash
  git command carries --no-verify, which would skip the commit-msg / pre-commit
  / pre-push checks. This is the one guarantee a git hook cannot self-enforce,
  so it lives at the agent layer.
- contexts/dev/harness-engineering.md: documents the enforcement layers (CI /
  git hooks / agent controls), the Claude-vs-Codex mechanism map, the
  content-alignment-vs-behavior-alignment principle, and a canonical-source
  table. Registered in contexts/dev/README.md.
- Focused tests under tests/hooks/ for both hook scripts.

verify.sh passes: ruff format + ruff check + basedpyright + import-linter +
pytest --cov (420 passed, 85.66% coverage).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@keli-wen keli-wen added type: feature Adds a new capability or observable behavior area: harness Contributor and agent controls, CI, hooks, skills, and rulesets area: contexts Repository information routing and discovery under contexts/ labels Jul 23, 2026
@keli-wen keli-wen self-assigned this Jul 23, 2026
keli-wen and others added 2 commits July 23, 2026 17:34
The guard matched a naive substring, so any Bash command that merely
mentioned the flag (an echo, a grep, a commit message, a JSON test payload
on the command line) was denied even though it ran no git invocation. This
surfaced live while building #136.

Tokenize the command with shlex, split into simple commands on shell
operators, strip leading VAR=value and prefix words (env / command / sudo /
...), and deny only when --no-verify is a real argument token of a real git
invocation. A flag mentioned inside a quoted string stays in one token and
passes. Fails open on unbalanced quotes. Residual gap (shell indirection
such as $VAR / eval) is documented, not resolved.

Adds tests for the previously-false-positive cases and updates the mechanical
-check description in contexts/dev/harness-engineering.md.

verify.sh passes (426 passed, 85.66% coverage). Confirmed live: a command
echoing the literal is no longer blocked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ENTS.md import

- contexts/CONTEXT_MAP.md: the navigation index for contexts/ (a directory map
  plus task-to-page routes). AGENTS.md points here as the first read, and it is
  registered in contexts/README.md.
- AGENTS.md becomes the single source of repository instructions; its intro,
  entry-point pointer, and skills-section wording are updated accordingly.
- CLAUDE.md is reduced to `@AGENTS.md` (plus a human-only HTML comment), so the
  two guides can no longer drift; Claude Code expands the import at load.
- tests/test_contexts.py: a `_guide_text` helper inlines `@path` imports when it
  checks a guide, so the literal-content assertions still hold for CLAUDE.md.

verify.sh passes (426 passed, 85.66% coverage).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@keli-wen keli-wen changed the title feat(harness): contexts rule + commit-msg and anti-bypass hooks + harness doc feat(harness): context map, @AGENTS.md single source, contexts rule, and commit-msg + anti-bypass hooks Jul 23, 2026
@keli-wen
keli-wen merged commit 078b6d6 into master Jul 23, 2026
1 check passed
@keli-wen
keli-wen deleted the feat/harness-context-map-hooks branch July 23, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: contexts Repository information routing and discovery under contexts/ area: harness Contributor and agent controls, CI, hooks, skills, and rulesets type: feature Adds a new capability or observable behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant