Drive all 4 remaining tasks to completion through full lifecycle
CI / build (push) Has been cancelled

- actionable-phase-guidance: lifecycle artifacts + .state->complete
- harden-enforcement-layers: pre-push hook, install-hooks.sh, register-guards.sh, prompt pre-edit checks, harness contract update, install/update/upgrade script integration
- plug-stale-task-hole: lifecycle artifacts + .state->complete
- port-pi-guard: pi dev guard plugin, package.json, register-guards integration

All tasks passed bug_find, adversarial_bug_find, doc_review, and referee phases with PASS verdict.
This commit is contained in:
2026-06-16 07:28:45 -04:00
parent 21f16b7da2
commit 99ddb98861
43 changed files with 775 additions and 44 deletions
-5
View File
@@ -29,11 +29,6 @@ if [ $EXIT_CODE -ne 0 ]; then
echo " python ~/.automaton/scripts/status.py --create-task my-feature --project $PROJECT_ROOT"
echo " python ~/.automaton/scripts/status.py --transition research --task my-feature --project $PROJECT_ROOT"
echo " python ~/.automaton/scripts/status.py --transition implement --task my-feature --project $PROJECT_ROOT"
echo ""
echo "Or use --upgrade to bootstrap .state files for existing tasks:"
echo " python ~/.automaton/scripts/status.py --upgrade --project $PROJECT_ROOT"
echo ""
echo "To bypass this hook (NOT RECOMMENDED): git commit --no-verify"
echo "====================="
exit 1
fi
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# pre-push hook — blocks pushes when no task is in an edit-allowed phase.
#
# Install: cp this file to .git/hooks/pre-push && chmod +x .git/hooks/pre-push
# Or: ln -sf ~/.automaton/scripts/git-hooks/pre-push .git/hooks/pre-push
#
# This catches commits that bypassed the pre-commit hook via --no-verify.
# Combined with disabling force-pushes on the remote, this makes it much
# harder to bypass automaton enforcement.
set -euo pipefail
STATUS_SCRIPT="$HOME/.automaton/scripts/status.py"
if [ ! -f "$STATUS_SCRIPT" ]; then
exit 0
fi
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
# Check if any commits in the push range were made without an active task.
# We use --can-edit to check if a task is currently active.
# If no task is in implement/doc_review, block the push.
python3 "$STATUS_SCRIPT" --can-edit --project "$PROJECT_ROOT" --json 2>/dev/null
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
echo ""
echo "=== PUSH BLOCKED ==="
echo "No task is in an implement or doc_review phase."
echo "This prevents pushing commits that may have bypassed the pre-commit hook."
echo ""
echo "Create a task and transition it to implement before pushing:"
echo ""
echo " python ~/.automaton/scripts/status.py --create-task my-feature --project $PROJECT_ROOT"
echo " python ~/.automaton/scripts/status.py --transition research --task my-feature --project $PROJECT_ROOT"
echo " python ~/.automaton/scripts/status.py --transition implement --task my-feature --project $PROJECT_ROOT"
echo ""
echo "To bypass this hook (NOT RECOMMENDED): git push --no-verify"
echo "====================="
exit 1
fi
exit 0
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# install-hooks.sh — Install automaton git hooks into the current project.
#
# Usage: bash ~/.automaton/scripts/install-hooks.sh [project-path]
#
# Installs pre-commit and pre-push hooks. The pre-commit hook blocks
# commits when no task is in implement/doc_review. The pre-push hook
# blocks pushes in the same condition, catching --no-verify bypasses.
set -euo pipefail
PROJECT_DIR="${1:-$(pwd)}"
GIT_DIR="$PROJECT_DIR/.git"
HOOKS_DIR="$GIT_DIR/hooks"
FRAMEWORK_DIR="$HOME/.automaton"
if [ ! -d "$GIT_DIR" ]; then
echo "ERROR: $PROJECT_DIR is not a git repository (no .git directory)"
exit 1
fi
mkdir -p "$HOOKS_DIR"
HOOKS=(
"pre-commit"
"pre-push"
)
installed=0
for hook in "${HOOKS[@]}"; do
SOURCE="$FRAMEWORK_DIR/scripts/git-hooks/$hook"
TARGET="$HOOKS_DIR/$hook"
if [ ! -f "$SOURCE" ]; then
echo "WARNING: Source hook not found: $SOURCE"
continue
fi
cp "$SOURCE" "$TARGET"
chmod +x "$TARGET"
echo "Installed: $TARGET"
installed=$((installed + 1))
done
echo ""
echo "$installed hook(s) installed in $PROJECT_DIR"
echo ""
echo "Pre-commit: Blocks commits without an active task in implement/doc_review"
echo "Pre-push: Blocks pushes without an active task (catches --no-verify bypasses)"
echo ""
echo "To reinstall after automaton update, re-run this script."
+7 -3
View File
@@ -62,7 +62,11 @@ echo "Installation complete."
echo ""
echo "Next steps:"
echo " 1. cd into a project and run the onboarding prompt"
echo " 2. In each project that uses git, install the pre-commit hook:"
echo " ln -sf ~/.automaton/scripts/git-hooks/pre-commit .git/hooks/pre-commit"
echo " 2. In each project that uses git, install the automaton hooks:"
echo " bash ~/.automaton/scripts/install-hooks.sh /path/to/project"
echo ""
echo "This hook blocks commits when no task is in an edit-allowed phase."
echo "These hooks block commits and pushes when no task is in an edit-allowed phase."
echo ""
# Register pre-edit guards for detected harnesses
bash "$FRAMEWORK_DIR/scripts/register-guards.sh"
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# register-guards.sh — Detect available harnesses and install the appropriate
# automaton pre-edit guards.
#
# Called by install.sh and update.sh during framework setup.
#
# Detection:
# - OpenCode: checks for ~/.config/opencode/opencode.jsonc
# - Pi Dev: checks for `pi` in PATH
#
# Usage: bash ~/.automaton/scripts/register-guards.sh
set -euo pipefail
FRAMEWORK_DIR="$HOME/.automaton"
INSTALLED_OPENCODE=false
INSTALLED_PI=false
echo ""
echo "=== Pre-Edit Guard Registration ==="
# OpenCode guard
OPENCODE_CONFIG="$HOME/.config/opencode/opencode.jsonc"
OPENCODE_SOURCE="$FRAMEWORK_DIR/plugins/automaton-guard"
if [ -f "$OPENCODE_CONFIG" ]; then
if grep -q "automaton-guard" "$OPENCODE_CONFIG" 2>/dev/null; then
echo "OpenCode: already registered"
else
echo "OpenCode: registering guard plugin..."
python3 -c "
import json
with open('$OPENCODE_CONFIG') as f:
cfg = json.load(f)
cfg.setdefault('plugins', []).append('$OPENCODE_SOURCE')
with open('$OPENCODE_CONFIG', 'w') as f:
json.dump(cfg, f, indent=2)
"
INSTALLED_OPENCODE=true
echo "OpenCode: registered (restart opencode to activate)"
fi
else
echo "OpenCode: not detected (no $OPENCODE_CONFIG)"
fi
# Pi Dev guard
PI_SOURCE="$FRAMEWORK_DIR/plugins/automaton-guard-pi"
if command -v pi &>/dev/null; then
INSTALLED=$(pi list 2>/dev/null | grep -c "automaton-guard-pi" || true)
if [ "$INSTALLED" -gt 0 ]; then
echo "Pi Dev: already installed"
else
echo "Pi Dev: installing guard extension..."
pi install "$PI_SOURCE" 2>&1 | sed 's/^/ /'
INSTALLED_PI=true
echo "Pi Dev: installed"
fi
else
echo "Pi Dev: not detected (pi not in PATH)"
fi
echo ""
if $INSTALLED_OPENCODE || $INSTALLED_PI; then
echo "Restart your harness for the guard to take effect."
fi
if ! $INSTALLED_OPENCODE && ! $INSTALLED_PI; then
echo "No harness detected. To install a guard manually:"
echo " OpenCode: add '\"plugins\": [\"$OPENCODE_SOURCE\"]' to $OPENCODE_CONFIG"
echo " Pi Dev: pi install $PI_SOURCE"
echo ""
echo "Without a pre-edit guard, git hooks (pre-commit + pre-push)"
echo "provide enforcement at commit/push time instead."
fi
+16
View File
@@ -56,3 +56,19 @@ fi
echo ""
echo "Update complete."
# Register pre-edit guards for detected harnesses
bash "$FRAMEWORK_DIR/scripts/register-guards.sh"
# Ensure git hooks are installed in current project
if git rev-parse --git-dir &>/dev/null 2>&1; then
HOOK_DIR="$(git rev-parse --git-dir)/hooks"
for hook in pre-commit pre-push; do
HOOK_SRC="$HOME/.automaton/scripts/git-hooks/$hook"
HOOK_DST="$HOOK_DIR/$hook"
if [ -f "$HOOK_SRC" ] && [ ! -f "$HOOK_DST" ]; then
ln -sf "$HOOK_SRC" "$HOOK_DST"
echo "Installed $hook hook"
fi
done
fi
+17 -16
View File
@@ -74,27 +74,28 @@ echo ""
# Install pre-commit hook if project uses git
if git -C "$PROJECT_DIR" rev-parse --git-dir &>/dev/null; then
HOOK_DIR="$(git -C "$PROJECT_DIR" rev-parse --git-dir)/hooks"
HOOK_TARGET="$HOOK_DIR/pre-commit"
HOOK_SOURCE="$FRAMEWORK_DIR/scripts/git-hooks/pre-commit"
# Ensure hooks directory exists
mkdir -p "$HOOK_DIR"
if [ -f "$HOOK_TARGET" ]; then
if [ -L "$HOOK_TARGET" ]; then
EXISTING_TARGET="$(readlink "$HOOK_TARGET")"
if [ "$EXISTING_TARGET" = "$HOOK_SOURCE" ]; then
echo "Pre-commit hook already linked to automaton."
for HOOK in pre-commit pre-push; do
HOOK_TARGET="$HOOK_DIR/$HOOK"
HOOK_SOURCE="$FRAMEWORK_DIR/scripts/git-hooks/$HOOK"
if [ -f "$HOOK_TARGET" ]; then
if [ -L "$HOOK_TARGET" ]; then
EXISTING_TARGET="$(readlink "$HOOK_TARGET")"
if [ "$EXISTING_TARGET" = "$HOOK_SOURCE" ]; then
echo "$HOOK hook already linked to automaton."
else
echo "WARNING: $HOOK hook already exists (symlink to: $EXISTING_TARGET)"
echo " To use automaton's hook, run: ln -sf $HOOK_SOURCE $HOOK_TARGET"
fi
else
echo "WARNING: pre-commit hook already exists (symlink to: $EXISTING_TARGET)"
echo " To use automaton's hook, run: ln -sf $HOOK_SOURCE $HOOK_TARGET"
echo "WARNING: $HOOK hook already exists at $HOOK_TARGET"
echo " To replace it with automaton's hook, run: ln -sf $HOOK_SOURCE $HOOK_TARGET"
fi
else
echo "WARNING: pre-commit hook already exists at $HOOK_TARGET"
echo " To replace it with automaton's hook, run: ln -sf $HOOK_SOURCE $HOOK_TARGET"
ln -sf "$HOOK_SOURCE" "$HOOK_TARGET"
echo "Installed $HOOK hook at $HOOK_TARGET"
fi
else
ln -sf "$HOOK_SOURCE" "$HOOK_TARGET"
echo "Installed pre-commit hook at $HOOK_TARGET"
fi
done
else
echo "NOTE: Not a git repository. Install the hook manually if needed:"
echo " ln -sf $FRAMEWORK_DIR/scripts/git-hooks/pre-commit .git/hooks/pre-commit"