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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,5 @@ docs/superpowers/

# Internal benchmark scratch configs/logs/results
.archie-bench/

.venv-test/
5 changes: 4 additions & 1 deletion archie/assets/gitignore.default
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ tmp/
# them. EXCEPTION: the small hook-runtime set below is committed so the
# enforcement hooks keep working even without a local Archie install. Their file
# reads are routed through one validated sink (_common.safe_read_text), so a
# security scanner has nothing to flag.
# security scanner has nothing to flag. intent_review.py is committed for the same
# reason — the Intent Review GitHub Action runs `python3 .archie/intent_review.py`
# in CI, where no Archie install exists to regenerate it.
*.py
!_common.py
!lint_gate.py
!align_check.py
!arch_review.py
!intent_review.py
99 changes: 99 additions & 0 deletions archie/assets/setup-archie-intent-review.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env bash
# setup-archie-intent-review.sh
#
# Idempotent setup for the Archie Intent Review GitHub Action.
# Prereq checks, secure secret setup, workflow install (copies the canonical
# YAML — no embedded duplicate), Actions probe, fork-PR caveat.
#
# Usage: bash setup-archie-intent-review.sh
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="${REPO_ROOT:-.}"
WORKFLOW_FILE="${REPO_ROOT}/.github/workflows/archie-intent-review.yml"

log_info() { echo -e "${BLUE}i ${NC}$*"; }
log_success() { echo -e "${GREEN}OK ${NC}$*"; }
log_warn() { echo -e "${YELLOW}! ${NC}$*"; }
log_error() { echo -e "${RED}x ${NC}$*"; }
die() { log_error "$1"; exit 1; }

# Resolve the canonical workflow YAML (single source of truth). Priority:
# 1. .archie/workflows/ (if the npx bundle ever places it there)
# 2. <script dir>/workflows/ (running from a checked-out asset bundle)
resolve_workflow_src() {
local candidates=(
"${REPO_ROOT}/.archie/workflows/archie-intent-review.yml"
"${SCRIPT_DIR}/workflows/archie-intent-review.yml"
)
for c in "${candidates[@]}"; do
if [ -f "$c" ]; then printf '%s\n' "$c"; return 0; fi
done
return 1
}

# ===== SECTION 1: PREREQUISITES =====
log_info "Checking prerequisites..."

git rev-parse --git-dir >/dev/null 2>&1 || die "Not inside a git repository. Run from the repo root."
log_success "Inside a git repository"

git config --get remote.origin.url >/dev/null 2>&1 || die "No 'origin' remote found."
log_success "Git remote 'origin' found"

command -v gh >/dev/null 2>&1 || die "gh CLI not found. Install from https://github.com/cli/cli or 'brew install gh'."
log_success "gh CLI is installed ($(gh --version | head -1))"

gh auth status >/dev/null 2>&1 || die "gh CLI not authenticated. Run 'gh auth login' first."
GITHUB_ACCOUNT="$(gh api user --jq .login)"
log_success "gh authenticated as ${GITHUB_ACCOUNT}"

[ -f "${REPO_ROOT}/.archie/blueprint.json" ] || die ".archie/blueprint.json not found. Run '/archie-deep-scan' first to establish the baseline."
log_success ".archie/blueprint.json baseline exists"

WORKFLOW_SRC="$(resolve_workflow_src)" || die "Canonical workflow YAML not found (looked in .archie/workflows/ and ${SCRIPT_DIR}/workflows/). Reinstall archie assets."
log_success "Canonical workflow YAML resolved: ${WORKFLOW_SRC}"

# ===== SECTION 2: SECRET SETUP =====
log_info "Setting up ANTHROPIC_API_KEY secret (available to GitHub Actions on this repo)..."
printf 'Enter your ANTHROPIC_API_KEY (will not be displayed): '
read -rs ANTHROPIC_API_KEY
echo ""
[ -n "$ANTHROPIC_API_KEY" ] || die "ANTHROPIC_API_KEY cannot be empty."

printf '%s' "$ANTHROPIC_API_KEY" | gh secret set ANTHROPIC_API_KEY
unset ANTHROPIC_API_KEY
log_success "ANTHROPIC_API_KEY secret set (stored encrypted on GitHub)"

# ===== SECTION 3: WORKFLOW INSTALL (copy canonical, no heredoc) =====
log_info "Installing workflow file..."
mkdir -p "$(dirname "$WORKFLOW_FILE")"
cp "$WORKFLOW_SRC" "$WORKFLOW_FILE"
log_success "Workflow installed at ${WORKFLOW_FILE} (byte-identical to canonical)"

