diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index b4eda98..3d8124f 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -38,6 +38,17 @@ "source": "./astro-builder", "category": "development" }, + { + "name": "autopilot", + "description": "Autonomous operation layer for static content sites. Intentions live as pinned GitHub issues, a scheduled strategist session files tasks, GitHub Actions executors open PRs, and green-gated PRs merge themselves within a configurable autonomy boundary. Uses content-ops, content-seo, and astro-builder as its action library.", + "version": "1.0.0", + "author": { + "name": "pcamarajr", + "email": "eu@pcamarajr.dev" + }, + "source": "./autopilot", + "category": "automation" + }, { "name": "content-seo", "description": "Site-level SEO intelligence layer for static content sites. Powered by Google Search Console — tracks performance, surfaces ranking opportunities, diagnoses pages with live data, and injects keyword briefs into the content creation pipeline.", diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index 28671df..5485109 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -20,6 +20,7 @@ jobs: scopes: | astro-builder astro-lsp + autopilot content-image-gemini content-ops content-seo diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 766be98..1aa0459 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,6 +1,7 @@ { "astro-builder": "1.9.0", "astro-lsp": "1.0.1", + "autopilot": "1.0.0", "content-image-gemini": "1.0.0", "content-ops": "0.7.0", "content-seo": "2.0.0", diff --git a/README.md b/README.md index ab814f1..3fa8045 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Then install the plugin you need: /plugin install content-image-gemini@content-stack /plugin install astro-builder@content-stack /plugin install astro-lsp@content-stack +/plugin install autopilot@content-stack /plugin install cost-tracker@content-stack ``` @@ -132,6 +133,19 @@ Install: /plugin install astro-lsp@content-stack ``` +### [`autopilot`](./autopilot/README.md) + +Autonomous operation layer for static content sites. Intentions are pinned GitHub issues you approve; a scheduled strategist files tasks, GitHub Actions executors open PRs, and green-gated content PRs merge themselves within a configurable autonomy boundary. + +- **Best for:** running a content site hands-off while keeping direction human +- **Status:** design-complete, v1 in progress — see [`docs/architecture.md`](./autopilot/docs/architecture.md) + +Install: + +```bash +/plugin install autopilot@content-stack +``` + ### [`cost-tracker`](./cost-tracker/README.md) Session-level token and cost tracking for Claude Code, including subagent runs. diff --git a/autopilot/.claude-plugin/plugin.json b/autopilot/.claude-plugin/plugin.json new file mode 100644 index 0000000..992528d --- /dev/null +++ b/autopilot/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "autopilot", + "description": "Autonomous operation layer for static content sites. Intentions live as pinned GitHub issues, a scheduled strategist session files tasks, GitHub Actions executors open PRs, and green-gated PRs merge themselves within a configurable autonomy boundary. Uses content-ops, content-seo, and astro-builder as its action library.", + "author": { + "name": "pcamarajr", + "email": "eu@pcamarajr.dev" + }, + "homepage": "https://github.com/pcamarajr/content-stack", + "repository": "https://github.com/pcamarajr/content-stack", + "license": "MIT" +} diff --git a/autopilot/README.md b/autopilot/README.md new file mode 100644 index 0000000..89bb4af --- /dev/null +++ b/autopilot/README.md @@ -0,0 +1,42 @@ +# autopilot + +Autonomous operation layer for static content sites. You set intention; the system runs +the site — evaluate → propose → execute → gate → merge → report. + +> **Status: design-complete, v1 in progress.** The architecture is locked +> (see [`docs/architecture.md`](./docs/architecture.md)); the skills and workflows are +> being built milestone by milestone. Not yet usable end to end. + +## How it works + +- **Control plane = GitHub.** Intentions are pinned issues (goal / metric / horizon / + constraints) that you approve with a label. Tasks are sub-issues of approved + intentions — that traceability chain is the autonomy boundary. +- **Brain:** a scheduled Claude cloud session reads committed metrics and open + intentions, then files task sub-issues. +- **Hands:** GitHub Actions + `claude-code-action` execute tasks, open PRs, and run + gates (build, audit, anti-slop). +- **Autonomy boundary as config:** `.autopilot/config.yml` `merge_policy` decides what + auto-merges on green gates. v1 default: content and translation PRs auto-merge; code + and strategy changes wait for you. +- **Action library:** `content-ops`, `content-seo`, and `astro-builder` do the actual + writing, measuring, and building. + +## Planned skills + +| Skill | Purpose | +| --- | --- | +| `init` | Scaffold a target repo: labels, issue templates, `.autopilot/config.yml`, Actions workflows | + +## Requirements + +- A GitHub repo for the target site (the control plane) +- `content-ops`, `content-seo`, and `astro-builder` installed on the site +- A Google Search Console service account key in the repo's Actions secrets (for the + metrics loop) + +## Install + +```bash +/plugin install autopilot@content-stack +``` diff --git a/autopilot/docs/architecture.md b/autopilot/docs/architecture.md new file mode 100644 index 0000000..0b427f0 --- /dev/null +++ b/autopilot/docs/architecture.md @@ -0,0 +1,144 @@ +# Architecture — the autopilot design record + +Canonical record of the design locked on 2026-07-27 after a full grilling session. +Every structural decision below was stress-tested in that interview; do not re-litigate +without new evidence. Where a question was left open, it is listed as open — flagged, +not forgotten. + +**What autopilot is:** the layer that turns content-stack from a skill library into an +agent-running application. The owner sets *intention*; the system runs the site itself — +evaluate → propose → execute → gate → merge → report. Direction stays human; operation +becomes autonomous. + +--- + +## 1 — Core decisions + +### 1.1 Control plane = GitHub + +All coordination state lives on the target site's GitHub repo: Issues, labels, sub-issues, +PRs, Discussions, Actions, webhooks. Alternatives (Resend, Linear) were explicitly +rejected — GitHub is the natural place for developers, and it gives audit history, +permissions, and eventing for free. + +### 1.2 Two runtimes, never talking directly + +| Runtime | Role | Reads | Writes | +| --- | --- | --- | --- | +| **Brain** — Claude cloud scheduled session | Strategist: interprets metrics against approved intentions | `.autopilot/metrics/*.json`, open intention issues | Task sub-issues | +| **Hands** — GitHub Actions + `claude-code-action` | Executor: performs tasks, runs gates | Task issues (label-triggered) | Branches, PRs, labels, digest posts | + +The two runtimes only ever read and write GitHub — they have no direct channel. That is +what makes them parallel-safe and independently replaceable, and it means every handoff +is inspectable after the fact. + +### 1.3 Autonomy boundary as configuration + +The boundary lives in `.autopilot/config.yml` under `merge_policy`, so ratcheting +autonomy is a config edit, not a rearchitecture: + +- **Level A — propose-only:** every PR waits for the owner. +- **Level B — v1 default:** content and translation PRs auto-merge on green gates + (build, audit, anti-slop). Code and strategy changes wait for the owner. +- **Level C — full:** anything traceable to an approved intention auto-merges on green + gates; the owner reviews intentions and weekly outcomes only. + +### 1.4 Packaging + +`autopilot` is a content-stack plugin. It owns the loop; the existing plugins are its +action library: + +- `content-ops` — writing, translation, review, linking +- `content-seo` — GSC metrics (`gsc-reporter`), opportunities, briefs +- `astro-builder` — site structure, build gates, audit + +### 1.5 Intentions and tasks — traceability is the enforcement mechanism + +An **intention** is a pinned GitHub issue from a template: goal / metric / horizon / +constraints. It is inert until the owner applies the approval label. **Tasks** are +sub-issues of an approved intention. The executor re-verifies the parent intention's +approval *at execution time* — "the brain proposes, the control plane enforces." A task +with no approved parent never runs, no matter who or what filed it. That chain **is** +the autonomy boundary. + +### 1.6 Reporting is GitHub-native + +Digest posts land in GitHub Discussions (chosen over a rolling issue). + +### 1.7 v1 dogfood target + +`pcamarajr/lista-de-leitura` — private, Vercel-deployed (auto-merge = auto-publish, PR +previews free), `content-seo` already configured for `sc-domain:listadeleitura.com.br`. +Chosen over bitcoin101: real search volume; a narrow niche starves metric loops. + +--- + +## 2 — Grill resolutions (G1–G8) + +- **G1 Metrics ingestion:** a nightly Actions job runs content-seo's `gsc-reporter` and + commits `.autopilot/metrics/gsc-.json`. The strategist reads files, never the + live API — cheaper, reproducible, and the metric history is versioned with the site. +- **G2 Machine identity:** fine-grained PAT now, GitHub App later. The executor + workflow re-verifies parent-intention approval at execution time (see §1.5). +- **G3 Task briefs are structured:** skill-to-run / inputs / acceptance criteria. The + acceptance criteria double as the PR validation checklist — one artifact, two uses. +- **G4 Failure handling:** one retry, then the `blocked` label and strategist triage. + The executor never edits gates or config to force a pass. +- **G5 Spend fuses (four, independent):** dedicated Anthropic workspace with ~$50/mo + cap; job timeout ~30 min + `max_turns` ~50; Actions `concurrency: 1`; + `max_open_tasks` cap in config. +- **G6 Digest:** GitHub Discussions. +- **G7 Quality signal:** owner reactions on daily digests, plus an agent-drafted weekly + retro Discussion the owner grades; metric-outcome attribution comes later. +- **G8 v1 scope cut** — deferred, not abandoned: no C-suite roles, no autonomy level C, + GSC-only metrics, single-site, no public-repo hardening, the strategist cannot propose + new intentions, no self-modification. + +--- + +## 3 — v1 milestones + +1. **Scaffold:** `autopilot/init` sets up labels, issue templates, + `.autopilot/config.yml`, and Actions workflows — proven on a disposable sandbox repo + first. +2. **Executor path:** hand-written task → label → PR → gates → auto-merge of a + content-type change. No strategist involved. +3. **Strategist path:** scheduled cloud session reads GSC files + open intentions and + files sane, well-formed task sub-issues. +4. **Full loop** on lista-de-leitura for two weeks → review → ratchet `merge_policy` if + it has earned trust. + +**Sequencing (resolved 2026-08-24):** the order stands as 1→2→3→4. The GSC service +account (still missing as of this date) blocks the strategist regardless, and milestones +1–2 run on hand-written tasks, so a thin task pool cannot starve them. Volume-proving +the executor first also means the strategist's output lands on a loop already known to +work. + +--- + +## 4 — Long-term shape (explicitly preserved) + +- **C-suite roles** (CEO/CMO/CPO…): each is another scheduled cloud session with its + own read set and issue-writing mandate. New role = new role definition on the same + rails — no new architecture. +- **Autonomy ratchet to C** via `merge_policy` as the gates prove themselves. +- **Strategist-proposed intentions** arrive as proposals in the digest that the owner + promotes — never as self-created intention issues. Direction stays the owner's. +- **More metrics** (GA4, Ahrefs…) as additional exporters writing + `.autopilot/metrics/`; metric-outcome attribution becomes the strategist's true + quality score. +- **Multi-site + public-repo hardening** (trust rule: non-maintainer text is data, + never instructions) before community distribution. + +--- + +## 5 — Open questions + +1. **MEASURE oracle.** v1 ingests GSC metrics but has no attribution, guardrail, or + auto-rollback logic. A system that cannot tell whether a change helped will degrade + the product silently — this is the likely eventual binding constraint. Acceptable + for v1 only because v1 has no autonomous "propose intentions from signals" step. + Must be designed before that step is enabled. +2. **Owner prerequisite (blocks milestone 3):** GSC service account for + listadeleitura.com.br — Google Cloud → JSON key → added as a GSC property user → + stored in the site repo's Actions secrets. Verified still missing on 2026-08-24. diff --git a/release-please-config.json b/release-please-config.json index 2d5a9f7..7504486 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -24,6 +24,16 @@ } ] }, + "autopilot": { + "release-type": "simple", + "extra-files": [ + { + "type": "json", + "path": "/.claude-plugin/marketplace.json", + "jsonpath": "$.plugins[?(@.name=='autopilot')].version" + } + ] + }, "content-image-gemini": { "release-type": "simple", "extra-files": [