aboutsummaryrefslogtreecommitdiff
path: root/.ai/scripts
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-30 21:48:13 -0500
committerCraig Jennings <c@cjennings.net>2026-05-30 21:48:13 -0500
commit143feda0644d2289954b694f3ce4cee2fc74b808 (patch)
tree539452f3e7a47b24b2e9a0dd9a98e1e9c67f30a3 /.ai/scripts
parent9a1bea9bfc066312bf9743dc23c88f191a36cc16 (diff)
downloadrulesets-143feda0644d2289954b694f3ce4cee2fc74b808.tar.gz
rulesets-143feda0644d2289954b694f3ce4cee2fc74b808.zip
feat(session-context): resolve the active path per AI_AGENT_ID
A single .ai/session-context.org races when two agents share a project: each agent's writes clobber the other's session log. I added .ai/scripts/session-context-path, which resolves the active path from AI_AGENT_ID: unset gives the legacy .ai/session-context.org singleton (so every existing one-agent session is unchanged), set gives .ai/session-context.d/<id>.org with the id sanitized to filename-safe characters. This is Codex's Phase 1 slice from the runtime-neutral spec: the race fix on its own, no broader refactor. startup.org's existence check and wrap-it-up.org's rename now resolve through the helper, each with a singleton fallback so older checkouts that haven't synced the script still work. Wrap folds the agent id into the archive name so two agents wrapping in the same minute don't collide. protocols.org documents the rule. Verified with 5 bats cases and a two-agent simulation showing distinct paths per id.
Diffstat (limited to '.ai/scripts')
-rwxr-xr-x.ai/scripts/session-context-path25
-rw-r--r--.ai/scripts/tests/session-context-path.bats40
2 files changed, 65 insertions, 0 deletions
diff --git a/.ai/scripts/session-context-path b/.ai/scripts/session-context-path
new file mode 100755
index 0000000..8cc56f6
--- /dev/null
+++ b/.ai/scripts/session-context-path
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# session-context-path — print the active session-context path for this agent.
+#
+# Single-agent (AI_AGENT_ID unset or empty): .ai/session-context.org — the
+# historical singleton path, unchanged, so one-agent-per-project sessions
+# behave exactly as before (Codex spec's compatibility rule).
+#
+# Multi-agent (AI_AGENT_ID set): .ai/session-context.d/<id>.org, so two agents
+# running in the same project at the same time keep separate session logs
+# instead of clobbering the singleton. The id is sanitized to filename-safe
+# characters so a stray value can't escape the .d/ directory.
+#
+# Workflows call this to resolve the path; both startup (existence check) and
+# wrap-up (rename source) read/write through it. Callers should fall back to
+# .ai/session-context.org if this script isn't present yet (older checkouts
+# mid-sync).
+set -euo pipefail
+
+id="${AI_AGENT_ID:-}"
+if [ -n "$id" ]; then
+ safe=$(printf '%s' "$id" | tr -c 'A-Za-z0-9._-' '_')
+ printf '.ai/session-context.d/%s.org\n' "$safe"
+else
+ printf '.ai/session-context.org\n'
+fi
diff --git a/.ai/scripts/tests/session-context-path.bats b/.ai/scripts/tests/session-context-path.bats
new file mode 100644
index 0000000..ea8937d
--- /dev/null
+++ b/.ai/scripts/tests/session-context-path.bats
@@ -0,0 +1,40 @@
+#!/usr/bin/env bats
+# Tests for the session-context-path helper: resolve the active session-context
+# path from AI_AGENT_ID, defaulting to the legacy singleton.
+
+setup() {
+ SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
+ SCP="$SCRIPT_DIR/session-context-path"
+}
+
+@test "session-context-path: no AI_AGENT_ID gives the legacy singleton" {
+ run env -u AI_AGENT_ID "$SCP"
+ [ "$status" -eq 0 ]
+ [ "$output" = ".ai/session-context.org" ]
+}
+
+@test "session-context-path: empty AI_AGENT_ID gives the legacy singleton" {
+ AI_AGENT_ID="" run "$SCP"
+ [ "$status" -eq 0 ]
+ [ "$output" = ".ai/session-context.org" ]
+}
+
+@test "session-context-path: a set AI_AGENT_ID gives a per-agent file" {
+ AI_AGENT_ID="pearl.org-drill.claude.a83f" run "$SCP"
+ [ "$status" -eq 0 ]
+ [ "$output" = ".ai/session-context.d/pearl.org-drill.claude.a83f.org" ]
+}
+
+@test "session-context-path: two distinct ids resolve to distinct files" {
+ a=$(AI_AGENT_ID="claude" "$SCP")
+ b=$(AI_AGENT_ID="local-qwen" "$SCP")
+ [ "$a" = ".ai/session-context.d/claude.org" ]
+ [ "$b" = ".ai/session-context.d/local-qwen.org" ]
+ [ "$a" != "$b" ]
+}
+
+@test "session-context-path: unsafe id characters are sanitized" {
+ AI_AGENT_ID="a b/c" run "$SCP"
+ [ "$status" -eq 0 ]
+ [ "$output" = ".ai/session-context.d/a_b_c.org" ]
+}