diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-13 16:06:13 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-13 16:06:13 -0500 |
| commit | 6cd3aa32b9f3b033c3890f08ab430e757696e5e3 (patch) | |
| tree | 763dcb361796935330dc7e8afa98c0e427ed2966 | |
| parent | 0ee94abca7dde8356709d712b2dbf735b029f2b8 (diff) | |
| download | rulesets-6cd3aa32b9f3b033c3890f08ab430e757696e5e3.tar.gz rulesets-6cd3aa32b9f3b033c3890f08ab430e757696e5e3.zip | |
feat(runtime): add the thin-pointer AGENTS.md agent entry file
claude-templates/AGENTS.md points any harness at protocols.org, the rules locations, and the /name-to-file resolution rule, and tells it to degrade per each rule's documented fallback instead of skipping gates. make install links it to ~/.codex/AGENTS.md (new CODEX_DIR stanza) and install-ai.sh seeds a project-owned copy at bootstrap, never overwriting an existing one. The rulesets root carries a tracked symlink as dogfood. Five new bats tests cover the link idiom and the seeding. This resolves the generic-instruction-file blocker from the runtime spec, and velox picks up the global link on its next session's make install.
| l--------- | AGENTS.md | 1 | ||||
| -rw-r--r-- | Makefile | 12 | ||||
| -rw-r--r-- | claude-templates/AGENTS.md | 19 | ||||
| -rw-r--r-- | inbox/lint-followups.org | 1 | ||||
| -rwxr-xr-x | scripts/install-ai.sh | 7 | ||||
| -rw-r--r-- | scripts/tests/install-agents-entry.bats | 51 | ||||
| -rw-r--r-- | scripts/tests/install-ai.bats | 23 | ||||
| -rw-r--r-- | todo.org | 9 |
8 files changed, 119 insertions, 4 deletions
diff --git a/AGENTS.md b/AGENTS.md new file mode 120000 index 0000000..1e43f54 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +claude-templates/AGENTS.md
\ No newline at end of file @@ -5,6 +5,7 @@ SKILLS_DIR := $(HOME)/.claude/skills RULES_DIR := $(HOME)/.claude/rules HOOKS_DIR := $(HOME)/.claude/hooks CLAUDE_DIR := $(HOME)/.claude +CODEX_DIR := $(HOME)/.codex LOCAL_BIN := $(HOME)/.local/bin AI_LAUNCHER := $(CURDIR)/claude-templates/bin/ai SKILLS := $(patsubst %/SKILL.md,%,$(wildcard */SKILL.md)) @@ -220,6 +221,17 @@ install: ## Symlink skills, rules, config, hooks, and bin scripts into place fi \ fi @echo "" + @echo "Agent entry (codex):" + @mkdir -p "$(CODEX_DIR)" + @if [ -L "$(CODEX_DIR)/AGENTS.md" ]; then \ + echo " skip AGENTS.md (already linked)"; \ + elif [ -e "$(CODEX_DIR)/AGENTS.md" ]; then \ + echo " WARN AGENTS.md exists and is not a symlink — skipping"; \ + else \ + ln -s "$(CURDIR)/claude-templates/AGENTS.md" "$(CODEX_DIR)/AGENTS.md"; \ + echo " link AGENTS.md → $(CODEX_DIR)/AGENTS.md"; \ + fi + @echo "" @echo "Hooks (default):" @for hook in $(DEFAULT_HOOKS); do \ name=$$(basename $$hook); \ diff --git a/claude-templates/AGENTS.md b/claude-templates/AGENTS.md new file mode 100644 index 0000000..97fd001 --- /dev/null +++ b/claude-templates/AGENTS.md @@ -0,0 +1,19 @@ +# Agent Entry Point + +You are this project's agent, whichever model or harness is running you. + +1. If the project has `.ai/protocols.org`, read it now and follow all + instructions. It is the single entry point for session behavior: + startup, session logging, inbox processing, wrap-up. +2. Behavioral rules live in `.claude/rules/*.md` in the project (when + present) and `~/.claude/rules/*.md` globally. Read them; they bind + every session regardless of harness. +3. A `/name` reference in any rule or workflow (`/voice`, + `/review-code`, `/brainstorm`, ...) resolves to a file: + `~/.claude/skills/<name>/SKILL.md` or `~/.claude/commands/<name>.md`. + Read that file and follow it. If it is absent, say so and apply the + rule's documented fallback rather than skipping the gate. +4. Harness mechanics these files assume (hooks, `/clear`, popup tools) + may not exist in your harness. Degrade per each rule's own fallback + language. Never silently skip a verification or approval gate because + the tooling that enforces it is missing. diff --git a/inbox/lint-followups.org b/inbox/lint-followups.org index 85580a0..8132c30 100644 --- a/inbox/lint-followups.org +++ b/inbox/lint-followups.org @@ -3,6 +3,5 @@ * 2026-07-04 Sat — Task-review health: 5 top-level [#A]/[#B]/[#C] tasks unreviewed for >30 days (daily review may have slipped) * lint-org follow-ups — todo.org (2026-07-11) -** TODO link-to-local-file — Link to non-existent local file "→id" (line 1314) * 2026-07-11 Sat — Task-review health: 11 top-level [#A]/[#B]/[#C] tasks unreviewed for >30 days (daily review may have slipped) diff --git a/scripts/install-ai.sh b/scripts/install-ai.sh index 7007eed..0c90f64 100755 --- a/scripts/install-ai.sh +++ b/scripts/install-ai.sh @@ -141,6 +141,13 @@ today="$(date +%Y-%m-%d)" sed "s|\[Project Name\]|$project_name|g; s|\[Date\]|$today|g" \ "$CANONICAL/notes.org" > "$project/.ai/notes.org" +# Seed AGENTS.md — the runtime-neutral agent entry file (thin pointer at +# protocols.org, rules, and /name resolution) for Codex-style harnesses. +# Seed-only, like CLAUDE.md: project-owned after bootstrap, never overwritten. +if [ ! -e "$project/AGENTS.md" ]; then + cp "$REPO/claude-templates/AGENTS.md" "$project/AGENTS.md" +fi + # Tracking setup. case "$track_mode" in track) diff --git a/scripts/tests/install-agents-entry.bats b/scripts/tests/install-agents-entry.bats new file mode 100644 index 0000000..03343a6 --- /dev/null +++ b/scripts/tests/install-agents-entry.bats @@ -0,0 +1,51 @@ +#!/usr/bin/env bats +# make install must link the runtime-neutral agent entry file (AGENTS.md) +# into CODEX_DIR so Codex-style harnesses bootstrap from the same +# protocols/rules/skills the Claude side reads. The thin-pointer shape and +# the decision trail live in docs/design/2026-07-13-runtime-portability- +# inventories.org and the generic-agent-runtime task. + +setup() { + REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../.." && pwd)" + TMPHOME="$(mktemp -d)" +} + +teardown() { + rm -rf "$TMPHOME" +} + +run_install() { + make -C "$REPO_ROOT" install \ + SKILLS_DIR="$TMPHOME/skills" \ + RULES_DIR="$TMPHOME/rules" \ + HOOKS_DIR="$TMPHOME/hooks" \ + CLAUDE_DIR="$TMPHOME/claude" \ + CODEX_DIR="$TMPHOME/codex" \ + LOCAL_BIN="$TMPHOME/bin" +} + +@test "install links AGENTS.md into CODEX_DIR" { + run run_install + [ "$status" -eq 0 ] + [ -L "$TMPHOME/codex/AGENTS.md" ] + grep -q "protocols.org" "$TMPHOME/codex/AGENTS.md" +} + +@test "install is idempotent on the agent entry (second run skips)" { + run run_install + [ "$status" -eq 0 ] + run run_install + [ "$status" -eq 0 ] + [[ "$output" == *"skip AGENTS.md (already linked)"* ]] + [ -L "$TMPHOME/codex/AGENTS.md" ] +} + +@test "install warns on a non-symlink AGENTS.md collision and leaves it alone" { + mkdir -p "$TMPHOME/codex" + echo "hand-written entry" > "$TMPHOME/codex/AGENTS.md" + run run_install + [ "$status" -eq 0 ] + [[ "$output" == *"WARN AGENTS.md exists and is not a symlink"* ]] + [ ! -L "$TMPHOME/codex/AGENTS.md" ] + grep -q "hand-written entry" "$TMPHOME/codex/AGENTS.md" +} diff --git a/scripts/tests/install-ai.bats b/scripts/tests/install-ai.bats index 8e91770..a7eb3c0 100644 --- a/scripts/tests/install-ai.bats +++ b/scripts/tests/install-ai.bats @@ -149,3 +149,26 @@ EOF [ -d "$TEST_HOME/code/pickme/.ai" ] [ ! -d "$TEST_HOME/code/skipme/.ai" ] } + +@test "install-ai: seeds AGENTS.md at the project root" { + mkdir -p "$TEST_HOME/code/fresh" + (cd "$TEST_HOME/code/fresh" && git init -q) + + run bash "$INSTALL_AI" --gitignore "$TEST_HOME/code/fresh" + + [ "$status" -eq 0 ] + [ -f "$TEST_HOME/code/fresh/AGENTS.md" ] + grep -q "protocols.org" "$TEST_HOME/code/fresh/AGENTS.md" +} + +@test "install-ai: never overwrites an existing AGENTS.md" { + mkdir -p "$TEST_HOME/code/fresh" + (cd "$TEST_HOME/code/fresh" && git init -q) + echo "project-owned entry file" > "$TEST_HOME/code/fresh/AGENTS.md" + + run bash "$INSTALL_AI" --gitignore "$TEST_HOME/code/fresh" + + [ "$status" -eq 0 ] + grep -q "project-owned entry file" "$TEST_HOME/code/fresh/AGENTS.md" + ! grep -q "protocols.org" "$TEST_HOME/code/fresh/AGENTS.md" +} @@ -159,6 +159,9 @@ Make the tooling agent-agnostic instead of Claude-specific. Three threads from C *** 2026-06-24 Wed @ 00:21:20 -0400 Partial — agent-neutral wording sweep + thread-3 note landed Thread 2's wording half shipped in 6ad0442 (=refactor(rules): use agent-neutral language in shared rules=): agent-as-actor phrasing replaced with "the agent" across interaction.md, cross-project.md, triggers.md, working-files.md. Thread 3's note reached =.emacs.d=, whose 2026-06-23 inbox FYI confirms it received and filed the "multi-LLM support" ai-term handoff. Remaining and still TODO: thread 1 (give the agent a name), and thread 2's structural half (extract agent-neutral content into a shared source with a Codex entry-file pointer, then have Codex review the workflows for literal-reading gaps). +*** 2026-07-13 Mon @ 16:04:04 -0500 Thread 2's entry-file half landed via the runtime-portability build +The Codex entry-file pointer now exists: =claude-templates/AGENTS.md= (thin pointer at protocols.org + rules + /name resolution), linked to =~/.codex/AGENTS.md= by =make install= and seeded per-project by =install-ai.sh= (see the generic-agent-runtime parent's 2026-07-13 children). Remaining here: thread 1 (agent naming — the entry file's "you are this project's agent" phrasing is a start, not the whole answer) and the Codex literal-reading review of workflows. + ** TODO [#C] Flashcard tooling improvements :feature: :PROPERTIES: :CREATED: [2026-06-28 Sun] @@ -260,8 +263,8 @@ Codex re-ran spec-review after the dispositions were folded in. Outcome by arc: *** 2026-07-13 Mon @ 13:26:57 -0500 Gap assessment decomposed into child tasks Craig asked what's left to run ChatGPT or a local LLM as the agent. Assessment: the =.ai/= layer (protocols, workflows, scripts, inbox, todo, session anchors) is already runtime-neutral — plain org + bash, and a Codex session has run in it (2026-06-13). The Claude-bound remainder decomposed into the child tasks below; each overlapping spec-blocker decision is named in its body. The phases 2-5 go/no-go above still gates any big build, but several children are useful standalone. -*** TODO Instruction bootstrap per runtime -An install target that emits the non-Claude entry file (=AGENTS.md= for Codex-style agents; assembled system prompt for a local harness) pointing at =protocols.org= and the agent-neutral rules. Resolves the spec's "generic instruction-file strategy" blocker. Overlaps the shared-source thread of the =Multiple agent-source improvements= task (line ~150) — reconcile rather than build twice. +*** 2026-07-13 Mon @ 16:04:04 -0500 Instruction bootstrap built — thin-pointer AGENTS.md, both install paths +Craig picked the thin-pointer shape (Decisions: option 1, definitively). Shipped TDD (bats red → green): canonical =claude-templates/AGENTS.md= (you-are-this-project's-agent + read protocols.org + rules locations + the /name resolution rule from the skill-parity finding + degrade-per-fallback, never skip gates); =make install= links it to =~/.codex/AGENTS.md= (new CODEX_DIR stanza, house skip/WARN/link idiom, covered by NEW =scripts/tests/install-agents-entry.bats=, 3 tests); =install-ai.sh= seeds a project-owned copy at bootstrap, never overwriting (+2 tests in install-ai.bats); rulesets root gets a tracked symlink as dogfood. Resolves the spec's "generic instruction-file strategy" blocker. velox picks up the global link automatically — startup Phase A.0 runs =make install= every session. Existing projects get seeded on demand (no auto-sweep in v1). *** 2026-07-13 Mon @ 14:52:38 -0500 Skill parity resolved — one resolution rule, no per-skill matrix Analysis in [[file:docs/design/2026-07-13-runtime-portability-inventories.org]] (Skill and command parity section). All 29 artifacts (11 skills + 18 commands) are markdown bodies; a single resolution sentence in the bootstrap entry file ("a /name reference resolves to the skill/command file — read and follow it") makes the library portable to any file-reading harness. Auto-invocation degrades to by-name invocation (the publish flow already invokes by name), native slash registration is an optional install nicety, flush is explicitly excluded (session-plumbing child owns it). Folds into the instruction-bootstrap child's build. @@ -1354,4 +1357,4 @@ Added the spec-sort probe to startup.org Phase A (item 12) and the one-line nudg All 13 file:docs/specs/ links lived in todo.org (zero in .ai/ or docs/ outside specs). 11 converted straight to [[id:UUID][label]] (bare links labeled with the spec filename); the 2 links carrying a ::*Review findings search target got full fidelity by minting an :ID: on that heading in the docs-lifecycle spec (cc77a7f6-e4c3-488a-ac3b-e739420a5c2b) — the id index scans whole files, so heading-level ids resolve. Residue grep zero; every id verified against its target's :ID:. Gate had cleared earlier tonight via .emacs.d's org-spec-links.el delivery (verified org-id-find on their side); M-x cj/org-id-refresh-spec-locations is the fix if a fresh id doesn't resolve on click. *** 2026-07-04 Sat @ 11:46:31 -0500 Flipped the spec to IMPLEMENTED -All four build phases had shipped (docs-lifecycle rule + spec-workflow updates, spec-sort helper + 30-test bats suite, rulesets pilot + status board, startup nudge) plus the file:→id: link conversion, so the spec's status heading went DOING → IMPLEMENTED with a dated history line and the Metadata mirror, per the transition-ownership table. Parent closed; manual validation promoted to its own task. +All four build phases had shipped (docs-lifecycle rule + spec-workflow updates, spec-sort helper + 30-test bats suite, rulesets pilot + status board, startup nudge) plus the conversion of file-style links to id-style links, so the spec's status heading went DOING → IMPLEMENTED with a dated history line and the Metadata mirror, per the transition-ownership table. Parent closed; manual validation promoted to its own task. |
