From 682bd79fa722a249ea0eaa82449deef67a0447e7 Mon Sep 17 00:00:00 2001 From: Kris Hicks Date: Wed, 22 Jul 2026 16:22:01 -0700 Subject: [PATCH] docs: document issue lifecycle labels and roadmap sequencing Add a published Issue Triage and Lifecycle page and align AGENTS.md, CONTRIBUTING.md, README.md, the PR template, and the issue-handling skills on the state:*/agent:* label model. Signed-off-by: Kris Hicks --- .agents/skills/build-from-issue/SKILL.md | 112 +++++++---- .agents/skills/create-github-issue/SKILL.md | 2 + .agents/skills/create-github-pr/SKILL.md | 10 +- .agents/skills/create-spike/SKILL.md | 38 ++-- .agents/skills/fix-security-issue/SKILL.md | 54 +++--- .agents/skills/review-security-issue/SKILL.md | 18 +- .agents/skills/sync-agent-infra/SKILL.md | 4 +- .agents/skills/triage-issue/SKILL.md | 125 ++++++++---- .github/PULL_REQUEST_TEMPLATE.md | 7 +- .github/workflows/stale.yml | 2 +- AGENTS.md | 12 +- CONTRIBUTING.md | 53 ++++- README.md | 6 +- docs/resources/issue-lifecycle.mdx | 181 ++++++++++++++++++ 14 files changed, 480 insertions(+), 144 deletions(-) create mode 100644 docs/resources/issue-lifecycle.mdx diff --git a/.agents/skills/build-from-issue/SKILL.md b/.agents/skills/build-from-issue/SKILL.md index 33219998d7..8d6e2ac585 100644 --- a/.agents/skills/build-from-issue/SKILL.md +++ b/.agents/skills/build-from-issue/SKILL.md @@ -1,6 +1,6 @@ --- name: build-from-issue -description: Given a GitHub issue number, plan and implement the work described in the issue. Operates iteratively - creates an implementation plan, responds to feedback, and only builds when the 'state:agent-ready' label is applied. Includes tests, documentation updates, and PR creation. Trigger keywords - build from issue, implement issue, work on issue, build issue, start issue. +description: Given a GitHub issue number, plan and implement the work described in the issue. Supports direct user requests and unattended queue processing through the `agent:*` workflow labels. Includes tests, documentation updates, and PR creation. Trigger keywords - build from issue, implement issue, work on issue, build issue, start issue. --- # Build From Issue @@ -14,16 +14,18 @@ This skill operates as a stateful workflow — it can be run repeatedly against - The `gh` CLI must be authenticated (`gh auth status`) - You must be in a git repository with a GitHub remote -## Critical: `state:agent-ready` Label Is Human-Only +## Invocation and Authorization -The `state:agent-ready` label is a **human gate**. It signals that a human has reviewed the plan and authorized the agent to build. Under **no circumstances** should this skill or any agent: +This skill supports two invocation modes: -- Apply the `state:agent-ready` label -- Ask the user to let the agent apply it -- Suggest automating its application -- Bypass the check by proceeding without it +- **Direct mode:** A user explicitly asks the agent to plan or implement a specific issue. The request itself authorizes the requested phase; the corresponding `agent:*` request label is not required. +- **Queue mode:** An always-on or unattended agent scans for work without a live user directing it to a specific issue. In this mode, `agent:plan-requested` authorizes planning and `agent:implementation-requested` authorizes implementation. -If the label is not present, the agent **must stop and wait**. This is a non-negotiable safety control — it ensures a human explicitly authorizes every build. +A direct request authorizes only what it says. A request to review or plan does not authorize implementation. A request to build, implement, or work on an issue authorizes both the planning needed to perform the work and implementation unless the user asks to stop after planning. + +The two request labels remain human-only queue controls. Under **no circumstances** should this skill or any agent apply them, ask to apply them, or suggest automating their application. + +Do not refuse a direct user request merely because its request label is absent. If direct work begins on an issue that was not already in the label-driven workflow, do not introduce `agent:in-progress` or `agent:pr-opened` solely for that invocation. If a matching request label is present, preserve the existing label transitions so unattended agents can track the workflow. ## Agent Comment Markers @@ -54,31 +56,43 @@ Each invocation follows this decision tree: ``` Fetch issue + comments │ - ├─ No plan comment (🏗️ build-plan) found? + ├─ topic:security present? + │ → Route to review-security-issue or fix-security-issue; STOP + │ + ├─ Triage incomplete, awaiting information, or awaiting human disposition? + │ → Report the blocking state and STOP + │ + ├─ state:accepted absent? + │ → Human has not accepted the issue; STOP + │ + ├─ No plan comment and no direct planning request and agent:plan-requested absent? + │ → No request for agent planning; STOP + │ + ├─ No plan comment + direct planning request or agent:plan-requested present? │ → Generate plan via principal-engineer-reviewer │ → Post plan comment - │ → Add 'state:review-ready' label - │ → STOP + │ → Advance labels only for a label-driven invocation + │ → Continue if the direct request also authorized implementation; otherwise STOP │ ├─ Plan exists + new human comments since last agent response? │ → Respond to each comment (quote context, address feedback) │ → Update the plan comment if feedback requires plan changes │ → STOP │ - ├─ Plan exists + 'state:agent-ready' label + no 'state:in-progress' or 'state:pr-opened' label? + ├─ Plan exists + direct implementation request or 'agent:implementation-requested' label? │ → Run scope check (warn if high complexity) │ → Check for conflicting branches/PRs │ → BUILD (Steps 6–14) │ - ├─ 'state:in-progress' label present? + ├─ 'agent:in-progress' label present? │ → Detect existing branch and resume if possible │ → Otherwise report current state │ - ├─ 'state:pr-opened' label present? + ├─ 'agent:pr-opened' label present? │ → Report that PR already exists, link to it │ → STOP │ - └─ Plan exists + no new comments + no 'state:agent-ready'? + └─ Plan exists + no new comments + no direct implementation request or 'agent:implementation-requested'? → Report: "Plan is posted and awaiting review. No new comments to address." → STOP ``` @@ -93,7 +107,15 @@ gh issue view --json number,title,body,state,labels,author If the issue is closed, report that and stop. -If the issue has the `state:triage-needed` label, report that the issue has not been triaged yet. Suggest using the `triage-issue` skill first to assess and classify the issue before planning implementation. Stop. +If `topic:security` is present, stop. General build agents must not plan or implement security issues. Route planning/review to `review-security-issue` and authorized remediation to `fix-security-issue`. + +Stop before planning in any of these states: + +- `state:triage-needed`: the issue has not been assessed; use `triage-issue`. +- `state:needs-info`: triage is waiting for evidence from the reporter. +- `state:validated`: triage is complete, but a human has not yet decided whether OpenShell should invest in the work. + +Next, require `state:accepted`. It records the human decision to pursue the work. If no plan exists, require either a direct user request for planning or the human-applied `agent:plan-requested` label before generating one. Record any roadmap association as sequencing context, but do not require one. Never add or remove `state:accepted`, either human request label, or the `roadmap` label. ## Step 2: Fetch and Classify Comments @@ -117,7 +139,8 @@ Using the state machine above, determine what to do based on: 1. Whether a plan comment exists 2. Whether there are human comments newer than the last agent comment (plan or conversation) -3. Which labels are present (`state:review-ready`, `state:agent-ready`, `state:in-progress`, `state:pr-opened`) +3. Whether this is direct mode and which phase the user requested +4. Which disposition, roadmap, and agent-workflow labels are present (`state:accepted`, `agent:plan-requested`, `agent:plan-ready`, `agent:implementation-requested`, `agent:in-progress`, `agent:pr-opened`, and the `roadmap` label) Follow the appropriate branch below. @@ -125,7 +148,7 @@ Follow the appropriate branch below. ## Branch A: Generate the Plan -If no plan comment exists, generate one. +If no plan comment exists, generate one when the user directly requested planning or implementation, or when `agent:plan-requested` is present. Otherwise report that no one has requested agent planning and stop. ### A1: Analyze the Issue with Principal Engineer Reviewer @@ -195,13 +218,15 @@ EOF )" ``` -### A3: Add the `state:review-ready` Label +### A3: Mark the Plan Ready in Queue Mode + +If `agent:plan-requested` was present, replace it with `agent:plan-ready`. Do not add `agent:plan-ready` for a direct invocation that was not already using the label workflow. ```bash -gh issue edit --add-label "state:review-ready" +gh issue edit --remove-label "agent:plan-requested" --add-label "agent:plan-ready" ``` -Report to the user that the plan has been posted and is awaiting review. Stop. +If the direct request authorized implementation, continue to Branch C. Otherwise report that the plan has been posted and stop. In queue mode, a human reviews the plan and applies `agent:implementation-requested` before an unattended agent can build. --- @@ -269,7 +294,7 @@ Report to the user what feedback was addressed and whether the plan was updated. ## Branch C: Build -If the plan exists and the `state:agent-ready` label is present (and neither `state:in-progress` nor `state:pr-opened` is set), proceed with implementation. +Proceed with implementation when the plan exists and either the user directly requested implementation or `agent:implementation-requested` is present. An existing `agent:in-progress` or `agent:pr-opened` label still triggers the resume or existing-PR checks below. ### Step 4: Scope Check @@ -279,7 +304,7 @@ Read the plan comment and check the **Complexity** and **Confidence** fields. > "This issue is rated High complexity / Low confidence. The plan includes open questions that may need human decisions during implementation. Proceeding, but flagging this for your awareness." - Continue — do not hard-stop. The human chose to apply `state:agent-ready`. + Continue — do not hard-stop. The user directly requested implementation or chose to apply `agent:implementation-requested`. ### Step 5: Conflict Detection @@ -324,10 +349,12 @@ git pull origin main git checkout -b -/$USERNAME ``` -### Step 7: Add `state:in-progress` Label +### Step 7: Mark Queue Work In Progress + +If `agent:implementation-requested` is present, replace it and `agent:plan-ready` with `agent:in-progress`. In direct mode without a request label, do not add an agent-workflow label. ```bash -gh issue edit --add-label "state:in-progress" +gh issue edit --remove-label "agent:implementation-requested" --remove-label "agent:plan-ready" --add-label "agent:in-progress" ``` ### Step 8: Implement the Changes @@ -594,10 +621,10 @@ Include **every test** that ran (not just the new ones) so the reviewer can see #### Update labels -Remove `state:in-progress` and `state:review-ready`, add `state:pr-opened`: +If `agent:in-progress` is present, replace it with `agent:pr-opened`. Do not add `agent:pr-opened` for an unlabeled direct invocation: ```bash -gh issue edit --remove-label "state:in-progress" --remove-label "state:review-ready" --add-label "state:pr-opened" +gh issue edit --remove-label "agent:in-progress" --add-label "agent:pr-opened" ``` #### Report workflow run URL @@ -615,7 +642,7 @@ Report the workflow run URL and suggest the user can use the `watch-github-actio ## Branch D: Resume In-Progress Build -If the `state:in-progress` label is present, the skill was previously started but may not have completed. +If the `agent:in-progress` label is present, the skill was previously started but may not have completed. 1. Check for an existing branch matching the issue ID: ```bash @@ -623,7 +650,7 @@ If the `state:in-progress` label is present, the skill was previously started bu ``` 2. If found, check it out and inspect the state (are there uncommitted changes? committed but not pushed? pushed but no PR?). 3. Resume from the appropriate step (9, 10, 12, or 13). -4. If the state is unrecoverable, report to the user and suggest starting fresh (remove `state:in-progress` label and re-run). +4. If the state is unrecoverable, report to the user and suggest starting fresh. Queue mode requires a human to reapply `agent:implementation-requested`; a new direct implementation request can resume without it. --- @@ -649,15 +676,16 @@ If the `state:in-progress` label is present, the skill was previously started bu ### First run — no plan exists -User says: "Build from issue #42" +User says: "Plan issue #42" 1. Fetch issue #42 — title: "Add pagination to dataset list endpoint" -2. Fetch comments — no `🏗️ build-plan` marker found -3. Pass issue to `principal-engineer-reviewer` for analysis -4. Reviewer produces a plan: feat type, Medium complexity, 3 implementation steps, unit + integration tests needed -5. Post the plan comment with the `🏗️ build-plan` marker -6. Add `state:review-ready` label -7. Report to user: "Plan posted on issue #42. Awaiting review." +2. Confirm `state:accepted` with no blocking triage state; the user's direct request authorizes planning even if `agent:plan-requested` is absent +3. Fetch comments — no `🏗️ build-plan` marker found +4. Pass issue to `principal-engineer-reviewer` for analysis +5. Reviewer produces a plan: feat type, Medium complexity, 3 implementation steps, unit + integration tests needed +6. Post the plan comment with the `🏗️ build-plan` marker +7. Because this direct invocation was unlabeled, leave the `agent:*` workflow labels unchanged +8. Report to user: "Plan posted on issue #42. Awaiting review." ### Second run — human left feedback @@ -679,29 +707,29 @@ User says: "Check issue #42" 4. Edit the plan comment to include search endpoint pagination — Revision 2 5. Report to user: "Updated plan to include search pagination (Revision 2)." -### Fourth run — state:agent-ready applied +### Fourth run — implementation requested User says: "Build issue #42" -1. Fetch issue #42 — labels include `state:agent-ready` +1. Fetch issue #42 — `state:accepted` is present; the user's direct request authorizes implementation 2. Plan exists (Revision 2), complexity: Medium, confidence: High 3. No conflicting branches or PRs 4. Create branch `feat/42-add-pagination/jmyers` -5. Add `state:in-progress` label +5. Leave `agent:*` labels unchanged because this direct invocation was not picked up from the queue 6. Implement pagination for both endpoints per the plan 7. Add unit tests for pagination logic, integration tests for both endpoints 8. `mise run pre-commit` passes on first attempt 9. E2E tests skipped (no changes under `e2e/`) 10. Commit, push, create PR with `Closes #42` 11. Post summary comment on issue with PR link -12. Update labels: remove `state:in-progress` + `state:review-ready`, add `state:pr-opened` +12. No agent-workflow label transition is needed 13. Report PR URL and workflow run status to user ### Run on issue with existing PR User says: "Build issue #42" -1. Fetch issue #42 — `state:pr-opened` label present +1. Fetch issue #42 — `agent:pr-opened` label present 2. Find existing PR #789 linked to the issue 3. Report: "PR [#789](...) already exists for issue #42. Nothing to build." @@ -709,7 +737,7 @@ User says: "Build issue #42" User says: "Build issue #99" -1. Fetch issue #99 — `state:agent-ready` label present +1. Fetch issue #99 — `state:accepted` is present; the user's direct request authorizes implementation 2. Plan exists: complexity High, confidence Low, has open questions 3. Warn user: "Issue #99 is rated High complexity / Low confidence. Proceeding but flagging for your awareness." 4. Continue with build diff --git a/.agents/skills/create-github-issue/SKILL.md b/.agents/skills/create-github-issue/SKILL.md index d196fc8c8d..8352603e76 100644 --- a/.agents/skills/create-github-issue/SKILL.md +++ b/.agents/skills/create-github-issue/SKILL.md @@ -114,6 +114,8 @@ EOF GitHub built-in issue types (`Bug`, `Feature`, `Task`) should come from the matching issue template when possible, or be set manually afterward. Do not try to emulate them through labels. +Creating an issue does not accept it for roadmap work or queue agent work. Agents never apply the `roadmap` label, add issues to the roadmap project, or apply `agent:plan-requested` or `agent:implementation-requested`. Community issues proceed through `triage-issue`; a human decides whether technically validated work should be accepted and places it on the roadmap. The request labels queue work for unattended agents; a user may instead direct an agent to a specific issue. + ## Useful Options | Option | Description | diff --git a/.agents/skills/create-github-pr/SKILL.md b/.agents/skills/create-github-pr/SKILL.md index 6c36af3833..d98aba37f2 100644 --- a/.agents/skills/create-github-pr/SKILL.md +++ b/.agents/skills/create-github-pr/SKILL.md @@ -11,7 +11,7 @@ Create pull requests on GitHub using the `gh` CLI. - The `gh` CLI must be authenticated (`gh auth status`) - You must have commits on a branch that's pushed to the remote -- Branch should follow naming convention: `-/` +- For issue-backed work, the branch should follow `-/`. Exempt issue-less changes may use `/`. ## Before Creating a PR @@ -47,7 +47,7 @@ Before creating a PR, verify: git branch --show-current ``` -2. **Branch follows naming convention** - Format: `-/` +2. **Branch follows naming convention** - Use `-/` for issue-backed work or `/` for an exempt issue-less change. ```bash # Example: 1234-add-pagination/jd @@ -114,7 +114,7 @@ gh pr create --title "PR title" --body "PR description" ### Link to an Issue -Use `Closes #` in the body to auto-close the issue when merged: +Features, user-visible behavior changes, public API changes, architecture changes, and multi-PR efforts must link an accepted issue. Use `Closes #` in the body to auto-close the issue when merged: ```bash gh pr create \ @@ -126,6 +126,8 @@ gh pr create \ - Returns 400 instead of 500" ``` +Small documentation fixes, mechanical maintenance, and obvious localized bug fixes may omit a separate issue when the PR contains enough context to review the decision and implementation together. In that case, write `No issue required: ` in the Related Issue section. Do not use this exception for security fixes; follow `SECURITY.md`. + ### Create as Draft For work-in-progress that's not ready for review: @@ -157,7 +159,7 @@ PR descriptions must follow the project's [PR template](.github/PULL_REQUEST_TEM ## Related Issue - + ## Changes diff --git a/.agents/skills/create-spike/SKILL.md b/.agents/skills/create-spike/SKILL.md index 3c09d20de1..4f30c3829a 100644 --- a/.agents/skills/create-spike/SKILL.md +++ b/.agents/skills/create-spike/SKILL.md @@ -5,7 +5,7 @@ description: Investigate a plain-language problem description by deeply explorin # Create Spike -Investigate a problem, map it to the codebase, and produce a structured GitHub issue ready for `build-from-issue`. +Investigate a problem, map it to the codebase, and produce a structured GitHub issue ready for human disposition and roadmap placement. A **spike** is an exploratory investigation. The user has a vague idea — a feature they want, a bug they've noticed, a performance concern — but hasn't mapped it to code, assessed feasibility, or structured it as a buildable issue. This skill does that mapping. @@ -122,7 +122,9 @@ Based on the investigation results, select appropriate labels: - **Do not add issue type labels** — GitHub built-in issue types come from issue templates or manual follow-up, not labels - **Include area labels** if they exist in the repo (e.g., `area:sandbox`, `area:proxy`, `area:policy`, `area:cli`) - **Do not invent labels** — only use labels that already exist in the repo -- **Add `state:review-ready`** — the issue is ready for human review upon creation +- **Add `state:validated` only when the evidence is sufficient for human disposition** — the spike established a coherent problem or proposal and completed the factual assessment needed for a human yes/no decision +- **Add `state:needs-info` instead when material evidence is missing** — identify the exact evidence, reproduction details, or decision input still needed in the issue body +- **Never add `state:accepted`, an `agent:*` label, or the `roadmap` label** — acceptance, roadmap placement, and requests for agent work require a human decision ## Step 4: Create the GitHub Issue @@ -131,7 +133,7 @@ Create the issue with a structured body containing both the stakeholder-readable ```bash gh issue create \ --title ": " \ - --label "" --label "state:review-ready" \ + --label "" --label "" \ --body "$(cat <<'EOF' ## Problem Statement @@ -195,6 +197,12 @@ gh issue create \ - - ... +## Disposition Readiness + +- **State:** `` +- **Assessment:** +- **Missing evidence:** + ## Test Considerations - @@ -203,7 +211,7 @@ gh issue create \ - --- -*Created by spike investigation. Use `build-from-issue` to plan and implement.* +*Created by spike investigation. `state:validated` means the issue is ready for human disposition; `state:needs-info` means specific evidence is still required. A human applies `state:accepted` if OpenShell should pursue the work and places it on the roadmap separately. To queue unattended agent planning, a human applies `agent:plan-requested`; a direct request to an agent does not require that label.* EOF )" ``` @@ -225,7 +233,13 @@ After creating the issue, report: 3. Key risks or decisions that need human attention 4. Next steps: -> Review the issue. Refine the proposed approach if needed, then use `build-from-issue` on the issue to create an implementation plan and build it. +For `state:validated`: + +> Review the issue and decide whether OpenShell should pursue it. If yes, replace `state:validated` with `state:accepted` and separately associate it with a roadmap item. The work may remain human-owned. Apply `agent:plan-requested` to queue planning for an unattended agent, or directly ask an agent to use `build-from-issue`. If no, close it as not planned and record the rationale. + +For `state:needs-info`: + +> Collect the missing evidence identified in the issue. Leave it off the roadmap. Once the evidence is sufficient, replace `state:needs-info` with `state:validated` for human disposition. ## Design Principles @@ -239,6 +253,8 @@ After creating the issue, report: 5. **Cross-reference `build-from-issue`.** Mention it as the natural next step in the issue body footer. +6. **Treat validation as an evidence threshold, not an automatic spike outcome.** Apply `state:validated` only when the investigation supports a human accept/decline decision. Otherwise apply `state:needs-info`, state what is missing, and leave the issue off the roadmap. + ## Useful Commands Reference | Command | Description | @@ -263,9 +279,9 @@ User says: "Allow sandbox egress to private IP space via networking policy" - Reads `architecture/security-policy.md` and `architecture/sandbox.md` - Identifies exact insertion points: policy field addition, SSRF check bypass path, OPA rule extension - Assesses: Medium complexity, High confidence, ~6 files -3. Fetch labels — select `area:sandbox`, `area:proxy`, `area:policy`, `state:review-ready` +3. Fetch labels — select `area:sandbox`, `area:proxy`, `area:policy`, `state:validated` 4. Create issue: `feat: allow sandbox egress to private IP space via networking policy` — body includes both the summary and full investigation (code references, architecture context, alternative approaches) -5. Report: "Created issue #59. The investigation found that private IP blocking is enforced at the SSRF check layer in the proxy. The proposed approach adds a policy-level override. Review the issue and use `build-from-issue` when ready." +5. Report: "Created issue #59. The investigation found that private IP blocking is enforced at the SSRF check layer in the proxy. The proposed approach adds a policy-level override. A human must now accept or decline it and place it on the roadmap if accepted." ### Bug investigation spike @@ -279,9 +295,9 @@ User says: "The proxy retry logic seems too aggressive — I'm seeing cascading - Maps the failure propagation path - Identifies that retries happen without backoff jitter, causing thundering herd - Assesses: Low complexity, High confidence, ~2 files -3. Fetch labels — select `area:proxy`, `state:review-ready` +3. Fetch labels — select `area:proxy`, `state:validated` 4. Create issue: `fix: proxy retry logic causes cascading failures under load` — body includes both the summary and full investigation (retry code references, current behavior trace, comparison to standard backoff patterns) -5. Report: "Created issue #74. The proxy retries without jitter or circuit breaking, which amplifies failures under load. Straightforward fix. Review and use `build-from-issue` when ready." +5. Report: "Created issue #74. The proxy retries without jitter or circuit breaking, which amplifies failures under load. A human must now accept or decline it and place it on the roadmap if accepted." ### Performance/refactoring spike @@ -295,6 +311,6 @@ User says: "Policy evaluation is getting slow — can we cache compiled OPA poli - Reads the policy reload/hot-swap mechanism - Identifies that policies are recompiled on every evaluation - Assesses: Medium complexity, Medium confidence (cache invalidation is a design decision), ~4 files -3. Fetch labels — select `area:policy`, `state:review-ready` +3. Fetch labels — select `area:policy`, `state:validated` 4. Create issue: `perf: cache compiled OPA policies to reduce evaluation latency` — body includes both the summary and full investigation (compilation hot path, per-request overhead, cache invalidation strategies with trade-offs) -5. Report: "Created issue #81. Policies are recompiled per-request with no caching. The main design decision is the cache invalidation strategy — flagged as an open question. Review and use `build-from-issue` when ready." +5. Report: "Created issue #81. Policies are recompiled per-request with no caching. The main design decision is the cache invalidation strategy. A human must now accept or decline it and place it on the roadmap if accepted." diff --git a/.agents/skills/fix-security-issue/SKILL.md b/.agents/skills/fix-security-issue/SKILL.md index 75703c4bfb..4e6610c8a1 100644 --- a/.agents/skills/fix-security-issue/SKILL.md +++ b/.agents/skills/fix-security-issue/SKILL.md @@ -1,6 +1,6 @@ --- name: fix-security-issue -description: Implement a fix for a reviewed security issue. Takes an issue number or scans for issues labeled "topic:security" and "state:agent-ready". Reads the security review from the issue comments and implements the remediation plan. Trigger keywords - fix security issue, remediate security, implement security fix, patch vulnerability. +description: Implement a fix for a reviewed security issue. Takes a directly requested issue number or scans for issues labeled `topic:security` and `agent:implementation-requested`. Reads the security review from the issue comments and implements the remediation plan. Trigger keywords - fix security issue, remediate security, implement security fix, patch vulnerability. --- # Fix Security Issue @@ -11,7 +11,7 @@ Implement a code fix for a security issue that has already been reviewed by the - The `gh` CLI must be authenticated (`gh auth status`) - You must be in a git repository with a GitHub remote -- The issue **must** have both the `topic:security` and `state:agent-ready` labels. If either is missing, do not proceed. +- The issue must have `topic:security`. In unattended scan mode it must also have `agent:implementation-requested`; a direct user request to fix a specific issue does not require that label. - The issue must have a prior security review comment (posted by `review-security-issue`) with a **Legitimate concern** determination and a remediation plan ## Agent Comment Marker @@ -30,14 +30,14 @@ The user may provide an issue number directly, or ask the agent to find issues t ### If an issue number is provided -Strip any leading `#` and proceed to Step 2 with that issue ID. +Strip any leading `#` and proceed to Step 2 with that issue ID. The user's explicit fix request authorizes implementation; do not refuse solely because `agent:implementation-requested` is absent. ### If no issue number is provided -Scan for open issues labeled `topic:security` and `state:agent-ready`: +Scan for open issues labeled `topic:security` and `agent:implementation-requested`: ```bash -gh issue list --label "topic:security" --label "state:agent-ready" --state open --json number,title,labels,updatedAt +gh issue list --label "topic:security" --label "agent:implementation-requested" --state open --json number,title,labels,updatedAt ``` - **If no issues are found**, report to the user that there are no security issues ready for fixing and stop. @@ -52,20 +52,16 @@ Fetch the issue details: gh issue view --json number,title,body,state,labels,author ``` -### Require both `topic:security` and `state:agent-ready` labels +### Validate the Security Label and Invocation Mode -**This is a hard gate.** Check the issue's `labels` array from the response above. Both of the following labels **must** be present: +Check the issue's `labels` array from the response above: -- `topic:security` -- `state:agent-ready` +- `topic:security` is required because this specialized skill handles security issues. +- `agent:implementation-requested` is required only when an unattended agent discovered the issue by scanning the queue. -If **either label is missing**, do **not** proceed. Report to the user which label(s) are missing and stop. For example: +If `topic:security` is missing, report that this skill only handles security issues and stop. If queue mode selected an issue without `agent:implementation-requested`, report that it is not ready for unattended pickup and stop. -- Missing `state:agent-ready`: "Issue #42 has the `topic:security` label but is not marked `state:agent-ready`. It may still need review or human triage before a fix can be implemented." -- Missing `topic:security`: "Issue #42 is marked `state:agent-ready` but does not have the `topic:security` label. This skill only handles security issues." -- Missing both: "Issue #42 is missing both the `topic:security` and `state:agent-ready` labels. Cannot proceed." - -**Do not offer to add the labels or bypass this check.** The labels are a deliberate human-controlled gate. +Never apply `agent:implementation-requested` yourself. Its absence does not block a direct user request to fix a specific issue. ### Validate the security review @@ -100,6 +96,12 @@ git checkout -b fix/security-- Follow the project's branch naming conventions. The branch name should reference the issue ID. +In queue mode, replace the human request and ready-plan labels with the agent execution state. For an unlabeled direct invocation, do not add an agent-workflow label: + +```bash +gh issue edit --remove-label "agent:implementation-requested" --remove-label "agent:plan-ready" --add-label "agent:in-progress" +``` + ## Step 5: Implement the Fix Implement the changes described in the remediation plan. Follow these principles: @@ -232,6 +234,12 @@ EOF Created PR [#](https://github.com/OWNER/REPO/pull/) ``` +In queue mode, replace `agent:in-progress` with `agent:pr-opened` after the PR is created. For an unlabeled direct invocation, do not add an agent-workflow label: + +```bash +gh issue edit --remove-label "agent:in-progress" --add-label "agent:pr-opened" +``` + ## Step 9: Report to User Summarize what was done: @@ -247,7 +255,7 @@ Summarize what was done: | Command | Description | | --- | --- | -| `gh issue list --label "topic:security" --label "state:agent-ready" --state open` | Find open security issues ready for fixing | +| `gh issue list --label "topic:security" --label "agent:implementation-requested" --state open` | Find security issues whose fixes a human requested | | `gh issue view --json number,title,body,state,labels,author` | Fetch full issue metadata | | `gh issue view --json comments` | Fetch all comments on an issue | | `gh pr create --title "..." --body "..."` | Create a pull request | @@ -271,11 +279,11 @@ User says: "Fix security issue #42" 8. Commit, push, and open PR with `Closes #42` 9. Report the PR link and changes to the user -### Scan and fix agent-ready issues +### Scan and fix requested security issues User says: "Fix any ready security issues" -1. Query for open issues with labels `topic:security` + `state:agent-ready` +1. Query for open issues with labels `topic:security` + `agent:implementation-requested` 2. Find issue #78: "SQL injection in search endpoint" 3. Fetch the review comment -- determination is "Legitimate concern" 4. Implement parameterized queries @@ -292,20 +300,20 @@ User says: "Fix security issue #99" 3. Report to the user: "Issue #99 was reviewed and determined to be not actionable. No fix is needed." 4. Stop -### Issue missing `state:agent-ready` label +### Directly requested issue without `agent:implementation-requested` User says: "Fix security issue #55" 1. Fetch issue #55 metadata -2. Labels are `["topic:security"]` -- missing `state:agent-ready` -3. Report to the user: "Issue #55 has the `topic:security` label but is not marked `state:agent-ready`. It may still need review or human triage before a fix can be implemented." -4. Stop +2. Labels are `["topic:security"]` -- missing `agent:implementation-requested` +3. Confirm that a legitimate security review and remediation plan exist +4. Proceed because the user's direct request authorizes implementation ### Issue without a review User says: "Fix security issue #60" -1. Fetch issue #60 metadata -- labels include both `topic:security` and `state:agent-ready` +1. Fetch issue #60 metadata -- `topic:security` is present and the user directly requested the fix 2. Fetch comments -- no `security-review-agent` comment found 3. Report to the user: "Issue #60 has not been reviewed yet. Run the review-security-issue skill first." 4. Stop diff --git a/.agents/skills/review-security-issue/SKILL.md b/.agents/skills/review-security-issue/SKILL.md index caac9fd1c1..b84e8b597a 100644 --- a/.agents/skills/review-security-issue/SKILL.md +++ b/.agents/skills/review-security-issue/SKILL.md @@ -11,6 +11,7 @@ Review an issue that outlines a security, vulnerability, or privacy concern. - The `gh` CLI must be authenticated (`gh auth status`) - You must be in a git repository with a GitHub remote +- The issue must have `topic:security`. In unattended queue mode it must also have `agent:plan-requested`; a direct user request to review a specific issue does not require that label. ## Agent Comment Marker @@ -40,7 +41,10 @@ gh issue view --json title,body,state,labels,author First, check the issue's labels from the metadata fetched in Step 1. -- **If the issue has the `state:agent-ready` label**, the issue has already been reviewed and is ready for implementation. There is no review to perform. Report to the user that this issue is already reviewed and marked as `state:agent-ready`, and suggest using the `fix-security-issue` skill instead. Stop. +- **If the issue has `agent:implementation-requested`**, the issue has already been reviewed and a human authorized remediation. There is no review to perform. Suggest using `fix-security-issue` and stop. +- **If `topic:security` is missing**, report that this specialized skill only reviews security issues and stop. +- **If this is queue mode and `agent:plan-requested` is missing**, report that the issue is not ready for unattended pickup and stop. +- **If the user directly requested review of this issue**, proceed even when `agent:plan-requested` is absent. Never add or offer to add the human-only request label. Next, fetch existing comments on the issue: @@ -133,15 +137,15 @@ EOF )" ``` -## Step 5: Add `state:review-ready` Label +## Step 5: Mark the Security Plan Ready -After posting the review comment (whether legitimate or not actionable), add the `state:review-ready` label to the issue: +After posting a legitimate-concern review with a remediation plan, replace `agent:plan-requested` with `agent:plan-ready` only when the request label was present: ```bash -gh issue edit --add-label "state:review-ready" +gh issue edit --remove-label "agent:plan-requested" --add-label "agent:plan-ready" ``` -This signals to humans and downstream skills (e.g., `fix-security-issue`) that the review is complete. +This signals that an unattended agent produced a remediation plan that awaits human review. For an unlabeled direct invocation, leave the `agent:*` labels unchanged. A later direct request can authorize remediation without `agent:implementation-requested`; unattended remediation still requires that label. For a not-actionable determination, remove `agent:plan-requested` if present, do not add another `agent:*` label, and report that a human should close the issue or record the risk decision. ## Step 6: Address Follow-up Comments @@ -163,7 +167,7 @@ For each unanswered human comment: | `gh issue view --json title,body,state,labels,author` | Fetch full issue metadata as JSON | | `gh issue view --json comments --jq '.comments[].body'` | Fetch all comments on an issue | | `gh issue comment --body "..."` | Post a comment on an issue | -| `gh issue edit --add-label "state:review-ready"` | Add a label to an issue | +| `gh issue edit --remove-label "agent:plan-requested" --add-label "agent:plan-ready"` | Mark a remediation plan ready for human review | ## Example Usage @@ -176,7 +180,7 @@ User says: "Review security issue #42" 3. No prior review found -- pass issue to `principal-engineer-reviewer` with security lens 4. Reviewer determines it's a legitimate XSS vulnerability in the API response handler 5. Post a comment with severity assessment and remediation plan -6. Add the `state:review-ready` label to the issue +6. If `agent:plan-requested` was present, replace it with `agent:plan-ready`; otherwise leave the direct invocation unlabeled 7. Report the finding and posted comment to the user ### Re-review with new comments diff --git a/.agents/skills/sync-agent-infra/SKILL.md b/.agents/skills/sync-agent-infra/SKILL.md index 06082190a1..391e81337e 100644 --- a/.agents/skills/sync-agent-infra/SKILL.md +++ b/.agents/skills/sync-agent-infra/SKILL.md @@ -87,7 +87,7 @@ The canonical workflow chains are defined in `AGENTS.md` under "## Workflow Chai ### Labels -The canonical label set is used by skills and templates. The key labels are: `state:agent-ready`, `state:review-ready`, `state:in-progress`, `state:pr-opened`, `state:triage-needed`, `topic:security`, `good first issue`, `spike`, and the relevant `area:*`, `topic:*`, `integration:*`, and `test:*` labels. +The canonical label set is used by skills and templates. The key labels are: `state:triage-needed`, `state:needs-info`, `state:validated`, `state:accepted`, `agent:plan-requested`, `agent:plan-ready`, `agent:implementation-requested`, `agent:in-progress`, `agent:pr-opened`, `roadmap`, `topic:security`, `good first issue`, `help wanted`, `spike`, and the relevant `area:*`, `topic:*`, `integration:*`, and `test:*` labels. The `agent:*` request labels control unattended queue pickup; they are not prerequisites when a user directly asks an agent to work on a specific issue. ## Step 2: Check Each File for Drift @@ -125,7 +125,7 @@ For each file in the table above, check for the following inconsistencies: 1. **`triage-issue`** — Skills referenced in gate check and diagnosis steps must exist. 2. **`openshell-cli`** — Companion skills table entries must exist. -3. **`build-from-issue`** — Label names must match the project's label taxonomy. +3. **`build-from-issue`** — Label names must match the project's label taxonomy, and request labels must gate unattended queue pickup without blocking direct user requests. 4. **`create-spike`** — Reference to `build-from-issue` as next step must be accurate. 5. **`review-security-issue`** / **`fix-security-issue`** — Cross-references between the two must be accurate. 6. **PR creation and review checks** — The `create-github-pr`, `review-github-pr`, `build-from-issue`, and `principal-engineer-reviewer` references to `sync-agent-infra` must exist and use trigger conditions aligned with this skill. diff --git a/.agents/skills/triage-issue/SKILL.md b/.agents/skills/triage-issue/SKILL.md index ec9858a59d..5e5d503025 100644 --- a/.agents/skills/triage-issue/SKILL.md +++ b/.agents/skills/triage-issue/SKILL.md @@ -1,20 +1,33 @@ --- name: triage-issue -description: Assess, classify, and route community-filed issues. Takes a specific issue number or processes all open issues with the state:triage-needed label in batch. Validates agent-first gate compliance, attempts diagnosis using relevant skills, and classifies issues for routing into the spike-build pipeline. Trigger keywords - triage issue, triage, assess issue, review incoming issue, triage issues. +description: Assess, validate, and route community-filed issues for human disposition and roadmap placement. Takes a specific issue number or processes a confirmed batch of issues labeled state:triage-needed. Investigates reported behavior, separates objective findings from product decisions, and prepares validated issues for a human yes/no decision. Trigger keywords - triage issue, triage, assess issue, review incoming issue, triage issues. --- # Triage Issue -Assess, classify, and route community-filed issues. This is the front door for community inflow — distinct from `build-from-issue`, which is the maintainer execution tool for implementation. +Establish the facts a human needs to decide whether OpenShell should address an issue and, if so, where it belongs on the roadmap. Triage does not authorize work, sequence it, or produce an implementation plan. ## Prerequisites - The `gh` CLI must be authenticated (`gh auth status`) - You must be in a git repository with a GitHub remote +- The workflow labels `state:validated`, `state:accepted`, and `state:needs-info` must exist. Report missing labels to the operator; do not create them implicitly. -## Critical: `state:agent-ready` Label Is Human-Only +## Critical: Disposition and Roadmap Placement Are Human-Only -The `state:agent-ready` label is a **human gate**. Triage **never** applies this label. Triage assesses and classifies — humans decide what gets built. This is a non-negotiable safety control. +Triage establishes technical validity; it does not decide whether valid work belongs on the roadmap. Agents must never: + +- Decide that OpenShell should or should not invest in otherwise valid work. +- Apply or remove `state:accepted`. +- Add an issue to the roadmap project, apply or remove the `roadmap` label, or recommend a specific roadmap item. +- Apply `agent:plan-requested` or `agent:implementation-requested`. +- Treat technical validity as product acceptance. + +OpenShell has no `priority:*` labels. Sequencing comes from association with an item on the OpenShell Roadmap, and that association is a maintainer decision. + +`state:validated` means the factual assessment is complete and awaits human disposition. A human declines by closing the issue as not planned with a rationale, or accepts by replacing `state:validated` with `state:accepted` and placing the issue on the roadmap as documented in `CONTRIBUTING.md`. Accepted work may remain human-owned. A maintainer can queue deeper agent investigation or planning with `agent:plan-requested`, or directly ask an agent to work on a specific issue. + +The optional `agent:*` workflow controls unattended queue pickup: `agent:plan-requested` queues planning, and `agent:implementation-requested` queues implementation after plan review. A direct user instruction separately authorizes the phase it requests and does not require either label. ## Agent Comment Marker @@ -85,25 +98,24 @@ Search the issue comments for the triage agent marker (`> **📋 triage-agent**` - **If the marker is found** and no subsequent human comments exist with new information or questions, report that the issue has already been triaged and stop. - **If the marker is found** but there are newer human comments with additional information, proceed to Step 3 to re-evaluate with the new context. +- **If a human already declined the issue or applied `state:accepted`**, do not undo or reinterpret that decision. - **If the marker is not found**, proceed to Step 3. ## Step 3: Validate the Agent-First Gate -Check whether the issue body contains a substantive agent diagnostic section. Look for: +Check whether the issue body contains a substantive agent diagnostic section. Treat this as evidence quality, not as a reason to skip obvious safety or routing actions. Look for: - An "Agent Diagnostic" heading or section (from the bug report template) - Evidence that the reporter used agent skills (skill names mentioned, diagnostic output pasted) - Concrete investigation output (not just placeholder text or "N/A") -**If the diagnostic section is missing or clearly placeholder:** +If the diagnostic is missing, continue when the report already contains enough concrete evidence to assess safely. Otherwise classify it as `needs-information`, request the exact missing evidence, remove `state:triage-needed`, and add `state:needs-info`. -1. Add the `state:triage-needed` label if not already present: - ```bash - gh issue edit --add-label "state:triage-needed" - ``` -2. Do not post a standalone redirect comment. Report the missing diagnostic to the operator and stop unless a human explicitly asks you to continue triage anyway. +- If a public issue may disclose a security vulnerability, do not repeat or expand sensitive details. Classify it as `security-report` and direct the operator to `SECURITY.md`. +- Route usage questions and support requests to the documented support venue. +- Handle clear duplicates, wrong-repository reports, and objectively expected behavior without requiring a full technical investigation. -**If the diagnostic section is substantive**, proceed to Step 4. +Proceed to Step 4 for reports requiring technical validation. ## Step 4: Check Reported Version and Known Fixes @@ -113,13 +125,13 @@ Before deeper diagnosis, determine whether the report may already be fixed in a 2. Check current release information and known fixes when available: - `gh release list --limit 10` - `gh release view ` - - linked issues, merged PRs, release notes, and local git tags/history + - linked issues, merged PRs, release notes, local git tags/history, and both open and closed possible duplicates 3. If network access or release metadata is unavailable, state the limitation in the triage comment instead of guessing. If the issue targets an older OpenShell release and a newer release or merged PR appears to address the same behavior: - If the reporter has already reproduced the issue on the fixed/current release, continue to Step 5. -- If the reporter has not tested the fixed/current release, use the `fixed-in-release` classification in Step 6. Reference the fixing version and PR/issue when known, and ask for a fresh report or reopen if the issue still reproduces on that version. +- If the reporter has not tested the fixed/current release, identify a concrete fixing change before using `fixed-in-release`. If the causal link is uncertain, request a retest instead of declaring the issue fixed. ## Step 5: Diagnose and Validate @@ -134,8 +146,9 @@ Prompt the sub-agent with: 2. Can the described behavior be reproduced from the information given? 3. Does the reporter's agent diagnostic match what you see in the codebase? 4. If this is a bug, what component is affected? - 5. If this is a feature request, does the design make sense given the architecture? - 6. Are there any existing issues that duplicate this? + 5. If this is a feature request, is it technically coherent and feasible? Do not decide whether the project should accept it. + 6. Are there any open or closed issues that duplicate this? + 7. What uncertainty remains, and what exact evidence would resolve it? ``` Based on the sub-agent's analysis, also attempt to validate the report directly: @@ -146,19 +159,27 @@ Based on the sub-agent's analysis, also attempt to validate the report directly: - For inference and provider-topology issues: reference the `debug-inference` skill's known failure patterns - For CLI/usage issues: reference the `openshell-cli` skill's command reference +Record impact signals for the human decision: affected users and scope, regression status, workaround availability, severity evidence, and evidence quality. Do not convert those facts into a roadmap or sequencing recommendation. + ## Step 6: Classify Based on the investigation, classify the issue into one of these categories: -| Classification | Criteria | Action | -|---------------|----------|--------| -| **bug-confirmed** | Agent diagnostic and codebase analysis confirm a real defect | Apply relevant `area:*` or `topic:*` labels as needed, remove `state:triage-needed`, and assign the built-in `Bug` issue type manually if needed | -| **feature-valid** | Design proposal is sound, feasible given the architecture | Apply relevant `area:*` or `topic:*` labels as needed, remove `state:triage-needed`, and assign the built-in `Feature` issue type manually if needed | -| **fixed-in-release** | Report targets an older OpenShell release and a newer release or merged PR appears to address the behavior; no fixed/current-release reproduction is provided | Comment with the fixing version and PR/issue when known. Close as completed when the fix is clear, or request a retest if confirmation is still needed. Remove `state:triage-needed` when closing | -| **duplicate** | An existing open issue covers this | Link the duplicate, close with comment | -| **user-error** | The reported behavior is expected, or the issue is a misconfiguration | Comment with explanation and guidance, close | -| **needs-more-info** | Report is substantive but missing critical reproduction details | Comment requesting specifics, keep `state:triage-needed` | -| **needs-investigation** | Report appears valid but requires deeper analysis (spike candidate) | Label `spike`, remove `state:triage-needed` | +| Classification | Meaning | Agent action | +|---|---|---| +| **validated-bug** | Evidence confirms a real defect | Add relevant area/topic labels; replace triage/needs-info state with `state:validated`; leave open | +| **validated-feature** | The proposal is technically coherent and feasible | Add relevant area/topic labels; replace triage/needs-info state with `state:validated`; leave open | +| **needs-investigation** | The report is credible but needs a deeper spike | Add `spike` if available; replace triage/needs-info state with `state:validated`; leave open for a human decision on whether to invest in the spike | +| **needs-information** | Critical reproduction or environment evidence is missing | Replace `state:triage-needed` with `state:needs-info`; request the exact missing evidence | +| **cannot-reproduce** | A faithful attempt did not reproduce, but the report may still be valid | Replace `state:triage-needed` with `state:needs-info`; document the attempt and request discriminating evidence | +| **fixed-in-release** | A concrete released change fixes the reported behavior | Explain the fix and version; close only when the causal link is clear, otherwise request a retest | +| **duplicate** | Another open or closed issue is the canonical report | Link the canonical issue and close | +| **expected-behavior** | Code and documentation establish that the behavior is intentional | Explain the behavior and close | +| **support-request** | The report asks for usage help rather than tracking work | Provide the support route and close | +| **wrong-repository** | Another repository owns the affected component | Link the correct tracker and close | +| **security-report** | The report may contain a vulnerability | Avoid further public analysis and direct the operator to `SECURITY.md` for safe handling | + +Do not use `validated-feature` to imply roadmap acceptance. Do not use `expected-behavior` to decline a technically valid feature request. ## Step 7: Post Triage Comment @@ -169,21 +190,34 @@ Post a structured comment with the triage marker: > > ## Triage Assessment > -> **Classification:** +> **Classification:** > > ### Summary -> <2-3 sentences: what was found, whether the report is valid> +> > > ### Investigation -> +> +> +> ### Impact Signals +> - **Affected users/scope:** +> - **Regression:** +> - **Workaround:** +> - **Evidence quality:** > -> ### Recommendation -> +> ### Human Decision Required +> Decide whether OpenShell should address this issue. If yes, replace +> `state:validated` with `state:accepted`, associate it with a roadmap +> item, and decide whether the work remains human-owned. +> To queue investigation or planning for an unattended agent, also apply +> `agent:plan-requested`. You can instead directly ask an agent to use +> `create-spike` or `build-from-issue` on this issue. If no, close it as not +> planned and record the rationale. +> Roadmap association is independent sequencing metadata. ``` -Apply the appropriate labels as determined in Step 6. +For other outcomes, replace the impact and decision sections with the exact information request, objective resolution, or safe routing guidance. -**Do not apply `state:agent-ready`.** That is always a human decision. +Keep exactly one intake/triage state among `state:triage-needed`, `state:needs-info`, and `state:validated`. Remove `state:triage-needed` after every completed assessment. Never apply `state:accepted`, any `agent:*` label, or the `roadmap` label during triage. Never close a validated issue. ## Relationship to Other Skills @@ -192,15 +226,28 @@ Community issue filed | [GitHub Action: instant gate check] | - triage-issue ← this skill + triage-issue + | + state:validated + | + human decline OR state:accepted + roadmap placement + | + create-spike (if deeper investigation is approved) + | + human queues planning with agent:plan-requested + OR directly requests planning + | + build-from-issue (creates implementation plan) | - create-spike (if classification is needs-investigation) + human queues implementation with agent:implementation-requested + OR directly requests implementation | - build-from-issue (if human applies state:agent-ready) + implementation ``` -- **triage-issue** decides whether an issue is valid and how to classify it. -- **create-spike** does deep feasibility investigation for issues that need it. -- **build-from-issue** implements once a human approves. +- **triage-issue** establishes technical validity and impact evidence. +- **Humans** decide whether to accept valid work and where it lands on the roadmap. +- **create-spike** deepens investigation only after that investment is approved. +- **build-from-issue** may be invoked directly for a specific issue. Unattended agents use `agent:plan-requested` to pick up planning and `agent:implementation-requested` to pick up implementation. -Triage is the assessment layer. It does not plan or build — it evaluates and routes. +Triage is the assessment layer. It does not sequence work, accept it onto the roadmap, plan, or build. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index faaa1739ad..f6de74c859 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,12 @@ ## Related Issue - + ## Changes diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 5b745057da..dfdc4b8c95 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -25,7 +25,7 @@ jobs: days-before-pr-stale: 14 days-before-pr-close: -1 # -1 puts this into dry-run mode. Update to 7 to enable closing. - exempt-issue-labels: state:triage-needed,roadmap + exempt-issue-labels: state:triage-needed,state:validated,state:accepted,agent:plan-requested,agent:plan-ready,agent:implementation-requested,agent:in-progress,agent:pr-opened,roadmap close-issue-reason: not_planned stale-issue-message: > diff --git a/AGENTS.md b/AGENTS.md index 04e5bc5c7b..ce7fc7cd63 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,12 +16,12 @@ Agent skills live in `.agents/skills/`. Your harness can discover and load them These pipelines connect skills into end-to-end workflows. Individual skill files don't describe these relationships. -- **Community inflow:** `triage-issue` → `create-spike` → `build-from-issue` - - Triage assesses and classifies community-filed issues. Spike investigates unknowns. Build implements. -- **Internal development:** `create-spike` → `build-from-issue` - - Spike explores feasibility, then build executes once `state:agent-ready` is applied by a human. +- **Community inflow:** `triage-issue` → human disposition and roadmap placement → `create-spike` when needed → `build-from-issue` + - Triage establishes facts and marks technically valid issues `state:validated`. A human applies `state:accepted` if the project should pursue the work and separately places it on the roadmap. The `agent:*` labels support unattended agents that scan for queued work: a human queues a plan with `agent:plan-requested`, the agent returns `agent:plan-ready`, and a human queues implementation with `agent:implementation-requested`. A direct user request to an agent authorizes the requested phase without those labels. +- **Internal development:** `create-spike` → human disposition and roadmap placement → `build-from-issue` + - Spike explores feasibility and marks its issue `state:validated` when sufficient evidence exists. A human accepts it with `state:accepted` or declines it, separately places it on the roadmap, and optionally queues it through the `agent:*` workflow or directs an agent to it. - **Security:** `review-security-issue` → `fix-security-issue` - - Review produces a severity assessment and remediation plan. Fix implements it. Both require the `topic:security` label; fix also requires `state:agent-ready`. + - General build agents must not process `topic:security` issues. For unattended processing, a human queues specialized review with `agent:plan-requested`; review produces a severity assessment and remediation plan; a human queues remediation with `agent:implementation-requested`. Direct requests to the specialized skills do not require those labels. - **Policy iteration:** `openshell-cli` → `generate-sandbox-policy` - CLI manages the sandbox lifecycle; policy generation authors the YAML constraints. @@ -73,7 +73,9 @@ These pipelines connect skills into end-to-end workflows. Individual skill files - **Bug reports** must include an agent diagnostic section — proof that the reporter's agent investigated the issue before filing. See the issue template. - **Feature requests** must include a design proposal, not just a "please build this" request. See the issue template. - **New features** must start as GitHub issues using the feature request template. Open an RFC only after an issue exists; maintainers decide when one is needed and assign RFC numbers from the issue. +- **Issue triage** establishes technical validity and impact evidence. Agents never decide roadmap acceptance, apply `state:accepted`, place issues on the roadmap, or apply `agent:plan-requested` or `agent:implementation-requested`. Humans accept or decline validated work and separately place it on the roadmap. The request labels queue work for unattended agents; an explicit user instruction can instead authorize an agent to plan or implement a specific issue. OpenShell has no `priority:*` labels; roadmap association carries sequencing. - **PRs** must follow the PR template structure: Summary, Related Issue, Changes, Testing, Checklist. +- **PRs for features, user-visible behavior, public APIs, architecture, or multi-PR efforts** must link an accepted issue. Small docs fixes, mechanical maintenance, and obvious localized bug fixes may state why no issue is required. - **PRs from unvouched external contributors** are automatically closed. See the Vouch System section above. - **Security vulnerabilities** must NOT be filed as GitHub issues. Follow [SECURITY.md](SECURITY.md). - Skills that create issues or PRs (`create-github-issue`, `create-github-pr`, `build-from-issue`) should produce output conforming to these templates. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0465f88f7d..e431894fa0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ We use a vouch system. This exists because AI makes it trivial to generate plaus Issues labeled [`good first issue`](https://github.com/NVIDIA/OpenShell/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) are scoped, well-documented, and friendly to new contributors. Start there. If you need guidance, comment on the issue. -All open issues are actionable — if it's in the issue tracker, it's ready to be worked on. +An open issue is not necessarily accepted or ready to be worked on. Human contributors should look for `state:accepted`, `good first issue`, or `help wanted`, or ask a maintainer before starting. Unattended agents additionally require the appropriate human-applied `agent:*` request label; an agent directly asked to work on a specific issue does not. Roadmap placement describes sequencing and does not authorize work. ## Before You Open an Issue @@ -92,14 +92,51 @@ Skills live in `.agents/skills/`. Your agent's harness can discover and load the Skills connect into pipelines. Individual skill files don't describe these relationships. -- **Community inflow:** `triage-issue` → `create-spike` → `build-from-issue` -- **Internal development:** `create-spike` → `build-from-issue` +- **Community inflow:** `triage-issue` → human disposition and roadmap placement → `create-spike` when needed → `build-from-issue` +- **Internal development:** `create-spike` → human disposition and roadmap placement → `build-from-issue` - **Security:** `review-security-issue` → `fix-security-issue` - **Policy iteration:** `openshell-cli` → `generate-sandbox-policy` -Workflow state labels use the `state:*` prefix, and security work uses `topic:security`. GitHub issue templates assign built-in issue types where applicable, and agent-created issues should use issue types or manual follow-up rather than type labels. -New issues opened by users without `write`, `maintain`, or `admin` repository permission are automatically labeled `state:triage-needed` by the issue triage workflow. -Inactive issues and pull requests are automatically labeled `state:stale` after 14 days without activity and may be closed after 7 more days without activity. Comment on the item or remove `state:stale` to keep it open. Issues labeled `state:triage-needed` or `roadmap` are exempt from stale handling. +### Issue Lifecycle, Roadmap, and Agent Work + +See [Issue Triage and Lifecycle](docs/resources/issue-lifecycle.mdx) for the human-facing process, including triage outcomes, maintainer decisions, roadmap placement, ownership, spikes, and agent delegation. + +Label namespaces represent independent dimensions. `state:*` records the issue's universal disposition and `agent:*` is an optional queue workflow for unattended agents. A user can instead directly instruct an agent to work on a specific issue. Sequencing is not a label: it comes from the [OpenShell Roadmap](https://github.com/orgs/NVIDIA/projects/233). + +| State | Meaning | +|---|---| +| `state:triage-needed` | The issue has not been assessed. New issues from users without repository write access receive this automatically. | +| `state:needs-info` | Triage needs specific evidence or reproduction details from the reporter. | +| `state:validated` | The factual assessment is complete and awaits a human accept/decline decision. This is not roadmap acceptance. | +| `state:accepted` | A human decided that OpenShell should pursue the issue. This does not assign the work to an agent. | + +For an issue labeled `state:validated`, a maintainer makes one of these decisions: + +- **Decline:** close it as not planned and record the rationale. +- **Accept:** replace `state:validated` with `state:accepted` and associate the issue with a roadmap item. +- **Await more evidence:** replace `state:validated` with `state:needs-info` and leave it off the roadmap. + +OpenShell does not use priority labels. Accepted work is sequenced by associating it with an item on the [OpenShell Roadmap](https://github.com/orgs/NVIDIA/projects/233); the roadmap item's timing implies the urgency. Issues tracked there carry the `roadmap` label. An accepted issue with no roadmap association is intended work that is not yet scheduled. + +Roadmap placement is sequencing metadata. `build-from-issue` requires `state:accepted` before it creates an implementation plan. An unattended agent also requires `agent:plan-requested`; a direct user request for a specific issue supplies the request instead. Roadmap placement does not gate agent work. + +Accepted issues may be implemented by humans or by directly instructed agents without any `agent:*` labels. To queue work for an unattended agent, maintainers move the issue through exactly one agent-workflow label at a time: + +| Agent workflow | Applied by | Meaning | +|---|---|---| +| `agent:plan-requested` | Human | Ask an agent to produce an implementation plan. | +| `agent:plan-ready` | Agent | The plan is ready for human review. | +| `agent:implementation-requested` | Human | The plan is approved; replace `agent:plan-ready` with this label to request implementation. | +| `agent:in-progress` | Agent | Authorized agent implementation is underway. | +| `agent:pr-opened` | Agent | Agent implementation produced a pull request. | + +Agents never apply the two request labels. GitHub permits users with the Triage repository role or greater to apply existing labels, but OpenShell reserves `agent:plan-requested` and `agent:implementation-requested` for maintainers. These labels authorize unattended queue pickup; a live user can authorize the same phase by directly instructing an agent. Planning authority does not imply implementation authority. General implementation agents must exclude `topic:security`; the specialized security workflow uses the same queue controls. + +`help wanted` and `good first issue` describe contributor suitability, not sequencing. `good first issue` is suitable for someone with very little project experience; `help wanted` invites broader contributor involvement. + +GitHub issue templates assign built-in issue types where applicable, and agent-created issues should use issue types or manual follow-up rather than type labels. Security work uses `topic:security` and follows the separate process in `SECURITY.md`. + +Inactive issues and pull requests are automatically labeled `state:stale` after 14 days without activity. Automated closing is currently disabled. Comment on the item or remove `state:stale` to keep it active. Issues awaiting triage or human disposition, accepted issues, active agent workflows, and roadmap issues are exempt. `state:needs-info` may become stale when no new evidence arrives. ## Prerequisites @@ -286,6 +323,10 @@ See [docs/CONTRIBUTING.mdx](docs/CONTRIBUTING.mdx) for the current docs authorin 3. Run `mise run ci` to verify. 4. Open a PR using the `create-github-pr` skill or manually following the [PR template](.github/PULL_REQUEST_TEMPLATE.md). +PRs for new features, user-visible behavior changes, public API changes, architecture changes, or multi-PR efforts must link an accepted issue. Small documentation fixes, mechanical maintenance, and obvious localized bug fixes may omit a separate issue when the PR contains enough context to review the decision and implementation together. + +In the PR's **Related Issue** section, use `Fixes #NNN` or `Closes #NNN` when an issue is required. For an exempt change, write `No issue required:` followed by a brief reason. Security fixes follow the private disclosure process in [SECURITY.md](SECURITY.md). + ### Commit Messages This project uses [Conventional Commits](https://www.conventionalcommits.org/). All commit messages must follow the format: diff --git a/README.md b/README.md index cf4793cca8..3d5aeb6fb4 100644 --- a/README.md +++ b/README.md @@ -216,12 +216,12 @@ Your agent can load skills for CLI usage (`openshell-cli`), gateway troubleshoot OpenShell is developed using the same agent-driven workflows it enables. The `.agents/skills/` directory contains workflow automation that powers the project's development cycle: -- **Spike and build:** Investigate a problem with `create-spike`, then implement it with `build-from-issue` once a human approves. -- **Triage and route:** Community issues are assessed with `triage-issue`, classified, and routed into the spike-build pipeline. +- **Spike and build:** Investigate a problem with `create-spike`; a human accepts or declines it and separately places it on the [roadmap](https://github.com/orgs/NVIDIA/projects/233). Accepted work can remain human-owned or enter the optional, human-gated `agent:*` planning and implementation workflow. +- **Triage and route:** Community issues are assessed with `triage-issue`. Agents establish technical validity and impact; humans decide whether the project should act and where the work sits on the roadmap. - **Security review:** `review-security-issue` produces a severity assessment and remediation plan. `fix-security-issue` implements it. - **Policy authoring:** `generate-sandbox-policy` creates YAML policies from plain-language requirements or API documentation. -All implementation work is human-gated — agents propose plans, humans approve, agents build. See [AGENTS.md](AGENTS.md) for the full workflow chain documentation. +All agent implementation work is human-gated: maintainers explicitly request a plan, agents propose it, maintainers approve it, and agents build. See [AGENTS.md](AGENTS.md) for the full workflow chain documentation. ## Getting Help diff --git a/docs/resources/issue-lifecycle.mdx b/docs/resources/issue-lifecycle.mdx new file mode 100644 index 0000000000..5bca97542c --- /dev/null +++ b/docs/resources/issue-lifecycle.mdx @@ -0,0 +1,181 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Issue Triage and Lifecycle" +sidebar-title: "Issue Triage" +description: "Understand how OpenShell assesses issues, makes roadmap decisions, sequences work, and delegates it to agents." +keywords: "OpenShell, issue triage, issue lifecycle, contribution workflow, GitHub labels" +position: 1 +--- + +OpenShell separates technical assessment, roadmap decisions, sequencing, and agent delegation. This page describes the process for reporters, contributors, and maintainers. + +An open issue is not automatically accepted or ready for implementation. Check its `state:*` label before starting work, and ask a maintainer when its status is unclear. + +## Understand the Four Decisions + +Each issue can require four independent decisions: + +| Decision | Question | Recorded by | +|---|---|---| +| Assessment | Is the report technically valid, and is there enough evidence to act on it? | `state:*` | +| Disposition | Should OpenShell pursue the work? | `state:accepted` or closure as not planned | +| Sequencing | Where does accepted work sit relative to everything else? | Placement on the [OpenShell Roadmap](https://github.com/orgs/NVIDIA/projects/233) | +| Ownership | Will a human implement the issue, will a user directly instruct an agent, or will a maintainer queue it for an unattended agent? | Direct instruction or optional `agent:*` workflow | + +Completing one decision does not imply the others. For example, `state:validated` confirms that the factual assessment is complete, but it does not mean the project has accepted the work. Roadmap placement communicates sequencing, but it does not authorize an agent to begin. + +## Know Who Controls Each Decision + +Agents investigate issues, collect evidence, and report technical findings. Humans retain the product and investment decisions. + +| Action | Who performs it | +|---|---| +| Assess technical validity and impact | Triage agent or human triager | +| Request missing evidence | Triage agent or human triager | +| Mark the assessment complete with `state:validated` | Triage agent or human triager | +| Accept or decline the work | Maintainer | +| Place the issue on the roadmap or move it | Maintainer | +| Directly request an agent plan | User | +| Queue an agent plan with `agent:plan-requested` | Maintainer | +| Produce a plan, implement it, and open a pull request | Agent | +| Directly request agent implementation | User | +| Queue approved implementation with `agent:implementation-requested` | Maintainer | + +Agents do not apply `state:accepted`, place issues on the roadmap, or apply `agent:plan-requested` or `agent:implementation-requested`. + +## Follow the Issue State + +The `state:*` namespace records the issue's disposition for all contributors, regardless of who might implement it. + +| State | Meaning | Normal next action | +|---|---|---| +| `state:triage-needed` | The issue has not been assessed. | Investigate the report and record the result. | +| `state:needs-info` | The assessment needs specific evidence or reproduction details. | The reporter or another contributor supplies the requested information. | +| `state:validated` | The factual assessment is complete. | A maintainer accepts the issue, declines it, or asks for more evidence. | +| `state:accepted` | A maintainer decided that OpenShell should pursue the issue. | A human may implement it, or a maintainer may delegate work to an agent. | + +Keep one of these states on an open issue. When new evidence resolves a `state:needs-info` request, reassess the issue and move it to `state:validated` if the evidence is sufficient. + +`state:stale` is an inactivity marker, not a lifecycle decision. Accepted issues and issues awaiting human disposition are exempt from stale handling. An issue in `state:needs-info` can become stale if no new evidence arrives. + +## Assess an Incoming Issue + +New issues from users without repository write access receive `state:triage-needed` automatically. Triage then checks the report, its diagnostic evidence, related issues, current releases, and the relevant code paths. + +The assessment ends in one of these outcomes: + +| Outcome | State or resolution | +|---|---| +| A bug is confirmed. | Replace the intake state with `state:validated`. | +| A feature proposal is technically coherent and feasible. | Replace the intake state with `state:validated`. | +| The report is credible but needs a deeper investigation or spike. | Add the `spike` label when available and use `state:validated` so a human can decide whether to invest in the investigation. | +| Critical evidence is missing, or a faithful attempt cannot reproduce the problem. | Use `state:needs-info` and request the exact evidence needed. | +| A released change already fixes the behavior. | Explain the fix and version. Close the issue only when the causal link is clear; otherwise request a retest. | +| Another issue is the canonical report. | Link the canonical issue and close the duplicate. | +| The behavior is expected or caused by unsupported configuration. | Explain the finding and close the issue with the appropriate GitHub reason. | +| The report describes a security vulnerability. | Stop public triage and follow the private process in `SECURITY.md`. | + +Triage establishes facts and impact. It does not decide whether the project should spend time on the work. + +## Make the Human Disposition Decision + +When an issue reaches `state:validated`, a maintainer chooses one of three paths: + +- Accept the issue. Replace `state:validated` with `state:accepted` and place it on the roadmap. +- Decline the issue. Close it as not planned and record the rationale. +- Ask for more evidence. Replace `state:validated` with `state:needs-info` and leave it off the roadmap. + +Do not use `state:accepted` as shorthand for technical validity, roadmap sequencing, or agent authorization. It records only the human decision that OpenShell should pursue the work. + +## Place Work on the Roadmap + +OpenShell does not use priority labels. Sequencing comes from the [OpenShell Roadmap](https://github.com/orgs/NVIDIA/projects/233): a maintainer associates an accepted issue with a roadmap item, and the roadmap item's own timing carries the urgency. Issues tracked on the roadmap carry the `roadmap` label. + +An accepted issue with no roadmap association is real work the project intends to do, but it is not scheduled. Ask a maintainer before starting on one. + +Roadmap placement does not assign an owner. A roadmap issue still needs a human contributor, a direct user instruction to an agent, or an unattended-agent queue label. + +The `good first issue` and `help wanted` labels describe contributor suitability, not sequencing. + +## Choose Human or Agent Ownership + +A human contributor may implement an accepted issue without any `agent:*` label. Before starting, check for an assignee, linked pull request, active branch, or comment that shows someone else is already working on it. + +Maintainers use the `agent:*` workflow to queue work for always-on or unattended agents that scan issues. Keep exactly one agent-workflow label on the issue at a time. When a user directly asks an agent to plan or implement a specific issue, that instruction authorizes the requested phase and the corresponding request label is not required. + +| Agent workflow | Applied by | Meaning | +|---|---|---| +| `agent:plan-requested` | Maintainer | Ask an agent to produce an implementation plan. | +| `agent:plan-ready` | Agent | The plan is ready for human review. | +| `agent:implementation-requested` | Maintainer | The plan is approved and an agent may implement it. | +| `agent:in-progress` | Agent | Authorized implementation is underway. | +| `agent:pr-opened` | Agent | The implementation produced a pull request. | + +The normal delegated workflow is: + +```text +state:accepted + | + +-- agent:plan-requested + | + +-- agent:plan-ready + | + +-- agent:implementation-requested + | + +-- agent:in-progress + | + +-- agent:pr-opened +``` + +The two request labels are deliberate queue controls: + +- `agent:plan-requested` authorizes an unattended agent to pick up planning, not implementation. +- `agent:implementation-requested` confirms that a human reviewed the plan and authorizes an unattended agent to pick up implementation. + +An unattended agent replaces the current workflow label as it completes each authorized phase. It does not infer authorization from `state:accepted`, roadmap placement, comments, or the absence of objections. A direct user request is separate explicit authorization, but only for the phase requested. + +## Handle Spikes + +Use a spike when the report is credible but technical uncertainty prevents a buildable plan. The triage assessment should identify the unknowns and the evidence the spike needs to produce. + +A maintainer first decides whether OpenShell should invest in the investigation. If accepted, the maintainer places it on the roadmap and may request agent work. The spike records its findings in an issue and uses: + +- `state:validated` when the evidence supports a human accept or decline decision. +- `state:needs-info` when material evidence or an external decision is still missing. + +A completed spike does not automatically authorize implementation. The resulting issue follows the same human disposition process, after which a user can directly request agent work or use the optional queue labels. + +## Handle Security Issues + +Do not file or discuss suspected vulnerabilities in a public GitHub issue. Follow the disclosure instructions in `SECURITY.md`. + +Maintainers use the specialized security review and remediation workflow for an authorized security issue. For unattended processing, it uses the same queue controls: + +1. A maintainer applies `agent:plan-requested` to request a security review and remediation plan. +2. The review agent replaces it with `agent:plan-ready`. +3. A maintainer reviews the plan and applies `agent:implementation-requested`. +4. The remediation agent implements the approved plan. + +A user may instead directly request review or remediation from the specialized skill. The direct request replaces the corresponding queue label, but a request for review still does not authorize remediation. + +General implementation agents do not process issues labeled `topic:security`. + +## Know When an Issue Is Ready for Work + +Use these checks before starting: + +| You are | Ready when | +|---|---| +| A human contributor | The issue has `state:accepted`, invites contribution or has maintainer confirmation, and has no conflicting owner or implementation. | +| An unattended agent scanning for planning work | The issue has `state:accepted` and the human-applied `agent:plan-requested` label. | +| An unattended agent scanning for implementation work | The issue has `state:accepted`, an approved plan, and the human-applied `agent:implementation-requested` label. | +| An agent directly instructed by a user | The issue has `state:accepted`, no conflicting owner or implementation, and the instruction explicitly requests the phase the agent will perform. | + +Issues with `state:triage-needed`, `state:needs-info`, or `state:validated` are not ready for implementation. Roadmap placement alone never makes an issue ready. + +## Link Pull Requests to Decisions + +Pull requests for features, user-visible behavior, public APIs, architecture changes, or multi-pull-request efforts must link an accepted issue. Use `Fixes #NNN` or `Closes #NNN` in the pull request's **Related Issue** section. + +Small documentation fixes, mechanical maintenance, and obvious localized bug fixes may omit a separate issue when the pull request provides enough context to review the decision and implementation together. State why no issue is required.