diff --git a/docs/README.skills.md b/docs/README.skills.md index 400eb0554..c49e9784a 100644 --- a/docs/README.skills.md +++ b/docs/README.skills.md @@ -35,6 +35,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-skills) for guidelines on how to | [ai-prompt-engineering-safety-review](../skills/ai-prompt-engineering-safety-review/SKILL.md) | Comprehensive AI prompt engineering safety review and improvement prompt. Analyzes prompts for safety, bias, security vulnerabilities, and effectiveness while providing detailed improvement recommendations with extensive frameworks, testing methodologies, and educational content. | None | | [appinsights-instrumentation](../skills/appinsights-instrumentation/SKILL.md) | Instrument a webapp to send useful telemetry data to Azure App Insights | `LICENSE.txt`
`examples`
`references/ASPNETCORE.md`
`references/AUTO.md`
`references/NODEJS.md`
`references/PYTHON.md`
`scripts/appinsights.ps1` | | [apple-appstore-reviewer](../skills/apple-appstore-reviewer/SKILL.md) | Serves as a reviewer of the codebase with instructions on looking for Apple App Store optimizations or rejection reasons. | None | +| [arc](../skills/arc/SKILL.md) | Composable LLM agent orchestration via .arc.yml files. Reads declarative arc templates, generates reviewable execution plans (traces), and runs steps sequentially using existing skills as primitives. Use when orchestrating multi-skill development tasks, automating feature arcs, or creating reproducible development processes. Trigger: 'run arc', 'execute arc', 'arc', 'orchestrate skills', 'run the feature flow'. | `examples`
`references/acceptance-criteria.md`
`references/expression-syntax.md`
`references/file-format.md` | | [arch-linux-triage](../skills/arch-linux-triage/SKILL.md) | Triage and resolve Arch Linux issues with pacman, systemd, and rolling-release best practices. | None | | [architecture-blueprint-generator](../skills/architecture-blueprint-generator/SKILL.md) | Comprehensive project architecture blueprint generator that analyzes codebases to create detailed architectural documentation. Automatically detects technology stacks and architectural patterns, generates visual diagrams, documents implementation patterns, and provides extensible blueprints for maintaining architectural consistency and guiding new development. | None | | [arize-ai-provider-integration](../skills/arize-ai-provider-integration/SKILL.md) | INVOKE THIS SKILL when creating, reading, updating, or deleting Arize AI integrations. Covers listing integrations, creating integrations for any supported LLM provider (OpenAI, Anthropic, Azure OpenAI, AWS Bedrock, Vertex AI, Gemini, NVIDIA NIM, custom), updating credentials or metadata, and deleting integrations using the ax CLI. | `references/ax-profiles.md`
`references/ax-setup.md` | diff --git a/skills/arc/SKILL.md b/skills/arc/SKILL.md new file mode 100644 index 000000000..cdbdd4c15 --- /dev/null +++ b/skills/arc/SKILL.md @@ -0,0 +1,409 @@ +--- +name: arc +type: skill +version: '1.0.0' +description: > + Composable LLM agent orchestration via .arc.yml files. Reads declarative + arc templates, generates reviewable execution plans (traces), and runs + steps sequentially using existing skills as primitives. Use when orchestrating + multi-skill development tasks, automating feature arcs, or creating + reproducible development processes. Trigger: 'run arc', 'execute arc', + 'arc', 'orchestrate skills', 'run the feature flow'. +--- +# Skill Arcs — Composable LLM Agent Orchestration + +## Overview + +Execute declarative arc templates that chain existing skills into +reproducible, reviewable development processes. Bridges the gap between +manual step-by-step skill invocation and unpredictable autopilot mode. + +**The model**: You write the choreography (`.arc.yml`); the AI does the dancing. + +> **Customize**: Define your team's arcs in `.github/arcs/*.arc.yml`. +> Different projects share the same `/arc` skill but configure their own templates. + +## How It Works + +``` +1. User prompt → "Run feature-flow for issue #42" +2. /arc reads .arc.yml, binds parameters +3. Trace presented for review (Terraform plan-style) +4. User approves → steps execute sequentially +5. Each step invokes a skill or shell command +6. Context flows between steps via ${{ }} expressions +``` + +## Modes + +| Mode | Description | +|------|------------| +| **Template** | Read a `.arc.yml` file and execute it with bound parameters | +| **Ad-hoc** | Sketch an arc from a natural language prompt (no file needed) | +| **Inspect** | Show available arcs and their steps without executing | + + +## Arc Execution + +### Phase 1: Discover + +Find the arc to run: + +1. **Named arc** — user specifies an arc name: + - Search `.github/arcs/*.arc.yml` in the current repo + - Match by `name:` field in the arc file +2. **Ad-hoc** — user describes a task without naming an arc: + - Generate a trace from the prompt using available skills + - Present the generated trace for review before executing + +### Phase 2: Bind Parameters + +Resolve all `params:` from: +1. Values explicitly provided in the user's prompt +2. Default values defined in the arc file +3. **Ask the user** for any `required: true` params not yet resolved + +Validate: +- All required params are bound +- No `${{` expression references undefined params +- Warn (don't fail) on unused params + +### Phase 3: Generate Trace + +Build the concrete execution plan: + +``` +Arc: feature-flow +Params: issue_id = "42", branch_prefix = "feature" + +Steps: + 1. ✅ [run] Create feature branch + 2. ✅ [create-implementation-plan] Generate implementation plan + 3. 🔒 [GATE] Review the plan before proceeding + 4. ✅ [breakdown-test] Write failing tests + 5. ✅ [run] Run tests and implement + 6. ✅ [doublecheck] Review changes for quality + 7. ✅ [run] lint and test + 8. ✅ [git-commit] Commit with conventional message + 9. ✅ [run] Create pull request + +⚠️ 0 steps will be skipped (all skills available) +Approve this trace? [Y/n/edit] +``` + +Mark steps with: +- ✅ — skill/command available, ready to execute +- ⚠️ — skill not installed, will be **skipped** with a warning +- 🔒 — gate step, will pause for user approval + + +### Phase 4: Review Gate + +Present the trace to the user. The user can: +- **Approve** — execute all steps +- **Edit** — reorder, remove, or modify steps +- **Abort** — cancel without executing + + +### Phase 5: Execute + +Run each step sequentially: + +1. **Update status** — mark step as `running` in the session SQL database +2. **Invoke** — call the skill or run the shell command +3. **Capture outputs** — store outputs in the context object +4. **Update status** — mark step as `done`, `failed`, or `skipped` +5. **Check gates** — if next step is `gate: true`, pause for approval +6. **Handle failures** — based on `on_failure`: + - `pause` (default) — stop and ask: retry, skip, or abort + - `skip` — mark as skipped, continue to next step + - `retry` — re-invoke the step (max 1 retry) + - `abort` — stop the entire arc + + +### Phase 6: Report + +After completion (or abort), generate a summary: + +``` +Arc: feature-flow — COMPLETED +Duration: 12m 34s +Steps: 8/9 done, 1 gate + + 1. ✅ create-branch (5s) → branch: feature/42-add-rate-limiting + 2. ✅ plan (45s) → plan: docs/implementation-plan.md + 3. 🔒 review-plan (user approved) + 4. ✅ write-tests (1m 12s) + 5. ✅ implement (2m 48s) + 6. ✅ review (1m 05s) + 7. ✅ lint-and-test (18s) + 8. ✅ commit (12s) → commit: abc1234 + 9. ✅ create-pr (15s) → PR: #43 +``` + +## Arc File Format + +Arc files use YAML with `${{` expressions (GitHub Actions-style). +See `references/file-format.md` for the complete schema. + +### Minimal Example + +```yaml +name: tdd-cycle +description: TDD cycle for a single change. + +steps: + - id: implement + description: Implement the change + + - id: test + run: npm test + description: Run the test suite + + - id: review + skill: doublecheck + description: Quick review for quality and correctness + + - id: commit + skill: git-commit + description: Commit changes with a conventional commit message +``` + +### Full Example with Parameters and Context + +```yaml +name: feature-flow +description: End-to-end feature implementation from issue to PR. + +params: + issue_id: + description: Issue or work item ID + type: string + required: true + branch_prefix: + description: Branch naming prefix + type: string + default: feature + +steps: + - id: create-branch + run: git checkout -b ${{ params.branch_prefix }}/${{ params.issue_id }} + description: Create a feature branch + outputs: + - branch_name + + - id: plan + skill: create-implementation-plan + description: Generate implementation plan + outputs: + - plan_file + + - id: review-plan + gate: true + description: Review the implementation plan before proceeding + + - id: write-tests + skill: breakdown-test + description: Write failing tests for the first step + with: + plan_file: ${{ steps.plan.outputs.plan_file }} + + - id: implement + description: Make failing tests pass + + - id: review + skill: doublecheck + description: Review changes for quality + + - id: lint-and-test + run: npm run lint && npm test + description: Verify lint and tests pass + + - id: commit + skill: git-commit + description: Commit changes + + - id: create-pr + run: gh pr create --fill --base main + description: Create a pull request + outputs: + - pr_url +``` + +## Context Object + +A structured state map flows between steps, accumulating outputs: + +```json +{ + "params": { "issue_id": "42" }, + "steps": { + "create-branch": { + "status": "done", + "outputs": { "branch_name": "feature/42-add-rate-limiting" } + }, + "plan": { + "status": "done", + "outputs": { "plan_file": "docs/implementation-plan.md" } + } + } +} +``` + +See `references/expression-syntax.md` for the full expression reference. + +## SQL State Tracking + +Track arc execution in the session database: + +```sql +-- Create tables (auto-created on first arc run) +CREATE TABLE IF NOT EXISTS arc_runs ( + id TEXT PRIMARY KEY, + arc_name TEXT NOT NULL, + arc_file TEXT, + params TEXT, + status TEXT DEFAULT 'pending', + current_step TEXT, + context TEXT, + created_at TEXT DEFAULT (datetime('now')), + updated_at TEXT DEFAULT (datetime('now')) +); + +-- Auto-update updated_at on every state change +CREATE TRIGGER IF NOT EXISTS update_arc_runs_timestamp +AFTER UPDATE ON arc_runs +FOR EACH ROW +BEGIN + UPDATE arc_runs SET updated_at = datetime('now') + WHERE id = NEW.id; +END; + +CREATE TABLE IF NOT EXISTS arc_steps ( + run_id TEXT NOT NULL, + step_id TEXT NOT NULL, + step_index INTEGER NOT NULL, + skill TEXT, + status TEXT DEFAULT 'pending', + started_at TEXT, + completed_at TEXT, + outputs TEXT, + error TEXT, + PRIMARY KEY (run_id, step_id), + FOREIGN KEY (run_id) REFERENCES arc_runs(id) +); +``` + +Query progress at any time: +```sql +SELECT step_id, status, skill FROM arc_steps +WHERE run_id = '' ORDER BY step_index; +``` + +## Ad-hoc Arc Generation + +When no `.arc.yml` is specified, generate a trace from the user's prompt: + +1. Parse the prompt for skill references (`/git-commit`, `/doublecheck`, etc.) +2. Identify the development task type (feature, bugfix, refactor) +3. Generate a step sequence using a standard development workflow: + - Plan: `create-implementation-plan` → gate for review + - Build: `breakdown-test` → implement → `doublecheck` + - Verify: `run: ` → `run: ` + - Ship: `git-commit` → `run: gh pr create` +4. Present the generated trace for review (same approve/edit/abort flow) + +> **Note**: The skill names above are examples of a typical development +> workflow. Replace them with whatever skills are installed in your project. +> The arc skill discovers available skills at runtime and gracefully skips +> any that are not installed. + + +## Error Handling + +| Scenario | Behavior | +|----------|----------| +| Skill not installed | Step marked ⚠️ SKIP during trace generation | +| Step fails at runtime | Pause (default), offer retry/skip/abort | +| `${{` expression resolves to null | Warn during trace generation; step that uses it should handle gracefully | +| User aborts mid-arc | State preserved in SQL; report shows completed steps | +| Arc file has syntax errors | Fail at parse time with clear error message | +| Required param missing | Ask user before generating trace | + + +## Crash Recovery and Cleanup + +Arc state lives in the session SQL database, which is **ephemeral** — it +disappears when the Copilot CLI session ends (normally or via crash). This +means stale "running" state is not a concern; it simply vanishes. + +However, **side effects persist** after a crash or abort: + +| Side effect | Created by | Persists after crash? | +|-------------|-----------|----------------------| +| Git branches | `run: git checkout -b` | ✅ Yes — on disk | +| Files (plans, tests) | skill steps | ✅ Yes — on disk | +| Commits | `git-commit` | ✅ Yes — in git history | +| Draft PRs | `run: gh pr create` | ✅ Yes — in remote | +| SQL arc state | arc skill | ❌ No — lost with session | + +### Current behavior (v1) + +If an arc crashes or the user aborts mid-execution: + +1. The completion report shows which steps finished and which are pending +2. Git working tree may have uncommitted changes from the in-progress step +3. Branches and PRs from completed steps remain +4. The user must manually assess the state: `git status`, `git branch`, etc. + +### Recommended recovery steps + +After a crashed or abandoned arc: + +``` +git status # Check for uncommitted changes +git stash # Stash partial work if needed +git branch --list 'feature/*' # Find branches created during the arc +``` + + +## Inspecting Arcs + +List available arcs without executing: + +``` +> /arc list + +Available arcs: + feature-flow End-to-end feature implementation from issue to PR + bugfix-flow Test-first bug fix with PR creation + tdd-cycle TDD cycle — implement, test, review, commit + +Source: .github/arcs/ +``` + +Show arc details: + +``` +> /arc inspect feature-flow + +feature-flow: End-to-end feature implementation from issue to PR + Params: issue_id (required), branch_prefix (default: "feature") + Steps: 9 (1 gate) + Skills used: create-implementation-plan, breakdown-test, doublecheck, git-commit + Commands: git checkout, npm run lint, npm test, gh pr create +``` + + +## Checklist + +- [ ] Arc file parsed and validated (no syntax errors) +- [ ] All required parameters bound (asked user for missing values) +- [ ] Trace generated with correct status indicators (✅, ⚠️, 🔒) +- [ ] User reviewed and approved the trace before execution +- [ ] Steps executed sequentially with context flowing between them +- [ ] Gate steps paused for user approval +- [ ] Failed steps offered retry/skip/abort options +- [ ] Arc state tracked in session SQL database +- [ ] Completion report generated with step statuses and outputs +- [ ] Missing skills degraded gracefully (skip with warning) diff --git a/skills/arc/examples/bugfix-flow.arc.yml b/skills/arc/examples/bugfix-flow.arc.yml new file mode 100644 index 000000000..446a74e28 --- /dev/null +++ b/skills/arc/examples/bugfix-flow.arc.yml @@ -0,0 +1,64 @@ +# Example: Test-first bug fix arc +# +# Usage: +# /arc run bugfix-flow --issue_id 5678 +# +# This arc follows a TDD approach to fixing bugs: write a test that +# reproduces the bug, fix it, verify with a review, and create a PR +# linked to the work item. + +name: bugfix-flow +description: > + Test-first bug fix with code review and PR creation. + Writes a reproducing test, fixes the bug, reviews the change, + commits, and creates a PR. + +params: + issue_id: + description: Issue or work item ID for the bug + type: string + required: true + +steps: + - id: create-branch + run: git checkout -b fix/${{ params.issue_id }} + description: Create a bugfix branch + + - id: write-repro-test + skill: breakdown-test + description: Write a failing test that reproduces the bug + with: + issue_id: ${{ params.issue_id }} + + - id: fix-bug + description: Fix the bug — make the reproducing test pass + + - id: review + skill: doublecheck + description: Review the fix for correctness and regressions + on_failure: pause + + - id: lint-and-test + run: npm run lint && npm test + description: Lint and test + on_failure: skip + + - id: commit + skill: git-commit + description: Commit with conventional message linking the bug + with: + message_hint: "fix: resolve bug #${{ params.issue_id }}" + + - id: create-pr + run: gh pr create --fill --base main + description: Create PR for the bug fix + outputs: + - pr_url + + - id: summary + description: Bug fix report + template: | + ## Bug Fix Complete + - Bug: #${{ params.issue_id }} + - PR: ${{ steps.create-pr.outputs.pr_url }} + - Review: ${{ steps.review.status }} diff --git a/skills/arc/examples/feature-flow.arc.yml b/skills/arc/examples/feature-flow.arc.yml new file mode 100644 index 000000000..125c2e938 --- /dev/null +++ b/skills/arc/examples/feature-flow.arc.yml @@ -0,0 +1,78 @@ +# Example: End-to-end feature implementation arc +# +# Usage: +# /arc run feature-flow --issue_id 42 +# +# This arc creates a feature branch, generates an implementation plan, +# runs a full write-test-implement cycle, and creates a PR. It includes +# a review gate after planning so you can verify the approach before building. + +name: feature-flow +description: > + End-to-end feature implementation from issue to merged PR. + Creates a branch, plans, implements with tests, reviews, and opens a PR. + +params: + issue_id: + description: Issue or work item ID + type: string + required: true + branch_prefix: + description: Branch naming prefix + type: string + default: feature + +steps: + - id: create-branch + run: git checkout -b ${{ params.branch_prefix }}/${{ params.issue_id }} + description: Create a feature branch from main + outputs: + - branch_name + + - id: plan + skill: create-implementation-plan + description: Generate implementation plan for the feature + outputs: + - plan_file + - step_count + + - id: review-plan + gate: true + description: Review the implementation plan before proceeding + + - id: write-tests + skill: breakdown-test + description: Write failing tests for the implementation plan + with: + plan_file: ${{ steps.plan.outputs.plan_file }} + + - id: implement + description: Make failing tests pass with minimal code + + - id: review + skill: doublecheck + description: Review changes for correctness and quality + + - id: lint-and-test + run: npm run lint && npm test + description: Verify lint and tests pass + on_failure: skip + + - id: commit + skill: git-commit + description: Commit changes with conventional commit message + + - id: create-pr + run: gh pr create --fill --base main + description: Create a pull request + outputs: + - pr_url + + - id: summary + description: Report what was accomplished + template: | + ## Feature Flow Complete + - Issue: ${{ params.issue_id }} + - Branch: ${{ steps.create-branch.outputs.branch_name }} + - Plan: ${{ steps.plan.outputs.plan_file }} + - PR: ${{ steps.create-pr.outputs.pr_url }} diff --git a/skills/arc/examples/tdd-cycle.arc.yml b/skills/arc/examples/tdd-cycle.arc.yml new file mode 100644 index 000000000..b0b831c2b --- /dev/null +++ b/skills/arc/examples/tdd-cycle.arc.yml @@ -0,0 +1,29 @@ +# Example: TDD cycle arc +# +# Usage: +# /arc run tdd-cycle +# +# A simple test-driven development arc — implement a change, run tests, +# review, and commit. No parameters needed, no gates. Good for small changes +# and iterative development. + +name: tdd-cycle +description: > + TDD cycle for a single change. Implement → Test → Review → Commit. + +steps: + - id: implement + description: Implement the change + + - id: test + run: npm test + description: Run the test suite + on_failure: skip + + - id: review + skill: doublecheck + description: Quick review for quality and correctness + + - id: commit + skill: git-commit + description: Commit changes with a conventional commit message diff --git a/skills/arc/references/acceptance-criteria.md b/skills/arc/references/acceptance-criteria.md new file mode 100644 index 000000000..0eab48692 --- /dev/null +++ b/skills/arc/references/acceptance-criteria.md @@ -0,0 +1,323 @@ + +# Acceptance Criteria — Arc Skill + +## AC-1: Arc file parsing and validation + +The skill must parse `.arc.yml` files and catch errors at parse time. + +### Correct + +```yaml +# Valid arc file with required fields +name: feature-flow +description: End-to-end feature implementation. + +steps: + - id: implement + description: Implement the feature + + - id: test + run: npm test + description: Run test suite +``` + +``` +✅ Parsed: feature-flow (2 steps, 0 gates, 0 params) +``` + +### Incorrect + +```yaml +# Missing required 'name' field +description: An arc without a name. + +steps: + - id: implement + description: Implement +``` + +``` +❌ Parse error: arc file must have a 'name' field +``` + +```yaml +# Duplicate step IDs +name: bad-arc +steps: + - id: build + description: Build + - id: build + description: Also build +``` + +``` +❌ Parse error: duplicate step id 'build' +``` + +--- + +## AC-2: Parameter binding and resolution + +Required parameters must be resolved before execution. Missing required params +trigger a user prompt; defaults fill in optional params automatically. + +### Correct + +```yaml +params: + issue_id: + type: string + required: true + branch_prefix: + type: string + default: feature + +steps: + - id: init + run: git checkout -b ${{ params.branch_prefix }}/${{ params.issue_id }} + description: Create feature branch +``` + +``` +> /arc run feature-flow --issue_id 1234 + +Params resolved: + issue_id = "1234" (from prompt) + branch_prefix = "feature" (default) +``` + +### Incorrect + +``` +> /arc run feature-flow + +❌ Missing required parameter: issue_id + Description: Issue or work item ID + Please provide a value: +``` + +The skill must NOT proceed with unresolved required parameters. It must +ask the user for missing values before generating the trace. + +--- + +## AC-3: Trace generation with status indicators + +The generated trace must clearly show which steps will run, skip, or gate. + +### Correct + +``` +Arc: feature-flow +Params: issue_id = "1234" + +Steps: + 1. ✅ [run] Create feature branch + 2. ✅ [create-implementation-plan] Generate implementation plan + 3. 🔒 [GATE] Review plan before proceeding + 4. ⚠️ [breakdown-test] Write failing tests — skill not available, will SKIP + 5. ✅ [run] Run tests + 6. ✅ [git-commit] Commit changes + +⚠️ 1 step will be skipped (missing skills) +Approve and execute? [Y/n/edit] +``` + +### Incorrect + +``` +Running feature-flow... +Step 1: create branch... done +Step 2: plan... done +Step 3: breakdown-test... ERROR: skill not found +Arc failed. +``` + +The skill must NEVER fail at runtime due to a missing skill. Missing skills +are detected during trace generation and marked as skipped. + +--- + +## AC-4: Gate steps pause for user approval + +Steps marked `gate: true` must always pause and wait for user input. + +### Correct + +```yaml +steps: + - id: plan + skill: create-implementation-plan + description: Generate plan + + - id: review + gate: true + description: Review the plan before implementing + + - id: implement + description: Implement the plan +``` + +``` +Step 2/3: 🔒 GATE — Review the plan before implementing +The implementation plan has been generated. +Continue to implementation? [Y/n/abort] +``` + +### Incorrect + +``` +Step 1: plan... done +Step 2: review gate... auto-approved +Step 3: implement... done +``` + +Gate steps must NEVER be auto-approved. They always require explicit user +confirmation to continue. + +--- + +## AC-5: Context flows between steps via expressions + +Step outputs must be accessible to subsequent steps via `${{ }}` expressions. + +### Correct + +```yaml +steps: + - id: create-branch + run: git checkout -b feature/new-feature + description: Create feature branch + outputs: + - branch_name + + - id: plan + skill: create-implementation-plan + description: Plan for the current branch + with: + branch: ${{ steps.create-branch.outputs.branch_name }} +``` + +The `branch` parameter passed to `create-implementation-plan` resolves to the actual branch +name created in the previous step (e.g., `feature/1234/add-rate-limiting`). + +### Incorrect + +```yaml +steps: + - id: plan + skill: create-implementation-plan + description: Plan for the current branch + with: + branch: ${{ steps.nonexistent.outputs.branch_name }} +``` + +``` +⚠️ Warning: expression references undefined step 'nonexistent' + ${{ steps.nonexistent.outputs.branch_name }} will resolve to null +``` + +Broken expressions must be caught during trace generation, not at runtime. + +--- + +## AC-6: Failure handling respects on_failure policy + +Each step's `on_failure` setting determines behavior when it fails. + +### Correct + +```yaml +steps: + - id: lint + run: npm run lint + description: Lint check + on_failure: skip + + - id: commit + skill: git-commit + description: Commit changes + # on_failure defaults to 'pause' +``` + +``` +Step 1: lint... FAILED (exit code 1) + on_failure: skip — continuing to next step + +Step 2: git-commit... + 🔄 FAILED — git-commit returned an error + [R]etry / [S]kip / [A]bort? +``` + +### Incorrect + +``` +Step 1: lint... FAILED +Arc aborted. +``` + +The default `on_failure` is `pause` (not `abort`). The arc must +offer the user a choice on failure unless explicitly configured otherwise. + +--- + +## AC-7: SQL state tracking is accurate + +Arc runs and step statuses must be tracked in the session database. + +### Correct + +```sql +-- After step 3 completes in a 5-step arc: +SELECT step_id, status FROM arc_steps WHERE run_id = 'abc-123'; + +-- Returns: +-- init-stack | done +-- plan | done +-- review | done +-- write-tests | running +-- commit | pending +``` + +### Incorrect + +```sql +-- No records found — arc ran without tracking +SELECT * FROM arc_runs; +-- (empty) +``` + +Every arc execution must create records in `arc_runs` and +`arc_steps`. State must be updated in real time as steps complete. + +--- + +## AC-8: Graceful degradation for missing skills + +Arcs must run successfully even when some referenced skills are not +installed, by skipping unavailable steps. + +### Correct + +``` +Arc: feature-flow (2 of 5 skills unavailable) + +Steps: + 1. ✅ [run] Create feature branch + 2. ⚠️ [create-implementation-plan] SKIP — skill not available + 3. ✅ [breakdown-test] Write failing tests + 4. ⚠️ [doublecheck] SKIP — skill not available + 5. ✅ [git-commit] Commit changes + +⚠️ 2 steps will be skipped. Continue? [Y/n] +``` + +### Incorrect + +``` +ERROR: skill 'create-implementation-plan' is not installed. Arc cannot run. +``` + +The arc must NEVER hard-fail because a skill is missing. Missing skills +are skipped with a warning. The user sees which steps will be skipped during +trace review and can decide whether to proceed. diff --git a/skills/arc/references/expression-syntax.md b/skills/arc/references/expression-syntax.md new file mode 100644 index 000000000..b63923cbd --- /dev/null +++ b/skills/arc/references/expression-syntax.md @@ -0,0 +1,181 @@ + +# Expression Syntax Reference + +## Overview + +Arc expressions use `${{ }}` delimiters to reference parameters, step +outputs, and step statuses. The syntax is intentionally aligned with GitHub +Actions expressions to lower the learning curve. + +## Expression Format + +``` +${{ . }} +``` + +Expressions are resolved: +- **At trace generation time** for `params.*` references +- **At execution time** for `steps.*` references (since outputs aren't known upfront) + +## Namespaces + +### params + +Access arc parameters: + +```yaml +${{ params.issue_id }} # → "1234" +${{ params.branch_prefix }} # → "feature" +``` + +### steps + +Access step outputs and status: + +```yaml +${{ steps.create-branch.outputs.branch_name }} # → "feature/42-add-rate-limiting" +${{ steps.create-branch.status }} # → "done" +${{ steps.plan.outputs.plan_file }} # → "docs/implementation-plan.md" +``` + +## Available Properties + +### Step properties + +| Expression | Type | Description | +|-----------|------|-------------| +| `steps..status` | string | `pending`, `running`, `done`, `skipped`, `failed` | +| `steps..outputs.` | any | Output value set by the step | + +### Param properties + +| Expression | Type | Description | +|-----------|------|-------------| +| `params.` | any | Bound parameter value | + + + + + +## Resolution Rules + +1. **Params** resolve to their bound value (from user prompt or default) +2. **Step outputs** resolve to the value set during execution +3. **Undefined references** resolve to `null` with a warning +4. **Skipped step outputs** resolve to `null` (the step never ran) + +## Usage in Steps + +### In `with:` parameters + +```yaml +- id: plan + skill: create-implementation-plan + with: + branch: ${{ steps.create-branch.outputs.branch_name }} + issue: ${{ params.issue_id }} +``` + +### In `if:` conditions + +```yaml +- id: security-check + skill: security-check + if: ${{ steps.implement.status == 'done' }} +``` + +### In `template:` output + +```yaml +- id: summary + template: | + Branch: ${{ steps.create-branch.outputs.branch_name }} + PR: ${{ steps.create-pr.outputs.pr_url }} +``` + +## Comparison Operators (in `if:` conditions) + +| Operator | Example | Description | +|----------|---------|-------------| +| `==` | `${{ steps.x.status == 'done' }}` | Equality check | +| `!=` | `${{ steps.x.status != 'failed' }}` | Inequality check | + + + + + +## Error Handling + +| Scenario | Behavior | +|----------|----------| +| `${{ params.undefined_param }}` | Warning at trace generation time | +| `${{ steps.nonexistent.outputs.x }}` | Warning at trace generation time | +| `${{ steps.skipped-step.outputs.x }}` | Resolves to `null` at execution time | +| Malformed expression (missing `}}`) | Parse error at trace generation time | +| Self-referencing expression | Parse error (step cannot reference its own outputs) | + +## Examples + +### Basic parameter passing + +```yaml +params: + issue_id: + type: string + required: true + +steps: + - id: create-branch + run: git checkout -b feature/${{ params.issue_id }} + description: Create a feature branch +``` + +### Chaining step outputs + +```yaml +steps: + - id: create-branch + run: git checkout -b feature/new-feature + description: Create a branch + outputs: + - branch_name + + - id: plan + skill: create-implementation-plan + with: + branch: ${{ steps.create-branch.outputs.branch_name }} + outputs: + - plan_file + + - id: tests + skill: breakdown-test + with: + plan: ${{ steps.plan.outputs.plan_file }} +``` + +### Conditional execution + +```yaml +steps: + - id: implement + description: Implement the feature + + - id: review + skill: doublecheck + if: ${{ steps.implement.status == 'done' }} + description: Only run review if implementation succeeded +``` + +### Summary template + +```yaml +steps: + - id: report + description: Final report + template: | + ## Arc Complete + - Issue: ${{ params.issue_id }} + - Branch: ${{ steps.create-branch.outputs.branch_name }} + - Tests: ${{ steps.test.status }} + - PR: ${{ steps.create-pr.outputs.pr_url }} +``` diff --git a/skills/arc/references/file-format.md b/skills/arc/references/file-format.md new file mode 100644 index 000000000..174e55fab --- /dev/null +++ b/skills/arc/references/file-format.md @@ -0,0 +1,230 @@ + +# Arc File Format Reference + +## Overview + +Arc files define reusable, parameterized templates for multi-skill +development tasks. They use YAML syntax with `${{ }}` expressions (inspired +by GitHub Actions) and live in `.github/arcs/*.arc.yml`. + +## File Location + +``` +.github/arcs/ +├── feature-flow.arc.yml +├── bugfix-flow.arc.yml +└── tdd-cycle.arc.yml +``` + +The `/arc` skill searches `.github/arcs/` for `*.arc.yml` files. + + + + +## Top-Level Schema + +```yaml +# Required fields +name: string # Unique arc name (kebab-case) +description: string # Human-readable description shown during review + +# Optional fields +params: map # Parameters bound at runtime (see Params section) +steps: list # Ordered list of steps (see Steps section) +``` + +## Params + +Parameters make arcs reusable. They are bound from the user's prompt, +defaults, or interactive prompts. + +```yaml +params: + issue_id: + description: string # Shown when asking user for value + type: string # string | number | boolean + required: true # If true, must be provided before execution + branch_prefix: + description: string + type: string + default: feature # Used if not provided by user +``` + +### Type validation + +| Type | Accepts | Example | +|------|---------|---------| +| `string` | Any text | `"1234"`, `"feature"` | +| `number` | Integer or float | `42`, `3.14` | +| `boolean` | true/false | `true`, `false` | + + + + +## Steps + +Steps are the core of an arc. Each step invokes a skill, runs a command, +or acts as a gate. + +### Step Schema + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `id` | string | **Yes** | Unique kebab-case identifier | +| `description` | string | **Yes** | Shown during review and execution | +| `skill` | string | No | Skill to invoke (mutually exclusive with `run`) | +| `run` | string | No | Shell command to execute (mutually exclusive with `skill`) | +| `with` | map | No | Parameters passed to the skill, supports `${{ }}` | +| `outputs` | list[string] | No | Keys this step writes to the context | +| `gate` | boolean | No | If true, pause for user approval | +| `if` | string | No | Condition — step skipped if false | +| `on_failure` | string | No | `pause` (default), `skip`, `retry`, `abort` | +| `template` | string | No | Output template rendered at completion | + +### Step Types + +**Skill step** — invokes an existing Copilot skill: +```yaml +- id: write-tests + skill: breakdown-test + description: Write failing tests + with: + plan_file: ${{ steps.plan.outputs.plan_file }} +``` + +**Command step** — runs a shell command: +```yaml +- id: lint-check + run: npm run lint + description: Verify no lint violations +``` + +**Gate step** — pauses for human review: +```yaml +- id: review-plan + gate: true + description: Review the implementation plan before proceeding +``` + +**Template step** — renders a summary (no skill or command): +```yaml +- id: summary + description: Report what was accomplished + template: | + Branch: ${{ steps.init-stack.outputs.branch_name }} + PR: ${{ steps.create-pr.outputs.pr_url }} +``` + +### Validation Rules + +1. Every step must have `id` and `description` +2. `id` values must be unique within an arc +3. `id` must be kebab-case (lowercase, hyphens only) +4. `skill` and `run` are mutually exclusive +5. `gate` steps should not have `skill` or `run` +6. Steps execute in declaration order (top to bottom) + + + + + +## on_failure Behavior + +| Value | Behavior | +|-------|----------| +| `pause` | Stop and ask user: retry, skip, or abort (default) | +| `skip` | Mark step as skipped, continue to next | +| `retry` | Re-invoke the step once, then pause if still failing | +| `abort` | Stop the entire arc immediately | + + + +## Conditional Steps + +Use `if` to conditionally skip steps: + +```yaml +- id: security-check + skill: security-check + description: Security scan + if: ${{ steps.implement.status == 'done' }} +``` + +The condition is evaluated at execution time. If it evaluates to false +or null, the step is skipped. + + + + +## Complete Example + +```yaml +name: feature-flow +description: > + End-to-end feature implementation from issue to merged PR. + Creates a branch, plans, implements with tests, and opens a PR. + +params: + issue_id: + description: Issue or work item ID + type: string + required: true + branch_prefix: + description: Branch naming prefix + type: string + default: feature + +steps: + - id: create-branch + run: git checkout -b ${{ params.branch_prefix }}/${{ params.issue_id }} + description: Create a feature branch + outputs: + - branch_name + + - id: plan + skill: create-implementation-plan + description: Generate implementation plan for the feature + outputs: + - plan_file + - step_count + + - id: review-plan + gate: true + description: Review the implementation plan before proceeding + + - id: write-tests + skill: breakdown-test + description: Write failing tests for the implementation plan + with: + plan_file: ${{ steps.plan.outputs.plan_file }} + + - id: implement + description: Make failing tests pass with minimal code + + - id: review + skill: doublecheck + description: Review changes for quality + + - id: lint-and-test + run: npm run lint && npm test + description: Verify lint and tests pass + on_failure: skip + + - id: commit + skill: git-commit + description: Commit changes with conventional commit message + + - id: create-pr + run: gh pr create --fill --base main + description: Create a pull request + outputs: + - pr_url + + - id: summary + description: Report what was accomplished + template: | + Completed: ${{ params.issue_id }} + Branch: ${{ steps.create-branch.outputs.branch_name }} + PR: ${{ steps.create-pr.outputs.pr_url }} + Plan: ${{ steps.plan.outputs.plan_file }} +```