Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,19 @@ Standing Order #3 (vault hygiene) is **in-session, not 'later'**. Every "later"

### Overrides of Harness Defaults (non-negotiable)

These rules **counter agent harness defaults** that would otherwise silently win at runtime (e.g. a CLI whose default appends `Co-Authored-By` to commits). They are re-affirmed here because a default not explicitly overridden is the default that ships. Canonical source: `00_meta/patterns/pattern-git-workflow.md` §6–§7. *(Hand-maintained today; HARNESS-001 (#156) will generate this block from the pattern.)*

* **No AI attribution.** No `Co-Authored-By` trailers, no "Generated with" / "🤖" footers, no bot-style emojis — in commits, PR descriptions, or issue comments. All git/GitHub artifacts must appear human-authored.
* **English only** in git/GitHub artifacts: commit messages, branch names, PR/issue titles and bodies, and code comments. (Conversation with the user may be in any language; the durable record is English.)
* **No internal phase/milestone references** in branch names, commit messages, or PR titles (e.g. `phase-3.1`). Phase tracking lives in the issue tracker, not in git history.
These rules **counter agent harness defaults** that would otherwise silently win at runtime (e.g. a CLI whose default appends `Co-Authored-By` to commits). They are re-affirmed here because a default not explicitly overridden is the default that ships. Canonical source: `00_meta/patterns/pattern-git-workflow.md` §6–§8. *(Generated by the HARNESS engine via `scripts/compile-harness.sh` — edit the vault pattern, then re-run setup. Do NOT edit between the markers.)*

<!-- BEGIN HARNESS GENERATED (sha256:82589eb0b0204879) — SSOT: vault 00_meta/patterns; edit there + re-run setup, do NOT edit between markers -->
- **No AI attribution** in git history or GitHub messages (commits, PRs, issues).
- No `Co-Authored-By` trailers referencing AI agents.
- No bot-style emojis or "Generated with" footers.
- All artifacts must appear human-authored.
- **English only** in git/GitHub artifacts: commit messages, branch names, PR/issue titles and bodies, and code comments. Conversation with the user may be in any language; the durable record is English.
- **No internal phase/milestone references** in branch names, commit messages, or PR titles.
- Bad: `feat/phase-3.1-scaffold`, `chore: scaffold repo (Phase 3.1)`
- Good: `feat/scaffold-pyhydra3d`, `chore: scaffold PyHydra3D repository`
- Phase tracking belongs in the vault backlog (`11-tasks.md`), not in git history.
<!-- END HARNESS GENERATED -->

### Interaction Discipline

Expand Down
13 changes: 12 additions & 1 deletion ai/claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,18 @@ For the full dual-memory protocol, query `00_meta/patterns/pattern-dual-memory.m

## Claude Code Tooling Notes

* **No attribution / English-only (overrides Claude default).** Per `AGENTS.md` § Operational Rules → "Overrides of Harness Defaults": no `Co-Authored-By` / "Generated with" / 🤖 footers on commits, PRs, or issues; English only in git/GitHub artifacts — even when the harness default suggests otherwise.
* **Overrides of harness defaults (generated).** Sourced from the vault via `scripts/compile-harness.sh` — edit the vault pattern + re-run setup, not here:
<!-- BEGIN HARNESS GENERATED (sha256:82589eb0b0204879) — SSOT: vault 00_meta/patterns; edit there + re-run setup, do NOT edit between markers -->
- **No AI attribution** in git history or GitHub messages (commits, PRs, issues).
- No `Co-Authored-By` trailers referencing AI agents.
- No bot-style emojis or "Generated with" footers.
- All artifacts must appear human-authored.
- **English only** in git/GitHub artifacts: commit messages, branch names, PR/issue titles and bodies, and code comments. Conversation with the user may be in any language; the durable record is English.
- **No internal phase/milestone references** in branch names, commit messages, or PR titles.
- Bad: `feat/phase-3.1-scaffold`, `chore: scaffold repo (Phase 3.1)`
- Good: `feat/scaffold-pyhydra3d`, `chore: scaffold PyHydra3D repository`
- Phase tracking belongs in the vault backlog (`11-tasks.md`), not in git history.
<!-- END HARNESS GENERATED -->
* **Skills.** `~/.claude/skills/<skill>/SKILL.md` auto-load via slash commands. Skill auto-loading is a Claude Code feature, not portable. Skill **content** is portable: `AI-012-opencode-commands-port` mechanically transforms each skill into an OpenCode command in `ai/opencode/commands/*.md`.
* **TaskCreate / TaskUpdate / TaskList.** Use for non-trivial multi-step work (≥3 distinct steps). Mark `in_progress` BEFORE starting; mark `completed` immediately on finish. Don't batch updates.
* **AskUserQuestion.** Use for branching decisions with 2-4 mutually exclusive options. Always include "(Recommended)" on the preferred option.
Expand Down
1 change: 1 addition & 0 deletions harness/enforced/english-only.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- **English only** in git/GitHub artifacts: commit messages, branch names, PR/issue titles and bodies, and code comments. Conversation with the user may be in any language; the durable record is English.
4 changes: 4 additions & 0 deletions harness/enforced/no-attribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- **No AI attribution** in git history or GitHub messages (commits, PRs, issues).
- No `Co-Authored-By` trailers referencing AI agents.
- No bot-style emojis or "Generated with" footers.
- All artifacts must appear human-authored.
4 changes: 4 additions & 0 deletions harness/enforced/no-phase-references.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- **No internal phase/milestone references** in branch names, commit messages, or PR titles.
- Bad: `feat/phase-3.1-scaffold`, `chore: scaffold repo (Phase 3.1)`
- Good: `feat/scaffold-pyhydra3d`, `chore: scaffold PyHydra3D repository`
- Phase tracking belongs in the vault backlog (`11-tasks.md`), not in git history.
23 changes: 23 additions & 0 deletions harness/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": 1,
"vault_subpath": "00_meta/patterns",
"enforced": [
{ "id": "no-attribution", "source": "pattern-git-workflow.md#6-attribution-policy" },
{ "id": "english-only", "source": "pattern-git-workflow.md#8-language-policy" },
{ "id": "no-phase-references", "source": "pattern-git-workflow.md#7-message-content-policy" }
],
"targets": [
{
"agent": "agents",
"kind": "native",
"file": "AGENTS.md",
"inject": ["no-attribution", "english-only", "no-phase-references"]
},
{
"agent": "claude",
"kind": "pointer",
"file": "ai/claude/CLAUDE.md",
"inject": ["no-attribution", "english-only", "no-phase-references"]
}
]
}
227 changes: 227 additions & 0 deletions scripts/compile-harness.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#!/usr/bin/env bash
# compile-harness.sh — agent-artifact deploy engine (ENGINE-001 / HARNESS-001 #162).
#
# Compiles enforced vault patterns into a marker-delimited "Overrides of Harness
# Defaults" block inside the deployed agent instruction files. The SSOT is the
# vault (00_meta/patterns); the generated output is COMMITTED so CI and machines
# without the vault can still verify it (ADR-013, builds on ADR-012).
#
# Modes:
# --refresh vault section -> harness/enforced/<id>.md (source-of-record)
# -> injected, marker-delimited, into each target.
# Requires the vault. Asserts per-file line caps. Run by setup.
# --check offline: render from harness/enforced/<id>.md and diff against
# each target's region. NO vault access. Used by CI / healthcheck.
# --help
#
# Spec: specs/ENGINE-001-deploy-engine-core/proposal.md
set -euo pipefail

BEGIN_PREFIX='<!-- BEGIN HARNESS GENERATED'
END_MARKER='<!-- END HARNESS GENERATED -->'

usage() {
cat <<EOF
Usage: compile-harness.sh (--refresh | --check | --help)

--refresh Extract enforced sections from the vault, write source-of-record
files under harness/enforced/, and inject them into each target's
managed region. Requires the vault. Asserts line caps.
--check Offline drift check: render from harness/enforced/ and diff each
target's managed region. No vault needed (CI / healthcheck).
--help This help.
EOF
}

# --- locate repo + inputs ---
if ! REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"; then
printf '[ERROR] not in a git repo\n' >&2
exit 1
fi
MANIFEST="$REPO_ROOT/harness/manifest.json"
RECORD_DIR="$REPO_ROOT/harness/enforced"
VAULT_PATH="${VAULT_PATH:-$HOME/Projects/knowledge}"

require_tools() {
command -v jq >/dev/null 2>&1 || { printf '[ERROR] jq is required\n' >&2; exit 2; }
}

# --- helpers ---

# Extract a markdown section body by GitHub-style heading slug.
# Args: <pattern_file> <slug>. Prints the section body (heading excluded).
extract_section() {
local file="$1" want="$2" out
out="$(awk -v want="$want" '
function slug(s){ s=tolower(s); gsub(/[^a-z0-9 -]/,"",s); gsub(/ +/,"-",s); gsub(/-+/,"-",s); return s }
/^#{1,6} / {
if (cap) { exit }
hdr=$0; sub(/^#{1,6} +/,"",hdr)
if (slug(hdr)==want) { cap=1; next }
}
cap { print }
' "$file")"
if [[ -z "$out" ]]; then
printf '[ERROR] section "%s" not found (or empty) in %s\n' "$want" "$file" >&2
return 1
fi
printf '%s\n' "$out"
}

# Validate a target has exactly one well-ordered BEGIN/END marker pair.
validate_markers() {
local file="$1" b e bl el
b="$(grep -c "^$BEGIN_PREFIX" "$file" 2>/dev/null || true)"
e="$(grep -cF "$END_MARKER" "$file" 2>/dev/null || true)"
if [[ "$b" != "1" || "$e" != "1" ]]; then
printf '[ERROR] %s: need exactly 1 BEGIN + 1 END HARNESS marker (found %s/%s)\n' "$file" "$b" "$e" >&2
return 1
fi
bl="$(grep -n "^$BEGIN_PREFIX" "$file" | head -1 | cut -d: -f1)"
el="$(grep -nF "$END_MARKER" "$file" | head -1 | cut -d: -f1)"
if [[ "$bl" -ge "$el" ]]; then
printf '[ERROR] %s: END marker precedes BEGIN marker\n' "$file" >&2
return 1
fi
}

# Print the content strictly between the markers of a target file.
region_content() {
awk -v b="$BEGIN_PREFIX" -v e="$END_MARKER" '
index($0,b)==1 {inreg=1; next}
$0==e {inreg=0; next}
inreg {print}
' "$1"
}

# Render the expected region for a target: concat of record files, in order.
# Args: id... . Prints to stdout. Fails if a record is missing.
render_region() {
local id
for id in "$@"; do
if [[ ! -f "$RECORD_DIR/$id.md" ]]; then
printf '[ERROR] missing source-of-record: harness/enforced/%s.md (run --refresh)\n' "$id" >&2
return 1
fi
cat "$RECORD_DIR/$id.md"
done
}

# Per-file deployed line cap (0 = no cap).
cap_for() {
case "$1" in
ai/claude/CLAUDE.md) printf '100' ;;
ai/agy/AGY.md) printf '50' ;;
*) printf '0' ;;
esac
}

# Replace a target's managed region with new content + a fresh BEGIN marker.
# Args: <file> <begin_marker> <content_file>
replace_region() {
local file="$1" begin_marker="$2" content_file="$3" tmp rc=0
tmp="$(mktemp)"
if awk -v beginm="$begin_marker" -v endm="$END_MARKER" -v bp="$BEGIN_PREFIX" -v cf="$content_file" '
index($0,bp)==1 {
print beginm
while ((getline l < cf) > 0) print l
close(cf)
skip=1; next
}
$0==endm { if (skip){ print; skip=0; next } }
skip { next }
{ print }
' "$file" > "$tmp"; then rc=0; else rc=$?; fi
if [[ $rc -ne 0 ]]; then rm -f "$tmp"; return $rc; fi
mv "$tmp" "$file"
}

sha_of() { sha256sum "$1" | cut -c1-16; }

target_inject() { jq -r --arg f "$1" '.targets[] | select(.file==$f) | .inject[]' "$MANIFEST"; }

# --- modes ---

do_refresh() {
require_tools
local vsub pat_dir
vsub="$(jq -r '.vault_subpath' "$MANIFEST")"
pat_dir="$VAULT_PATH/$vsub"
if [[ ! -d "$pat_dir" ]]; then
cat >&2 <<EOF
[FATAL] --refresh needs the vault. Patterns dir not found: $pat_dir
-> clone the vault to \$VAULT_PATH (default ~/Projects/knowledge), or set VAULT_PATH.
( --check works offline and needs no vault. )
EOF
exit 2
fi

mkdir -p "$RECORD_DIR"

# 1. vault section -> source-of-record per enforced rule
local id source pat slug body
while IFS=$'\t' read -r id source; do
pat="${source%%#*}"; slug="${source#*#}"
body="$(extract_section "$pat_dir/$pat" "$slug")"
printf '%s\n' "$body" > "$RECORD_DIR/$id.md"
printf '[refresh] record: harness/enforced/%s.md <- %s#%s\n' "$id" "$pat" "$slug"
done < <(jq -r '.enforced[] | "\(.id)\t\(.source)"' "$MANIFEST")

# 2. inject into each target
local file ids tmpc sha begin cap lines
while IFS= read -r file; do
mapfile -t ids < <(target_inject "$file")
validate_markers "$REPO_ROOT/$file"
tmpc="$(mktemp)"
render_region "${ids[@]}" > "$tmpc"
sha="$(sha_of "$tmpc")"
begin="$BEGIN_PREFIX (sha256:$sha) — SSOT: vault $vsub; edit there + re-run setup, do NOT edit between markers -->"
replace_region "$REPO_ROOT/$file" "$begin" "$tmpc"
rm -f "$tmpc"
cap="$(cap_for "$file")"
if [[ "$cap" != "0" ]]; then
lines="$(wc -l < "$REPO_ROOT/$file")"
if [[ "$lines" -gt "$cap" ]]; then
printf '[ERROR] %s is %s lines after injection (cap %s)\n' "$file" "$lines" "$cap" >&2
exit 1
fi
fi
printf '[refresh] injected -> %s (%s)\n' "$file" "$(wc -l < "$REPO_ROOT/$file" | tr -d ' ')L"
done < <(jq -r '.targets[].file' "$MANIFEST")

printf '[refresh] OK\n'
}

do_check() {
require_tools
local file ids drift=0 expected actual
while IFS= read -r file; do
if ! validate_markers "$REPO_ROOT/$file"; then drift=1; continue; fi
mapfile -t ids < <(target_inject "$file")
expected="$(mktemp)"; actual="$(mktemp)"
if ! render_region "${ids[@]}" > "$expected"; then drift=1; rm -f "$expected" "$actual"; continue; fi
region_content "$REPO_ROOT/$file" > "$actual"
if ! diff -u "$expected" "$actual" >/dev/null 2>&1; then
printf '[DRIFT] %s: managed region differs from harness/enforced/ (run --refresh)\n' "$file" >&2
diff -u "$actual" "$expected" | sed 's/^/ /' >&2 || true
drift=1
else
printf '[check] OK -> %s\n' "$file"
fi
rm -f "$expected" "$actual"
done < <(jq -r '.targets[].file' "$MANIFEST")

if [[ "$drift" -ne 0 ]]; then
printf '[check] FAIL: harness drift detected\n' >&2
exit 1
fi
printf '[check] OK: no harness drift\n'
}

# --- dispatch ---
case "${1:-}" in
--refresh) do_refresh ;;
--check) do_check ;;
-h|--help) usage ;;
*) usage >&2; exit 2 ;;
esac
12 changes: 12 additions & 0 deletions scripts/healthcheck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,18 @@ else
skip "diff-check.sh not found at $SCRIPT_DIR/diff-check.sh"
fi

# Harness override drift (ENGINE-001): generated blocks vs their source-of-record.
# Offline (no vault); run from the repo so git resolves regardless of CWD.
if [ -x "$SCRIPT_DIR/compile-harness.sh" ]; then
if ( cd "$DOTFILES_DIR" && "$SCRIPT_DIR/compile-harness.sh" --check ) >/dev/null 2>&1; then
pass "harness override blocks match their source-of-record (no drift)"
else
fail "harness override drift (run: $SCRIPT_DIR/compile-harness.sh --refresh, then re-deploy)"
fi
else
skip "compile-harness.sh not found at $SCRIPT_DIR/compile-harness.sh"
fi

# ==================================================
section "13/13" "Antigravity CLI Health"

Expand Down
14 changes: 14 additions & 0 deletions setup-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,20 @@ fi

log_success "Antigravity CLI configuration complete"

# Harness deploy engine (ENGINE-001 / HARNESS-001): re-render the generated
# "Overrides of Harness Defaults" blocks in AGENTS.md + ai/claude/CLAUDE.md from
# the vault SSOT before deploying agent configs. Committed blocks are the fallback
# when the vault is absent (fresh machine), so this only re-renders when possible.
if [ -d "${VAULT_PATH:-$HOME/Projects/knowledge}/00_meta/patterns" ]; then
if ( cd "$CURRENT_DIR" && "$CURRENT_DIR/scripts/compile-harness.sh" --refresh ) >/dev/null 2>&1; then
log_success "Harness override blocks refreshed from vault SSOT"
else
log_warning "compile-harness --refresh failed; deploying committed blocks"
fi
else
log_info "Vault absent; deploying committed harness override blocks"
fi

# Claude Code
ensure_directory "$HOME/.claude"
ensure_directory "$HOME/.claude/skills"
Expand Down
Loading
Loading