aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
l---------AGENTS.md1
-rw-r--r--Makefile12
-rw-r--r--claude-templates/AGENTS.md19
-rw-r--r--inbox/lint-followups.org1
-rwxr-xr-xscripts/install-ai.sh7
-rw-r--r--scripts/tests/install-agents-entry.bats51
-rw-r--r--scripts/tests/install-ai.bats23
-rw-r--r--todo.org9
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
diff --git a/Makefile b/Makefile
index a6e636f..2d744a1 100644
--- a/Makefile
+++ b/Makefile
@@ -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"
+}
diff --git a/todo.org b/todo.org
index 2ad3709..02215c9 100644
--- a/todo.org
+++ b/todo.org
@@ -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.