From e15581a7540ca62885f9544503a1121ff1cd8168 Mon Sep 17 00:00:00 2001
From: "clagentic-builder[bot]"
<290147524+clagentic-builder[bot]@users.noreply.github.com>
Date: Sun, 19 Jul 2026 15:32:52 -0400
Subject: [PATCH 1/2] fix(docs): remove leaked deployment values from sidecar
worked example (lr-f1e995)
The worked example in SIDECAR-READ-CONTRACT.md (added by lr-61cc4a)
embedded local/retired deployment values in a public doc:
file_prefix: crew-agent-spawn- (retired pre-lr-6fd8f4; the live prefix is
subagent-) and session_id_env: CREW_SPAWN_AGENT_ID (a local harness var).
Rewrite the spawn-scoped entry to neutral placeholders matching the style
already used in docs/SETUP.md, and reword the surrounding prose so it no
longer frames the example as "Gatekeeper's own deployed configuration
cited as a concrete instance" -- the spec defect was the instruction to
copy local config into a public doc. Public docs carry generalized shapes
only; local implementations live in deployed config, not here.
Cross-ref: lr-61cc4a (PR #21 introduced the defect).
---
docs/SIDECAR-READ-CONTRACT.md | 46 +++++++++++++++++------------------
1 file changed, 22 insertions(+), 24 deletions(-)
diff --git a/docs/SIDECAR-READ-CONTRACT.md b/docs/SIDECAR-READ-CONTRACT.md
index 29c71f4..f5159d1 100644
--- a/docs/SIDECAR-READ-CONTRACT.md
+++ b/docs/SIDECAR-READ-CONTRACT.md
@@ -16,9 +16,8 @@ harness exists.
**No tool names are normative here.** Directory paths, filename prefixes, and
environment variable names below are illustrative placeholders. Section
-"Worked example" cites one deployed configuration and one reference
-implementation to make the shapes concrete — it documents an example, not a
-required naming scheme.
+"Worked example" cites one reference implementation to make the shapes
+concrete — it documents an example, not a required naming scheme.
## Convention, not coupling
@@ -172,14 +171,17 @@ it.
## Worked example (illustrative — not normative naming)
-Clagentic: Gatekeeper's own deployed configuration and Go reference
-implementation are cited here as one concrete instance of the shapes above.
-Nothing in this section is a required name, path, or environment variable
-for any other consumer.
+Clagentic: Gatekeeper's Go reference implementation is cited here to show
+one way the shapes above can be implemented. The config snippet below uses
+the same field names as `config.example.yaml`'s `attestation.sidecars`,
+but the directory, prefix, and env-var values are illustrative
+placeholders only — not any deployment's actual configuration. Nothing in
+this section is a required name, path, or environment variable for any
+other consumer; per section 6, those values always come from each
+consumer's own config.
**Config shape** (same fields as `config.example.yaml`'s
-`attestation.sidecars`, reordered here to lead with spawn-first per
-section 2 — see the note below on Gatekeeper's currently deployed order):
+`attestation.sidecars`, ordered spawn-first per section 2):
```yaml
attestation:
@@ -187,30 +189,26 @@ attestation:
# Spawn-scoped namespace — checked first, per section 2's spawn-first
# resolution order. Short-lived subagent invocations, one file per
# concurrent spawn.
- - dir: /tmp
- file_prefix: crew-agent-spawn-
- session_id_env: CREW_SPAWN_AGENT_ID
+ - dir:
+ file_prefix:
+ session_id_env:
# Session-scoped namespace — checked second. A lead/interactive
- # process. Owned by LORE; prefix is not renamed (see section 7 above).
- - dir: /tmp
- file_prefix: lore-agent-name-
- session_id_env: CLAUDE_CODE_SESSION_ID
+ # process. If pointed at LORE's session sidecar, its prefix is not
+ # renamed (see section 7 above).
+ - dir:
+ file_prefix:
+ session_id_env:
```
Both `dir`, `file_prefix`, and the id-env-var name are ordinary config
-values (section 6) — nothing about `/tmp`, `lore-agent-name-`, or
-`CLAUDE_CODE_SESSION_ID` is hardcoded in Gatekeeper's Go source.
+values (section 6) — a consumer's Go (or other language) source never
+hardcodes them.
The order above follows section 2's spawn-first resolution
recommendation. A local deployment MAY choose a different order as its own
config decision — the list order is read straight from `config.yaml` and
Gatekeeper's chain does not enforce spawn-before-session itself (see
-"Reference read implementation" below). Gatekeeper's own currently
-deployed `config.example.yaml` lists the session-scoped entry first; that
-is a config ordering value to reconcile locally against section 2 (a
-separate, non-doc change), and does not change the contract itself. This
-worked example leads with spawn-first so it illustrates the contract's own
-recommendation rather than appearing to contradict it.
+"Reference read implementation" below).
**Reference read implementation**
([`internal/attestation/sidecar.go`](../internal/attestation/sidecar.go)):
From c892595cfe2b3010a150f7a9a7202b580b5dbe10 Mon Sep 17 00:00:00 2001
From: "clagentic-builder[bot]"
<290147524+clagentic-builder[bot]@users.noreply.github.com>
Date: Sun, 19 Jul 2026 15:39:09 -0400
Subject: [PATCH 2/2] fix(config): remove remaining retired spawn-prefix
references (lr-f1e995)
Scope amendment on lr-f1e995 (comment #1, operator directive) widened
this task from the docs-only fix to remove ALL remaining
crew-agent-spawn-/CREW_SPAWN_AGENT_ID references repo-wide.
- config.example.yaml: replace the retired file_prefix and local
session_id_env in the illustrative dual-namespace sidecar block with
neutral/fictional placeholder values (spawn- / MY_HARNESS_SPAWN_ID),
and update the explanatory comment to match.
- internal/attestation/chain_test.go, internal/config/config_test.go,
cmd/gatekeeper/main_test.go: rename the fixture prefix/env-var
consistently across path literals, FilePrefix fields, session_id_env
values, and assertions.
make check (go vet + go test ./...) is green.
---
cmd/gatekeeper/main_test.go | 4 ++--
config.example.yaml | 12 +++++++-----
internal/attestation/chain_test.go | 10 +++++-----
internal/config/config_test.go | 8 ++++----
4 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/cmd/gatekeeper/main_test.go b/cmd/gatekeeper/main_test.go
index 5c591fa..27a15d1 100644
--- a/cmd/gatekeeper/main_test.go
+++ b/cmd/gatekeeper/main_test.go
@@ -320,7 +320,7 @@ func TestRunMint_MultipleSidecarsConfig_SecondResolves(t *testing.T) {
const spawnEnv = "GATEKEEPER_TEST_MAIN_SPAWN_LR86779F"
t.Setenv(spawnEnv, "spawn-main-1")
- spawnPath := filepath.Join(spawnDir, "crew-agent-spawn-spawn-main-1")
+ spawnPath := filepath.Join(spawnDir, "spawn-spawn-main-1")
if err := os.WriteFile(spawnPath, []byte("peaches"), 0o600); err != nil {
t.Fatalf("setup: write spawn sidecar file: %v", err)
}
@@ -346,7 +346,7 @@ attestation:
file_prefix: lore-agent-name-
session_id_env: GATEKEEPER_TEST_MAIN_SESSION_LR86779F_UNSET
- dir: `+spawnDir+`
- file_prefix: crew-agent-spawn-
+ file_prefix: spawn-
session_id_env: `+spawnEnv+`
`)
diff --git a/config.example.yaml b/config.example.yaml
index 670824a..b8ec96d 100644
--- a/config.example.yaml
+++ b/config.example.yaml
@@ -51,16 +51,18 @@ attestation:
# spawned subagents. The example below shows both — a session-scoped
# namespace (crew-manifest's write-agent-sidecar.sh,
# /tmp/lore-agent-name-, keyed on CLAUDE_CODE_SESSION_ID)
- # and a per-spawn namespace (/tmp/crew-agent-spawn-, keyed on
- # CREW_SPAWN_AGENT_ID) — but nothing here hardcodes either plugin as a
- # dependency; leave the list empty to disable this layer entirely.
+ # and a per-spawn namespace (/tmp/spawn-, keyed on
+ # MY_HARNESS_SPAWN_ID — a fictional example var; substitute your own
+ # harness's per-spawn env var name) — but nothing here hardcodes either
+ # plugin as a dependency; leave the list empty to disable this layer
+ # entirely.
sidecars:
- dir: /tmp
file_prefix: lore-agent-name-
session_id_env: CLAUDE_CODE_SESSION_ID
- dir: /tmp
- file_prefix: crew-agent-spawn-
- session_id_env: CREW_SPAWN_AGENT_ID
+ file_prefix: spawn-
+ session_id_env: MY_HARNESS_SPAWN_ID
# Deprecated: the legacy singular `sidecar:` block (dir/file_prefix/
# session_id_env) is still accepted for back-compat and, when fully
# configured, is tried before the `sidecars:` list above. New
diff --git a/internal/attestation/chain_test.go b/internal/attestation/chain_test.go
index f0e051b..cfc90d8 100644
--- a/internal/attestation/chain_test.go
+++ b/internal/attestation/chain_test.go
@@ -103,7 +103,7 @@ func TestNewChain_MultipleSidecars_FirstMatchWins(t *testing.T) {
if err := os.WriteFile(sessionPath, []byte("holden"), 0o600); err != nil {
t.Fatalf("setup: write session sidecar file: %v", err)
}
- spawnPath := filepath.Join(spawnDir, "crew-agent-spawn-spawn-9")
+ spawnPath := filepath.Join(spawnDir, "spawn-spawn-9")
if err := os.WriteFile(spawnPath, []byte("peaches"), 0o600); err != nil {
t.Fatalf("setup: write spawn sidecar file: %v", err)
}
@@ -117,7 +117,7 @@ func TestNewChain_MultipleSidecars_FirstMatchWins(t *testing.T) {
},
{
Dir: spawnDir,
- FilePrefix: "crew-agent-spawn-",
+ FilePrefix: "spawn-",
SessionIDEnv: spawnEnv,
},
},
@@ -150,7 +150,7 @@ func TestNewChain_MultipleSidecars_FirstDeclinesSecondResolves(t *testing.T) {
os.Unsetenv(sessionEnv)
t.Setenv(spawnEnv, "spawn-10")
- spawnPath := filepath.Join(spawnDir, "crew-agent-spawn-spawn-10")
+ spawnPath := filepath.Join(spawnDir, "spawn-spawn-10")
if err := os.WriteFile(spawnPath, []byte("bobbie"), 0o600); err != nil {
t.Fatalf("setup: write spawn sidecar file: %v", err)
}
@@ -164,7 +164,7 @@ func TestNewChain_MultipleSidecars_FirstDeclinesSecondResolves(t *testing.T) {
},
{
Dir: spawnDir,
- FilePrefix: "crew-agent-spawn-",
+ FilePrefix: "spawn-",
SessionIDEnv: spawnEnv,
},
},
@@ -204,7 +204,7 @@ func TestNewChain_MultipleSidecars_BothAbsent_BuiltinFallback(t *testing.T) {
},
{
Dir: spawnDir,
- FilePrefix: "crew-agent-spawn-",
+ FilePrefix: "spawn-",
SessionIDEnv: spawnEnv,
},
},
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index e7fb823..2d6955e 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -201,8 +201,8 @@ attestation:
file_prefix: lore-agent-name-
session_id_env: CLAUDE_CODE_SESSION_ID
- dir: /tmp
- file_prefix: crew-agent-spawn-
- session_id_env: CREW_SPAWN_AGENT_ID
+ file_prefix: spawn-
+ session_id_env: MY_HARNESS_SPAWN_ID
`)
cfg, err := Load(path)
@@ -216,8 +216,8 @@ attestation:
if cfg.Attestation.Sidecars[0].FilePrefix != "lore-agent-name-" {
t.Errorf("Sidecars[0].FilePrefix = %q, want %q", cfg.Attestation.Sidecars[0].FilePrefix, "lore-agent-name-")
}
- if cfg.Attestation.Sidecars[1].FilePrefix != "crew-agent-spawn-" {
- t.Errorf("Sidecars[1].FilePrefix = %q, want %q", cfg.Attestation.Sidecars[1].FilePrefix, "crew-agent-spawn-")
+ if cfg.Attestation.Sidecars[1].FilePrefix != "spawn-" {
+ t.Errorf("Sidecars[1].FilePrefix = %q, want %q", cfg.Attestation.Sidecars[1].FilePrefix, "spawn-")
}
resolved := cfg.Attestation.ResolveSidecars()