From f382d42bc360921f72fe8b6416f3d1d72ece1a27 Mon Sep 17 00:00:00 2001 From: Boden Fuller Date: Sun, 3 May 2026 00:41:09 -0400 Subject: [PATCH] docs: clarify AgentOps golden paths --- README.md | 46 ++++--- cli/cmd/ao/agentopsd_test.go | 8 +- cli/cmd/ao/quickstart.go | 40 ++++--- cli/cmd/ao/quickstart_test.go | 4 +- cli/internal/daemon/wiki_jobs.go | 29 +++-- cli/internal/daemon/wiki_jobs_test.go | 17 +++ docs/SKILL-ROUTER.md | 5 +- docs/SKILLS.md | 2 +- docs/_hooks/gen_cli_reference.py | 2 +- docs/getting-started/index.md | 58 ++++++++- docs/index.md | 4 +- docs/skills-decision-tree.md | 2 +- docs/workflows/README.md | 18 ++- skills-codex-overrides/quickstart/prompt.md | 2 +- skills-codex/.agentops-manifest.json | 4 +- .../pre-mortem/.agentops-generated.json | 2 +- skills-codex/pre-mortem/SKILL.md | 2 + ...scope-predicate-positive-negative-cases.md | 113 ++++++++++++++++++ .../quickstart/.agentops-generated.json | 2 +- skills-codex/quickstart/SKILL.md | 6 +- skills-codex/quickstart/prompt.md | 2 +- skills/quickstart/SKILL.md | 6 +- 22 files changed, 292 insertions(+), 82 deletions(-) create mode 100644 skills-codex/pre-mortem/references/scope-predicate-positive-negative-cases.md diff --git a/README.md b/README.md index 4cc3a9e1c..e96d91390 100644 --- a/README.md +++ b/README.md @@ -164,34 +164,15 @@ Troubleshooting: [docs/troubleshooting.md](docs/troubleshooting.md) · Configura ## Quick Start -Inside a repo, run one command in your agent chat: +Inside a repo, use the path that matches what you are trying to do. -```text -/quickstart -``` +| Path | Run | Done when | +|------|-----|-----------| +| **First repo setup** | `ao quick-start`, then `/quickstart` | AgentOps reports repo readiness and a next action | +| **First validated change** | `/rpi "a small goal"` | Discovery, implementation, validation, and learning closeout leave evidence in `.agents/` | +| **Review something now** | `/council validate this PR` or `/vibe recent` | You get a PASS/WARN/FAIL verdict before shipping | -That detects setup, explains the system, and gives you the next action. - -Then try the smallest useful flow: - -```text -/council validate this PR -``` - -Or let AgentOps run the full discovery-to-validation loop: - -```text -/rpi "a small goal" -``` - -If you installed the CLI, check your local setup: - -```bash -ao doctor -ao demo -``` - -New project? Use the guided CLI path: +New project? Use the guided CLI seed first: ```bash ao quick-start # Canonical @@ -203,6 +184,19 @@ AgentOps instructions, starter knowledge, and readiness guidance. Use `/bootstrap` after that when you want the product/operations layer: `PRODUCT.md`, `README.md`, `PROGRAM.md`/`AUTODEV.md`, and optional hooks. +Already installed? Ask your agent for the next action: + +```text +/quickstart +``` + +If you installed the CLI, check your local setup: + +```bash +ao doctor +ao demo +``` + Full catalog: [docs/SKILLS.md](docs/SKILLS.md) · Unsure what to run? [Skill Router](docs/SKILL-ROUTER.md) --- diff --git a/cli/cmd/ao/agentopsd_test.go b/cli/cmd/ao/agentopsd_test.go index 83e349ebe..effcfa2dd 100644 --- a/cli/cmd/ao/agentopsd_test.go +++ b/cli/cmd/ao/agentopsd_test.go @@ -342,7 +342,13 @@ func TestDaemonRunWorkerOnceCompletesWikiForgeFakeJob(t *testing.T) { t.Fatalf("snapshot: %v", err) } if len(snapshot.Jobs) != 1 || snapshot.Jobs[0].Status != daemonpkg.JobStatusCompleted { - t.Fatalf("jobs = %#v, want completed wiki job", snapshot.Jobs) + t.Fatalf( + "jobs = %#v, failure = %#v, artifacts = %#v, artifact refs = %#v, want completed wiki job", + snapshot.Jobs, + snapshot.Jobs[0].Failure, + snapshot.Jobs[0].Artifacts, + snapshot.Jobs[0].ArtifactRefs, + ) } if snapshot.Jobs[0].Artifacts["worker_session_refs"] == "" || snapshot.Jobs[0].Artifacts["session_id"] == "" { t.Fatalf("wiki artifacts = %#v, want worker session refs", snapshot.Jobs[0].Artifacts) diff --git a/cli/cmd/ao/quickstart.go b/cli/cmd/ao/quickstart.go index 31ccaa41c..7d0635fc8 100644 --- a/cli/cmd/ao/quickstart.go +++ b/cli/cmd/ao/quickstart.go @@ -256,7 +256,7 @@ func printReadinessSummary(report *lifecycle.ReadinessReport) { } fmt.Printf(" %-13s %s (%d/%d)\n", string(layer)+":", status, present, total) } - fmt.Println("\nNext: /rpi \"your first objective\"") + fmt.Println("\nNext: pick a golden path below, or run /rpi \"your first objective\"") } func readinessLayerStatus(report *lifecycle.ReadinessReport, layer lifecycle.ReadinessLayer) (int, int, string) { @@ -519,40 +519,46 @@ git push # NEVER stop before pushing func showNextSteps(hasBeads bool) { fmt.Print(` ═══════════════════════════════════════════════════════════════════ - NEXT STEPS + GOLDEN PATHS ═══════════════════════════════════════════════════════════════════ `) if hasBeads { - fmt.Println(` 1. Start the software-factory lane for a concrete goal: + fmt.Println(` 1. First validated change: $ ao factory start --goal "your first objective" + > /rpi "your first objective" - 2. Create your first issue: + 2. Tracked work: + $ bd ready $ bd create "My first task" - 3. Start working: - $ claude - > /rpi "your first objective" + 3. Terminal-native lifecycle: + $ ao rpi phased "your first objective" + $ ao rpi status - 4. When done, close the loop explicitly: - $ ao codex stop`) + 4. Close the learning loop: + > /validation + $ ao codex stop # Codex hookless fallback only`) } else { - fmt.Println(` 1. Start the software-factory lane for a concrete goal: + fmt.Println(` 1. First validated change: $ ao factory start --goal "your first objective" - - 2. Start Claude in your project: - $ claude - - 3. Work normally: > /rpi "your first objective" - 4. When ready for tracked execution: + 2. Start your agent in this repo: + > /quickstart + > /rpi "your first objective" + + 3. Terminal-native lifecycle: + $ ao rpi phased "your first objective" + $ ao rpi status + + 4. Add tracked execution when ready: $ bd init $ bd create "My first task"`) } fmt.Print(` - 5. Your knowledge compounds through briefings, RPI, and flywheel closeout + Success signal: the run leaves validation evidence and reusable context in .agents/ ═══════════════════════════════════════════════════════════════════ diff --git a/cli/cmd/ao/quickstart_test.go b/cli/cmd/ao/quickstart_test.go index e65fda448..a1af8aaff 100644 --- a/cli/cmd/ao/quickstart_test.go +++ b/cli/cmd/ao/quickstart_test.go @@ -575,7 +575,7 @@ func TestQuickstart_showNextSteps_withBeads(t *testing.T) { showNextSteps(true) }) - if !strings.Contains(got, "Create your first issue") { + if !strings.Contains(got, "Tracked work") { t.Fatalf("expected beads next steps, got: %s", got) } } @@ -585,7 +585,7 @@ func TestQuickstart_showNextSteps_withoutBeads(t *testing.T) { showNextSteps(false) }) - if !strings.Contains(got, "Start Claude in your project") { + if !strings.Contains(got, "Start your agent in this repo") { t.Fatalf("expected no-beads next steps, got: %s", got) } } diff --git a/cli/internal/daemon/wiki_jobs.go b/cli/internal/daemon/wiki_jobs.go index ba154bf3a..cd958dd5a 100644 --- a/cli/internal/daemon/wiki_jobs.go +++ b/cli/internal/daemon/wiki_jobs.go @@ -299,14 +299,13 @@ type wikiForgePromptContext struct { // worker session is created so the failure surfaces as a job-validation // error, never as a partial worker run. // -// Containment rule: each path, after filepath.Abs + filepath.Clean (and -// EvalSymlinks if the path exists), must equal the canonical repo root or -// live underneath it. EvalSymlinks errors on non-existent paths are -// tolerated — the lexical check still rejects paths whose form escapes -// the root, and downstream existing-source reads surface missing-file -// errors with their own context. The repo root itself is canonicalized -// via EvalSymlinks once so symlinked tmp dirs (e.g. macOS /tmp -> -// /private/tmp) don't produce false positives. +// Containment rule: each path, after filepath.Abs + filepath.Clean, must +// live under either the repo root spelling the caller supplied or the +// canonicalized root. If the path exists, its EvalSymlinks result must live +// under the canonical root. EvalSymlinks errors on non-existent paths are +// tolerated — the lexical check still rejects paths whose form escapes the +// root, and downstream existing-source reads surface missing-file errors +// with their own context. func validateWikiForgeSourcePathsContainment(repoRoot string, paths []string) error { if strings.TrimSpace(repoRoot) == "" { return fmt.Errorf("wiki forge source path containment: repo root is empty") @@ -315,11 +314,11 @@ func validateWikiForgeSourcePathsContainment(repoRoot string, paths []string) er if err != nil { return fmt.Errorf("wiki forge source path containment: resolve repo root %q: %w", repoRoot, err) } - rootCanon := filepath.Clean(rootAbs) + rootClean := filepath.Clean(rootAbs) + rootCanon := rootClean if resolved, err := filepath.EvalSymlinks(rootCanon); err == nil { rootCanon = resolved } - rootWithSep := rootCanon + string(filepath.Separator) for _, p := range paths { if strings.TrimSpace(p) == "" { return fmt.Errorf("wiki forge source path is empty") @@ -331,13 +330,13 @@ func validateWikiForgeSourcePathsContainment(repoRoot string, paths []string) er clean := filepath.Clean(abs) // Lexical containment first — catches `..` traversal regardless of // whether the target file exists or is a symlink. - if clean != rootCanon && !strings.HasPrefix(clean, rootWithSep) { + if !wikiForgePathWithinRoot(clean, rootClean) && !wikiForgePathWithinRoot(clean, rootCanon) { return fmt.Errorf("wiki forge source path %q escapes repo root %q", p, rootCanon) } // Symlink containment second — only enforced when the path exists, // to allow paths-to-be-created and to keep test fixtures simple. if resolved, err := filepath.EvalSymlinks(clean); err == nil { - if resolved != rootCanon && !strings.HasPrefix(resolved, rootWithSep) { + if !wikiForgePathWithinRoot(resolved, rootCanon) { return fmt.Errorf("wiki forge source path %q resolves via symlink to %q which escapes repo root %q", p, resolved, rootCanon) } } @@ -345,6 +344,12 @@ func validateWikiForgeSourcePathsContainment(repoRoot string, paths []string) er return nil } +func wikiForgePathWithinRoot(path, root string) bool { + path = filepath.Clean(path) + root = filepath.Clean(root) + return path == root || strings.HasPrefix(path, root+string(filepath.Separator)) +} + // expandWikiForgeSourcePaths flattens directory entries in spec.SourcePaths // into the regular files they contain. Top-level only — nested subdirectories // are skipped (operators who want recursion can list specific subdirs). Stable diff --git a/cli/internal/daemon/wiki_jobs_test.go b/cli/internal/daemon/wiki_jobs_test.go index bc325cb03..c4e669c03 100644 --- a/cli/internal/daemon/wiki_jobs_test.go +++ b/cli/internal/daemon/wiki_jobs_test.go @@ -345,6 +345,23 @@ func TestValidateWikiForgeSourcePathsContainment_Unit(t *testing.T) { } } +func TestValidateWikiForgeSourcePathsContainment_AllowsSymlinkRootSpelling(t *testing.T) { + realRoot := t.TempDir() + linkParent := t.TempDir() + linkRoot := filepath.Join(linkParent, "repo") + if err := os.Symlink(realRoot, linkRoot); err != nil { + t.Skipf("symlink unavailable: %v", err) + } + sourcePath := filepath.Join(linkRoot, "session.jsonl") + if err := os.WriteFile(sourcePath, []byte("decision: accept symlink root spelling\n"), 0o644); err != nil { + t.Fatalf("write source: %v", err) + } + + if err := validateWikiForgeSourcePathsContainment(linkRoot, []string{sourcePath}); err != nil { + t.Fatalf("expected symlink-root path spelling to stay inside root: %v", err) + } +} + // TestWikiJobs_RejectsEmptyProvider confirms that WikiForgeJobSpec validation // rejects an empty Provider at every reachable submission entrypoint: // Validate(), ToJobSpec(), and the payload roundtrip path diff --git a/docs/SKILL-ROUTER.md b/docs/SKILL-ROUTER.md index 82e5c3716..bba84a653 100644 --- a/docs/SKILL-ROUTER.md +++ b/docs/SKILL-ROUTER.md @@ -40,7 +40,8 @@ What are you trying to do? │ └─ Generate ideas ────────────► /brainstorm │ ├─ "Learn from past work" -│ ├─ What do we know about X? ──► /knowledge +│ ├─ What do we know about X? ──► ao lookup "" / ao search +│ ├─ Turn corpus into operator surfaces ─► /knowledge-activation │ ├─ Save this insight ─────────► /retro --quick "insight" │ └─ Run a retrospective ───────► /retro │ @@ -56,5 +57,5 @@ What are you trying to do? │ ├─ Save for next session ─────► /handoff │ └─ Recover after compaction ──► /recover │ -└─ "First time here" ────────────► /quickstart +└─ "First time here" ────────────► ao quick-start → /quickstart ``` diff --git a/docs/SKILLS.md b/docs/SKILLS.md index 3f27b8680..7fee4e086 100644 --- a/docs/SKILLS.md +++ b/docs/SKILLS.md @@ -69,7 +69,7 @@ What are you trying to do? │ ├─ Save for next session ─────► /handoff │ └─ Recover after compaction ──► /recover │ -└─ "First time here" ────────────► /quickstart +└─ "First time here" ────────────► ao quick-start → /quickstart ``` ## Core Flow Skills diff --git a/docs/_hooks/gen_cli_reference.py b/docs/_hooks/gen_cli_reference.py index f63e99b27..0588c011d 100644 --- a/docs/_hooks/gen_cli_reference.py +++ b/docs/_hooks/gen_cli_reference.py @@ -78,7 +78,7 @@ This installs: ```bash ao --version # Verify install -ao rpi "fix the flaky auth test" # Full Research -> Plan -> Implement -> Validate cycle +ao rpi phased "fix the flaky auth test" # Full Research -> Plan -> Implement -> Validate cycle ao status # Where was I? ao goals measure # Fitness gate ``` diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 10101090f..4e59d9587 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -2,7 +2,7 @@ New to AgentOps? You're in the right place. This section answers three questions in order: **what is it**, **how do I install it**, and **what's the first useful thing I can run**. -If you're evaluating AgentOps for a team, start with the [Newcomer Guide](../newcomer-guide.md) — it frames the product in fifteen minutes. If you're ready to ship code with it, skip to [Install](#install) and then [First command](#first-command). If you want a structured curriculum, jump to the [Levels](../levels/index.md) path at the bottom. If you are upgrading from an older release, read [Upgrading](../UPGRADING.md) first. +If you're evaluating AgentOps for a team, start with the [Newcomer Guide](../newcomer-guide.md) — it frames the product in fifteen minutes. If you're ready to ship code with it, skip to [Install](#install) and then [Golden Paths](#golden-paths). If you want a structured curriculum, jump to the [Levels](../levels/index.md) path at the bottom. If you are upgrading from an older release, read [Upgrading](../UPGRADING.md) first.
@@ -47,6 +47,45 @@ If you're evaluating AgentOps for a team, start with the [Newcomer Guide](../new ## Install +Pick the installer for your runtime. + +=== "Claude Code" + + ```bash + claude plugin marketplace add boshu2/agentops + claude plugin install agentops@agentops-marketplace + ``` + +=== "Codex CLI" + + ```bash + curl -fsSL https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install-codex.sh | bash + ``` + +=== "OpenCode" + + ```bash + curl -fsSL https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install-opencode.sh | bash + ``` + +Then install the `ao` CLI for repo seeding, health checks, and terminal +workflows. + +=== "macOS" + + ```bash + brew tap boshu2/agentops https://github.com/boshu2/homebrew-agentops + brew install agentops + ``` + +=== "Windows PowerShell" + + ```powershell + irm https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install-ao.ps1 | iex + ``` + +For other skills-compatible agents, install selected skills with: + ```bash bash <(curl -fsSL https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install.sh) ``` @@ -62,13 +101,26 @@ ao --version # Prints installed ao version and non-zero exits on a real problem. If anything looks wrong, see [Troubleshooting](../troubleshooting.md) or run `ao doctor --verbose`. -## First command +## Golden Paths + +Pick one path. Each path ends with proof in `.agents/` or an explicit +PASS/WARN/FAIL verdict. + +| I want to... | Run | Success signal | +|--------------|-----|----------------| +| Set up a repo for the first time | `ao quick-start`, then `/quickstart` | Readiness summary shows the next action | +| Make the first validated change | `/rpi "a small goal"` | Discovery, implementation, validation, and learning artifacts exist | +| Review code before shipping | `/council validate this PR` or `/vibe recent` | Verdict is recorded before merge | +| Continue tracked work | `bd ready`, then `/implement ` or `/crank ` | Issue status and validation evidence are updated | +| Run from the terminal | `ao factory start --goal "goal"`, then `ao rpi phased "goal"` | `ao rpi status` shows the phase result | + +## Command Reference ```bash ao quick-start # Canonical repo seed and readiness repair ao quickstart # Stable alias for the same golden path ao status # Where was I? -ao rpi "goal" # Full Research-Plan-Implement-Validate loop +ao rpi phased "goal" # Full terminal Research-Plan-Implement-Validate loop ``` ## Learning path diff --git a/docs/index.md b/docs/index.md index c88d21a96..2f3335001 100644 --- a/docs/index.md +++ b/docs/index.md @@ -195,8 +195,8 @@ Run Dream overnight, then Evolve in the morning against a fresher corpus. Same m ## Next steps 1. **[Install](#install)** — pick your runtime. -2. **Run** `ao quick-start` in your repo (`ao quickstart` also works), then `/quickstart` in your agent chat. -3. **Validate** with `/council validate this PR` on your next change. +2. **Seed** your repo with `ao quick-start` (`ao quickstart` also works), then run `/quickstart` in your agent chat. +3. **Choose a golden path:** `/rpi "a small goal"` for a first validated change, `/council validate this PR` for review-only, or `bd ready` to continue tracked work. Read the lineage at [12factoragentops.com](https://12factoragentops.com) — DevOps applied to coding agents in twelve factors. diff --git a/docs/skills-decision-tree.md b/docs/skills-decision-tree.md index 793a78fe1..7dcb6057d 100644 --- a/docs/skills-decision-tree.md +++ b/docs/skills-decision-tree.md @@ -37,7 +37,7 @@ Rationale: groups by subject alphabetically in file listings; matches the existi | Overnight compounding + fitness-driven corpus improvement | `$dream` | | Turn compiled knowledge into playbooks + beliefs for future sessions | `$knowledge-activation` | | Copy raw `.md` files verbatim without dedup | `rsync` (not AgentOps) | -| New project / new repo / first-time AgentOps setup | `$quickstart` | +| New project / new repo / first-time AgentOps setup | `ao quick-start`, then `$quickstart` | | Full research → plan → implement → validate cycle | `$rpi` | | Validate a plan or spec before implementation | `$pre-mortem` | | Validate code quality after implementation | `$vibe` | diff --git a/docs/workflows/README.md b/docs/workflows/README.md index 59f587173..cf467cf6c 100644 --- a/docs/workflows/README.md +++ b/docs/workflows/README.md @@ -2,6 +2,20 @@ > Which workflow should I use? Find the right one in seconds. +## Golden Paths + +Use these as the default user journeys before reaching for the full decision +tree. + +| Situation | Start with | Continue with | +|-----------|------------|---------------| +| First repo setup | `ao quick-start` | `/quickstart`, then `/rpi "a small goal"` | +| Small, obvious change | [Quick Fix](quick-fix.md) | `/implement`, then `/vibe --quick recent` | +| New feature or broad change | [Complete Cycle](complete-cycle.md) | `/rpi "goal"` or `/plan` -> `/crank ` | +| Existing tracked backlog | `bd ready` | `/implement ` or `/crank ` | +| Review-only checkpoint | `/council validate this PR` | `/vibe recent` before merge | +| Terminal-native operation | `ao factory start --goal "goal"` | `ao rpi phased "goal"` and `ao rpi status` | + ## Decision Tree | I want to... | Use this workflow | Complexity | Key Skills | @@ -12,7 +26,7 @@ | Deploy infrastructure changes | [Infrastructure Deployment](infrastructure-deployment.md) | High | /plan, /implement, /vibe | | Work across multiple domains at once | [Multi-Domain](multi-domain.md) | High | /plan, /swarm | | Validate research assumptions before planning | [Assumption Validation](assumption-validation.md) | Medium | /research | -| Understand a new codebase or extract patterns | [Knowledge Synthesis](knowledge-synthesis.md) | Medium | /research, /knowledge | +| Understand a new codebase or extract patterns | [Knowledge Synthesis](knowledge-synthesis.md) | Medium | /research, /knowledge-activation | | Run a retrospective after completing work | [Post-Work Retro](post-work-retro.md) | Low | /retro, /post-mortem | | Improve system quality over time | [Continuous Improvement](continuous-improvement.md) | Medium | /retro, /vibe | | Manage a session from start to finish | [Session Lifecycle](session-lifecycle.md) | Low | (natural language) | @@ -53,7 +67,7 @@ ### [Knowledge Synthesis](knowledge-synthesis.md) **When to use:** Onboarding to a new codebase, creating comprehensive docs, extracting patterns from multiple implementations. **Complexity:** Medium (30-60 min, single session) -**Key skills:** /research, /knowledge +**Key skills:** /research, /knowledge-activation ### [Post-Work Retro](post-work-retro.md) **When to use:** After completing significant work, to capture learnings and identify improvements. diff --git a/skills-codex-overrides/quickstart/prompt.md b/skills-codex-overrides/quickstart/prompt.md index d923dd120..0cdcbf9d5 100644 --- a/skills-codex-overrides/quickstart/prompt.md +++ b/skills-codex-overrides/quickstart/prompt.md @@ -13,7 +13,7 @@ Guide new users through AgentOps in a Codex-first flow. 1. Do not require Claude CLI checks to proceed. 2. Avoid instructions that assume `.claude/` directories. -3. Be explicit that current Codex CLI v0.125.0 uses native hooks under `~/.codex/hooks.json`; older installs without native hooks fall back to entry skills ensuring `ao codex ensure-start` once per thread and dedicated closeout skills ensuring `ao codex ensure-stop` once per thread. +3. Be explicit that current Codex installs with native hooks under `~/.codex/hooks.json` handle lifecycle automatically; hookless installs fall back to entry skills ensuring `ao codex ensure-start` once per thread and dedicated closeout skills ensuring `ao codex ensure-stop` once per thread. 4. Keep `ao codex status` as the manual lifecycle escape hatch, not the primary workflow. 5. Keep onboarding output action-oriented: next command, expected result, fallback. 6. Mention `$bootstrap` only as the product/operations expansion after the core seed, not as a competing initializer. diff --git a/skills-codex/.agentops-manifest.json b/skills-codex/.agentops-manifest.json index 3fb199484..311b46485 100644 --- a/skills-codex/.agentops-manifest.json +++ b/skills-codex/.agentops-manifest.json @@ -860,7 +860,7 @@ "name": "pre-mortem", "source_skill": "skills/pre-mortem", "source_hash": "9ed2f0290ccc16ce45a79d0a22b2dae54f525875fa2a8375bf470de54c08912d", - "generated_hash": "ba9828b228f13bc6ee3758281342754c1792439be9627b81e2af420b36b11dc5" + "generated_hash": "76c803dbb09ebd1f9833a1ca852d366c48f6a2956141b8b9245bfd816e93155c" }, { "name": "product", @@ -884,7 +884,7 @@ "name": "quickstart", "source_skill": "skills/quickstart", "source_hash": "68a6463ab7dded893cbdd27d7697c70d871ed4149b5c7cbe8bf20369c1e0a813", - "generated_hash": "a5c90f2639ed15029203f7ff1ab8fd2dcfbc2afe260f1e4816317c81fb2cf907" + "generated_hash": "47873041d4557d92f938779fe03385b54a32f597aa59aadf711804a83ba190bd" }, { "name": "ratchet", diff --git a/skills-codex/pre-mortem/.agentops-generated.json b/skills-codex/pre-mortem/.agentops-generated.json index aaad76ae9..8eaa2e79c 100644 --- a/skills-codex/pre-mortem/.agentops-generated.json +++ b/skills-codex/pre-mortem/.agentops-generated.json @@ -3,5 +3,5 @@ "source_skill": "skills/pre-mortem", "layout": "modular", "source_hash": "9ed2f0290ccc16ce45a79d0a22b2dae54f525875fa2a8375bf470de54c08912d", - "generated_hash": "ba9828b228f13bc6ee3758281342754c1792439be9627b81e2af420b36b11dc5" + "generated_hash": "76c803dbb09ebd1f9833a1ca852d366c48f6a2956141b8b9245bfd816e93155c" } diff --git a/skills-codex/pre-mortem/SKILL.md b/skills-codex/pre-mortem/SKILL.md index 8319fa2f8..7235700df 100644 --- a/skills-codex/pre-mortem/SKILL.md +++ b/skills-codex/pre-mortem/SKILL.md @@ -548,6 +548,7 @@ $pre-mortem ← You are here - [references/prediction-tracking.md](references/prediction-tracking.md) - [references/spec-verification-checklist.md](references/spec-verification-checklist.md) - [references/temporal-interrogation.md](references/temporal-interrogation.md) +- [references/scope-predicate-positive-negative-cases.md](references/scope-predicate-positive-negative-cases.md) ## Local Resources @@ -558,6 +559,7 @@ $pre-mortem ← You are here - [references/error-rescue-map-template.md](references/error-rescue-map-template.md) - [references/failure-taxonomy.md](references/failure-taxonomy.md) - [references/prediction-tracking.md](references/prediction-tracking.md) +- [references/scope-predicate-positive-negative-cases.md](references/scope-predicate-positive-negative-cases.md) - [references/simulation-prompts.md](references/simulation-prompts.md) - [references/spec-verification-checklist.md](references/spec-verification-checklist.md) - [references/temporal-interrogation.md](references/temporal-interrogation.md) diff --git a/skills-codex/pre-mortem/references/scope-predicate-positive-negative-cases.md b/skills-codex/pre-mortem/references/scope-predicate-positive-negative-cases.md new file mode 100644 index 000000000..eedce3f8c --- /dev/null +++ b/skills-codex/pre-mortem/references/scope-predicate-positive-negative-cases.md @@ -0,0 +1,113 @@ +# Pre-Mortem Check: Regex Scope Predicates Need Positive AND Negative Test Cases + +> **When this check applies:** A plan adds or modifies a regex-based scope +> predicate — e.g., a goal-gate that decides which files to lint, an +> orchestrator that filters which scripts to run, a search filter that +> determines which records to process. + +## Rule + +When a plan introduces a regex (or grep pattern, or glob, or any +predicate that classifies inputs into "in scope" / "out of scope"), the +plan MUST enumerate: + +- **At least 3 positive cases** the predicate MUST match (true + positives — if any is missed, the predicate is too narrow). +- **At least 3 negative cases** the predicate MUST NOT match (true + negatives — if any matches, the predicate is too broad). + +Without both lists, the regex will iterate to correctness in CI or +production rather than in pre-mortem. Each iteration is a real cycle of +broken-then-fixed code. + +## Why this matters + +Regex scope predicates have two failure modes that are mirror images: + +1. **Too narrow** — fails to match real cases, silent miss. Bug ships. +2. **Too broad** — matches things it shouldn't, generates false positives + that block CI on unrelated changes. + +Each iteration to fix one mode often breaks the other. Without both +positive and negative case lists in the plan, the predicate's actual +shape is whatever the implementer typed in the moment. + +## Prior incident + +C3 of the 2026-05-02 Mt. Olympus validation pass (mol-ukmdp) added a +goal gate that lints orchestrator.sh callers for `MTO_CITY_DIR` env +isolation. The initial regex matched any line containing +`orchestrator.sh`, which produced false positives for string literals +in test data like `"orchestrator.sh sling zeus"`. The fix added a +`(bash|sh|exec)` precedence requirement — but the tightened regex then +failed to match `bash scripts/orchestrator.sh` (path starts with a +letter, not `[$/.]`). A second iteration relaxed the path-prefix +requirement. + +Two iterations could have been zero if the plan had specified: + +- **Positive cases** (must match): + - `bash scripts/orchestrator.sh sling zeus` + - `sh /repo/scripts/orchestrator.sh quest start` + - `exec ./scripts/orchestrator.sh sling` +- **Negative cases** (must NOT match): + - `# This invokes orchestrator.sh somehow` + - `echo "orchestrator.sh sling zeus"` (string literal in test data) + - `grep "orchestrator.sh" file.txt` + +The first iteration's regex would have failed cases 4-6 (matching +literals); the second iteration's regex would have failed cases 1-3 +(too restrictive on path prefix). The final regex satisfies all six. + +## How to apply during pre-mortem + +When reviewing a plan that introduces a regex predicate, demand the +enumeration before approval. If the plan does not include both lists, +WARN with the following pseudocode fix: + +```markdown +## Fix: Add positive + negative cases for the predicate + +The plan introduces a regex `` to classify . +Before implementation, enumerate: + +**Must match (≥3 positive cases):** +1. +2. +3. + +**Must NOT match (≥3 negative cases):** +1. +2. +3. + +The implementation includes a unit test asserting both lists. +``` + +## How to apply during planning + +When writing a plan that includes a regex predicate, include the two +lists in the plan document under the predicate's section. The +implementation must include a unit test that covers both lists. + +## Audit candidates + +Plans that warrant this check: + +- Goal gates that scan `scripts/**/*.sh`, `docs/**/*.md`, etc. +- Lint rules that classify code as compliant / non-compliant. +- Orchestrators that filter which work to dispatch. +- Search/inject filters that decide which records to surface. +- Migration scripts that classify which files to rewrite. + +## See also + +- `.agents/council/2026-05-02-post-mortem-validation-pass.md` (N4 — the + source finding from the Mt. Olympus validation pass) +- `scripts/goals/check-orchestrator-test-isolation.sh` (the C3 deliverable + whose iteration cost motivated this rule) + +--- + +*Cross-referenced from `mandatory-checks.md` as an additional check +trigger when a plan introduces a regex scope predicate.* diff --git a/skills-codex/quickstart/.agentops-generated.json b/skills-codex/quickstart/.agentops-generated.json index ebb67b895..373a780dc 100644 --- a/skills-codex/quickstart/.agentops-generated.json +++ b/skills-codex/quickstart/.agentops-generated.json @@ -3,5 +3,5 @@ "source_skill": "skills/quickstart", "layout": "modular", "source_hash": "68a6463ab7dded893cbdd27d7697c70d871ed4149b5c7cbe8bf20369c1e0a813", - "generated_hash": "a5c90f2639ed15029203f7ff1ab8fd2dcfbc2afe260f1e4816317c81fb2cf907" + "generated_hash": "47873041d4557d92f938779fe03385b54a32f597aa59aadf711804a83ba190bd" } diff --git a/skills-codex/quickstart/SKILL.md b/skills-codex/quickstart/SKILL.md index fe1c0a969..ddf94f696 100644 --- a/skills-codex/quickstart/SKILL.md +++ b/skills-codex/quickstart/SKILL.md @@ -51,9 +51,9 @@ Match the first row that applies. Output only that message — nothing else. | AO=false | "📦 Install ao CLI first:\n brew tap boshu2/agentops https://github.com/boshu2/homebrew-agentops\n brew install agentops\n ao quick-start && ao init --hooks\nThen: `$rpi \"a small goal\"` to run your first cycle.\nUse `$bootstrap` after the core seed when you want PRODUCT.md, README.md, and PROGRAM.md." | | AGENTS=false + CODEX=true | "🌱 ao is installed but not initialized here.\n Run `ao quick-start` to apply the repeatable core seed. `ao quickstart` is the stable alias.\n Then run `$bootstrap` only if you want the product/operations layer: PRODUCT.md, README.md, PROGRAM.md/AUTODEV.md, and optional hooks.\nThen: `$rpi \"a small goal\"` to run your first cycle." | | AGENTS=false | "🌱 ao is installed but not initialized here.\n Run `ao quick-start` to apply the repeatable core seed. `ao quickstart` is the stable alias.\n Then run `$bootstrap` only if you want the product/operations layer: PRODUCT.md, README.md, PROGRAM.md/AUTODEV.md, and optional hooks.\nThen: `$rpi \"a small goal\"` to run your first cycle." | -| BD=false + CODEX=true | "✅ Codex native-hooks path ready.\n Start with `$rpi \"your goal\"`, `$research `, or `$status`\n On Codex CLI v0.125.0, native hooks handle startup and closeout automatically after install.\n Older installs without native hooks fall back to entry skills auto-running `ao codex ensure-start` once per thread and closeout skills auto-running `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`\n Want issue tracking? `brew install boshu2/agentops/beads && bd init --prefix `" | +| BD=false + CODEX=true | "✅ Codex native-hooks path ready.\n Start with `$rpi \"your goal\"`, `$research `, or `$status`\n Current Codex installs with native hooks handle startup and closeout automatically after install.\n Older hookless installs fall back to entry skills auto-running `ao codex ensure-start` once per thread and closeout skills auto-running `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`\n Want issue tracking? `brew install boshu2/agentops/beads && bd init --prefix `" | | BD=false | "✅ Flywheel active. Start now:\n `$rpi \"your goal\"` — full $discovery → $crank → $validation pipeline\n `$validation` — close out recent work and capture learnings\n `$research ` — explore the codebase\n Want issue tracking? `brew install boshu2/agentops/beads && bd init --prefix `" | -| BD=true + CODEX=true | "✅ Codex full stack ready.\n `bd ready` — see open work\n Start with `$rpi \"your goal\"`, `$research `, or `$status`\n On Codex CLI v0.125.0, native hooks handle startup and closeout automatically after install.\n Older installs without native hooks fall back to entry skills auto-running `ao codex ensure-start` once per thread and closeout skills auto-running `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`" | +| BD=true + CODEX=true | "✅ Codex full stack ready.\n `bd ready` — see open work\n Start with `$rpi \"your goal\"`, `$research `, or `$status`\n Current Codex installs with native hooks handle startup and closeout automatically after install.\n Older hookless installs fall back to entry skills auto-running `ao codex ensure-start` once per thread and closeout skills auto-running `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`" | | BD=true | "✅ Full stack ready.\n `bd ready` — see open work\n `$rpi \"your goal\"` — start a new goal from scratch\n `$status` — see current session state" | --- @@ -83,7 +83,7 @@ Starting a new project? Run `$scaffold ` to generate project st | Problem | Solution | |---------|----------| | Skills not installed | `bash <(curl -fsSL https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install.sh)` | -| Codex installs without native hooks | Codex CLI v0.125.0 uses native hooks by default after install. Older installs without native hooks fall back to entry skills auto-running `ao codex ensure-start` and closeout skills auto-running `ao codex ensure-stop`; `ao codex status` is the manual escape hatch | +| Codex installs without native hooks | Current Codex installs with native hooks handle lifecycle automatically. Hookless installs fall back to entry skills auto-running `ao codex ensure-start` and closeout skills auto-running `ao codex ensure-stop`; `ao codex status` is the manual escape hatch | | Flywheel count is 0 | First session — run `$rpi "a small goal"` to start it | | Want the full skill catalog | Ask: "show me all the skills" or see `references/full-catalog.md` | diff --git a/skills-codex/quickstart/prompt.md b/skills-codex/quickstart/prompt.md index d923dd120..0cdcbf9d5 100644 --- a/skills-codex/quickstart/prompt.md +++ b/skills-codex/quickstart/prompt.md @@ -13,7 +13,7 @@ Guide new users through AgentOps in a Codex-first flow. 1. Do not require Claude CLI checks to proceed. 2. Avoid instructions that assume `.claude/` directories. -3. Be explicit that current Codex CLI v0.125.0 uses native hooks under `~/.codex/hooks.json`; older installs without native hooks fall back to entry skills ensuring `ao codex ensure-start` once per thread and dedicated closeout skills ensuring `ao codex ensure-stop` once per thread. +3. Be explicit that current Codex installs with native hooks under `~/.codex/hooks.json` handle lifecycle automatically; hookless installs fall back to entry skills ensuring `ao codex ensure-start` once per thread and dedicated closeout skills ensuring `ao codex ensure-stop` once per thread. 4. Keep `ao codex status` as the manual lifecycle escape hatch, not the primary workflow. 5. Keep onboarding output action-oriented: next command, expected result, fallback. 6. Mention `$bootstrap` only as the product/operations expansion after the core seed, not as a competing initializer. diff --git a/skills/quickstart/SKILL.md b/skills/quickstart/SKILL.md index 146800bb6..9cbe35e75 100644 --- a/skills/quickstart/SKILL.md +++ b/skills/quickstart/SKILL.md @@ -61,9 +61,9 @@ Match the first row that applies. Output only that message — nothing else. | AO=false | "📦 Install ao CLI first:\n brew tap boshu2/agentops https://github.com/boshu2/homebrew-agentops\n brew install agentops\n ao quick-start && ao init --hooks\nThen: `/rpi \"a small goal\"` to run your first cycle.\nUse `/bootstrap` after the core seed when you want PRODUCT.md, README.md, and PROGRAM.md." | | AGENTS=false + CODEX=true | "🌱 ao is installed but not initialized here.\n Run `ao quick-start` to apply the repeatable core seed. `ao quickstart` is the stable alias.\n Then run `/bootstrap` only if you want the product/operations layer: PRODUCT.md, README.md, PROGRAM.md/AUTODEV.md, and optional hooks.\nThen: `/rpi \"a small goal\"` to run your first cycle." | | AGENTS=false | "🌱 ao is installed but not initialized here.\n Run `ao quick-start` to apply the repeatable core seed. `ao quickstart` is the stable alias.\n Then run `/bootstrap` only if you want the product/operations layer: PRODUCT.md, README.md, PROGRAM.md/AUTODEV.md, and optional hooks.\nThen: `/rpi \"a small goal\"` to run your first cycle." | -| BD=false + CODEX=true | "✅ Codex native-hooks path ready.\n `/rpi \"your goal\"` — full /discovery → /crank → /validation pipeline\n `/research ` — explore the codebase\n On Codex CLI v0.115.0+, native hooks handle startup and closeout automatically after install.\n Older versions fall back to `ao codex ensure-start` / `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`\n Want issue tracking? `brew install boshu2/agentops/beads && bd init --prefix `" | +| BD=false + CODEX=true | "✅ Codex native-hooks path ready.\n `/rpi \"your goal\"` — full /discovery → /crank → /validation pipeline\n `/research ` — explore the codebase\n Current Codex installs with native hooks handle startup and closeout automatically after install.\n Older hookless installs fall back to `ao codex ensure-start` / `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`\n Want issue tracking? `brew install boshu2/agentops/beads && bd init --prefix `" | | BD=false | "✅ Flywheel active. Start now:\n `/rpi \"your goal\"` — full /discovery → /crank → /validation pipeline\n `/validation` — close out recent work and capture learnings\n `/research ` — explore the codebase\n Want issue tracking? `brew install boshu2/agentops/beads && bd init --prefix `" | -| BD=true + CODEX=true | "✅ Codex full stack ready.\n `bd ready` — see open work\n `/rpi \"your goal\"` — start a new goal from scratch\n On Codex CLI v0.115.0+, native hooks handle startup and closeout automatically after install.\n Older versions fall back to `ao codex ensure-start` / `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`" | +| BD=true + CODEX=true | "✅ Codex full stack ready.\n `bd ready` — see open work\n `/rpi \"your goal\"` — start a new goal from scratch\n Current Codex installs with native hooks handle startup and closeout automatically after install.\n Older hookless installs fall back to `ao codex ensure-start` / `ao codex ensure-stop`.\n Manual escape hatch: `ao codex status`" | | BD=true | "✅ Full stack ready.\n `bd ready` — see open work\n `/rpi \"your goal\"` — start a new goal from scratch\n `/status` — see current session state" | Starting a new project? Run `/scaffold ` to generate project structure with best practices. @@ -89,7 +89,7 @@ Starting a new project? Run `/scaffold ` to generate project st | Problem | Solution | |---------|----------| | Skills not installed | `bash <(curl -fsSL https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install.sh)` | -| Codex hooks on older versions (pre-v0.115.0) | Codex CLI v0.115.0+ has native hooks. For older versions, use `ao codex start` to begin and `ao codex stop` to close out; `ao codex status` shows hookless lifecycle health | +| Codex hooks on older installs | Current Codex installs with native hooks handle lifecycle automatically. For hookless installs, use `ao codex start` to begin and `ao codex stop` to close out; `ao codex status` shows hookless lifecycle health | | Flywheel count is 0 | First session — run `/rpi "a small goal"` to start it | | Want the full skill catalog | Ask: "show me all the skills" or see `references/full-catalog.md` |