# ===== SECTION 4: ACTIONS ENABLEMENT PROBE (advisory) =====
log_info "Probing GitHub Actions (advisory only)..."
REPO_SLUG="$(git config --get remote.origin.url | sed 's|.*github.com[:/]||; s|\.git$||')"
if gh workflow list -R "$REPO_SLUG" >/dev/null 2>&1; then
log_success "Actions appear enabled (probe is advisory; verify in repo settings if unsure)"
else
log_warn "Could not verify Actions status — you may need to enable Actions on GitHub"
fi

# ===== SECTION 5: SUMMARY & CAVEATS =====
log_success "Setup complete."
echo ""
echo "Next steps:"
echo " 1. Commit .github/workflows/archie-intent-review.yml"
echo " 2. Push and open a PR"
echo " 3. The Action posts an FYI comment on the PR"
echo ""
echo -e "${YELLOW}Fork PR limitation:${NC}"
echo " - Uses the 'pull_request' event (non-blocking FYI)."
echo " - Fork PRs cannot access repo secrets; the Action skips silently on them."
echo " - To cover fork PRs, 'pull_request_target' is a security tradeoff (out of scope)."
echo ""
log_info "To rotate the key later: gh secret set ANTHROPIC_API_KEY"
log_info "Design doc: docs/archie-intent-review-design.md"
19 changes: 14 additions & 5 deletions archie/assets/workflow/sync/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ echo '<your JSON array>' | python3 .archie/sync.py record .
(Add `--agent claude` under Claude Code, or `--agent codex` under Codex, to tag the
record's provenance.)

A statement is **eligible** to fold only if `confidence: medium|high`, `reconstructed:
false`, and grounded in a file inside the diff; else it's `staged` (provisional).
A statement is **eligible** to fold only if it is a DESCRIPTIVE kind (the mirror) AND
`confidence: medium|high`, `reconstructed: false`, and grounded in a file inside the diff.
ADVISORY kinds (`decision`/`pitfall`/`rule`/`guideline`) are ALWAYS `staged` — the contract
(the law) changes only deliberately, never via a code-fold. Everything else is `staged`.

## Phase 2 — reconcile eligible statements into the snapshot

Expand All @@ -77,13 +79,20 @@ For each statement, read the target section of the CURRENT snapshot and pick ONE
- **ADD** — not represented → add it to the right section.
- **REMOVE** — the section describes behavior the code no longer has → remove/correct it.

Where edits land (descriptive = the headline):
Where edits land — **the descriptive MIRROR only** (what the code is now):
- `behavior`/`structure` → `.archie/blueprint.json` `components[]` (responsibilities) / `communication`
- `dataflow` → `communication`, `architecture_diagram`
- `data` → `data_models` / `persistence_stores` / `data_overview`
- `tech` → `technology` · `reference` → `quick_reference`
- advisory: `decision` → `decisions` · `pitfall` → `pitfalls` + a verifier entry in
`.archie/findings.json` · `rule` → `.archie/rules.json`

**Don't AUTO-change the CONTRACT (the law).** Advisory claims (`decision`/`pitfall`/`rule`/
`guideline`) are recorded `staged` and surface under `staged_amendments` in `fold-context` —
proposed changes for a separate, deliberate decision, NOT something the code-fold applies.
The fold reconciles the descriptive **mirror only**. If the law genuinely changes during the
work, change it **deliberately** (edit `rules.json` / `domain_invariants` on purpose) —
`fold-apply` allows it but reports `contract_changed` so the law never moves *silently*.
(Why: the PR Intent Review catches code-vs-law drift; the law must move deliberately and
visibly, never as a silent side effect of reconciling code.)

Then **reconcile the intent layer**: for each touched folder in `intent_files`, update the
**descriptive (AI-authored) section** of that folder's CLAUDE.md to match the code now —
Expand Down
29 changes: 29 additions & 0 deletions archie/assets/workflows/archie-intent-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Archie Intent Review
on:
pull_request:
types: [opened, synchronize]

permissions:
pull-requests: write
contents: read

jobs:
intent-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0

- uses: actions/setup-python@v6
with:
python-version: '3.11'

# No `git fetch` needed: with fetch-depth:0 the PR base SHA
# (github.event.pull_request.base.sha) is already in history, and the script
# diffs against it directly — so there is no origin/<base> resolution to fail.
- name: Run Archie Intent Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python3 .archie/intent_review.py
1 change: 1 addition & 0 deletions archie/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def _resolve_targets(requested: list[str] | None, connectors: list[Connector]) -
"analytics.py", "config.py",
"update_check.py", "upload.py", "share_setup.py", "refresh.py",
"viewer.py", "install_hooks.py", "_common.py", "sync.py",
"intent_review.py",
]


Expand Down
Loading
Loading